@letrquan/book 0.3.0 → 0.4.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +1024 -0
  2. package/README.md +6 -3
  3. package/dist/{additional-roots-H7UNAEHS.js → additional-roots-VAWRQ625.js} +8 -7
  4. package/dist/{app-GE4OHJOC.js → app-J7BVPSUH.js} +5397 -2953
  5. package/dist/app-J7BVPSUH.js.map +1 -0
  6. package/dist/chunk-32WBCUAN.js +660 -0
  7. package/dist/chunk-32WBCUAN.js.map +1 -0
  8. package/dist/{chunk-525CAZPY.js → chunk-4DKHLZRI.js} +6 -6
  9. package/dist/{chunk-4AS7LKKQ.js → chunk-62EEAUID.js} +2 -2
  10. package/dist/{chunk-AQEQX4FF.js → chunk-AHC7OU75.js} +385 -55
  11. package/dist/chunk-AHC7OU75.js.map +1 -0
  12. package/dist/{chunk-EFJ2NH6E.js → chunk-AJZWLKLQ.js} +63 -14
  13. package/dist/chunk-AJZWLKLQ.js.map +1 -0
  14. package/dist/chunk-B5FC3MYZ.js +395 -0
  15. package/dist/chunk-B5FC3MYZ.js.map +1 -0
  16. package/dist/{chunk-67UZEWWF.js → chunk-DNFQTSMJ.js} +53 -11
  17. package/dist/chunk-DNFQTSMJ.js.map +1 -0
  18. package/dist/{chunk-TLX3H2CL.js → chunk-E5WLQSKA.js} +231 -40
  19. package/dist/chunk-E5WLQSKA.js.map +1 -0
  20. package/dist/chunk-ECLC4CIJ.js +1181 -0
  21. package/dist/chunk-ECLC4CIJ.js.map +1 -0
  22. package/dist/chunk-EEX6QNXV.js +127 -0
  23. package/dist/chunk-EEX6QNXV.js.map +1 -0
  24. package/dist/chunk-EFXVSQ5J.js +931 -0
  25. package/dist/chunk-EFXVSQ5J.js.map +1 -0
  26. package/dist/{chunk-RFJ6Q6LE.js → chunk-ENLB7NYV.js} +577 -164
  27. package/dist/chunk-ENLB7NYV.js.map +1 -0
  28. package/dist/{chunk-IME7R2UI.js → chunk-FPR7SKIE.js} +1268 -883
  29. package/dist/chunk-FPR7SKIE.js.map +1 -0
  30. package/dist/{chunk-VPNLCMVR.js → chunk-HFB74CLM.js} +13 -5
  31. package/dist/chunk-HFB74CLM.js.map +1 -0
  32. package/dist/{chunk-5RDRAO4B.js → chunk-HOZXKOE3.js} +37 -1
  33. package/dist/chunk-HOZXKOE3.js.map +1 -0
  34. package/dist/chunk-IDYWN37T.js +36 -0
  35. package/dist/chunk-IDYWN37T.js.map +1 -0
  36. package/dist/{chunk-YC6W4EJH.js → chunk-JGF5HLSI.js} +193 -75
  37. package/dist/chunk-JGF5HLSI.js.map +1 -0
  38. package/dist/{chunk-5YHTKWJN.js → chunk-KDNWMKXV.js} +2447 -907
  39. package/dist/chunk-KDNWMKXV.js.map +1 -0
  40. package/dist/{chunk-Y2VHN7TC.js → chunk-MEOB2DZA.js} +11 -1
  41. package/dist/chunk-MEOB2DZA.js.map +1 -0
  42. package/dist/{chunk-KBQS35OV.js → chunk-MV5PQNIA.js} +2 -2
  43. package/dist/chunk-N2G4Q7ME.js +2672 -0
  44. package/dist/chunk-N2G4Q7ME.js.map +1 -0
  45. package/dist/{chunk-62QL5QUP.js → chunk-OJBMDM5H.js} +17 -1
  46. package/dist/chunk-OJBMDM5H.js.map +1 -0
  47. package/dist/{chunk-56SIEMDX.js → chunk-PTDC7ZUP.js} +2 -2
  48. package/dist/{chunk-X4NJT436.js → chunk-REASC2QG.js} +67 -28
  49. package/dist/chunk-REASC2QG.js.map +1 -0
  50. package/dist/chunk-SBTU5BEC.js +114 -0
  51. package/dist/chunk-SBTU5BEC.js.map +1 -0
  52. package/dist/{chunk-HQI7NYGX.js → chunk-SWPDKLNM.js} +2 -2
  53. package/dist/{chunk-W3XFHEF4.js → chunk-UCFJ43OS.js} +140 -28
  54. package/dist/chunk-UCFJ43OS.js.map +1 -0
  55. package/dist/{chunk-QYBD22H5.js → chunk-W7SLYS3M.js} +80 -16
  56. package/dist/chunk-W7SLYS3M.js.map +1 -0
  57. package/dist/{chunk-SOW4WRQP.js → chunk-WV3O5PGX.js} +3 -3
  58. package/dist/{chunk-JTPOI3KU.js → chunk-XJRJVXJR.js} +262 -38
  59. package/dist/chunk-XJRJVXJR.js.map +1 -0
  60. package/dist/{chunk-224FJZLH.js → chunk-YIL6HTJX.js} +228 -5
  61. package/dist/chunk-YIL6HTJX.js.map +1 -0
  62. package/dist/{command-approvals-VBIU6BLM.js → command-approvals-ZRY66LCW.js} +5 -4
  63. package/dist/context-C3RAP6K5.js +41 -0
  64. package/dist/{hook-approvals-ZVT4V7IM.js → hook-approvals-DPQD5H65.js} +5 -4
  65. package/dist/index.js +657 -754
  66. package/dist/index.js.map +1 -1
  67. package/dist/{interactive-assets-T4I4SEHU.js → interactive-assets-73AQO5WP.js} +11 -6
  68. package/dist/{interactive-assets-T4I4SEHU.js.map → interactive-assets-73AQO5WP.js.map} +1 -1
  69. package/dist/job-runner.js +10 -3
  70. package/dist/job-runner.js.map +1 -1
  71. package/dist/job-supervisor.js +13 -4
  72. package/dist/job-supervisor.js.map +1 -1
  73. package/dist/loader-DQNPDKOX.js +27 -0
  74. package/dist/{mcp-approvals-HJ2VDYMC.js → mcp-approvals-27LJYADQ.js} +5 -4
  75. package/dist/{mcp-config-RNB5LEVE.js → mcp-config-GXSODNCM.js} +3 -2
  76. package/dist/memory-store-I6Z54VUN.js +51 -0
  77. package/dist/{model-window-store-MTSQ5JDJ.js → model-window-store-6VKXXTPJ.js} +4 -3
  78. package/dist/{openai-compatible-2OB54YST.js → openai-compatible-IPUNBJ53.js} +5 -3
  79. package/dist/{permission-approvals-YLV6UC5W.js → permission-approvals-Q5IMFEZI.js} +5 -4
  80. package/dist/{permissions-DHOKF3W2.js → permissions-7Y35X6HZ.js} +26 -9
  81. package/dist/provider-approvals-5AGH3RVT.js +76 -0
  82. package/dist/{sandbox-WRYTZH3D.js → sandbox-N2RY72GN.js} +6 -5
  83. package/dist/{scrollback-35ME2GFX.js → scrollback-GD76GNM4.js} +36 -28
  84. package/dist/scrollback-GD76GNM4.js.map +1 -0
  85. package/dist/sdk.d.ts +876 -64
  86. package/dist/sdk.js +57 -37
  87. package/dist/sdk.js.map +1 -1
  88. package/dist/settings-loader-KDBH45AQ.js +43 -0
  89. package/dist/{settings-removed-JWWPT4WA.js → settings-removed-3ATWJEF3.js} +2 -2
  90. package/dist/shell-selection-Z5WORZU4.js +31 -0
  91. package/dist/shell-selection-Z5WORZU4.js.map +1 -0
  92. package/package.json +5 -5
  93. package/dist/app-GE4OHJOC.js.map +0 -1
  94. package/dist/chunk-224FJZLH.js.map +0 -1
  95. package/dist/chunk-5RDRAO4B.js.map +0 -1
  96. package/dist/chunk-5YHTKWJN.js.map +0 -1
  97. package/dist/chunk-62QL5QUP.js.map +0 -1
  98. package/dist/chunk-67UZEWWF.js.map +0 -1
  99. package/dist/chunk-6OQQOMZR.js +0 -785
  100. package/dist/chunk-6OQQOMZR.js.map +0 -1
  101. package/dist/chunk-AQEQX4FF.js.map +0 -1
  102. package/dist/chunk-C7ADUNPR.js +0 -273
  103. package/dist/chunk-C7ADUNPR.js.map +0 -1
  104. package/dist/chunk-EFJ2NH6E.js.map +0 -1
  105. package/dist/chunk-IME7R2UI.js.map +0 -1
  106. package/dist/chunk-J62VZYOB.js +0 -1339
  107. package/dist/chunk-J62VZYOB.js.map +0 -1
  108. package/dist/chunk-JTPOI3KU.js.map +0 -1
  109. package/dist/chunk-QYBD22H5.js.map +0 -1
  110. package/dist/chunk-RFJ6Q6LE.js.map +0 -1
  111. package/dist/chunk-S4JMID4G.js +0 -259
  112. package/dist/chunk-S4JMID4G.js.map +0 -1
  113. package/dist/chunk-TLX3H2CL.js.map +0 -1
  114. package/dist/chunk-VPNLCMVR.js.map +0 -1
  115. package/dist/chunk-W3XFHEF4.js.map +0 -1
  116. package/dist/chunk-X4NJT436.js.map +0 -1
  117. package/dist/chunk-X66I2NQO.js +0 -137
  118. package/dist/chunk-X66I2NQO.js.map +0 -1
  119. package/dist/chunk-Y2VHN7TC.js.map +0 -1
  120. package/dist/chunk-YC6W4EJH.js.map +0 -1
  121. package/dist/context-CBOBDY5Q.js +0 -38
  122. package/dist/loader-S77OVTHH.js +0 -18
  123. package/dist/memory-store-DZUT5HUH.js +0 -75
  124. package/dist/scrollback-35ME2GFX.js.map +0 -1
  125. package/dist/settings-loader-JUNPGAAM.js +0 -35
  126. package/dist/shell-selection-CDHGJ4GC.js +0 -17
  127. /package/dist/{additional-roots-H7UNAEHS.js.map → additional-roots-VAWRQ625.js.map} +0 -0
  128. /package/dist/{chunk-525CAZPY.js.map → chunk-4DKHLZRI.js.map} +0 -0
  129. /package/dist/{chunk-4AS7LKKQ.js.map → chunk-62EEAUID.js.map} +0 -0
  130. /package/dist/{chunk-KBQS35OV.js.map → chunk-MV5PQNIA.js.map} +0 -0
  131. /package/dist/{chunk-56SIEMDX.js.map → chunk-PTDC7ZUP.js.map} +0 -0
  132. /package/dist/{chunk-HQI7NYGX.js.map → chunk-SWPDKLNM.js.map} +0 -0
  133. /package/dist/{chunk-SOW4WRQP.js.map → chunk-WV3O5PGX.js.map} +0 -0
  134. /package/dist/{command-approvals-VBIU6BLM.js.map → command-approvals-ZRY66LCW.js.map} +0 -0
  135. /package/dist/{context-CBOBDY5Q.js.map → context-C3RAP6K5.js.map} +0 -0
  136. /package/dist/{hook-approvals-ZVT4V7IM.js.map → hook-approvals-DPQD5H65.js.map} +0 -0
  137. /package/dist/{loader-S77OVTHH.js.map → loader-DQNPDKOX.js.map} +0 -0
  138. /package/dist/{mcp-approvals-HJ2VDYMC.js.map → mcp-approvals-27LJYADQ.js.map} +0 -0
  139. /package/dist/{mcp-config-RNB5LEVE.js.map → mcp-config-GXSODNCM.js.map} +0 -0
  140. /package/dist/{memory-store-DZUT5HUH.js.map → memory-store-I6Z54VUN.js.map} +0 -0
  141. /package/dist/{model-window-store-MTSQ5JDJ.js.map → model-window-store-6VKXXTPJ.js.map} +0 -0
  142. /package/dist/{openai-compatible-2OB54YST.js.map → openai-compatible-IPUNBJ53.js.map} +0 -0
  143. /package/dist/{permission-approvals-YLV6UC5W.js.map → permission-approvals-Q5IMFEZI.js.map} +0 -0
  144. /package/dist/{permissions-DHOKF3W2.js.map → permissions-7Y35X6HZ.js.map} +0 -0
  145. /package/dist/{sandbox-WRYTZH3D.js.map → provider-approvals-5AGH3RVT.js.map} +0 -0
  146. /package/dist/{settings-loader-JUNPGAAM.js.map → sandbox-N2RY72GN.js.map} +0 -0
  147. /package/dist/{settings-removed-JWWPT4WA.js.map → settings-loader-KDBH45AQ.js.map} +0 -0
  148. /package/dist/{shell-selection-CDHGJ4GC.js.map → settings-removed-3ATWJEF3.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tui/app.tsx","../src/tui/layout.ts","../src/tui/global-key-handler.tsx","../src/tui/components/ChatPanel.tsx","../src/tui/components/AgentMessage.tsx","../src/tui/components/Spinner.tsx","../src/tui/hooks/useAnimation.ts","../src/tui/scroll-activity.ts","../src/tui/ui-clock.ts","../src/tui/shimmer.ts","../src/tui/quill.ts","../src/tui/components/ToolCallBlock.tsx","../src/tui/components/Diff.tsx","../src/tui/components/word-wrap.ts","../src/tui/components/syntax-highlight.ts","../src/tui/components/MarkdownBlock.tsx","../src/tui/density.tsx","../src/tui/transcript-layout.ts","../src/tui/marks.ts","../src/tui/components/markdown-layout.ts","../src/tui/components/tool-output.ts","../src/tui/file-mutation-display.ts","../src/tui/steps.ts","../src/tui/tool-presentation.ts","../src/tui/components/SubagentRow.tsx","../src/tui/components/tool-row-interactions.tsx","../src/tui/components/CommandPanel.tsx","../src/tui/components/chrome.tsx","../src/tui/tool-traces.ts","../src/tui/components/ManagedAgentActivityBlock.tsx","../src/tui/components/QuietToolRun.tsx","../src/tui/quiet-tools.ts","../src/tui/debug.ts","../src/tui/components/transcript-messages.ts","../src/tui/components/UserMessage.tsx","../src/tui/components/WelcomeScreen.tsx","../src/tui/relative-age.ts","../src/tui/roman.ts","../src/tui/components/virtual-transcript.tsx","../src/tui/components/InputBar.tsx","../src/tui/components/CommandMenu.tsx","../src/tui/components/FileMentionMenu.tsx","../src/tui/components/SkillMentionMenu.tsx","../src/input/skill-mentions.ts","../src/commands/recent.ts","../src/commands/filter.ts","../src/tui/mouse.ts","../src/tui/components/InputBox.tsx","../src/tui/line-edit.ts","../src/tui/components/QueuedInputPreview.tsx","../src/tui/components/StatusLine.tsx","../src/tui/mode-style.ts","../src/tui/components/WorkingIndicator.tsx","../src/tui/working-activity.ts","../src/tui/components/StartupFire.tsx","../src/tui/startup-fire.ts","../src/tui/startup-fire-frame.ts","../src/tui/components/CompactDiffCard.tsx","../src/tui/components/ErrorBoundary.tsx","../src/tui/components/TaskList.tsx","../src/tui/status-indicators.ts","../src/tui/components/StepsSheet.tsx","../src/tui/components/ModelPicker.tsx","../src/tui/components/TextInputField.tsx","../src/tui/hooks/useKeyState.ts","../src/provider/model-discovery.ts","../src/tui/model-options.ts","../src/tui/components/ByokWizard.tsx","../src/tui/components/model-picker-hints.ts","../src/tui/components/EffortPicker.tsx","../src/tui/components/ListPicker.tsx","../src/tui/components/PermissionModePicker.tsx","../src/tui/components/ConfigMenu.tsx","../src/tui/components/SkillManager.tsx","../src/tui/components/AgentProfilePicker.tsx","../src/tui/components/SessionPicker.tsx","../src/tui/components/RewindPicker.tsx","../src/tui/components/TranscriptView.tsx","../src/tui/transcript-scroll.ts","../src/tui/clipboard.ts","../src/tui/text-selection.ts","../src/tui/selection-highlight.ts","../src/tui/components/PermissionButtons.tsx","../src/tui/hooks/useReportLayout.ts","../src/tools/mutation-preview.ts","../src/tui/components/HelpPanel.tsx","../src/tui/help-catalog.ts","../src/tui/components/PlanApprovalButtons.tsx","../src/tui/components/AskUserQuestionWizard.tsx","../src/tui/components/McpElicitationForm.tsx","../src/tui/components/McpServerApprovalPrompt.tsx","../src/tui/hooks/useAgent.ts","../src/tui/hooks/streaming-state.ts","../src/tui/persist.ts","../src/session/interactive-session.ts","../src/tui/hooks/message-accumulator.ts","../src/tui/hooks/useTasks.ts","../src/tui/hooks/useManagedAgents.ts","../src/tui/hooks/useBackgroundShells.ts","../src/tui/hooks/useGitStatus.ts","../src/tui/hooks/useAgentCompletionDelivery.ts","../src/tui/components/SubagentPanel.tsx","../src/tui/components/BackgroundShellRow.tsx","../src/tui/components/SubagentDetail.tsx","../src/tui/components/BackgroundShellDetail.tsx","../src/tui/managed-agent-transcript.ts","../src/tui/markdown-inline.ts","../src/agents/importer.ts","../src/tui/components/PermissionsPanel.tsx","../src/tui/queued-inputs.ts","../src/input/clipboard-image.ts"],"sourcesContent":["import { Box, Text, useStdout, useApp, type Key } from 'ink';\nimport {\n useState,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n type ReactNode,\n} from 'react';\nimport { panelContentWidth, panelGrid } from './layout.js';\nimport { GlobalKeyHandler } from './global-key-handler.js';\nimport { ChatPanel } from './components/ChatPanel.js';\nimport { InputBar } from './components/InputBar.js';\nimport { QueuedInputPreview, type FlashNotice } from './components/QueuedInputPreview.js';\nimport { StatusLine } from './components/StatusLine.js';\nimport { WorkingIndicator } from './components/WorkingIndicator.js';\nimport { StartupFire } from './components/StartupFire.js';\nimport { CompactDiffCard } from './components/CompactDiffCard.js';\nimport { ErrorBoundary } from './components/ErrorBoundary.js';\nimport { TaskList } from './components/TaskList.js';\nimport { StepsSheet } from './components/StepsSheet.js';\nimport { statusStepLabel } from './steps.js';\nimport { ModelPicker, type ProviderRemovalResult } from './components/ModelPicker.js';\nimport { EffortPicker } from './components/EffortPicker.js';\nimport { PermissionModePicker } from './components/PermissionModePicker.js';\nimport { ConfigMenu, type ConfigSection } from './components/ConfigMenu.js';\nimport { SkillManager } from './components/SkillManager.js';\nimport { AgentProfilePicker } from './components/AgentProfilePicker.js';\nimport { SessionPicker } from './components/SessionPicker.js';\nimport { RewindPicker } from './components/RewindPicker.js';\nimport { TranscriptView, type TranscriptScrollRequest } from './components/TranscriptView.js';\nimport { PermissionButtons } from './components/PermissionButtons.js';\nimport { HelpPanel } from './components/HelpPanel.js';\nimport { KeyValueList, SoftPanel } from './components/chrome.js';\nimport { PlanApprovalActions, PlanApprovalDetails } from './components/PlanApprovalButtons.js';\nimport { AskUserQuestionWizard } from './components/AskUserQuestionWizard.js';\nimport { McpElicitationForm } from './components/McpElicitationForm.js';\nimport { McpServerApprovalPrompt } from './components/McpServerApprovalPrompt.js';\nimport { useAgent } from './hooks/useAgent.js';\nimport { useTasks } from './hooks/useTasks.js';\nimport { useManagedAgents } from './hooks/useManagedAgents.js';\nimport { useBackgroundShells } from './hooks/useBackgroundShells.js';\nimport { useGitStatus } from './hooks/useGitStatus.js';\nimport { useAgentCompletionDelivery } from './hooks/useAgentCompletionDelivery.js';\nimport { SubagentPanel } from './components/SubagentPanel.js';\nimport { SubagentDetail } from './components/SubagentDetail.js';\nimport { BackgroundShellDetail } from './components/BackgroundShellDetail.js';\nimport { projectManagedAgentTraces } from './managed-agent-transcript.js';\nimport { inlineCode } from './markdown-inline.js';\nimport {\n ThemeContext,\n resolveTheme,\n DEFAULT_THEME_NAME,\n RUBRIC_THEME,\n type ThemeTokens,\n type ResolvedTheme,\n} from './theme.js';\nimport type { AgentConfig, PermissionMode } from '../types/runtime.js';\nimport type { McpHostSnapshot, McpSessionHost } from '../mcp-host.js';\nimport { resolvePermissionMode } from '../permission-mode.js';\nimport type { ImageAttachment } from '../types/messages.js';\nimport type { CommandContext } from '../types/commands.js';\nimport type { RewindSnapshotStoreInterface, SessionStoreInterface } from '../types/sessions.js';\nimport type { SessionBootstrap } from '../session/resolve.js';\nimport { displaySessionName } from '../session/name.js';\nimport { DensityContext, resolveTuiDensity } from './density.js';\nimport { discoverCommands, resolveCommandBody } from '../commands/loader.js';\nimport { commandEnforcementContext, parseSlashInput } from '../commands/resolve.js';\nimport {\n createBuiltinCommandRegistry,\n type BuiltinCommandContext,\n type BuiltinCommandEffect,\n} from '../commands/builtins.js';\nimport { discoverSkills, type Skill } from '../skills.js';\nimport { runGit } from '../tools/git.js';\nimport { getMemoryIndex } from '../memory-display.js';\nimport { discoverClaudeMd } from '../claude-md.js';\nimport { discoverAgents } from '../subagent-discovery.js';\nimport { withBuiltInAgents } from '../agents/profiles.js';\nimport { ShellJobManager } from '../jobs/shell-manager.js';\nimport { buildModelOptions } from './model-options.js';\nimport { createUiDebugLogger } from '../debug-log.js';\nimport { createDefaultRegistry } from '../tools/registry.js';\nimport { getOrCreateAgentManager, type AgentManager } from '../agents/manager.js';\nimport { installAgentImports, previewAgentImport } from '../agents/importer.js';\nimport { runHostReview } from '../review/host.js';\nimport { fixRunnerFor, reviewRunnerFor } from '../review/runner.js';\nimport type { ReviewScope } from '../review/types.js';\nimport { join } from 'path';\nimport { selectExpandedToolId, selectLatestToolId } from './tool-traces.js';\nimport { halfPageScrollDirection, pagerChordsAvailable } from './transcript-scroll.js';\nimport {\n getTranscriptShortcutAction,\n isShortcutsToggleKey,\n type TranscriptMode,\n} from './tool-presentation.js';\nimport { permissionResultOf } from '../permissions.js';\nimport { startupAnimationEnvNote } from '../settings-loader.js';\nimport { PermissionsPanel } from './components/PermissionsPanel.js';\nimport { useDebugMount, useDebugValueChange } from './debug.js';\nimport { getAvailableEffortLevels, getEffortUnavailableError } from '../commands/effort.js';\nimport type { InteractiveAssets } from './interactive-assets.js';\nimport { resolveContextWindow, stripProvider } from '../models.js';\nimport { wordWrap } from './components/word-wrap.js';\nimport { foldControlCharacters } from '../control-characters.js';\nimport { countWrittenTurns } from './components/transcript-messages.js';\nimport {\n createQueuedInput,\n enqueueQueuedInput,\n recallNewestQueuedInput,\n restoreQueuedInputAttachments,\n restoreQueuedInputText,\n shouldRequeueQueuedSend,\n type QueuedInput,\n} from './queued-inputs.js';\nimport { readClipboardImage } from '../input/clipboard-image.js';\nimport { stripSgrMouseSequences } from './mouse.js';\n\nconst uiLog = createUiDebugLogger('tui:app');\nconst MAIN_TRANSCRIPT_SCOPE = 'main';\nconst EMPTY_TOOL_EXPANSION_OVERRIDES = new Map<string, boolean>();\nconst EMPTY_SHOW_ALL_TOOL_OUTPUT_IDS = new Set<string>();\n/** Duration of the idle Ctrl+C exit confirmation window. */\nexport const CTRL_C_EXIT_HINT_MS = 2_000;\nexport const CTRL_C_EXIT_HINT_TEXT = 'Press Ctrl+C again to exit';\n\nexport function ownsModalInput(\n pendingPermission: unknown,\n pendingPlanApproval: unknown,\n showModelPicker: boolean,\n showSessionPicker = false,\n pendingUserQuestion?: unknown,\n showEffortPicker = false,\n showRewindPicker = false,\n showConfigPicker = false,\n showAgentProfilePicker = false,\n showPermissionModePicker = false,\n showSkills = false,\n pendingMcpApproval: unknown = undefined,\n pendingElicitation: unknown = undefined,\n): boolean {\n return Boolean(\n pendingPermission ||\n pendingPlanApproval ||\n pendingUserQuestion ||\n pendingElicitation ||\n showModelPicker ||\n showSessionPicker ||\n showEffortPicker ||\n showPermissionModePicker ||\n showRewindPicker ||\n showConfigPicker ||\n showAgentProfilePicker ||\n showSkills ||\n pendingMcpApproval,\n );\n}\n\nexport function shouldPlayStartupFire(config: AgentConfig, session: SessionBootstrap): boolean {\n return Boolean(\n config.settings.ui.startupAnimation &&\n !config.accessibility.screenReader &&\n !config.accessibility.reducedMotion &&\n session.source === 'startup' &&\n session.created &&\n (session.transcript ?? session.history).length === 0,\n );\n}\n\nfunction containsDraftInput(input: string): boolean {\n return Array.from(input).some((character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint >= 0x20 && codePoint !== 0x7f;\n });\n}\n\n/**\n * The read-only reference sheets, at most one of which is open at a time.\n *\n * They are all the same kind of surface — a pinned block of text the user opened\n * deliberately and expects Esc to close — so they share one slot rather than a\n * boolean each.\n */\ntype ReferencePanel = 'help' | 'status' | 'permissions' | 'shortcuts' | 'steps' | 'tasks';\n\nexport function providerRemovalMessage(\n result: Extract<ProviderRemovalResult, { ok: true }>,\n): string {\n if (result.inheritedProviderRevealed) {\n return `Removed the local ${result.providerId} override; the inherited ${result.providerId} provider remains configured.`;\n }\n if (result.switched) {\n return `Removed local BYOK provider ${result.providerId} and switched to ${result.activeModel}.`;\n }\n const models = `${result.removedModelCount} model${result.removedModelCount === 1 ? '' : 's'}`;\n return `Removed local BYOK provider ${result.providerId} and its ${models}.`;\n}\n\n/**\n * Sequencing lives in `review/host.ts` so print mode runs the identical steps.\n * The TUI is the host that can apply patches, so it is the one that supplies a\n * fix runner, and it renders each segment as it is produced rather than waiting\n * for the (minutes-long) fix pass to finish.\n *\n * `parentSessionId` is what puts the reviewer, lens, verifier and patcher agents\n * in this session's agent panel and status line while they work; the runner\n * suppresses their completion notifications separately, so live progress costs\n * no extra model turn.\n */\nasync function runReviewCommand(\n scope: ReviewScope,\n manager: AgentManager,\n workspace: string,\n sessionId: string,\n report: (message: string) => void,\n signal: AbortSignal,\n hostRun: { rootRunId: string; runId: string },\n): Promise<void> {\n // One session-owned root for the whole pipeline, the way print mode spawns its\n // reviewers. Without a `rootRunId` each reviewer, lens and verifier becomes its\n // own root — and a root the session never registered, so no flush ever wrote\n // their spend and a resume restored a carry that had never been charged.\n const attribution = {\n parentSessionId: sessionId,\n rootRunId: hostRun.rootRunId,\n parentRunId: hostRun.runId,\n };\n await runHostReview({\n scope,\n workspace,\n runner: reviewRunnerFor(manager, attribution),\n fixRunner: fixRunnerFor(manager, attribution),\n onSegment: report,\n signal,\n });\n}\n\n/** Status text for a review in flight. Names the passes so the wait has a shape. */\nfunction reviewStatusLabel(scope: ReviewScope): string {\n if (scope.fix) return 'Reviewing, then applying verified fixes';\n if (scope.deep) return 'Deep review: four lenses, then verification';\n return 'Review in progress';\n}\n\nconst EMPTY_MCP_SNAPSHOT: McpHostSnapshot = { servers: [], pendingApprovals: [], events: [] };\n\ninterface AppProps {\n config: AgentConfig;\n permissionMode?: PermissionMode;\n interactiveAssets?: InteractiveAssets;\n /** Session MCP owner; servers connect in the background and tools join per send. */\n mcp?: McpSessionHost;\n session: SessionBootstrap & {\n store?: SessionStoreInterface;\n timelineStore?: SessionStoreInterface;\n snapshotStore?: RewindSnapshotStoreInterface;\n };\n redrawViewport?: () => void;\n}\n\nconst QUEUED_SEND_NOTICE = 'Sending queued follow-up...';\nconst QUEUE_PAUSED_NOTICE = 'Queue paused. Up then Enter resumes it; /queue clear drops it.';\n\nfunction capitalize(word: string): string {\n return word ? word[0]!.toUpperCase() + word.slice(1) : word;\n}\n\n/** One empty list, so a pending title page does not hand ChatPanel a new array each render. */\nconst NO_RECENT_SESSIONS: readonly never[] = [];\n\n/**\n * Full-screen interactive TUI with an application-owned transcript viewport.\n *\n * The transcript scrolls independently while approvals, input, and status stay\n * visible. The default CLI enters the alternate screen; --scrollback preserves\n * linear terminal-owned history as an accessibility/fallback mode.\n *\n * Layout (top to bottom):\n * 1. Scrollable transcript and informational panels\n * 2. Fixed approval/picker interaction area\n * 3. Working indicator, input bar, and status line\n *\n * Keyboard shortcuts:\n * Esc — cancel permission / abort stream\n * Ctrl+C — abort stream; when idle, clears a non-empty composer, or\n * press twice within CTRL_C_EXIT_HINT_MS to exit\n * Ctrl+T — toggle the agent's steps\n * Ctrl+O — toggle detailed transcript\n * Ctrl+E — expand the current tool output\n * Ctrl+L — redraw\n * Ctrl+J — insert newline\n * PgUp/PgDn, Ctrl+U/Ctrl+D — scroll transcript\n * Ctrl+Home/Ctrl+End — jump to transcript start/latest\n * Mouse wheel — scroll transcript\n * Drag — select and copy visible text\n * Shift+drag — terminal-native selection fallback\n * Alt+M — cycle permission mode\n * Alt+P — open model picker\n * Alt+V — attach clipboard image\n * Shift+Tab — cycle permission mode\n * Ctrl+/ — toggle keyboard shortcuts reference\n */\nexport function App({\n config,\n permissionMode,\n session,\n redrawViewport: wipeViewport,\n interactiveAssets,\n mcp,\n}: AppProps) {\n const {\n messages,\n contextHistory,\n compactBoundaries,\n isThinking,\n isCompacting,\n isCompactCommitted,\n isRewinding,\n compactUi,\n streamingMessageId,\n error,\n currentTurn,\n tokenCount,\n usage,\n sessionUsage,\n sessionUsageSinceResume,\n mode,\n pendingPermission,\n pendingPlanApproval,\n pendingUserQuestion,\n pendingUserQuestionCount,\n pendingElicitation,\n pendingElicitationCount,\n resolveElicitation,\n elicitationHandler,\n agentTodos,\n agentPlanCurrent,\n liveConfig,\n runtime,\n removableProviderIds,\n removableProviderModelCounts,\n sessionId,\n sessionName,\n send,\n sendAgentCompletions,\n sendBackgroundShellCompletion,\n startHostRun,\n clear,\n startNewConversation,\n resumeConversation,\n listSessions,\n endCurrentSession,\n resolvePermission,\n resolvePlanApproval,\n resolveUserQuestion,\n cancel,\n compact,\n rewind,\n getRewindTargets,\n cycleMode,\n addLocalMessage,\n setModel,\n upsertProviderAndSelect,\n removeProvider,\n setEffort,\n setAgentProfileModel,\n setCompactModel,\n setSkillActivation,\n setSkillExecution,\n setSkillsEnabled,\n setMemoryAutoSave,\n toggleMemoryAutoSave,\n toggleShowThinking,\n toggleStartupAnimation,\n refreshMemoryContext,\n persistPermissionRule,\n removePermissionRule,\n setDefaultPermissionMode,\n turnDurationMs,\n retryPhase,\n retryAttempt,\n retryMax,\n retryCountdownMs,\n } = useAgent(config, {\n ...session,\n permissionMode,\n additionalTools: mcp ? () => mcp.getToolDefinitions() : undefined,\n });\n\n const managedAgentManager = useMemo(\n () =>\n getOrCreateAgentManager(\n liveConfig,\n createDefaultRegistry({ agents: true }).getDefinitions(),\n {\n runtime,\n permissionMode: mode,\n persistPermissionRule,\n },\n ),\n [liveConfig, mode, persistPermissionRule, runtime],\n );\n const managedAgents = useManagedAgents(managedAgentManager, sessionId);\n const shellManager = useMemo(() => {\n const resolved = runtime?.shellManager ?? new ShellJobManager({ nextId: 1, shells: new Map() });\n resolved.configureWorkspace(liveConfig.workspace);\n return resolved;\n }, [liveConfig.workspace, runtime]);\n const backgroundShells = useBackgroundShells(shellManager, sessionId);\n // Branch and dirty state are what people glance at the footer for; the hook\n // existed with no consumer before the status line was reworked.\n const gitStatus = useGitStatus(config.workspace);\n\n const [startupFireActive, setStartupFireActive] = useState(() =>\n shouldPlayStartupFire(config, session),\n );\n // The four reference sheets share one slot. They were four independent\n // booleans, so `/help` then `/status` pinned 43 rows of chrome above the\n // composer and pushed the conversation off a 40-row terminal entirely. One\n // slot makes that impossible rather than merely discouraged, and gives Esc a\n // single thing to close.\n const [referencePanel, setReferencePanel] = useState<ReferencePanel | null>(null);\n const showHelp = referencePanel === 'help';\n const showShortcuts = referencePanel === 'shortcuts';\n const showStatus = referencePanel === 'status';\n const [showAllDetailedOutput, setShowAllDetailedOutput] = useState(false);\n const [showAllToolOutputIdsByTranscript, setShowAllToolOutputIdsByTranscript] = useState<\n Map<string, Set<string>>\n >(() => new Map());\n const [transcriptMode, setTranscriptMode] = useState<TranscriptMode>('compact');\n const [toolExpansionOverridesByTranscript, setToolExpansionOverridesByTranscript] = useState<\n Map<string, Map<string, boolean>>\n >(() => new Map());\n const [focusedToolIdsByTranscript, setFocusedToolIdsByTranscript] = useState<Map<string, string>>(\n () => new Map(),\n );\n const showPermissions = referencePanel === 'permissions';\n const [showSkills, setShowSkills] = useState(false);\n const [showModelPicker, setShowModelPicker] = useState(false);\n const [showEffortPicker, setShowEffortPicker] = useState(false);\n const [showPermissionModePicker, setShowPermissionModePicker] = useState(false);\n const [showConfigPicker, setShowConfigPicker] = useState(false);\n const [showAgentProfilePicker, setShowAgentProfilePicker] = useState(false);\n /**\n * The `/config` row a sub-picker was opened from, or null when it was opened\n * directly by its own command.\n *\n * `/config` is the only surface that exists to be *browsed* — it is the one\n * place the two settings with no command of their own (compact model,\n * subagent profiles) can be found — and it used to close the moment a row was\n * chosen, so browsing it was impossible and changing two settings meant\n * opening it twice. Two rows already came back, but only because\n * `selectingCompactModel` and `agentProfileForModel` happened to imply where\n * the picker had been opened from. Recording the origin explicitly is what\n * lets the other five come back too, and it is a ref rather than state\n * because the close handlers read it back inside their own keypress batch.\n */\n const configReturnRow = useRef<number | null>(null);\n const [configInitialRow, setConfigInitialRow] = useState(0);\n\n /** Reopen `/config` on the row a picker was launched from, if it was. */\n const returnToConfig = useCallback((): void => {\n const row = configReturnRow.current;\n configReturnRow.current = null;\n if (row === null) return;\n setConfigInitialRow(row);\n setShowConfigPicker(true);\n }, []);\n\n /**\n * Forget the origin, for the paths that must end at the composer: a picker\n * opened by its own command, and `/skills`'s \"use this skill\", which exists\n * to put text in the input bar.\n */\n const forgetConfigOrigin = useCallback(() => {\n configReturnRow.current = null;\n }, []);\n const [agentProfileForModel, setAgentProfileForModel] = useState<string>();\n const [selectingCompactModel, setSelectingCompactModel] = useState(false);\n const [showSessionPicker, setShowSessionPicker] = useState(false);\n const [showRewindPicker, setShowRewindPicker] = useState(false);\n const [isResolvingCommand, setIsResolvingCommandState] = useState(false);\n // Written with the state for the key handler, which a key can reach before the next render.\n const isResolvingCommandRef = useRef(false);\n const setIsResolvingCommand = useCallback((next: boolean) => {\n isResolvingCommandRef.current = next;\n setIsResolvingCommandState(next);\n }, []);\n /** Set for the lifetime of a `/review`; drives its status line and Esc. */\n const [reviewStatus, setReviewStatus] = useState<string | undefined>(undefined);\n const reviewAbortRef = useRef<AbortController | null>(null);\n /** The conversation currently on screen, for routing a review's late output. */\n const reviewSessionRef = useRef(sessionId);\n const [draftRestore, setDraftRestore] = useState<{\n key: number;\n value: string;\n attachments?: ImageAttachment[];\n }>();\n const [queuedInputs, setQueuedInputs] = useState<QueuedInput[]>([]);\n const [editingQueuedInput, setEditingQueuedInput] = useState<QueuedInput | undefined>(undefined);\n const [queueNotice, setQueueNotice] = useState<string | undefined>(undefined);\n /** Drops the \"Sending…\" notice without wiping a notice something else set since. */\n const clearQueuedSendNotice = useCallback(() => {\n setQueueNotice((current) => (current === QUEUED_SEND_NOTICE ? undefined : current));\n }, []);\n // A note above the composer that fades on its own: a setting saved, a server\n // connected, text copied. Confirmations used to be written into the\n // transcript as sentences, a permanent record of something the status line\n // or the next screen already showed.\n const [flash, setFlash] = useState<FlashNotice | undefined>(undefined);\n const flashTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const flashNotice = useCallback(\n (text: string, tone: FlashNotice['tone'] = 'done', ms = 3_000) => {\n setFlash({ text, tone });\n if (flashTimerRef.current) clearTimeout(flashTimerRef.current);\n flashTimerRef.current = setTimeout(() => {\n flashTimerRef.current = null;\n setFlash(undefined);\n }, ms);\n },\n [],\n );\n // A queue event that happened once (inputs restored, removed, cleared) is a\n // fading note. As a queue notice it stayed on screen until the next queue\n // event, which may never come: \"Queued inputs restored to the composer after\n // interrupt.\" sat above an empty composer for the rest of the session. The\n // state notices (editing a queued input, a paused queue) stay put, since they\n // describe something still true.\n const announceQueueEvent = useCallback(\n (text: string, tone: FlashNotice['tone'] = 'info', ms = 4_000) => {\n setQueueNotice((current) => (current === QUEUED_SEND_NOTICE ? current : undefined));\n flashNotice(text, tone, ms);\n },\n [flashNotice],\n );\n const handleCopiedNotice = useCallback(\n (message: string) => flashNotice(message, 'done', 2_000),\n [flashNotice],\n );\n // The timestamp ref keeps the second-press check current before React rerenders.\n // The timer only controls the visible hint and is cleared on replacement or unmount.\n const [ctrlCExitHintVisible, setCtrlCExitHintVisible] = useState(false);\n const ctrlCExitArmedAtRef = useRef<number | undefined>(undefined);\n const ctrlCExitHintTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const armCtrlCExit = useCallback(() => {\n ctrlCExitArmedAtRef.current = Date.now();\n setCtrlCExitHintVisible(true);\n if (ctrlCExitHintTimerRef.current) clearTimeout(ctrlCExitHintTimerRef.current);\n ctrlCExitHintTimerRef.current = setTimeout(() => {\n ctrlCExitHintTimerRef.current = null;\n ctrlCExitArmedAtRef.current = undefined;\n setCtrlCExitHintVisible(false);\n }, CTRL_C_EXIT_HINT_MS);\n }, []);\n const disarmCtrlCExit = useCallback(() => {\n ctrlCExitArmedAtRef.current = undefined;\n if (ctrlCExitHintTimerRef.current) {\n clearTimeout(ctrlCExitHintTimerRef.current);\n ctrlCExitHintTimerRef.current = null;\n }\n setCtrlCExitHintVisible(false);\n }, []);\n const isCtrlCExitArmed = useCallback(() => {\n const armedAt = ctrlCExitArmedAtRef.current;\n return armedAt !== undefined && Date.now() - armedAt <= CTRL_C_EXIT_HINT_MS;\n }, []);\n const [sendInFlight, setSendInFlightState] = useState(false);\n // Written with the state for the key handler, as `isResolvingCommandRef` is.\n const sendInFlightRef = useRef(false);\n const setSendInFlight = useCallback((next: boolean) => {\n sendInFlightRef.current = next;\n setSendInFlightState(next);\n }, []);\n // Work that starts inside the exit window ends it, so a later idle press arms again rather\n // than exiting at once: a turn, and equally a compaction, a rewind or a command resolution.\n useEffect(() => {\n if (isThinking || sendInFlight || isCompacting || isRewinding || isResolvingCommand) {\n disarmCtrlCExit();\n }\n }, [isThinking, sendInFlight, isCompacting, isRewinding, isResolvingCommand, disarmCtrlCExit]);\n const [, setQueueDrainTick] = useState(0);\n const [shellCompletionRetryTick, setShellCompletionRetryTick] = useState(0);\n const [followRequestKey, setFollowRequestKey] = useState(0);\n const [detailTaskPickerOpen, setDetailTaskPickerOpen] = useState(false);\n const [detailTaskPickerAgentId, setDetailTaskPickerAgentId] = useState<string | undefined>(\n undefined,\n );\n const [selectedShellId, setSelectedShellId] = useState<string>();\n const commandResolutionRef = useRef<AbortController | null>(null);\n /** Ends a command resolution in flight and frees the composer it was blocking (#262). */\n const abortCommandResolution = useCallback(() => {\n commandResolutionRef.current?.abort();\n commandResolutionRef.current = null;\n setIsResolvingCommand(false);\n }, [setIsResolvingCommand]);\n const queuedInputsRef = useRef<QueuedInput[]>([]);\n const editingQueuedInputRef = useRef<QueuedInput | undefined>(undefined);\n const dispatchingQueuedIdRef = useRef<string | undefined>(undefined);\n const draftRef = useRef('');\n const startupDraftRef = useRef('');\n const draftAttachmentsRef = useRef<ImageAttachment[]>([]);\n const queueDrainRunningRef = useRef(false);\n const shellCompletionDeliveryRef = useRef(false);\n const shellCompletionRetryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const queueDrainPausedRef = useRef(false);\n const queueInterruptEpochRef = useRef(0);\n const queueSessionRef = useRef(sessionId);\n // A `/compact` cancel is sent once per compaction: a second press is a user who is waiting, and\n // it arms the exit window instead of cancelling again.\n const compactCancelSentRef = useRef(false);\n useEffect(() => {\n if (!isCompacting) compactCancelSentRef.current = false;\n }, [isCompacting]);\n const [currentTheme] = useState<ResolvedTheme>(\n () =>\n interactiveAssets?.initialTheme ??\n resolveTheme(config.workspace, config.settings.theme ?? DEFAULT_THEME_NAME) ?? {\n preference: DEFAULT_THEME_NAME,\n resolvedName: DEFAULT_THEME_NAME,\n tokens: RUBRIC_THEME,\n },\n );\n const { tasks, addTask, updateTaskStatus, removeTask, clearTasks } = useTasks();\n const theme = currentTheme.tokens;\n // The title page's contents: this workspace's recent sessions, newest first.\n // Only read while the transcript is empty, which is the only time the title\n // page shows; the listing comes from the store's in-memory index.\n const transcriptEmpty = messages.length === 0;\n // The title page's contents. Listing reads the session index synchronously,\n // and a stale index loads every session file, so it waits for the first\n // paint: someone with hundreds of sessions sees the title page at once and\n // its chapters a moment later, instead of a blank terminal until they load.\n // `undefined` until listed: an empty list means a genuine first run, and the\n // title page must not show the getting-started contents while it waits.\n const [recentSessions, setRecentSessions] = useState<ReturnType<typeof listSessions> | undefined>(\n undefined,\n );\n useEffect(() => {\n if (!transcriptEmpty) {\n setRecentSessions(undefined);\n return;\n }\n const timer = setTimeout(() => {\n setRecentSessions(\n listSessions()\n .filter((meta) => meta.id !== sessionId && meta.messageCount > 0)\n .sort((left, right) => right.updatedAt - left.updatedAt)\n .slice(0, 5),\n );\n }, 0);\n return () => clearTimeout(timer);\n }, [listSessions, sessionId, transcriptEmpty]);\n // The status line's folio: one page per turn you have written.\n const turnCount = useMemo(() => countWrittenTurns(messages), [messages]);\n const { exit: exitApp, suspendTerminal } = useApp();\n const redrawInFlightRef = useRef(false);\n /**\n * Wipes the screen and has Ink paint the whole frame again. Ink skips a frame identical to the\n * last one it wrote, so wiping alone left the screen blank after Ctrl+L, and left rows blank that\n * a resized frame shared with the old one. suspendTerminal() erases Ink's frame, runs the wipe,\n * then forgets the old frame and repaints.\n */\n const redrawViewport = useCallback(() => {\n if (!wipeViewport || redrawInFlightRef.current) return;\n redrawInFlightRef.current = true;\n void suspendTerminal(wipeViewport)\n .catch((error: unknown) =>\n uiLog.event('redraw:failed', {\n error: error instanceof Error ? error.message : String(error),\n }),\n )\n .finally(() => {\n redrawInFlightRef.current = false;\n });\n }, [wipeViewport, suspendTerminal]);\n // Set once an exit starts. SessionEnd can take seconds, and a press meanwhile must neither\n // arm the window again nor start a second exit, which would cancel and log a second time\n // and show the hint over an exit already under way.\n const exitStartedRef = useRef(false);\n // The same fact as state, for what renders and effects gate on: nothing new is dispatched\n // while SessionEnd runs.\n const [exitStarted, setExitStarted] = useState(false);\n const exitOnce = useCallback(() => {\n if (exitStartedRef.current) return;\n exitStartedRef.current = true;\n setExitStarted(true);\n disarmCtrlCExit();\n // An exit ends the work under the UI as well as the UI: a turn still streaming, a command\n // still resolving, a permission prompt that, approved while a slow SessionEnd ran, still\n // ran its tool.\n abortCommandResolution();\n cancel();\n void endCurrentSession('exit').finally(exitApp);\n }, [abortCommandResolution, cancel, disarmCtrlCExit, endCurrentSession, exitApp]);\n /** The idle Ctrl+C decision: exit when the window is armed, otherwise arm it. True on exit. */\n const exitOrArmOnCtrlC = useCallback(\n (context: string): boolean => {\n if (isCtrlCExitArmed()) {\n uiLog.event('input:Ctrl+C', { action: 'exit', context });\n exitOnce();\n return true;\n }\n uiLog.event('input:Ctrl+C', { action: 'exit-armed', context });\n armCtrlCExit();\n return false;\n },\n [armCtrlCExit, exitOnce, isCtrlCExitArmed],\n );\n const replaceQueuedInputs = useCallback((next: QueuedInput[]) => {\n queuedInputsRef.current = next;\n setQueuedInputs(next);\n }, []);\n const replaceEditingQueuedInput = useCallback((next?: QueuedInput) => {\n editingQueuedInputRef.current = next;\n setEditingQueuedInput(next);\n }, []);\n /**\n * Ends a recalled queued edit: drops its marker and resumes the queue, unless `keepPaused`\n * leaves the inputs queued before it waiting.\n */\n const endQueuedEdit = useCallback(\n (keepPaused = false) => {\n replaceEditingQueuedInput(undefined);\n queueDrainPausedRef.current = keepPaused;\n },\n [replaceEditingQueuedInput],\n );\n const dispatchAgentSend = useCallback(\n async (value: string, commandContext?: CommandContext, attachments?: ImageAttachment[]) => {\n setSendInFlight(true);\n try {\n if (attachments && attachments.length > 0) {\n return await send(value, commandContext, attachments);\n }\n return commandContext === undefined ? await send(value) : await send(value, commandContext);\n } finally {\n setSendInFlight(false);\n }\n },\n [send],\n );\n const enqueueFollowUp = useCallback(\n (value: string, attachments: ImageAttachment[] = []): boolean => {\n const edited = editingQueuedInputRef.current;\n const input = createQueuedInput(value, sessionId, attachments, edited);\n const result = enqueueQueuedInput(queuedInputsRef.current, input);\n if (!result.accepted) {\n if (edited) {\n // Still out for editing, so say what to do about it rather than announcing a refusal\n // about a message that is not being added: Esc removes it, /queue clear empties the queue.\n setQueueNotice(\n 'Queue is full, so this input stays here. Esc removes it; /queue clear empties the queue.',\n );\n } else {\n announceQueueEvent(\n 'Queue is full. Edit or clear a queued message before adding another.',\n 'warning',\n 5_000,\n );\n }\n return false;\n }\n replaceQueuedInputs(result.queue);\n endQueuedEdit();\n setQueueNotice(undefined);\n return true;\n },\n [endQueuedEdit, replaceQueuedInputs, sessionId],\n );\n const recallQueuedInput = useCallback(():\n { value: string; attachments?: ImageAttachment[] } | undefined => {\n const result = recallNewestQueuedInput(queuedInputsRef.current, dispatchingQueuedIdRef.current);\n if (!result.recalled) return undefined;\n replaceQueuedInputs(result.queue);\n replaceEditingQueuedInput(result.recalled);\n queueDrainPausedRef.current = true;\n setQueueNotice('Editing queued input. Enter resubmits; Esc removes it.');\n return { value: result.recalled.value, attachments: result.recalled.attachments };\n }, [replaceEditingQueuedInput, replaceQueuedInputs]);\n const cancelQueuedEdit = useCallback(() => {\n endQueuedEdit();\n announceQueueEvent('Queued input removed.', 'done');\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: '',\n }));\n }, [endQueuedEdit]);\n const pasteClipboardImage = useCallback(async (): Promise<ImageAttachment> => {\n if (liveConfig.modelInfo?.vision === false) {\n throw new Error(`${liveConfig.model} does not support image input.`);\n }\n const store = session.timelineStore ?? session.store;\n if (!store?.saveImageAttachment) {\n throw new Error('Session attachment storage is unavailable.');\n }\n const image = await readClipboardImage();\n return store.saveImageAttachment(sessionId, {\n bytes: image.bytes,\n mediaType: image.mediaType,\n displayName: `clipboard-${Date.now()}.${image.mediaType.split('/')[1]}`,\n });\n }, [\n liveConfig.model,\n liveConfig.modelInfo?.vision,\n session.store,\n session.timelineStore,\n sessionId,\n ]);\n const interrupt = useCallback(() => {\n queueInterruptEpochRef.current += 1;\n // #262: clearing the handle before the resolution's own `finally` ran left \"Resolving…\" up\n // and the composer blocked for the rest of the session.\n abortCommandResolution();\n const pending = queuedInputsRef.current;\n if (pending.length > 0) {\n const restored = restoreQueuedInputText(pending, draftRef.current);\n replaceQueuedInputs([]);\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: restored,\n attachments: restoreQueuedInputAttachments(pending, draftAttachmentsRef.current),\n }));\n announceQueueEvent('Queued inputs restored to the composer after interrupt.');\n }\n endQueuedEdit(true);\n cancel();\n }, [abortCommandResolution, cancel, endQueuedEdit, replaceQueuedInputs]);\n\n useEffect(() => {\n return () => commandResolutionRef.current?.abort();\n }, []);\n\n /**\n * Start a review and keep a handle on it.\n *\n * A review outlives the keystroke that started it by minutes, so the session\n * has to hold onto something cancellable: without it the only way out of a\n * wrong or wedged review was Ctrl+C, which exits Book and orphans the agents\n * it spawned.\n */\n const startReview = useCallback(\n (scope: ReviewScope) => {\n if (reviewAbortRef.current) {\n addLocalMessage('A review is already running. Cancel it with Esc before starting another.');\n return;\n }\n const controller = new AbortController();\n reviewAbortRef.current = controller;\n setReviewStatus(reviewStatusLabel(scope));\n // A review's output belongs to the conversation that asked for it. Its\n // last segments can still arrive after a `/new`, and appending them to an\n // unrelated transcript is worse than dropping them.\n const startedIn = sessionId;\n const report = (message: string) => {\n if (reviewSessionRef.current !== startedIn) return;\n addLocalMessage(message);\n };\n void runReviewCommand(\n scope,\n managedAgentManager,\n config.workspace,\n sessionId,\n report,\n controller.signal,\n // A root the session owns and will persist, for spend no turn reports.\n startHostRun(),\n )\n .catch((reviewError) =>\n report(`✕ ${reviewError instanceof Error ? reviewError.message : String(reviewError)}`),\n )\n .finally(() => {\n if (reviewAbortRef.current !== controller) return;\n reviewAbortRef.current = null;\n setReviewStatus(undefined);\n // An ordinary agent leaves the panel when its completion is\n // acknowledged. These have no completion by design, so without this\n // every finished lens and verifier would stay pinned there — and in\n // the status-line count — for the rest of the session.\n void managedAgents.refresh().catch(() => {});\n });\n },\n [addLocalMessage, config.workspace, managedAgentManager, managedAgents.refresh, sessionId],\n );\n\n /** Returns whether a review was actually cancelled, so callers can fall through. */\n const cancelReview = useCallback((): boolean => {\n const controller = reviewAbortRef.current;\n if (!controller || controller.signal.aborted) return false;\n controller.abort();\n setReviewStatus('Cancelling review — stopping its agents');\n return true;\n }, []);\n\n // Abort on unmount so a review cannot keep spawning agents into a dead UI.\n useEffect(() => {\n return () => reviewAbortRef.current?.abort();\n }, []);\n\n /**\n * End a review when the conversation it belongs to does.\n *\n * A review is scoped to the session that started it: its agents are owned by\n * that `parentSessionId`, so after a `/new` or `/resume` they are invisible,\n * and its report would be appended to a conversation that never asked for it.\n * The run also holds the single-review slot, so leaving it alive would refuse\n * a `/review` typed in the new session.\n */\n useEffect(() => {\n if (reviewSessionRef.current === sessionId) return;\n reviewSessionRef.current = sessionId;\n const controller = reviewAbortRef.current;\n if (!controller) return;\n controller.abort();\n reviewAbortRef.current = null;\n setReviewStatus(undefined);\n }, [sessionId]);\n\n useEffect(() => {\n setDetailTaskPickerOpen(false);\n setDetailTaskPickerAgentId(undefined);\n setSelectedShellId(undefined);\n managedAgents.setSurface('main');\n managedAgents.selectAgent(undefined);\n }, [managedAgents.selectAgent, managedAgents.setSurface, sessionId]);\n\n useEffect(() => {\n if (queueSessionRef.current === sessionId) return;\n queueSessionRef.current = sessionId;\n queueInterruptEpochRef.current += 1;\n replaceQueuedInputs([]);\n endQueuedEdit();\n dispatchingQueuedIdRef.current = undefined;\n queueDrainRunningRef.current = false;\n setQueueNotice(undefined);\n draftRef.current = '';\n }, [endQueuedEdit, replaceQueuedInputs, sessionId]);\n\n useAgentCompletionDelivery({\n pending: managedAgents.pendingCompletions,\n parentSessionId: sessionId,\n blocked: Boolean(\n exitStarted ||\n isThinking ||\n isCompacting ||\n isRewinding ||\n isResolvingCommand ||\n pendingPermission ||\n pendingPlanApproval ||\n pendingUserQuestion ||\n pendingElicitation,\n ),\n deliver: sendAgentCompletions,\n acknowledge: managedAgents.acknowledgeCompletions,\n });\n\n const [commands, setCommands] = useState(\n () => interactiveAssets?.commands ?? discoverCommands(config.workspace),\n );\n const builtinCommandRegistry = useMemo(() => createBuiltinCommandRegistry(), []);\n const [skills, setSkills] = useState(\n () =>\n interactiveAssets?.skills ??\n discoverSkills(config.workspace, config.settings.skills.overrides, {\n executionOverrides: config.settings.skills.execution,\n enabled: config.settings.skills.enabled,\n }),\n );\n const [skillCatalogDirty, setSkillCatalogDirty] = useState(false);\n const [skillWatcherError, setSkillWatcherError] = useState<string>();\n useEffect(() => {\n if (!runtime) return;\n return runtime.subscribeSkillChanges(\n config.workspace,\n () => {\n const watcherError = runtime.skillWatcherError;\n setSkillWatcherError(watcherError);\n if (!watcherError) setSkillCatalogDirty(true);\n },\n liveConfig.settings.skills.enabled,\n );\n }, [config.workspace, liveConfig.settings.skills.enabled, runtime]);\n useEffect(() => {\n if (!runtime || !skillCatalogDirty || isThinking) return;\n const refreshed = runtime.consumeSkillChanges(config.workspace, liveConfig.settings.skills);\n setSkills(refreshed.list());\n setSkillWatcherError(undefined);\n setSkillCatalogDirty(false);\n }, [config.workspace, isThinking, liveConfig.settings.skills, runtime, skillCatalogDirty]);\n const [agentProfiles, setAgentProfiles] = useState(() =>\n withBuiltInAgents(discoverAgents(config.workspace)),\n );\n const modelOptions = useMemo(() => buildModelOptions(liveConfig.settings), [liveConfig.settings]);\n const configuredAgentModels = useMemo(\n () =>\n Object.fromEntries(\n Object.entries(liveConfig.settings.agents.profiles).map(([name, profile]) => [\n name,\n profile.model,\n ]),\n ),\n [liveConfig.settings.agents.profiles],\n );\n const activeAgentProfile = agentProfileForModel\n ? agentProfiles.find((profile) => profile.name === agentProfileForModel)\n : undefined;\n const modelPickerSelection = selectingCompactModel\n ? (liveConfig.compactModel ??\n liveConfig.settings.compactModel ??\n liveConfig.modelSelection ??\n liveConfig.model)\n : activeAgentProfile\n ? (configuredAgentModels[activeAgentProfile.name] ??\n activeAgentProfile.model ??\n liveConfig.modelSelection ??\n liveConfig.model)\n : (liveConfig.modelSelection ?? liveConfig.model);\n const effortLevels = useMemo(() => getAvailableEffortLevels(liveConfig), [liveConfig.modelInfo]);\n\n const { stdout } = useStdout();\n const readTerminalSize = useCallback(\n () => ({\n columns: Math.max(20, stdout?.columns ?? 80),\n rows: Math.max(8, stdout?.rows ?? 24),\n }),\n [stdout],\n );\n const [terminalSize, setTerminalSize] = useState(readTerminalSize);\n const lastAppliedSizeRef = useRef(terminalSize);\n const resizeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const applyTerminalSize = useCallback(\n (nextSize: { columns: number; rows: number }, redraw: boolean) => {\n const previousSize = lastAppliedSizeRef.current;\n if (nextSize.columns === previousSize.columns && nextSize.rows === previousSize.rows) return;\n if (redraw) redrawViewport?.();\n lastAppliedSizeRef.current = nextSize;\n setTerminalSize(nextSize);\n },\n [redrawViewport],\n );\n\n useEffect(() => {\n // Reconcile dimensions that changed between the initial render and effect\n // registration without destructively clearing the first frame.\n applyTerminalSize(readTerminalSize(), false);\n\n const updateSize = () => {\n if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current);\n resizeTimerRef.current = setTimeout(() => {\n resizeTimerRef.current = null;\n applyTerminalSize(readTerminalSize(), true);\n }, 50);\n };\n\n stdout?.on?.('resize', updateSize);\n return () => {\n stdout?.off?.('resize', updateSize);\n if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current);\n };\n }, [applyTerminalSize, readTerminalSize, stdout]);\n\n const termWidth = terminalSize.columns;\n const termHeight = terminalSize.rows;\n const isNarrow = termWidth < 64;\n const isTiny = termWidth < 42 || termHeight < 12;\n const maxCommandMenuRows = Math.max(2, Math.min(isTiny ? 3 : 8, Math.floor(termHeight / 3)));\n const compactStatus = isNarrow || isTiny;\n const density = resolveTuiDensity(termHeight);\n const reducedMotion = Boolean(config.accessibility?.reducedMotion);\n // Keep the whole live region quiescent while the terminal viewport belongs\n // to the user reviewing a plan. Any animation repaint can snap scrollback.\n const motionDisabled =\n reducedMotion || Boolean(pendingPlanApproval || pendingUserQuestion || pendingElicitation);\n const screenReader = Boolean(config.accessibility?.screenReader);\n const managedAgentUiEnabled = liveConfig.settings.agents.ui.enabled;\n // Withdrawn while an exit runs: the session's cancel does not reach a child's prompt, so one\n // approved during a slow SessionEnd still ran the child's tool.\n const childPermission = exitStarted\n ? undefined\n : managedAgents.pendingPermissions.find((event) => event.type === 'agent_permission');\n const childQuestion = exitStarted ? undefined : managedAgents.pendingQuestions[0];\n\n const subscribeMcp = useCallback(\n (listener: () => void) => mcp?.subscribe(listener) ?? (() => {}),\n [mcp],\n );\n const readMcpSnapshot = useCallback(() => mcp?.getSnapshot() ?? EMPTY_MCP_SNAPSHOT, [mcp]);\n const mcpSnapshot = useSyncExternalStore(subscribeMcp, readMcpSnapshot);\n // Servers connect in the background; this binds their elicitation prompts to\n // this session's interaction queue once the UI exists to answer them.\n useEffect(() => {\n if (!mcp) return;\n mcp.setElicitationHandler(elicitationHandler);\n return () => mcp.setElicitationHandler(undefined);\n }, [mcp, elicitationHandler]);\n const pendingMcpApproval = mcpSnapshot.pendingApprovals[0];\n // The trust prompt yields to every other modal surface and reappears once idle.\n const showMcpApproval =\n Boolean(pendingMcpApproval) &&\n !ownsModalInput(\n pendingPermission ?? childPermission ?? childQuestion,\n pendingPlanApproval,\n showModelPicker,\n showSessionPicker,\n pendingUserQuestion,\n showEffortPicker,\n showRewindPicker,\n showConfigPicker,\n showAgentProfilePicker,\n showPermissionModePicker,\n showSkills,\n undefined,\n pendingElicitation,\n );\n\n // Surface connection outcomes as transcript notices once the turn is idle;\n // addLocalMessage drops messages mid-turn, so consumption waits for idle.\n const lastMcpEventIdRef = useRef(0);\n useEffect(() => {\n const events = mcpSnapshot.events;\n const fresh = events.filter((event) => event.id > lastMcpEventIdRef.current);\n if (fresh.length === 0) return;\n if (isThinking || sendInFlight) return;\n lastMcpEventIdRef.current = fresh[fresh.length - 1].id;\n for (const event of fresh) {\n // A failure is kept in the transcript, since it explains the missing\n // tools later. The routine events are a note that fades: a line per\n // server at every launch buried the title page under connection chatter.\n if (event.type === 'failed') {\n addLocalMessage(`✕ MCP: failed to connect \"${event.server}\": ${event.error}`);\n } else if (event.type === 'connected') {\n flashNotice(\n `MCP ${event.server} · ${event.toolCount} tool${event.toolCount === 1 ? '' : 's'}`,\n );\n } else if (event.type === 'disconnected') {\n flashNotice(`MCP ${event.server} disconnected`, 'info');\n } else {\n flashNotice(`MCP ${event.server} · ${event.toolCount} tools`, 'info');\n }\n }\n }, [mcpSnapshot, isThinking, sendInFlight, addLocalMessage, flashNotice]);\n\n // A managed child that was refused something says so here (#305 item 4). The child's result is\n // a summary, so a step that never ran is otherwise indistinguishable from one the model chose\n // to skip. Kept in the transcript rather than flashed, because it is a fact about the run the\n // operator needs after the fact. Consumption waits for idle, as above.\n useEffect(() => {\n const next = managedAgents.noticeQueue[0];\n if (!next) return;\n if (isThinking || sendInFlight) return;\n managedAgents.takeNotice();\n addLocalMessage(next.message);\n }, [managedAgents, isThinking, sendInFlight, addLocalMessage]);\n\n const queueDrainBlocked = Boolean(\n exitStarted ||\n isThinking ||\n sendInFlight ||\n isCompacting ||\n isRewinding ||\n isResolvingCommand ||\n pendingPermission ||\n pendingPlanApproval ||\n pendingUserQuestion ||\n pendingElicitation ||\n childPermission ||\n childQuestion ||\n editingQueuedInput ||\n managedAgents.surface !== 'main',\n );\n\n const scheduleShellCompletionRetry = useCallback(() => {\n if (shellCompletionRetryTimerRef.current) {\n clearTimeout(shellCompletionRetryTimerRef.current);\n }\n shellCompletionRetryTimerRef.current = setTimeout(() => {\n shellCompletionRetryTimerRef.current = null;\n setShellCompletionRetryTick((current) => current + 1);\n }, 1_000);\n }, []);\n\n useEffect(\n () => () => {\n if (shellCompletionRetryTimerRef.current) {\n clearTimeout(shellCompletionRetryTimerRef.current);\n }\n },\n [],\n );\n\n useEffect(() => {\n const completion = backgroundShells.pendingAgentCompletions[0];\n if (!completion || queueDrainBlocked || shellCompletionDeliveryRef.current) return;\n shellCompletionDeliveryRef.current = true;\n void sendBackgroundShellCompletion(completion)\n .then((accepted) => {\n if (accepted) {\n if (shellCompletionRetryTimerRef.current) {\n clearTimeout(shellCompletionRetryTimerRef.current);\n shellCompletionRetryTimerRef.current = null;\n }\n backgroundShells.acknowledgeAgentCompletion(completion.id, completion.completionSequence);\n } else {\n scheduleShellCompletionRetry();\n }\n })\n .catch(() => scheduleShellCompletionRetry())\n .finally(() => {\n shellCompletionDeliveryRef.current = false;\n });\n }, [\n backgroundShells.acknowledgeAgentCompletion,\n backgroundShells.pendingAgentCompletions,\n queueDrainBlocked,\n scheduleShellCompletionRetry,\n sendBackgroundShellCompletion,\n shellCompletionRetryTick,\n ]);\n // Tab (`cycleAgentFocus`) reaches only agents with a Background-panel row. Keyed on\n // the sorted, joined ids, not the summaries array: a child's status event replaces the array,\n // and a re-sort reorders it, without changing which rows exist, and neither must re-project\n // every trace.\n const openableAgentKey = managedAgentUiEnabled\n ? managedAgents.summaries\n .map((summary) => summary.agentId)\n .sort()\n .join(' ')\n : '';\n const openableAgentIds = useMemo(\n () => new Set(openableAgentKey ? openableAgentKey.split(' ') : []),\n [openableAgentKey],\n );\n const managedAgentTraces = useMemo(\n () =>\n projectManagedAgentTraces(\n messages,\n managedAgents.records,\n managedAgents.activities,\n openableAgentIds,\n ),\n [managedAgents.activities, managedAgents.records, messages, openableAgentIds],\n );\n const returnToMain = useCallback(() => {\n setDetailTaskPickerOpen(false);\n setDetailTaskPickerAgentId(undefined);\n setSelectedShellId(undefined);\n managedAgents.setSurface('main');\n managedAgents.selectAgent(undefined);\n }, [managedAgents.selectAgent, managedAgents.setSurface]);\n\n const selectBackgroundJob = useCallback(\n (jobId?: string) => {\n if (!jobId) {\n setSelectedShellId(undefined);\n managedAgents.selectAgent(undefined);\n return;\n }\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\n setSelectedShellId(jobId);\n managedAgents.selectAgent(undefined);\n } else {\n setSelectedShellId(undefined);\n managedAgents.selectAgent(jobId);\n }\n },\n [backgroundShells.shells, managedAgents.selectAgent],\n );\n\n // Depend on `stopOrDismiss` rather than on the whole hook result: the hook returns a fresh object\n // on every render, which would rebuild this callback — and every consumer of it — each time.\n const { stopOrDismiss: stopOrDismissBackgroundShell } = backgroundShells;\n const stopOrDismissShell = useCallback(\n (jobId: string) => {\n void stopOrDismissBackgroundShell(jobId).then((failure) => {\n if (failure) flashNotice(failure, 'warning', 6_000);\n });\n },\n [stopOrDismissBackgroundShell, flashNotice],\n );\n\n // Terminal jobs are removed from the active list as soon as they finish or\n // stop. Leave their detail view even when notifications are disabled.\n useEffect(() => {\n if (selectedShellId && !backgroundShells.shells.some((shell) => shell.id === selectedShellId)) {\n returnToMain();\n }\n }, [backgroundShells.shells, returnToMain, selectedShellId]);\n\n useEffect(() => {\n const completed = backgroundShells.lastCompletion;\n if (!completed) return;\n const exit = completed.exitCode !== undefined ? ` (exit ${completed.exitCode ?? 'none'})` : '';\n // The title defaults to the whole command, and this row is what a user\n // reads to confirm *which* command finished — so it has to survive the\n // prose renderer that the rest of this sentence is written for. Inline\n // code also matches the `ToolCallBlock` that started the job.\n addLocalMessage(\n `${completed.status === 'exited' ? '✓' : '✕'} Background shell ${inlineCode(completed.title || completed.id)} ${completed.status}${exit}.`,\n );\n backgroundShells.acknowledge(completed.id);\n if (selectedShellId === completed.id) returnToMain();\n }, [\n addLocalMessage,\n backgroundShells.acknowledge,\n backgroundShells.lastCompletion,\n returnToMain,\n selectedShellId,\n ]);\n\n const readSelectedShellTail = useCallback(\n () => (selectedShellId ? (shellManager.readTail(selectedShellId, 16_000) ?? '') : ''),\n [selectedShellId, shellManager],\n );\n\n // Tab cycles focus flatly through [main, ...spawned agents], opening each\n // child's transcript directly. Wrapping past the last agent returns to main.\n // Returns false when there is nothing to cycle so InputBar can fall back to\n // its default Tab behavior.\n const cycleAgentFocus = useCallback((): boolean => {\n if (!managedAgentUiEnabled) return false;\n const jobIds = [\n ...managedAgents.summaries.map((agent) => agent.agentId),\n ...backgroundShells.shells.map((shell) => shell.id),\n ];\n if (jobIds.length === 0) return false;\n const rows: Array<string | undefined> = [undefined, ...jobIds];\n const currentId =\n managedAgents.surface === 'detail'\n ? (selectedShellId ?? managedAgents.selectedAgentId)\n : undefined;\n const currentIndex = currentId ? rows.indexOf(currentId) : 0;\n const next = rows[((currentIndex < 0 ? 0 : currentIndex) + 1) % rows.length];\n if (next === undefined) {\n returnToMain();\n } else {\n selectBackgroundJob(next);\n managedAgents.setSurface('detail');\n }\n return true;\n }, [\n backgroundShells.shells,\n managedAgentUiEnabled,\n managedAgents,\n returnToMain,\n selectBackgroundJob,\n selectedShellId,\n ]);\n\n useEffect(() => {\n if (\n queueDrainBlocked ||\n queueDrainRunningRef.current ||\n queueDrainPausedRef.current ||\n queuedInputs.length === 0\n ) {\n return;\n }\n\n const item = queuedInputsRef.current[0];\n if (!item) return;\n if (item.sessionId !== sessionId) {\n replaceQueuedInputs(queuedInputsRef.current.slice(1));\n announceQueueEvent('Discarded a queued input from a previous session.');\n return;\n }\n\n queueDrainRunningRef.current = true;\n dispatchingQueuedIdRef.current = item.id;\n const interruptEpoch = queueInterruptEpochRef.current;\n replaceQueuedInputs(queuedInputsRef.current.slice(1));\n setQueueNotice(QUEUED_SEND_NOTICE);\n\n void (async () => {\n try {\n const result = await dispatchAgentSend(item.value, undefined, item.attachments);\n if (queueInterruptEpochRef.current !== interruptEpoch && shouldRequeueQueuedSend(result)) {\n if (queueSessionRef.current === item.sessionId) {\n const restored = restoreQueuedInputText([item], draftRef.current);\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: restored,\n attachments: restoreQueuedInputAttachments([item], draftAttachmentsRef.current),\n }));\n announceQueueEvent('Interrupted queued input restored to the composer.');\n }\n return;\n }\n if (shouldRequeueQueuedSend(result)) {\n replaceQueuedInputs([item, ...queuedInputsRef.current]);\n queueDrainPausedRef.current = true;\n setQueueNotice(\n 'Queued send did not start. Press Up to edit it or Enter another message.',\n );\n } else if (result.status === 'failed') {\n queueDrainPausedRef.current = true;\n setQueueNotice('Queued send failed. Automatic queue dispatch is paused.');\n } else {\n clearQueuedSendNotice();\n }\n } catch (sendError) {\n replaceQueuedInputs([item, ...queuedInputsRef.current]);\n queueDrainPausedRef.current = true;\n setQueueNotice(\n `Queued send failed before dispatch: ${\n sendError instanceof Error ? sendError.message : String(sendError)\n }`,\n );\n } finally {\n dispatchingQueuedIdRef.current = undefined;\n queueDrainRunningRef.current = false;\n setQueueDrainTick((tick) => tick + 1);\n }\n })();\n }, [\n clearQueuedSendNotice,\n dispatchAgentSend,\n queueDrainBlocked,\n queuedInputs.length,\n replaceQueuedInputs,\n sessionId,\n ]);\n\n // `send` resolves when the whole turn ends, so a notice cleared only there said\n // \"Sending…\" under a reply that had been running for a minute. The follow-up\n // has been sent once it is on screen, which is the moment the turn starts\n // thinking; before that (a pre-turn compaction) the notice still holds.\n useEffect(() => {\n if (isThinking) clearQueuedSendNotice();\n }, [clearQueuedSendNotice, isThinking]);\n\n useDebugMount(uiLog, {\n workspace: config.workspace,\n model: config.model,\n provider: config.provider,\n commandsLen: commands.length,\n skillsLen: skills.length,\n });\n useDebugValueChange(uiLog, 'layout:width', termWidth);\n useDebugValueChange(uiLog, 'layout:height', termHeight);\n useDebugValueChange(uiLog, 'layout:compactStatus', compactStatus, (v) => String(v));\n useDebugValueChange(uiLog, 'referencePanel', referencePanel, (v) => String(v));\n useDebugValueChange(uiLog, 'showHelp', showHelp, (v) => String(v));\n useDebugValueChange(uiLog, 'showShortcuts', showShortcuts, (v) => String(v));\n useDebugValueChange(uiLog, 'showStatus', showStatus, (v) => String(v));\n useDebugValueChange(uiLog, 'showAllDetailedOutput', showAllDetailedOutput, (v) => String(v));\n useDebugValueChange(uiLog, 'transcriptMode', transcriptMode);\n useDebugValueChange(uiLog, 'showPermissions', showPermissions, (v) => String(v));\n useDebugValueChange(uiLog, 'showSkills', showSkills, (v) => String(v));\n useDebugValueChange(uiLog, 'showModelPicker', showModelPicker, (v) => String(v));\n useDebugValueChange(uiLog, 'showEffortPicker', showEffortPicker, (v) => String(v));\n useDebugValueChange(uiLog, 'showPermissionModePicker', showPermissionModePicker, (v) =>\n String(v),\n );\n useDebugValueChange(uiLog, 'showConfigPicker', showConfigPicker, (v) => String(v));\n useDebugValueChange(uiLog, 'showAgentProfilePicker', showAgentProfilePicker, (v) => String(v));\n\n // Ink hands a key to the handler its hook subscribed at the last passive-effect flush, which\n // can be a render behind the frame on screen, so a press could act on state the user no longer\n // sees: Ctrl+C just after a command resolution ended still cancelled it instead of arming the\n // exit window. The subscription forwards to the latest render's handler instead, and the state\n // this app sets itself before a key in the same read can follow (a send in flight, a command\n // resolving, a recalled queued edit) is read from refs written with it.\n const handleInputRef = useRef<(input: string, key: Key) => void>(() => {});\n const forwardInput = useCallback(\n (input: string, key: Key) => handleInputRef.current(input, key),\n [],\n );\n /**\n * Cancels a `/compact` still running its reducer, once. The follow-up queue behind it stays as it\n * was; a saved compaction's PostCompact hooks are left to finish; a second press is a user who\n * is waiting, so it falls through (Ctrl+C then arms the exit window as usual).\n */\n const cancelCompaction = (via: 'Escape' | 'Ctrl+C'): boolean => {\n if (!isCompacting || isCompactCommitted || compactCancelSentRef.current) return false;\n uiLog.event(`input:${via}`, { action: 'cancel-compaction' });\n compactCancelSentRef.current = true;\n cancel();\n return true;\n };\n handleInputRef.current = (input: string, key: Key) => {\n // Once an exit has started, Ctrl+C has nothing left to do: SessionEnd is running and the\n // app unmounts when it finishes.\n if (key.ctrl && input === 'c' && exitStartedRef.current) {\n uiLog.event('input:Ctrl+C', { action: 'noop-exiting' });\n return;\n }\n if (startupFireActive) {\n if (key.ctrl && input === 'c') {\n // The idle decision. Arming dismisses the splash so the hint shows; an exit leaves it up.\n if (!exitOrArmOnCtrlC('startup-fire')) setStartupFireActive(false);\n return;\n }\n if (key.escape) {\n uiLog.event('input:Escape', { action: 'skip-startup-fire' });\n setStartupFireActive(false);\n return;\n }\n const draftInput = stripSgrMouseSequences(input);\n if (!key.ctrl && !key.meta && containsDraftInput(draftInput)) {\n uiLog.event('input:printable', { action: 'skip-startup-fire' });\n // React may deliver several stdin chunks before the splash dismissal commits.\n startupDraftRef.current += draftInput;\n const startupDraft = startupDraftRef.current;\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: startupDraft,\n }));\n setStartupFireActive(false);\n return;\n }\n return;\n }\n\n // Modal prompts own the keyboard until they resolve. Let their own\n // useInput handlers receive the event, but do not open another modal or\n // mutate surrounding UI state from this global handler.\n if (\n ownsModalInput(\n pendingPermission ?? childPermission ?? childQuestion,\n pendingPlanApproval,\n showModelPicker,\n showSessionPicker,\n pendingUserQuestion,\n showEffortPicker,\n showRewindPicker,\n showConfigPicker,\n showAgentProfilePicker,\n showPermissionModePicker,\n showSkills,\n showMcpApproval,\n pendingElicitation,\n )\n ) {\n if (key.escape) {\n uiLog.event('input:Escape', { action: 'noop-modal-active' });\n } else if (key.ctrl && input === 'c') {\n if (isCtrlCExitArmed()) {\n // The visible \"press again to exit\" hint is a promise, including over a modal\n // that took the keyboard after the first press (e.g. behind the startup splash).\n // Armed, this exits; a modal never arms the window itself.\n exitOrArmOnCtrlC('modal');\n } else if (pendingUserQuestion || pendingElicitation) {\n uiLog.event('input:Ctrl+C', { action: 'cancel-question-turn' });\n interrupt();\n } else {\n uiLog.event('input:Ctrl+C', { action: 'noop-modal-active' });\n }\n }\n return;\n }\n\n if (transcriptMode === 'detailed') {\n const transcriptAction = getTranscriptShortcutAction(transcriptMode, input, key);\n if (transcriptAction === 'exit-detailed') {\n uiLog.event('input:detail-exit', {\n key: key.ctrl ? 'Ctrl+O' : key.escape ? 'Escape' : 'q',\n });\n setTranscriptMode('compact');\n setShowAllDetailedOutput(false);\n return;\n }\n if (transcriptAction === 'expand-output') {\n uiLog.event('input:Ctrl+E', { action: 'show-all-detailed-output' });\n setShowAllDetailedOutput(true);\n return;\n }\n }\n\n // An open composer menu owns Esc; InputBar closes it. Ink hands the same key\n // to this handler too, and acting on it here as well cancelled the running\n // turn, or dropped the queued input being edited, behind the menu.\n if (key.escape && composerMenuOpenRef.current) {\n uiLog.event('input:Escape', { action: 'close-composer-menu' });\n return;\n }\n\n if (key.escape && detailTaskPickerOpen) {\n setDetailTaskPickerOpen(false);\n setDetailTaskPickerAgentId(undefined);\n return;\n }\n if (key.escape && managedAgents.surface === 'detail') {\n returnToMain();\n return;\n }\n if (key.escape && managedAgents.surface === 'tasks') {\n managedAgents.setSurface('main');\n return;\n }\n\n if (key.escape && editingQueuedInputRef.current) {\n uiLog.event('input:Escape', { action: 'cancel-queued-edit' });\n cancelQueuedEdit();\n return;\n }\n\n // Escape aborts an in-flight stream when no prompt owns the keyboard.\n // A streaming turn outranks a background review: cancelling the thing the\n // user is watching is the established meaning of Esc.\n if (key.escape) {\n if (isThinking || sendInFlightRef.current || isResolvingCommandRef.current) {\n uiLog.event('input:Escape', { action: 'cancel-stream' });\n interrupt();\n return;\n }\n if (cancelCompaction('Escape')) return;\n if (cancelReview()) {\n uiLog.event('input:Escape', { action: 'cancel-review' });\n return;\n }\n // Nothing is in flight, so Esc falls through to the reference sheet the\n // user opened. It ranks last deliberately: a panel is a static block of\n // text, and Esc must never stop meaning \"cancel the running turn\".\n if (referencePanel) {\n uiLog.event('input:Escape', { action: 'close-panel', panel: referencePanel });\n setReferencePanel(null);\n return;\n }\n uiLog.event('input:Escape', { action: 'noop-idle' });\n }\n // Ctrl+C cancels active work (a turn, a compaction, a command resolution), drops a\n // recalled queued input, clears a non-empty composer, or confirms idle exit. A compaction\n // that does not stop when asked must not trap the user, so a press after the cancel went\n // out arms the exit window as usual.\n if (key.ctrl && input === 'c') {\n if (isThinking || sendInFlightRef.current || isResolvingCommandRef.current) {\n uiLog.event('input:Ctrl+C', { action: 'cancel-stream' });\n disarmCtrlCExit();\n interrupt();\n return;\n }\n if (cancelCompaction('Ctrl+C')) {\n disarmCtrlCExit();\n return;\n }\n // A review is in-flight work too, so Ctrl+C cancels it without exiting.\n if (cancelReview()) {\n uiLog.event('input:Ctrl+C', { action: 'cancel-review' });\n disarmCtrlCExit();\n return;\n }\n // A recalled queued input is removed, as Esc removes it. Clearing only its text\n // would leave the queue paused behind the edit.\n if (editingQueuedInputRef.current) {\n uiLog.event('input:Ctrl+C', { action: 'cancel-queued-edit' });\n disarmCtrlCExit();\n cancelQueuedEdit();\n return;\n }\n if (draftRef.current.length > 0 || draftAttachmentsRef.current.length > 0) {\n uiLog.event('input:Ctrl+C', { action: 'clear-composer' });\n disarmCtrlCExit();\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: '',\n }));\n return;\n }\n exitOrArmOnCtrlC('idle');\n return;\n }\n // Ctrl+T — the agent's steps, as a reference sheet Esc also closes\n if (key.ctrl && input === 't') {\n uiLog.event('input:Ctrl+T', { action: 'toggle-steps' });\n setReferencePanel((current) => (current === 'steps' ? null : 'steps'));\n return;\n }\n // Alt+M — cycle mode\n if (key.meta && input === 'm') {\n uiLog.event('input:Alt+M', { action: 'cycle-mode' });\n cycleMode();\n return;\n }\n // Alt+P — open model picker\n if (key.meta && input === 'p') {\n uiLog.event('input:Alt+P', { action: 'open-model-picker' });\n setShowModelPicker(true);\n return;\n }\n // Ctrl+L — clear the visible viewport and force a fresh Ink frame.\n if (key.ctrl && input === 'l') {\n uiLog.event('input:Ctrl+L', { action: 'redraw' });\n redrawViewport?.();\n return;\n }\n };\n\n // Log slash-command dispatches at a coarse level (command name + arg).\n // The detailed branching in handleSubmit stays unchanged; this only emits\n // one event per submit to make the dispatch traceable.\n useEffect(() => {\n if (isThinking) {\n uiLog.event('state:thinking', { messages: messages.length, currentTurn });\n }\n }, [isThinking, messages.length, currentTurn]);\n\n // Active tools open automatically; completed file mutations use their own default policy.\n const expandedToolId = useMemo(() => selectExpandedToolId(messages), [messages]);\n // Only a plan the agent wrote during this prompt names the work in the\n // footer; the Steps sheet (Ctrl+T) still lists whatever plan there is.\n const activeStep = agentPlanCurrent\n ? agentTodos.find((todo) => todo.status === 'in_progress')\n : undefined;\n const selectedManagedAgentRecord = managedAgents.selectedAgentId\n ? managedAgents.records.get(managedAgents.selectedAgentId)\n : undefined;\n const selectedManagedAgentLiveText = managedAgents.selectedAgentId\n ? managedAgents.liveText.get(managedAgents.selectedAgentId)\n : undefined;\n const activeTranscriptMessages =\n managedAgents.surface === 'detail' && !selectedShellId && selectedManagedAgentRecord\n ? selectedManagedAgentRecord.transcript\n : messages;\n const activeTranscriptScope =\n activeTranscriptMessages === messages\n ? MAIN_TRANSCRIPT_SCOPE\n : `managed:${selectedManagedAgentRecord!.id}`;\n const activeExpandedToolId = useMemo(\n () =>\n activeTranscriptMessages === messages\n ? expandedToolId\n : selectExpandedToolId(activeTranscriptMessages),\n [activeTranscriptMessages, expandedToolId, messages],\n );\n const toolExpansionOverrides =\n toolExpansionOverridesByTranscript.get(activeTranscriptScope) ?? EMPTY_TOOL_EXPANSION_OVERRIDES;\n const focusedToolId = focusedToolIdsByTranscript.get(activeTranscriptScope) ?? null;\n const showAllToolOutputIds =\n showAllToolOutputIdsByTranscript.get(activeTranscriptScope) ?? EMPTY_SHOW_ALL_TOOL_OUTPUT_IDS;\n const updateToolExpansionOverrides = useCallback(\n (update: (current: Map<string, boolean>) => Map<string, boolean>) => {\n setToolExpansionOverridesByTranscript((current) => {\n const currentOverrides = current.get(activeTranscriptScope) ?? new Map<string, boolean>();\n const nextOverrides = update(currentOverrides);\n if (nextOverrides === currentOverrides) return current;\n return new Map(current).set(activeTranscriptScope, nextOverrides);\n });\n },\n [activeTranscriptScope],\n );\n const focusTool = useCallback(\n (toolId: string) => {\n setFocusedToolIdsByTranscript((current) =>\n new Map(current).set(activeTranscriptScope, toolId),\n );\n },\n [activeTranscriptScope],\n );\n const showAllToolOutput = useCallback(\n (toolId: string) => {\n setShowAllToolOutputIdsByTranscript((current) => {\n const nextIds = new Set(current.get(activeTranscriptScope) ?? []).add(toolId);\n return new Map(current).set(activeTranscriptScope, nextIds);\n });\n },\n [activeTranscriptScope],\n );\n // The live turn renders as a streaming AgentMessage; its exact height depends\n // on markdown and reasoning collapse, so this is only a change signal.\n const selectedManagedAgentLiveRows = selectedManagedAgentLiveText\n ? wordWrap(selectedManagedAgentLiveText, Math.max(1, termWidth - 2)).split('\\n').length\n : 0;\n // Bumped by the composer when its height may have changed (a menu opened, the\n // draft gained a line). The footer shares the screen with the transcript, so\n // the transcript's viewport must be measured again.\n const [footerLayoutRevision, setFooterLayoutRevision] = useState(0);\n const bumpFooterLayout = useCallback(() => setFooterLayoutRevision((value) => value + 1), []);\n // A sheet with a text editor open takes the readline chords, so the transcript\n // must not read Ctrl+U and Ctrl+D as half-page scrolls while it is. The sheets\n // report this the same way they report their height — see `useReportLayout`.\n const [sheetEditorFocused, setSheetEditorFocused] = useState(false);\n // Sheets come and go, so a sheet that unmounts while focused has to hand the\n // chords back rather than leave them claimed for a surface that is gone.\n useEffect(() => {\n if (!pendingPlanApproval && !pendingUserQuestion && !pendingElicitation && !childQuestion) {\n setSheetEditorFocused(false);\n }\n }, [childQuestion, pendingElicitation, pendingPlanApproval, pendingUserQuestion]);\n // Whether a composer menu is open, as of the last commit. Read by the Esc\n // handler below, which must not also act on the Esc that closes a menu.\n const composerMenuOpenRef = useRef(false);\n const trackComposerMenu = useCallback((open: boolean) => {\n composerMenuOpenRef.current = open;\n }, []);\n const transcriptLayoutRevision = useMemo(\n () =>\n JSON.stringify([\n footerLayoutRevision,\n error ?? '',\n streamingMessageId ?? '',\n transcriptMode,\n activeExpandedToolId ?? '',\n [...toolExpansionOverrides.entries()].sort(([left], [right]) =>\n left < right ? -1 : left > right ? 1 : 0,\n ),\n showAllDetailedOutput,\n [...showAllToolOutputIds].sort(),\n liveConfig.settings.ui.showThinking,\n pendingPermission?.toolCall.id ?? '',\n managedAgents.surface,\n managedAgents.selectedAgentId ?? '',\n selectedManagedAgentRecord?.status ?? '',\n selectedManagedAgentRecord?.referencedEvidenceIds.length ?? 0,\n selectedManagedAgentLiveRows,\n referencePanel === 'steps'\n ? agentTodos.map((todo) => [todo.status, todo.content, todo.activeForm ?? ''])\n : [],\n referencePanel === 'tasks' ? tasks.map((task) => [task.id, task.status, task.subject]) : [],\n showHelp,\n showStatus,\n showPermissions,\n showSkills,\n showShortcuts,\n pendingPlanApproval?.plan ?? '',\n ]),\n [\n footerLayoutRevision,\n error,\n streamingMessageId,\n transcriptMode,\n activeExpandedToolId,\n toolExpansionOverrides,\n showAllDetailedOutput,\n showAllToolOutputIds,\n liveConfig.settings.ui.showThinking,\n pendingPermission,\n managedAgents.surface,\n managedAgents.selectedAgentId,\n selectedManagedAgentRecord,\n selectedManagedAgentLiveRows,\n referencePanel,\n agentTodos,\n tasks,\n showHelp,\n showStatus,\n showPermissions,\n showSkills,\n showShortcuts,\n pendingPlanApproval,\n ],\n );\n\n useEffect(() => {\n setTranscriptMode('compact');\n setShowAllDetailedOutput(false);\n setShowAllToolOutputIdsByTranscript(new Map());\n setToolExpansionOverridesByTranscript(new Map());\n setFocusedToolIdsByTranscript(new Map());\n }, [sessionId]);\n\n useEffect(\n () => () => {\n if (flashTimerRef.current) clearTimeout(flashTimerRef.current);\n if (ctrlCExitHintTimerRef.current) clearTimeout(ctrlCExitHintTimerRef.current);\n },\n [],\n );\n\n const toggleToolExpansion = useCallback(\n (toolId: string, expanded: boolean) => {\n focusTool(toolId);\n updateToolExpansionOverrides((current) => new Map(current).set(toolId, !expanded));\n },\n [focusTool, updateToolExpansionOverrides],\n );\n\n const handleSubmit = useCallback(\n async (value: string, attachments: ImageAttachment[] = []) => {\n // Nothing is submitted once an exit has started: SessionEnd is running.\n if (exitStartedRef.current) return;\n if (attachments.length > 0 && liveConfig.modelInfo?.vision === false) {\n addLocalMessage(`${liveConfig.model} does not support image input.`);\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value,\n attachments,\n }));\n return;\n }\n // A submission ends a recalled queued edit; a stale marker made the next idle Ctrl+C\n // remove an edit that no longer existed. What happens to the inputs queued before it\n // depends on what replaced it.\n if (editingQueuedInputRef.current) {\n const othersQueued = queuedInputsRef.current.length > 0;\n if (othersQueued && !value.startsWith('/') && managedAgents.surface === 'main') {\n // The edited text goes back to the end of the queue, where it was recalled from, so\n // the inputs queued before it are still sent first.\n if (enqueueFollowUp(value, attachments)) {\n // It follows the transcript to the bottom as any other submission does.\n setFollowRequestKey((key) => key + 1);\n } else {\n // The queue filled up while this input was out for editing. The composer has already\n // cleared it, so put it back, still recalled, rather than drop it; the notice the\n // rejection left says what Enter and Esc do with it.\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value,\n attachments,\n }));\n }\n return;\n }\n // Anything else, a slash command such as /exit included, leaves them waiting instead\n // of sending them behind it.\n endQueuedEdit(othersQueued);\n setQueueNotice(othersQueued ? QUEUE_PAUSED_NOTICE : undefined);\n }\n setFollowRequestKey((key) => key + 1);\n const selectedChild = managedAgents.selectedAgentId\n ? managedAgents.records.get(managedAgents.selectedAgentId)\n : undefined;\n if (\n managedAgents.surface === 'detail' &&\n !value.startsWith('/') &&\n selectedChild &&\n attachments.length === 0\n ) {\n await managedAgents.send(value);\n return;\n }\n if (managedAgents.surface === 'detail' && attachments.length > 0) {\n addLocalMessage('Image attachments are sent to the main conversation.');\n returnToMain();\n }\n if (\n managedAgents.surface === 'detail' &&\n !value.startsWith('/') &&\n (!selectedChild || selectedShellId)\n ) {\n returnToMain();\n }\n if (managedAgents.surface === 'detail' && value.startsWith('/')) {\n addLocalMessage('Session commands apply to the main conversation while viewing a child.');\n }\n // Coarse slash-command dispatch trace (one event per submit).\n const parsedSlash = parseSlashInput(value);\n if (parsedSlash && attachments.length > 0) {\n addLocalMessage('✕ Image attachments cannot be combined with slash commands.');\n return;\n }\n if (parsedSlash?.name === 'queue') {\n const operation = parsedSlash.rawArguments.trim().toLowerCase();\n if (operation === 'clear') {\n replaceQueuedInputs([]);\n endQueuedEdit();\n announceQueueEvent('Queued follow-up inputs cleared.', 'done');\n } else {\n const count = queuedInputsRef.current.length;\n const counted = `${count} follow-up input${count === 1 ? '' : 's'} queued.`;\n if (count > 0 && queueDrainPausedRef.current) {\n // A paused queue is a state, not an event: keep saying so where the paused notice\n // was, rather than announce the count over it and leave nothing on screen to say\n // the queue is waiting.\n setQueueNotice(`${counted} ${QUEUE_PAUSED_NOTICE}`);\n } else {\n announceQueueEvent(\n count === 0 ? 'The follow-up queue is empty.' : `${counted} Up edits the newest.`,\n 'info',\n 6_000,\n );\n }\n }\n return;\n }\n if (parsedSlash) {\n uiLog.event('slash:dispatch', {\n command: parsedSlash.name,\n hasArg: parsedSlash.rawArguments.length > 0,\n disabled: isThinking,\n });\n } else {\n uiLog.event('submit:text', { len: value.length, disabled: isThinking });\n }\n // Built-ins resolve through the shared exact-name registry before custom commands.\n const commandName = parsedSlash?.name ?? '';\n const commandArg = parsedSlash?.rawArguments ?? '';\n if (parsedSlash) {\n const commandContext: BuiltinCommandContext = {\n workspace: config.workspace,\n sessionId,\n model: liveConfig.model,\n provider: liveConfig.provider,\n currentTurn,\n messages,\n lastError: error,\n effortUnavailableError: getEffortUnavailableError(liveConfig),\n runtimeConfig: liveConfig,\n mode,\n usage,\n sessionUsage,\n sessionUsageSinceResume,\n turnDurationMs,\n contextHistory,\n compactBoundaries,\n commandCount: commands.length,\n skillCount: skills.length,\n skillSnapshot: runtime?.inspectSkills(currentTurn),\n mcpSnapshot,\n toolCallStats: runtime?.toolCallStats,\n // Records, not `summaries`: that list drops a terminal agent once its\n // completion has been delivered, which is right for the agent panel and\n // wrong for a bill. A finished agent's tokens were still spent.\n delegatedUsage: [...managedAgents.records.values()].flatMap((record) => {\n const usage = record.runUsage ?? record.usage;\n return usage\n ? [\n {\n label: `${record.profile ?? record.name} \"${record.displayName ?? record.name}\"`,\n model: record.resolvedModel ?? 'unknown',\n usage,\n },\n ]\n : [];\n }),\n resolveAmbientContext: () => ({\n subagentCount: discoverAgents(config.workspace).length,\n hasMemoryIndex: Boolean(\n liveConfig.memoryContext?.indexLoaded ?? getMemoryIndex(config.workspace).indexFile,\n ),\n hasClaudeMdLoader: discoverClaudeMd(config.workspace).length > 0,\n }),\n };\n let effect: BuiltinCommandEffect | undefined;\n try {\n effect = builtinCommandRegistry.execute(\n parsedSlash.name,\n parsedSlash.rawArguments,\n commandContext,\n );\n } catch (commandError) {\n addLocalMessage(\n `✕ ${commandError instanceof Error ? commandError.message : String(commandError)}`,\n );\n return;\n }\n if (effect?.type === 'send-prompt') {\n void dispatchAgentSend(effect.prompt, effect.context);\n return;\n }\n if (effect?.type === 'local-message') {\n if (effect.display) addLocalMessage(effect.content, effect.display);\n else addLocalMessage(effect.content);\n if (effect.refreshMemory) refreshMemoryContext();\n return;\n }\n if (effect?.type === 'start-new-conversation') {\n clearTasks();\n setReferencePanel(null);\n setShowSessionPicker(false);\n setShowRewindPicker(false);\n void startNewConversation(effect.previousName).catch((err) => {\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\n });\n stdout?.write('\\x1b[2J\\x1b[3J\\x1b[H');\n return;\n }\n if (effect?.type === 'resume-conversation') {\n if (!effect.session) {\n setShowSessionPicker(true);\n } else {\n clearTasks();\n void resumeConversation(effect.session).catch((err) => {\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\n });\n }\n return;\n }\n if (effect?.type === 'compact') {\n void compact(effect.focus);\n return;\n }\n if (effect?.type === 'exit') {\n exitOnce();\n return;\n }\n if (effect?.type === 'show-modal') {\n // Opened by its own command, so Esc belongs to the composer rather\n // than to a `/config` menu the user may have visited earlier.\n forgetConfigOrigin();\n if (effect.modal === 'config') {\n setConfigInitialRow(0);\n setShowConfigPicker(true);\n } else if (effect.modal === 'model') {\n setSelectingCompactModel(false);\n setShowModelPicker(true);\n } else if (effect.modal === 'rewind') setShowRewindPicker(true);\n else if (effect.modal === 'skills') setShowSkills(true);\n else if (effect.modal === 'agents') setShowAgentProfilePicker(true);\n else setShowEffortPicker(true);\n return;\n }\n if (effect?.type === 'set-model') {\n // The status line names the model; a switch needs no other word.\n const result = setModel(effect.selection);\n if (!result.ok) addLocalMessage(`✕ ${result.error}`);\n return;\n }\n if (effect?.type === 'set-effort') {\n // Shown beside the model in the status line.\n const result = setEffort(effect.level);\n if (!result.ok) addLocalMessage(`✕ ${result.error}`);\n return;\n }\n if (effect?.type === 'set-compact-model') {\n const result = setCompactModel(effect.model);\n if (result.ok) flashNotice(`Compact model: ${stripProvider(effect.model)}`);\n else addLocalMessage(`✕ ${result.error}`);\n return;\n }\n if (effect?.type === 'set-default-permission-mode') {\n const result = setDefaultPermissionMode(effect.mode);\n if (result.ok) flashNotice(`Default permissions: ${effect.mode}`);\n else addLocalMessage(`✕ ${result.error}`);\n return;\n }\n if (effect?.type === 'set-show-thinking') {\n const result = toggleShowThinking(effect.enabled);\n if (result.ok) flashNotice(effect.enabled ? 'Thinking shown' : 'Thinking hidden');\n else addLocalMessage(`✕ ${result.error ?? 'Could not save thinking setting.'}`);\n return;\n }\n if (effect?.type === 'set-startup-animation') {\n const result = toggleStartupAnimation(effect.enabled);\n if (result.ok) {\n // The row saves to `~/.book/settings.json`, and the variable outranks\n // that file at every launch, so a save here looks like it took effect\n // when it will not. Same sentence as the `BOOK_MODEL` warning above.\n const envNote = startupAnimationEnvNote();\n flashNotice(\n `Startup animation ${effect.enabled ? 'on' : 'off'}` +\n (envNote ? ` · ${envNote}` : ''),\n );\n } else {\n addLocalMessage(`✕ ${result.error ?? 'Could not save the startup animation setting.'}`);\n }\n return;\n }\n if (effect?.type === 'set-memory-auto-save') {\n setMemoryAutoSave(effect.enabled);\n flashNotice(\n effect.enabled\n ? liveConfig.settings.memory.requireApproval\n ? 'Memory writes on · new memories wait in /memory inbox'\n : 'Memory writes on · saved directly, external content to /memory inbox'\n : 'Memory writes off · approved memory still loads',\n 'done',\n 5_000,\n );\n return;\n }\n if (effect?.type === 'toggle-panel') {\n const panel = effect.panel;\n setReferencePanel((current) => (current === panel ? null : panel));\n return;\n }\n if (effect?.type === 'add-task') {\n addTask({ subject: effect.subject, status: 'pending' });\n return;\n }\n if (effect?.type === 'show-diff') {\n void runGit(['diff'], {\n workspaceRoot: config.workspace,\n env: process.env as Record<string, string>,\n }).then((result) => {\n addLocalMessage(\n result.error ? `✕ ${result.error}` : result.output.trim() || '(no changes)',\n );\n });\n return;\n }\n if (effect?.type === 'reload-assets') {\n setCommands(discoverCommands(config.workspace));\n const refreshedSkills = runtime?.reloadSkills(\n config.workspace,\n liveConfig.settings.skills,\n 'command',\n );\n setSkills(\n refreshedSkills?.list() ??\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\n executionOverrides: liveConfig.settings.skills.execution,\n enabled: liveConfig.settings.skills.enabled,\n }),\n );\n setSkillWatcherError(runtime?.skillWatcherError);\n setAgentProfiles(withBuiltInAgents(discoverAgents(config.workspace)));\n flashNotice('Commands and skills reloaded');\n return;\n }\n if (effect?.type === 'review') {\n startReview(effect.scope);\n return;\n }\n if (effect?.type === 'managed-agent') {\n const manager = managedAgentManager;\n const reportError = (managedError: unknown) =>\n addLocalMessage(\n `✕ ${managedError instanceof Error ? managedError.message : String(managedError)}`,\n );\n if (effect.operation === 'list') {\n managedAgents.setSurface('tasks');\n void managedAgents.refresh().catch(reportError);\n backgroundShells.refresh();\n } else if (effect.operation === 'import') {\n try {\n const previews = previewAgentImport(effect.importPath!);\n if (previews.length === 0) throw new Error('No Markdown agent definitions found.');\n const report = previews\n .map((preview) =>\n [\n `${preview.name}: ${preview.description}`,\n `tools: ${preview.tools.join(', ') || '(none)'}`,\n `model: ${preview.model ?? 'inherit'}`,\n ...preview.warnings.map((warning) => `warning: ${warning}`),\n ].join('\\n'),\n )\n .join('\\n\\n');\n if (!effect.confirmed) {\n addLocalMessage(\n `${report}\\n\\nRun /agents import --confirm ${effect.importPath} to install.`,\n );\n } else {\n const installed = installAgentImports(\n previews,\n join(config.workspace, '.book', 'agents'),\n );\n addLocalMessage(`${report}\\n\\nInstalled:\\n${installed.join('\\n')}`);\n setAgentProfiles(withBuiltInAgents(discoverAgents(config.workspace)));\n void managedAgents.refresh();\n }\n } catch (importError) {\n reportError(importError);\n }\n } else if (effect.operation === 'send') {\n void manager\n .send(effect.agentId!, effect.message ?? '')\n .then((record) => {\n managedAgents.selectAgent(record.id);\n managedAgents.setSurface('detail');\n })\n .catch(reportError);\n } else if (effect.operation === 'stop') {\n void manager\n .stop(effect.agentId!)\n .then((record) => flashNotice(`Stopped ${record.displayName ?? record.name}`))\n .catch(reportError);\n } else if (effect.operation === 'apply') {\n void manager\n .apply(effect.agentId!, effect.evidenceId)\n .then((result) =>\n addLocalMessage(\n result.status === 'applied'\n ? `Applied validated candidate${result.commit ? ` (${result.commit})` : ''}.`\n : `Application ${result.status}${result.error ? `: ${result.error}` : '.'}`,\n ),\n )\n .catch(reportError);\n } else {\n void manager\n .get(effect.agentId!)\n .then((record) => {\n if (!record) throw new Error(`Agent ${effect.agentId} was not found.`);\n managedAgents.selectAgent(record.id);\n managedAgents.setSurface('detail');\n })\n .catch(reportError);\n }\n return;\n }\n }\n if (value.startsWith('/')) {\n // Custom slash command: /name [args]\n const cmd = commands.find((c) => c.name === commandName);\n if (cmd) {\n const controller = new AbortController();\n commandResolutionRef.current?.abort();\n commandResolutionRef.current = controller;\n setIsResolvingCommand(true);\n let resolved: string;\n try {\n ({ resolved } = await resolveCommandBody(\n cmd,\n commandArg,\n {\n sessionId,\n workspace: config.workspace,\n model: liveConfig.model,\n projectCommands: liveConfig.settings.commands.projectCommands,\n },\n controller.signal,\n ));\n } catch (resolveError) {\n if (!controller.signal.aborted) {\n addLocalMessage(\n `✕ ${resolveError instanceof Error ? resolveError.message : String(resolveError)}`,\n );\n }\n return;\n } finally {\n if (commandResolutionRef.current === controller) {\n commandResolutionRef.current = null;\n setIsResolvingCommand(false);\n }\n }\n // Escape/Ctrl+C may abort after resolution succeeds; never dispatch stale input.\n if (controller.signal.aborted) return;\n // Pass command context for allowed-tools and model enforcement.\n // Shared with print/headless so both hosts enforce it identically.\n void dispatchAgentSend(resolved, commandEnforcementContext(cmd, resolved));\n } else {\n // Unknown command — send as-is (the model might handle it).\n void dispatchAgentSend(value);\n }\n } else {\n void dispatchAgentSend(value, undefined, attachments);\n }\n },\n [\n dispatchAgentSend,\n commandResolutionRef,\n clear,\n startNewConversation,\n resumeConversation,\n clearTasks,\n compact,\n addTask,\n commands,\n exitOnce,\n usage,\n liveConfig,\n addLocalMessage,\n setModel,\n setEffort,\n messages,\n currentTurn,\n turnDurationMs,\n error,\n skills,\n mcpSnapshot,\n sessionId,\n stdout,\n isThinking,\n redrawViewport,\n builtinCommandRegistry,\n managedAgentManager,\n managedAgents,\n endQueuedEdit,\n enqueueFollowUp,\n replaceQueuedInputs,\n ],\n );\n\n const canSubmitWhileParentBusy = useCallback((value: string) => {\n if (exitStartedRef.current) return false;\n const name = parseSlashInput(value)?.name;\n return name === 'tasks' || name === 'jobs' || name === 'queue';\n }, []);\n const canQueueWhileParentBusy = useCallback(\n (value: string) => !value.trimStart().startsWith('/'),\n [],\n );\n\n // Ctrl+U and Ctrl+D scroll the transcript half a page, but only when the\n // composer had no draft to edit. The composer is the only thing that knows\n // that, so it reports those chords through `forwardEmptyChord` and this hands\n // them back to the transcript as a request rather than as a keypress.\n const [transcriptScrollRequest, setTranscriptScrollRequest] = useState<TranscriptScrollRequest>({\n key: 0,\n direction: 'up',\n });\n const requestTranscriptHalfPage = useCallback((direction: 'up' | 'down') => {\n uiLog.event(`input:Ctrl+${direction === 'up' ? 'U' : 'D'}`, { action: 'scroll-transcript' });\n setTranscriptScrollRequest((current) => ({ key: current.key + 1, direction }));\n }, []);\n\n const handleGlobalShortcut = useCallback(\n (\n input: string,\n key: {\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n tab?: boolean;\n home?: boolean;\n end?: boolean;\n },\n ): boolean => {\n // Ctrl+/ and Ctrl+E must be handled here (not only in the parent useInput)\n // because ink-text-input consumes some Ctrl key events before they reach\n // the parent handler.\n if (\n showModelPicker ||\n showEffortPicker ||\n showPermissionModePicker ||\n showRewindPicker ||\n showConfigPicker ||\n showAgentProfilePicker ||\n showSkills\n )\n return true;\n // Ink broadcasts keypresses to every mounted input handler. The top-level\n // handler decides Ctrl+C behavior; this branch only consumes the key so\n // InputBar does not insert it into the composer.\n if (key.ctrl && input === 'c') {\n return true;\n }\n if (key.ctrl && input === 'l') {\n uiLog.event('input:Ctrl+L', { action: 'redraw' });\n redrawViewport?.();\n return true;\n }\n // Reached with Ctrl+U / Ctrl+D only when the composer had nothing to edit:\n // InputBar hands over the chords it cannot spend, and nothing else routes\n // them here, so a draft in hand never scrolls the transcript out from under\n // the person clearing it.\n const halfPage = halfPageScrollDirection(input, key);\n if (halfPage) {\n requestTranscriptHalfPage(halfPage);\n return true;\n }\n if (key.ctrl && (key.home || key.end)) {\n return true;\n }\n if (isShortcutsToggleKey(input, key)) {\n uiLog.event('input:Ctrl+/', { action: 'toggle-shortcuts' });\n setReferencePanel((current) => (current === 'shortcuts' ? null : 'shortcuts'));\n return true; // consumed\n }\n const transcriptAction = getTranscriptShortcutAction(transcriptMode, input, key);\n if (transcriptAction === 'enter-detailed') {\n uiLog.event('input:Ctrl+O', { action: 'enter-detailed-transcript' });\n setTranscriptMode('detailed');\n setShowAllDetailedOutput(false);\n return true;\n }\n if (transcriptAction === 'expand-output') {\n const targetToolId =\n activeExpandedToolId ?? focusedToolId ?? selectLatestToolId(activeTranscriptMessages);\n uiLog.event('input:Ctrl+E', { action: 'expand-current-tool', toolId: targetToolId });\n if (targetToolId) {\n updateToolExpansionOverrides((current) => new Map(current).set(targetToolId, true));\n showAllToolOutput(targetToolId);\n }\n return true; // consumed\n }\n return false; // not consumed — let text input handle it\n },\n [\n redrawViewport,\n requestTranscriptHalfPage,\n showEffortPicker,\n showPermissionModePicker,\n showModelPicker,\n showRewindPicker,\n showConfigPicker,\n showAgentProfilePicker,\n showSkills,\n activeExpandedToolId,\n activeTranscriptMessages,\n focusedToolId,\n showAllToolOutput,\n updateToolExpansionOverrides,\n ],\n );\n\n // Track input changes for command menu filtering — now handled inside InputBar.\n // handleGlobalShortcut remains for Ctrl+/ keyboard shortcut reference.\n\n // Hoisted so the composer and the interactive /permissions sheet agree on who\n // holds the keyboard, instead of restating the same fifteen flags twice.\n const modalOwnsInput = ownsModalInput(\n pendingPermission ?? childPermission ?? childQuestion,\n pendingPlanApproval,\n showModelPicker,\n showSessionPicker,\n pendingUserQuestion,\n showEffortPicker,\n showRewindPicker,\n showConfigPicker,\n showAgentProfilePicker,\n showPermissionModePicker,\n showSkills,\n showMcpApproval,\n pendingElicitation,\n );\n\n // The subset of `modalOwnsInput` that is genuinely a question. Everything else\n // it covers is a sheet holding the keyboard while it is open, and telling\n // someone to answer `/config` describes a prompt that is not there.\n const awaitingAnswer =\n Boolean(\n pendingPermission ??\n childPermission ??\n childQuestion ??\n pendingPlanApproval ??\n pendingUserQuestion ??\n pendingElicitation,\n ) || showMcpApproval;\n\n // Whether the composer is taking keys at all. The transcript asks the same\n // question before it reads Ctrl+U and Ctrl+D as paging chords, so the answer\n // is named once here instead of being restated in two places that could drift.\n const composerAcceptsInput = !(\n modalOwnsInput ||\n // The rules sheet is a list, not a page of text: while it is up\n // it takes the arrows, so the composer must not also read them\n // as history navigation. Esc closes it, as it does every panel.\n showPermissions ||\n transcriptMode === 'detailed' ||\n managedAgents.surface === 'tasks' ||\n detailTaskPickerOpen\n );\n\n // Whether the transcript may read Ctrl+U and Ctrl+D as its own half-page\n // scrolls. The rule is \"no editor on screen is taking the keys\", not \"the\n // composer is free\": the composer spends those chords on the draft and a\n // sheet's editor spends them on its field, and either one hands back a chord\n // it cannot spend as `transcriptScrollRequest` instead. A sheet that is up with\n // no editor open is a list of choices, and there the chords can only mean\n // paging. `pagerChordsAvailable` is that rule as one function, so it cannot be\n // restated — and read backwards — at a second call site.\n const pagerChordsFree = pagerChordsAvailable({ composerAcceptsInput, sheetEditorFocused });\n\n const pickerOwnsTranscript =\n showModelPicker ||\n showEffortPicker ||\n showPermissionModePicker ||\n showSessionPicker ||\n showRewindPicker ||\n showConfigPicker ||\n showAgentProfilePicker ||\n showSkills;\n\n // A render crash replaces the whole UI, so the error box is the only thing\n // left to say whether the conversation survived. It did — the session file is\n // appended synchronously — but only when there is a store to have written it,\n // and only worth reopening once it holds more than its own header. A crash\n // during startup would otherwise promise a conversation and hand back an\n // empty one.\n const resumeCommand =\n session.store && messages.length > 0 ? `book --resume ${sessionId}` : undefined;\n // The boundary cannot lean on the global handler below: that handler is still\n // mounted with whatever state it held when the render blew up, so it swallows\n // Ctrl+C behind `ownsModalInput` if a picker was open and spends it on\n // `interrupt()` if a turn was streaming. It gets the same exit path either\n // way, latch included, so the session still ends cleanly and only once.\n const exitFromCrash = exitOnce;\n\n if (startupFireActive) {\n return (\n <AppProviders theme={currentTheme.tokens} density={density}>\n <GlobalKeyHandler onInput={forwardInput} />\n <ErrorBoundary resumeCommand={resumeCommand} onExit={exitFromCrash}>\n <StartupFire\n width={termWidth}\n height={Math.max(1, termHeight - 1)}\n onComplete={() => setStartupFireActive(false)}\n />\n </ErrorBoundary>\n </AppProviders>\n );\n }\n\n const contextWindow = resolveContextWindow(liveConfig);\n\n // Shown for as long as SessionEnd runs; the composer takes nothing meanwhile. Read only once\n // an exit has started, so a host config without a hooks block renders as before.\n const exitingNotice = !exitStarted\n ? undefined\n : liveConfig.settings.hooks?.SessionEnd?.length\n ? 'Exiting: running SessionEnd hooks…'\n : 'Exiting…';\n\n return (\n <AppProviders theme={currentTheme.tokens} density={density}>\n <GlobalKeyHandler onInput={forwardInput} />\n <ErrorBoundary resumeCommand={resumeCommand} onExit={exitFromCrash}>\n <Box\n flexDirection=\"column\"\n width={termWidth}\n height={Math.max(1, termHeight - 1)}\n overflow=\"hidden\"\n >\n <TranscriptView\n key={sessionId}\n width={termWidth}\n isActive={!pickerOwnsTranscript && managedAgents.surface !== 'tasks'}\n followRequestKey={followRequestKey}\n layoutRevision={transcriptLayoutRevision}\n pagerChordsAvailable={pagerChordsFree}\n scrollRequest={transcriptScrollRequest}\n onToggleTool={toggleToolExpansion}\n onNotify={handleCopiedNotice}\n onRedrawViewport={redrawViewport}\n >\n <Box flexDirection=\"column\" width={termWidth}>\n {error && (\n <Box paddingX={1} marginBottom={1}>\n <Text color={theme.error}>✕ {error}</Text>\n </Box>\n )}\n {managedAgents.surface === 'detail' && selectedShellId ? (\n backgroundShells.shells.find((shell) => shell.id === selectedShellId) ? (\n <BackgroundShellDetail\n shell={backgroundShells.shells.find((shell) => shell.id === selectedShellId)!}\n readTail={readSelectedShellTail}\n width={termWidth}\n />\n ) : (\n <Box paddingX={1}>\n <Text color={theme.subtle}>Loading background shell…</Text>\n </Box>\n )\n ) : managedAgents.surface === 'detail' && managedAgents.selectedAgentId ? (\n // Viewing a child: never fall back to the main conversation.\n // The record can briefly lag its summary (a status event lists\n // an agent before its record is stored), so show a loading\n // placeholder until it arrives rather than the parent transcript.\n managedAgents.records.get(managedAgents.selectedAgentId) ? (\n <SubagentDetail\n record={managedAgents.records.get(managedAgents.selectedAgentId)!}\n liveText={managedAgents.liveText.get(managedAgents.selectedAgentId)}\n width={termWidth}\n height={termHeight}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n transcriptMode={transcriptMode}\n automaticToolCallId={activeExpandedToolId}\n toolExpansionOverrides={toolExpansionOverrides}\n showAllToolOutput={showAllDetailedOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n showThinking={liveConfig.settings.ui.showThinking}\n />\n ) : (\n <Box paddingX={1}>\n <Text color={theme.subtle}>Loading subagent…</Text>\n </Box>\n )\n ) : (\n <ChatPanel\n messages={messages}\n managedAgentTraces={managedAgentTraces}\n compactBoundaries={compactBoundaries}\n streamingMessageId={streamingMessageId}\n pendingPermission={pendingPermission}\n transcriptMode={transcriptMode}\n automaticToolCallId={expandedToolId}\n toolExpansionOverrides={toolExpansionOverrides}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n terminalWidth={termWidth}\n showThinking={liveConfig.settings.ui.showThinking}\n terminalHeight={termHeight}\n workspace={config.workspace}\n recentSessions={recentSessions ?? NO_RECENT_SESSIONS}\n contentsPending={recentSessions === undefined}\n model={liveConfig.modelSelection ?? liveConfig.model}\n mode={mode}\n commandCount={commands.length}\n skillCount={skills.length}\n retryPhase={retryPhase}\n showAllToolOutput={showAllDetailedOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n retryAttempt={retryAttempt}\n retryMax={retryMax}\n retryCountdownMs={retryCountdownMs}\n />\n )}\n {referencePanel === 'steps' && (\n <StepsSheet todos={agentTodos} width={panelGrid(termWidth).width} />\n )}\n {referencePanel === 'tasks' && (\n <TaskList\n tasks={tasks}\n width={panelGrid(termWidth).width}\n onUpdateStatus={updateTaskStatus}\n onRemove={removeTask}\n />\n )}\n {showHelp && (\n <HelpPanel width={panelGrid(termWidth).width} customCommands={commands} />\n )}\n {showStatus && (\n <SoftPanel title=\"Session\" meta=\"Esc to close\" width={panelGrid(termWidth).width}>\n <KeyValueList\n width={panelContentWidth(termWidth)}\n rows={[\n { key: 'model', value: liveConfig.modelSelection ?? liveConfig.model },\n { key: 'auth', value: liveConfig.apiKey ? 'API key' : 'none' },\n { key: 'session', value: displaySessionName(sessionName) },\n { key: 'workspace', value: config.workspace },\n { key: 'mode', value: mode },\n { key: 'turn', value: `${currentTurn}` },\n { key: 'tokens used', value: `${tokenCount}` },\n { key: 'max tokens', value: String(config.maxTokens) },\n {\n key: 'max turns',\n value:\n config.maxTurns == null || config.maxTurns <= 0\n ? 'unlimited'\n : String(config.maxTurns),\n },\n {\n key: 'tasks',\n value: `${tasks.length} (${tasks.filter((t) => t.status === 'in_progress').length} active)`,\n },\n ]}\n />\n </SoftPanel>\n )}\n {showPermissions && (\n <SoftPanel\n title=\"Permissions\"\n meta=\"Esc to close\"\n width={panelGrid(termWidth).width}\n >\n <PermissionsPanel\n mode={mode}\n permissions={liveConfig.settings.permissions}\n onRemove={removePermissionRule}\n active={!modalOwnsInput}\n terminalWidth={termWidth}\n screenReader={screenReader}\n />\n </SoftPanel>\n )}\n {pendingPlanApproval ? (\n <PlanApprovalDetails\n plan={pendingPlanApproval.plan}\n screenReader={screenReader}\n terminalWidth={termWidth}\n />\n ) : null}\n {showShortcuts && (\n <SoftPanel\n title=\"Keyboard shortcuts\"\n meta=\"Esc to close\"\n width={panelGrid(termWidth).width}\n >\n <KeyValueList\n keys=\"ink\"\n rows={SHORTCUT_ROWS}\n width={panelContentWidth(termWidth)}\n />\n </SoftPanel>\n )}\n </Box>\n </TranscriptView>\n\n <Box flexDirection=\"column\" flexShrink={0} width={termWidth}>\n {pendingPermission ? (\n <PermissionButtons\n key={pendingPermission.toolCall.id}\n toolCall={pendingPermission.toolCall}\n onResolve={resolvePermission}\n screenReader={screenReader}\n terminalWidth={termWidth}\n terminalRows={termHeight}\n workspaceRoot={config.workspace}\n onLayoutChange={bumpFooterLayout}\n />\n ) : childPermission?.type === 'agent_permission' ? (\n <Box flexDirection=\"column\">\n <Text color={theme.warning}>\n ? {childPermission.request.displayName} (\n {managedAgents.records.get(childPermission.agentId)?.profile ?? 'agent'}) requests{' '}\n {childPermission.request.toolName}\n </Text>\n <PermissionButtons\n key={childPermission.request.id}\n toolCall={childPermission.request.toolCall}\n onResolve={(decision) =>\n void managedAgents.resolvePermission(\n childPermission.request.id,\n // A managed agent persists rules through its own manager,\n // which has no scope ladder, so only the result travels.\n permissionResultOf(decision),\n )\n }\n screenReader={screenReader}\n terminalWidth={termWidth}\n terminalRows={termHeight}\n // A worktree-isolated agent mutates its own checkout, so the\n // preview must read the file the call will actually touch.\n workspaceRoot={\n managedAgents.records.get(childPermission.agentId)?.worktree ?? config.workspace\n }\n onLayoutChange={bumpFooterLayout}\n />\n </Box>\n ) : null}\n {pendingPlanApproval ? (\n <PlanApprovalActions\n plan={pendingPlanApproval.plan}\n onResolve={resolvePlanApproval}\n screenReader={screenReader}\n terminalWidth={termWidth}\n onLayoutChange={bumpFooterLayout}\n onEditorFocusChange={setSheetEditorFocused}\n />\n ) : null}\n {pendingElicitation ? (\n <McpElicitationForm\n key={pendingElicitation.request.id}\n request={pendingElicitation.request}\n queueLength={pendingElicitationCount}\n terminalWidth={termWidth}\n onResolve={resolveElicitation}\n screenReader={screenReader}\n onLayoutChange={bumpFooterLayout}\n onEditorFocusChange={setSheetEditorFocused}\n />\n ) : null}\n {pendingUserQuestion ? (\n <AskUserQuestionWizard\n key={pendingUserQuestion.request.id}\n request={pendingUserQuestion.request}\n queueLength={pendingUserQuestionCount}\n terminalWidth={termWidth}\n onResolve={resolveUserQuestion}\n screenReader={screenReader}\n onLayoutChange={bumpFooterLayout}\n onEditorFocusChange={setSheetEditorFocused}\n />\n ) : childQuestion ? (\n <AskUserQuestionWizard\n key={childQuestion.request.id}\n request={childQuestion.request}\n queueLength={managedAgents.pendingQuestions.length}\n terminalWidth={termWidth}\n onResolve={(response) =>\n void managedAgents.resolveQuestion(childQuestion.agentId, response)\n }\n screenReader={screenReader}\n onLayoutChange={bumpFooterLayout}\n onEditorFocusChange={setSheetEditorFocused}\n />\n ) : null}\n {showSessionPicker ? (\n <SessionPicker\n width={panelGrid(termWidth).width}\n sessions={listSessions()}\n currentSessionId={sessionId}\n onPick={(selected) => {\n setShowSessionPicker(false);\n clearTasks();\n void resumeConversation(selected.id).catch((err) => {\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\n });\n }}\n onCancel={() => setShowSessionPicker(false)}\n />\n ) : null}\n {showRewindPicker ? (\n <RewindPicker\n terminalWidth={termWidth}\n targets={getRewindTargets()}\n isRewinding={isRewinding}\n onAction={async (target, action) => {\n const result = await rewind(target.id, action);\n if (!result.ok) return result;\n if (action === 'conversation' || action === 'both') clearTasks();\n if (result.restoredPrompt !== undefined) {\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: result.restoredPrompt!,\n attachments: result.restoredAttachments,\n }));\n }\n setShowRewindPicker(false);\n setFollowRequestKey((key) => key + 1);\n return { ok: true };\n }}\n onCancel={() => setShowRewindPicker(false)}\n />\n ) : null}\n {showSkills ? (\n <SkillManager\n skills={skills}\n enabled={liveConfig.settings.skills.enabled}\n watcherError={skillWatcherError}\n lifecycleEvents={runtime?.inspectSkills(currentTurn)?.events}\n activeSkillNames={runtime\n ?.inspectSkills(currentTurn)\n ?.active.map((frame) => frame.skillName)}\n terminalWidth={termWidth}\n maxVisible={Math.max(3, Math.min(10, termHeight - 10))}\n onChangeActivation={(skillName, activation) => {\n const result = setSkillActivation(skillName, activation);\n if (!result.ok) return result;\n setSkills((current) =>\n current.map((skill) =>\n skill.name === skillName ? { ...skill, activation } : skill,\n ),\n );\n return result;\n }}\n onChangeExecution={(skillName, execution) => {\n const result = setSkillExecution(skillName, execution);\n if (!result.ok) return result;\n setSkills((current) =>\n current.map((skill) =>\n skill.name === skillName ? { ...skill, execution } : skill,\n ),\n );\n return result;\n }}\n onChangeEnabled={(enabled) => {\n const result = setSkillsEnabled(enabled);\n if (result.ok) {\n setSkills(\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\n executionOverrides: liveConfig.settings.skills.execution,\n enabled,\n }),\n );\n }\n return result;\n }}\n onUse={(skill: Skill) => {\n setDraftRestore((current) => ({\n key: (current?.key ?? 0) + 1,\n value: `$${skill.name} `,\n }));\n forgetConfigOrigin();\n setShowSkills(false);\n }}\n onReload={() => {\n const refreshed = runtime?.reloadSkills(\n config.workspace,\n liveConfig.settings.skills,\n );\n setSkills(\n refreshed?.list() ??\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\n executionOverrides: liveConfig.settings.skills.execution,\n enabled: liveConfig.settings.skills.enabled,\n }),\n );\n setSkillWatcherError(runtime?.skillWatcherError);\n }}\n onCancel={() => {\n setShowSkills(false);\n returnToConfig();\n }}\n />\n ) : null}\n {showConfigPicker ? (\n <ConfigMenu\n model={liveConfig.modelSelection ?? liveConfig.model}\n compactModel={liveConfig.compactModel ?? liveConfig.settings.compactModel}\n effort={liveConfig.effort}\n memoryAutoSave={liveConfig.settings.memory.autoSave}\n showThinking={liveConfig.settings.ui.showThinking}\n startupAnimation={liveConfig.settings.ui.startupAnimation}\n agentCount={agentProfiles.length}\n skillCount={skills.length}\n defaultPermissionMode={resolvePermissionMode(liveConfig.settings)}\n terminalWidth={termWidth}\n initialSelection={configInitialRow}\n onOpen={(section: ConfigSection, rowIndex: number) => {\n if (section === 'effort') {\n const unavailable = getEffortUnavailableError(liveConfig);\n if (unavailable) {\n addLocalMessage(`✕ ${unavailable}`);\n return;\n }\n }\n configReturnRow.current = rowIndex;\n setShowConfigPicker(false);\n if (section === 'model') {\n setSelectingCompactModel(false);\n setAgentProfileForModel(undefined);\n setShowModelPicker(true);\n } else if (section === 'compact-model') {\n setSelectingCompactModel(true);\n setAgentProfileForModel(undefined);\n setShowModelPicker(true);\n } else if (section === 'effort') {\n setShowEffortPicker(true);\n } else if (section === 'permission-mode') {\n setShowPermissionModePicker(true);\n } else if (section === 'skills') {\n setShowSkills(true);\n } else {\n setShowAgentProfilePicker(true);\n }\n }}\n onToggleMemory={() => toggleMemoryAutoSave()}\n onToggleThinking={() => {\n const result = toggleShowThinking();\n if (!result.ok)\n addLocalMessage(`✕ ${result.error ?? 'Could not save thinking setting.'}`);\n }}\n onToggleStartupAnimation={() => {\n const result = toggleStartupAnimation();\n if (!result.ok) {\n addLocalMessage(\n `✕ ${result.error ?? 'Could not save startup animation setting.'}`,\n );\n }\n }}\n startupAnimationWarning={startupAnimationEnvNote()}\n onCancel={() => {\n forgetConfigOrigin();\n setShowConfigPicker(false);\n }}\n />\n ) : null}\n {showAgentProfilePicker ? (\n <AgentProfilePicker\n profiles={agentProfiles}\n parentModel={liveConfig.modelSelection ?? liveConfig.model}\n configuredModels={configuredAgentModels}\n terminalWidth={termWidth}\n onSelect={(profile) => {\n setSelectingCompactModel(false);\n setAgentProfileForModel(profile);\n setShowAgentProfilePicker(false);\n setShowModelPicker(true);\n }}\n onReset={(profile) => {\n const result = setAgentProfileModel(profile);\n if (result.ok) flashNotice(`${capitalize(profile)} inherits the main model`);\n else addLocalMessage(`✕ ${result.error ?? `Could not reset ${profile}.`}`);\n }}\n onCancel={() => {\n setShowAgentProfilePicker(false);\n returnToConfig();\n }}\n />\n ) : null}\n {showModelPicker ? (\n <ModelPicker\n terminalWidth={termWidth}\n title={selectingCompactModel ? 'Choose compact model' : undefined}\n options={modelOptions}\n currentModel={modelPickerSelection}\n currentEffort={selectingCompactModel ? undefined : liveConfig.effort}\n effortLevels={\n selectingCompactModel || agentProfileForModel ? [] : (effortLevels ?? [])\n }\n hasPriorOutput={\n !selectingCompactModel && !agentProfileForModel && messages.length > 0\n }\n providers={liveConfig.settings.provider}\n workspace={config.workspace}\n retry={liveConfig.retry}\n compact={isNarrow || isTiny}\n maxVisibleModels={Math.max(3, Math.min(10, termHeight - 10))}\n warnings={[\n process.env.BOOK_MODEL\n ? `BOOK_MODEL is set to \"${process.env.BOOK_MODEL}\" — it overrides settings.model on next startup.`\n : '',\n liveConfig.model.startsWith('claude-') &&\n config.model &&\n !config.model.startsWith('claude-')\n ? 'Switching to an Anthropic model may need a separate API key.'\n : '',\n ].filter(Boolean)}\n onPick={(model, saveDefault) => {\n if (selectingCompactModel) {\n const result = setCompactModel(model);\n if (!result.ok) return result;\n flashNotice(`Compact model: ${stripProvider(model)}`);\n setSelectingCompactModel(false);\n setShowModelPicker(false);\n returnToConfig();\n return result;\n }\n if (agentProfileForModel) {\n const result = setAgentProfileModel(agentProfileForModel, model);\n if (!result.ok) return result;\n flashNotice(\n `${capitalize(agentProfileForModel)} model: ${stripProvider(model)}`,\n );\n setAgentProfileForModel(undefined);\n setShowModelPicker(false);\n setShowAgentProfilePicker(true);\n return result;\n }\n const result = setModel(model, { persist: saveDefault });\n if (!result.ok) return result;\n // The status line names the new model. Only a session-only switch\n // says anything, since nothing on screen tells it from a saved one.\n if (!saveDefault) flashNotice('For this session only', 'info');\n setShowModelPicker(false);\n returnToConfig();\n return result;\n }}\n onPickEffort={(level) => setEffort(level)}\n allowProviderManagement={!selectingCompactModel && !agentProfileForModel}\n onSaveProvider={upsertProviderAndSelect}\n removableProviderIds={removableProviderIds}\n removableProviderModelCounts={removableProviderModelCounts}\n onRemoveProvider={(providerId) => {\n const result = removeProvider(providerId);\n if (!result.ok) return result;\n flashNotice(providerRemovalMessage(result), 'done', 4_000);\n setShowModelPicker(false);\n returnToConfig();\n return result;\n }}\n onProviderSaved={(request) => {\n flashNotice(\n `Added ${request.providerId} · ${request.models.length} model${request.models.length === 1 ? '' : 's'}`,\n );\n setShowModelPicker(false);\n returnToConfig();\n }}\n onCancel={() => {\n // A model chosen *for a profile* was reached through the\n // profile picker, which is one step deeper than the menu; its\n // own cancel carries the user the rest of the way back, so the\n // recorded `/config` row must survive this close.\n const returnToAgents = Boolean(agentProfileForModel);\n setSelectingCompactModel(false);\n setAgentProfileForModel(undefined);\n setShowModelPicker(false);\n if (returnToAgents) setShowAgentProfilePicker(true);\n else returnToConfig();\n }}\n />\n ) : null}\n {showEffortPicker && effortLevels ? (\n <EffortPicker\n width={panelGrid(termWidth).width}\n current={liveConfig.effort}\n availableLevels={effortLevels}\n onSelect={(level) => {\n const result = setEffort(level);\n if (!result.ok) return result;\n // Shown beside the model in the status line.\n setShowEffortPicker(false);\n returnToConfig();\n return result;\n }}\n onCancel={() => {\n setShowEffortPicker(false);\n returnToConfig();\n }}\n />\n ) : null}\n {showPermissionModePicker ? (\n <PermissionModePicker\n width={panelGrid(termWidth).width}\n current={resolvePermissionMode(liveConfig.settings)}\n availableModes={\n [\n 'default',\n 'auto',\n 'plan',\n 'accept-edits',\n 'dontAsk',\n ...(liveConfig.settings.disableBypassPermissionsMode\n ? []\n : ['bypassPermissions']),\n ] as PermissionMode[]\n }\n onSelect={(nextMode) => {\n const result = setDefaultPermissionMode(nextMode);\n if (!result.ok) return result;\n flashNotice(`Default permissions: ${nextMode}`);\n setShowPermissionModePicker(false);\n returnToConfig();\n return result;\n }}\n onCancel={() => {\n setShowPermissionModePicker(false);\n returnToConfig();\n }}\n />\n ) : null}\n {showMcpApproval && pendingMcpApproval && mcp ? (\n <McpServerApprovalPrompt\n key={pendingMcpApproval.name}\n server={pendingMcpApproval}\n remainingCount={mcpSnapshot.pendingApprovals.length - 1}\n onApprove={() => mcp.approve(pendingMcpApproval.name)}\n onReject={() => mcp.reject(pendingMcpApproval.name)}\n onDefer={() => mcp.defer(pendingMcpApproval.name)}\n terminalWidth={termWidth}\n />\n ) : null}\n </Box>\n\n {compactUi &&\n (compactUi.phase === 'error' ||\n compactUi.phase === 'skipped' ||\n // A compaction that succeeded with something to say -- reduced\n // coverage, input that addressed the summarizer, or a deferred\n // checkpoint with a judge's verdict -- keeps its card; a clean\n // synchronous one is the boundary row in the transcript alone.\n (compactUi.phase === 'diff' && (compactUi.warning || compactUi.judge))) ? (\n <CompactDiffCard\n state={compactUi}\n terminalWidth={termWidth}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n />\n ) : null}\n\n {isResolvingCommand ? <Text dimColor>Resolving command shell expansions...</Text> : null}\n\n {reviewStatus ? <Text dimColor>{reviewStatus}... (Esc to cancel)</Text> : null}\n\n {managedAgents.persistenceEvent ? (\n <Text\n color={\n managedAgents.persistenceEvent.state === 'degraded' ? theme.warning : theme.success\n }\n >\n {managedAgents.persistenceEvent.state === 'degraded' ? '! ' : '✓ '}\n {managedAgents.persistenceEvent.message}\n </Text>\n ) : null}\n\n {/* While a decision sheet is up, it is the status: a \"Waiting for\n permission\" row under it only said the same thing a second time.\n Screen readers keep the row, which is how the wait is announced. */}\n {screenReader ||\n !(\n pendingPermission ||\n pendingUserQuestion ||\n pendingPlanApproval ||\n pendingElicitation\n ) ? (\n <WorkingIndicator\n isThinking={isThinking}\n isCompacting={isCompacting}\n compactComplete={isCompactCommitted}\n compactTrigger={compactUi?.trigger}\n messages={messages}\n streamingMessageId={streamingMessageId}\n pendingPermission={pendingPermission}\n pendingPlanApproval={pendingPlanApproval}\n pendingUserQuestion={pendingUserQuestion}\n pendingElicitation={pendingElicitation}\n retryPhase={retryPhase}\n retryAttempt={retryAttempt}\n retryMax={retryMax}\n retryCountdownMs={retryCountdownMs}\n terminalWidth={termWidth}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n activeStep={\n activeStep\n ? foldControlCharacters(activeStep.activeForm || activeStep.content)\n : undefined\n }\n />\n ) : null}\n\n {/* Input bar — above the status line. Command menu is built into InputBar. */}\n <Box\n flexDirection=\"column\"\n flexShrink={0}\n width={termWidth}\n marginTop={messages.length > 0 ? 1 : 0}\n >\n <QueuedInputPreview\n items={queuedInputs}\n terminalWidth={termWidth}\n // Keep the exit hint visible even when another transient notice remains.\n // An exit in progress outranks both: the queue's notices offer actions that no\n // longer do anything.\n notice={\n exitStarted\n ? exitingNotice\n : ctrlCExitHintVisible\n ? CTRL_C_EXIT_HINT_TEXT\n : (queueNotice ?? flash?.text)\n }\n noticeTone={\n exitStarted ? 'info' : ctrlCExitHintVisible || queueNotice ? 'warning' : flash?.tone\n }\n />\n <InputBar\n key={sessionId}\n onLayoutChange={bumpFooterLayout}\n onMenuOpenChange={trackComposerMenu}\n onSubmit={handleSubmit}\n onPasteImage={pasteClipboardImage}\n submissionMode={\n exitStarted\n ? 'blocked'\n : managedAgents.surface === 'detail'\n ? 'submit'\n : isThinking || sendInFlight\n ? 'queue'\n : isCompacting || isRewinding || isResolvingCommand\n ? 'blocked'\n : 'submit'\n }\n mode={mode}\n onCycleMode={cycleMode}\n canSubmitWhileBusy={canSubmitWhileParentBusy}\n canQueueWhileBusy={canQueueWhileParentBusy}\n onQueue={enqueueFollowUp}\n onRecallQueued={\n managedAgents.surface === 'main' && !exitStarted ? recallQueuedInput : undefined\n }\n onDraftChange={(value, attachments) => {\n draftRef.current = value;\n draftAttachmentsRef.current = attachments ?? [];\n }}\n onCycleAgentFocus={cycleAgentFocus}\n onFocusBackgroundTask={() => {\n if (managedAgents.surface === 'detail') {\n if (!managedAgentUiEnabled) return false;\n setDetailTaskPickerAgentId(undefined);\n setDetailTaskPickerOpen(true);\n return true;\n }\n const firstJobId =\n managedAgents.summaries[0]?.agentId ?? backgroundShells.shells[0]?.id;\n if (!managedAgentUiEnabled || !firstJobId) return false;\n selectBackgroundJob(firstJobId);\n managedAgents.setSurface('tasks');\n return true;\n }}\n inputSuppressed={!composerAcceptsInput}\n awaitingAnswer={awaitingAnswer}\n onGlobalShortcut={handleGlobalShortcut}\n commands={commands}\n skills={skills}\n terminalWidth={termWidth}\n maxMenuRows={maxCommandMenuRows}\n compact={isNarrow || isTiny}\n screenReader={screenReader}\n draftRestore={draftRestore}\n />\n </Box>\n\n {managedAgentUiEnabled &&\n (managedAgents.surface === 'main' ||\n managedAgents.surface === 'tasks' ||\n (managedAgents.surface === 'detail' && !detailTaskPickerOpen)) ? (\n <SubagentPanel\n agents={managedAgents.summaries}\n shells={backgroundShells.shells}\n selectedJobId={selectedShellId ?? managedAgents.selectedAgentId}\n isActive={managedAgents.surface === 'tasks'}\n onSelect={selectBackgroundJob}\n onOpen={(jobId) => {\n selectBackgroundJob(jobId);\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\n backgroundShells.acknowledge(jobId);\n }\n managedAgents.setSurface('detail');\n }}\n onClose={() => managedAgents.setSurface('main')}\n onCancel={() => managedAgents.setSurface('main')}\n onStopOrDismiss={(jobId) => {\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\n stopOrDismissShell(jobId);\n } else {\n void managedAgents.stopOrDismiss(jobId);\n }\n }}\n width={termWidth}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n />\n ) : null}\n\n {managedAgentUiEnabled && managedAgents.surface === 'detail' && detailTaskPickerOpen ? (\n <SubagentPanel\n agents={managedAgents.summaries}\n shells={backgroundShells.shells}\n selectedJobId={detailTaskPickerAgentId}\n isActive\n onSelect={setDetailTaskPickerAgentId}\n onOpen={(jobId) => {\n setDetailTaskPickerOpen(false);\n setDetailTaskPickerAgentId(undefined);\n selectBackgroundJob(jobId);\n }}\n onClose={returnToMain}\n onCancel={() => {\n setDetailTaskPickerOpen(false);\n setDetailTaskPickerAgentId(undefined);\n }}\n onStopOrDismiss={(jobId) => {\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\n stopOrDismissShell(jobId);\n } else {\n void managedAgents.stopOrDismiss(jobId);\n }\n }}\n width={termWidth}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n />\n ) : null}\n\n {/* Status line — stable footer */}\n <Box flexShrink={0} width={termWidth}>\n <StatusLine\n gitBranch={gitStatus.branch}\n gitStatus={gitStatus.status}\n model={liveConfig.modelSelection ?? liveConfig.model}\n effort={effortLevels && effortLevels.length > 0 ? liveConfig.effort : undefined}\n tokenCount={tokenCount}\n maxTokens={contextWindow.window}\n maxTokensSource={contextWindow.source}\n mode={mode}\n taskCount={tasks.length}\n activeTaskCount={tasks.filter((t) => t.status === 'in_progress').length}\n stepLabel={agentPlanCurrent ? statusStepLabel(agentTodos) : undefined}\n agentCount={managedAgentUiEnabled ? managedAgents.summaries.length : 0}\n activeAgentCount={\n managedAgentUiEnabled\n ? managedAgents.summaries.filter(\n (agent) =>\n !['completed', 'failed', 'stopped', 'interrupted'].includes(agent.status),\n ).length\n : 0\n }\n needsInputAgentCount={\n managedAgentUiEnabled\n ? managedAgents.summaries.filter(\n (agent) =>\n agent.status === 'waiting_input' || agent.status === 'waiting_permission',\n ).length\n : 0\n }\n turnCount={turnCount}\n terminalWidth={termWidth}\n compact={compactStatus}\n reducedMotion={motionDisabled}\n screenReader={screenReader}\n />\n </Box>\n </Box>\n </ErrorBoundary>\n </AppProviders>\n );\n}\n\nfunction AppProviders({\n theme,\n density,\n children,\n}: {\n theme: ThemeTokens;\n density: ReturnType<typeof resolveTuiDensity>;\n children: ReactNode;\n}) {\n return (\n <ThemeContext.Provider value={theme}>\n <DensityContext.Provider value={density}>{children}</DensityContext.Provider>\n </ThemeContext.Provider>\n );\n}\n\n/** The shortcuts reference (Ctrl+/): each key and what it does. */\nconst SHORTCUT_ROWS: ReadonlyArray<{ key: string; value: string }> = [\n { key: 'Esc', value: 'Deny a prompt, cancel the turn, or close this panel' },\n {\n key: 'Ctrl+C',\n value: 'Cancel current turn, clear the composer, or press twice idle to exit',\n },\n { key: 'Ctrl+T', value: \"Show or hide the agent's steps\" },\n { key: '/tasks', value: 'Focus background tasks; ↑↓ select, Enter open, x stop' },\n { key: 'Ctrl+O', value: 'Toggle detailed transcript' },\n { key: 'Ctrl+E', value: 'Expand current tool output (empty prompt)' },\n { key: 'Click', value: 'Expand or collapse a tool summary' },\n { key: 'Ctrl+L', value: 'Redraw screen' },\n { key: 'Alt+M', value: 'Cycle permission mode' },\n { key: 'Alt+P', value: 'Open model picker' },\n { key: 'Alt+V', value: 'Attach clipboard image' },\n { key: 'Up/Down', value: 'Navigate input history' },\n { key: 'Wheel', value: 'Scroll transcript' },\n { key: 'Drag', value: 'Select visible text and copy on release' },\n { key: 'Shift+drag', value: 'Use terminal-native text selection' },\n { key: 'PgUp/PgDn', value: 'Scroll transcript' },\n { key: 'Ctrl+U/Ctrl+D', value: 'Scroll transcript half a page (empty prompt)' },\n { key: 'Ctrl+Home/End', value: 'Jump to transcript start/latest' },\n { key: 'Ctrl+J / Shift+Enter', value: 'Insert newline (multiline)' },\n { key: 'Ctrl+A / Ctrl+E', value: 'Move to start / end of the prompt' },\n { key: 'Ctrl+W / Alt+Bksp', value: 'Delete the previous word' },\n { key: 'Ctrl+U / Ctrl+K', value: 'Delete to start / end of the prompt' },\n { key: 'Ctrl+Y', value: 'Put back the last deletion' },\n { key: 'Ctrl+/', value: 'Toggle this reference' },\n { key: '@path', value: 'Expand file contents' },\n { key: '!cmd', value: 'Run shell command' },\n];\n","/**\n * The transcript grid.\n *\n * Every row the TUI draws — an agent paragraph, a tool row, a turn rule, the\n * composer, the status line — resolves its horizontal position through this\n * module. Before it existed each component picked its own `marginLeft` and its\n * own `width - N` budget, so content landed on columns 1, 2, 4 and 5 with\n * nothing to scan down.\n *\n * The rule: a row is `[gutter][content]`. The gutter is exactly\n * {@link GUTTER_WIDTH} columns wide and carries status (a glyph, a rail, a\n * spinner); content always begins at {@link CONTENT_COLUMN}. Bordered surfaces\n * sit flush at column 0 so their one column of padding lands their text on the\n * same content column.\n *\n * Tool rows are the one deliberate step off that column. They carry their own\n * gutter one level in ({@link indentedGrid}) so the work a turn did reads as\n * nested under the prose that ordered it, instead of hanging a column of status\n * glyphs to the left of every sentence.\n */\n\n/** Status glyph plus its trailing space: `\"✓ \"`, `\"│ \"`, `\" \"`. */\nexport const GUTTER_WIDTH = 2;\n\n/**\n * Widest measure a floating surface uses, however wide the terminal is.\n *\n * Content and chrome want opposite things from a wide terminal. The transcript\n * holds the conversation — prose, diffs, code — and every column it is given is\n * a column it can use. A popover holds a list: slash commands, files, skills,\n * permission rules, none of them much past forty columns. Stretching that\n * border to two hundred draws an enormous empty box around a short list, which\n * is the same defect as a half-empty window wearing the opposite mask. So\n * content takes the terminal and chrome stops here.\n */\nexport const MAX_PANEL_MEASURE = 120;\n\n/**\n * Widest measure an aligned row lays its columns out in.\n *\n * A tool row puts its metadata flush against the right edge so the eye can scan\n * that column straight down a turn. This only reads as alignment while the edge\n * stays near the target: `67ms` sitting a hundred and seventy columns from the\n * command it timed is not aligned with that command, it is merely far away from\n * it. The prose around these rows takes the full terminal; the aligned columns\n * stop here, which also bounds the padding {@link composeToolRow} builds.\n */\nexport const MAX_ROW_MEASURE = 120;\n\n/** Columns a bordered surface spends on its own border plus one of padding. */\nexport const PANEL_CHROME = 4;\n\n/**\n * Width inside a sheet: a surface headed by a rule, whose rule spans the sheet\n * while its body sits two columns in from either end. The same\n * {@link PANEL_CHROME} a bordered surface spent, so content widths did not move\n * when the borders went.\n */\nexport function sheetContentWidth(sheetWidth: number, minimum = 1): number {\n return Math.max(minimum, Math.floor(sheetWidth) - PANEL_CHROME);\n}\n\n/**\n * Text columns of a sheet row that leads with a one-cell marker and a space.\n *\n * A sheet row that carries status is `[marker][space][text]`, the same shape as\n * a tool row: the glyph lands on the column a tool row's `✓` occupies and the\n * text starts at {@link CONTENT_COLUMN}. So the marker costs a sheet its full\n * {@link GUTTER_WIDTH} before it puts a character down, and the text that\n * follows has that much less room inside {@link sheetContentWidth}. A row\n * without a marker is indented by {@link SHEET_GUTTER_INDENT} to reach the same\n * column, and reads as one kind of row with the rest of the transcript.\n */\nexport function sheetRowTextWidth(sheetWidth: number, minimum = 1): number {\n return Math.max(minimum, sheetContentWidth(sheetWidth) - GUTTER_WIDTH);\n}\n\n/** The markerless row's gutter: the marker columns, left blank. */\nexport const SHEET_GUTTER_INDENT = ' '.repeat(GUTTER_WIDTH);\n\n/** Columns between two side-by-side columns of a sheet, such as /help's. */\nexport const SHEET_COLUMN_GAP = 4;\n\n/** Column where content begins on every row, nested or not. */\nexport const CONTENT_COLUMN = GUTTER_WIDTH;\n\n/** Below this width the label column collapses and rows render inline. */\nconst LABEL_COLUMN_MIN_WIDTH = 76;\n\n/** Widest label the aligned tool column holds without truncating. */\nexport const LABEL_COLUMN_WIDTH = 10;\n\n/** A target column narrower than this is not worth aligning around. */\nexport const MIN_TARGET_WIDTH = 12;\n\nexport interface TranscriptGrid {\n /** Full terminal width in columns. */\n width: number;\n /** Columns available to content, measured from {@link CONTENT_COLUMN}. */\n content: number;\n /**\n * Columns an aligned row lays its columns out in: {@link content}, bounded by\n * {@link MAX_ROW_MEASURE}. Shrinks with nesting exactly as `content` does, so\n * a nested row's right edge still lands on its parent's.\n */\n row: number;\n /** Width of the fixed label column; `0` when labels render inline. */\n label: number;\n /** Columns the middle (target) column may occupy. */\n target: number;\n /** Columns reserved for right-aligned metadata. */\n meta: number;\n}\n\n/**\n * Resolve the transcript grid for a terminal width.\n *\n * The grid takes the whole terminal. An earlier version capped the measure at\n * 120 columns to keep prose from running long, but a capped transcript on a\n * 200-column terminal does not read as a considered measure — it reads as a\n * broken window. Two thirds of the screen sits blank, the composer border stops\n * in mid-air, and diffs and code, which are most of what this UI exists to\n * show, get wrapped for no reason while the space to hold them goes unused.\n * The user picked the width of their terminal; do not reintroduce a cap here.\n */\nexport function transcriptGrid(terminalWidth: number): TranscriptGrid {\n // One trailing column stays empty: writing the last cell makes some\n // terminals emit a spurious wrap, which shears the row below.\n const width = Math.max(20, Math.floor(terminalWidth));\n const content = Math.max(8, width - CONTENT_COLUMN - 1);\n const label = width >= LABEL_COLUMN_MIN_WIDTH ? LABEL_COLUMN_WIDTH : 0;\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\n const target = Math.max(MIN_TARGET_WIDTH, content - label - meta - 1);\n return { width, content, row: Math.min(content, MAX_ROW_MEASURE), label, target, meta };\n}\n\n/**\n * A grid indented `depth` gutters, keeping its label column.\n *\n * The model says something, then shows its work; the work should sit under the\n * sentence that ordered it. Hanging the status glyph in a column to the *left*\n * of the prose made a turn read as a list of tool calls with text wedged\n * between them, the sentences pushed in from the margin rather than owning it.\n *\n * Indenting spends two columns, so the grid narrows as it shifts and the row's\n * right edge stays where the prose's is — right-aligned metadata still lines up\n * all the way down the transcript. Unlike {@link nestedGrid} the label column\n * survives: a top-level tool row is still the row that names its verb.\n */\nexport function indentedGrid(grid: TranscriptGrid, depth = 1): TranscriptGrid {\n const content = railContentWidth(grid, depth);\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\n const label = Math.min(grid.label, Math.max(0, content - meta - MIN_TARGET_WIDTH - 1));\n return {\n ...grid,\n content,\n row: railRowWidth(grid, depth),\n label,\n target: Math.max(MIN_TARGET_WIDTH, content - label - meta - 1),\n meta,\n };\n}\n\n/** Content width inside a rail nested `depth` levels under a transcript row. */\nexport function railContentWidth(grid: TranscriptGrid, depth = 1): number {\n return Math.max(8, grid.content - GUTTER_WIDTH * depth);\n}\n\n/**\n * Aligned-row width inside a rail nested `depth` levels under a transcript row.\n *\n * The bound has to travel down the nesting the same way the content width does.\n * Clamping every depth to a flat {@link MAX_ROW_MEASURE} would let a child row,\n * which starts two columns further in, end two columns further right than the\n * parent it hangs under — undoing the one thing {@link indentedGrid} exists for.\n */\nexport function railRowWidth(grid: TranscriptGrid, depth = 1): number {\n return Math.max(8, grid.row - GUTTER_WIDTH * depth);\n}\n\n/**\n * A grid for rows nested under a transcript row (a rail, a mutation child).\n *\n * Nested rows drop the label column: the parent row already named the verb, and\n * at this depth the columns left over are better spent on the target.\n */\nexport function nestedGrid(grid: TranscriptGrid, depth = 1): TranscriptGrid {\n const content = railContentWidth(grid, depth);\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\n return {\n ...grid,\n content,\n row: railRowWidth(grid, depth),\n label: 0,\n target: Math.max(MIN_TARGET_WIDTH, content - meta - 1),\n meta,\n };\n}\n\n/**\n * Narrow the label column to what a specific run of rows actually needs.\n *\n * The column is sized per message, not globally: a turn of `Bash` / `Read` /\n * `Grep` rows needs four columns, and padding those to fit a hypothetical\n * `Git status` opens a visible gulf between every verb and its target. A label\n * too wide for the measured column is not truncated — {@link composeToolRow}\n * runs it inline instead, so an under-measured column costs alignment on that\n * one row and never legibility.\n */\nexport function withLabelColumn(grid: TranscriptGrid, labelWidth: number): TranscriptGrid {\n if (grid.label === 0) return grid;\n const label = Math.max(1, Math.min(LABEL_COLUMN_WIDTH, Math.floor(labelWidth)));\n if (label === grid.label) return grid;\n return {\n ...grid,\n label,\n target: Math.max(MIN_TARGET_WIDTH, grid.content - label - grid.meta - 1),\n };\n}\n\nexport interface FrameGrid {\n /** Outer width of the bordered box. */\n width: number;\n /** Horizontal margin outside the border. Always 0: boxes sit flush left. */\n marginX: number;\n}\n\n/**\n * Metrics for a bordered surface that spans the transcript — the composer.\n *\n * The box is flush at column 0 so that its border plus one column of padding\n * places its text on {@link CONTENT_COLUMN}, matching every transcript row. It\n * takes the full terminal for the same reason the transcript does: it is as\n * wide as the thing the user is typing into, and a composer that stops halfway\n * is the most visible way a window can look broken. A surface that merely\n * floats over the transcript wants {@link panelGrid} instead.\n */\nexport function frameGrid(terminalWidth: number): FrameGrid {\n const outer = Math.max(20, Math.floor(terminalWidth));\n if (outer < 32) return { width: outer, marginX: 0 };\n return { width: outer - 1, marginX: 0 };\n}\n\n/**\n * Metrics for a floating surface (menu, picker, card, rules panel).\n *\n * Same geometry as {@link frameGrid}, bounded by {@link MAX_PANEL_MEASURE}.\n */\nexport function panelGrid(terminalWidth: number): FrameGrid {\n const outer = Math.min(MAX_PANEL_MEASURE, Math.max(20, Math.floor(terminalWidth)));\n if (outer < 32) return { width: outer, marginX: 0 };\n return { width: outer - 1, marginX: 0 };\n}\n\n/** Interior width of a bordered surface sized by {@link panelGrid}. */\nexport function panelContentWidth(terminalWidth: number, minimum = 24): number {\n return Math.max(minimum, panelGrid(terminalWidth).width - PANEL_CHROME);\n}\n","import { useInput, type Key } from 'ink';\n\n/**\n * Subscribes the app's global key handler ahead of every other `useInput`.\n *\n * Ink 7 subscribes each `useInput` handler once, from an effect, and calls handlers in the order\n * they subscribed. Effects run children first, so a handler in the app's own body would run after\n * every descendant's. Ink 6 re-subscribed a handler whenever it changed, and the composer's inline\n * handlers changed on every render, which in practice left the app's stable handler ahead of them.\n * Rendered as the first child of the app's tree, this keeps that order: the app decides Esc and\n * Ctrl+C before the composer acts on the key.\n */\nexport function GlobalKeyHandler({\n onInput,\n}: {\n onInput: (input: string, key: Key) => void;\n}): null {\n useInput(onInput);\n return null;\n}\n","import { Box, Text } from 'ink';\nimport React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, GUTTER_WIDTH, indentedGrid, transcriptGrid } from '../layout.js';\nimport type { CompactBoundary } from '../../types/sessions.js';\nimport type { Message } from '../../types/messages.js';\nimport type { PermissionResult, PlanApprovalResult } from '../../types/tools.js';\nimport type { RetryPhase } from '../../types/runtime.js';\nimport type {\n PendingPermissionRequest,\n PendingPlanApprovalRequest,\n} from '../../session/agent-interactions.js';\nimport { AgentMessage, managedAgentTracesEqualForMessage } from './AgentMessage.js';\nimport { UserMessage, userTurnRows } from './UserMessage.js';\nimport {\n createQuietCollapser,\n groupQuietInvocations,\n type QuietToolContext,\n} from '../quiet-tools.js';\nimport { WelcomeScreen, type RecentChapter } from './WelcomeScreen.js';\nimport { createRenderDebugLogger, createUiDebugLogger } from '../../debug-log.js';\nimport { useDebugMount, useDebugRender } from '../debug.js';\nimport { useDensity, type TuiDensity } from '../density.js';\nimport { mergeAssistantMessages } from './transcript-messages.js';\nimport { selectExpandedToolId } from '../tool-traces.js';\nimport type { TranscriptMode } from '../tool-presentation.js';\nimport type { ManagedAgentTrace } from '../managed-agent-transcript.js';\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\nimport { useTranscriptHistoryLoader, useTranscriptLayoutChange } from '../transcript-layout.js';\nimport { useVirtualTranscript, VirtualTranscriptRow } from './virtual-transcript.js';\n\nconst renderLog = createRenderDebugLogger('tui:chatpanel');\nconst uiLog = createUiDebugLogger('tui:chatpanel');\nconst EMPTY_BOUNDARIES: CompactBoundary[] = [];\nconst NO_SOURCE_IDS: ReadonlyMap<string, readonly string[]> = new Map();\nconst STREAMING_TIMELINE_MIN_WINDOW = 16;\nconst STREAMING_TIMELINE_MAX_WINDOW = 64;\nconst COMPLETED_TIMELINE_MIN_WINDOW = 80;\nconst COMPLETED_TIMELINE_MAX_WINDOW = 192;\n\nexport function getStreamingTimelineWindow(terminalHeight?: number): number {\n const height = Math.max(8, Math.floor(terminalHeight ?? 40));\n // Keep a small amount of context above the viewport without rendering an\n // entire long transcript on every streamed token.\n return Math.min(\n STREAMING_TIMELINE_MAX_WINDOW,\n Math.max(STREAMING_TIMELINE_MIN_WINDOW, Math.ceil(height * 1.25)),\n );\n}\n\nexport function getCompletedTimelineWindow(terminalHeight?: number): number {\n const height = Math.max(8, Math.floor(terminalHeight ?? 40));\n return Math.min(\n COMPLETED_TIMELINE_MAX_WINDOW,\n Math.max(COMPLETED_TIMELINE_MIN_WINDOW, Math.ceil(height * 3)),\n );\n}\n\nfunction estimateWrappedRows(content: string, contentWidth: number): number {\n // Wrap against the measure the row is actually rendered at, not the raw\n // terminal width: the virtual transcript sizes its spacers from this count,\n // so estimating against the wrong measure undercounts the wrapped rows.\n if (!content) return 1;\n return (\n content\n .split('\\n')\n // Ink wraps on display width, so a CJK or emoji line occupies more columns\n // than it has code units and `.length` would report half its true height.\n .reduce((rows, line) => rows + Math.max(1, Math.ceil(displayWidth(line) / contentWidth)), 0)\n );\n}\n\nfunction estimateToolRows(message: Message, quietTools: QuietToolContext | undefined): number {\n const calls = message.toolCalls ?? [];\n if (!quietTools) return calls.length * 2 + (message.toolResults?.length ?? 0);\n const invocations = calls.map((call) => ({\n call,\n result: message.toolResults?.find((result) => result.toolCallId === call.id),\n }));\n // A folded run of quiet calls draws one summary row.\n return groupQuietInvocations(invocations, message, quietTools).reduce(\n (rows, row) => rows + (row.kind === 'quiet' ? 1 : 2 + (invocations[row.index]!.result ? 1 : 0)),\n 0,\n );\n}\n\nfunction estimateTimelineRows(\n entry: Message | CompactBoundary,\n terminalWidth: number,\n quietTools?: QuietToolContext,\n density: TuiDensity = 'compact',\n): number {\n // A boundary is one row of its own plus the blank row it takes, which tight density drops.\n if ('transcriptOrdinal' in entry) return density === 'tight' ? 1 : 2;\n\n // A user turn is its prompt and the two blank rows above it (tight density\n // drops them): the margin belongs to the turn, so an unmeasured one is\n // estimated with it. The transcript's first turn has no margin — measuring\n // corrects that one row pair.\n if (entry.role === 'user') {\n return (\n userTurnRows(entry.content, terminalWidth, entry.timestamp, entry.attachments?.length ?? 0) +\n (density === 'tight' ? 0 : 2)\n );\n }\n const textRows = estimateWrappedRows(entry.content, transcriptGrid(terminalWidth).content);\n const attachmentRows = entry.attachments?.length ? 1 : 0;\n const toolRows = estimateToolRows(entry, quietTools);\n return Math.max(1, textRows + attachmentRows + toolRows);\n}\n\nfunction messageOwnsTool(message: Message, toolId: string | null | undefined): boolean {\n if (!toolId) return false;\n if (message.toolCalls?.some((call) => call.id === toolId)) return true;\n return Boolean(\n message.nestedToolInvocations?.some(\n (invocation) => invocation.traceId === toolId || invocation.call.id === toolId,\n ),\n );\n}\n\nfunction formatTurnTime(timestamp: number): string {\n if (!timestamp) return '';\n return new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n}\n\nfunction ScreenReaderRoleLabel({\n role,\n timestamp,\n}: {\n role: 'user' | 'assistant';\n timestamp: number;\n}) {\n const label = formatTurnTime(timestamp);\n return (\n <Box>\n <Text>\n {role === 'user' ? 'User' : 'Assistant'}\n {label ? ` at ${label}` : ''}\n </Text>\n </Box>\n );\n}\n\ninterface ChatPanelProps {\n messages: Message[];\n managedAgentTraces?: ReadonlyMap<string, ManagedAgentTrace>;\n compactBoundaries?: CompactBoundary[];\n streamingMessageId?: string | null;\n pendingPermission?: PendingPermissionRequest | null;\n /** @deprecated Approval actions now render in App's fixed interaction area. */\n onResolvePermission?: (result: PermissionResult) => void;\n /** @deprecated Plan details/actions now render outside ChatPanel. */\n pendingPlanApproval?: PendingPlanApprovalRequest | null;\n /** @deprecated Plan details/actions now render outside ChatPanel. */\n onResolvePlanApproval?: (result: PlanApprovalResult) => void;\n /** @deprecated Dynamic transcript rendering no longer needs Static replay epochs. */\n staticEpoch?: number;\n expandedToolCallId?: string | null;\n transcriptMode?: TranscriptMode;\n automaticToolCallId?: string | null;\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\n reducedMotion?: boolean;\n screenReader?: boolean;\n terminalWidth?: number;\n terminalHeight?: number;\n workspace?: string;\n /** This workspace's recent sessions, for the title page's contents. */\n recentSessions?: readonly RecentChapter[];\n /** The recent sessions are still being listed; the title page waits for them. */\n contentsPending?: boolean;\n model?: string;\n mode?: string;\n commandCount?: number;\n skillCount?: number;\n retryPhase?: RetryPhase;\n showAllToolOutput?: boolean;\n showAllToolOutputIds?: ReadonlySet<string>;\n showThinking?: boolean;\n retryAttempt?: number;\n retryMax?: number;\n retryCountdownMs?: number;\n}\n\n/** Dynamically renders transcript content. TranscriptView owns clipping and navigation. */\nexport function ChatPanelInner({\n messages,\n managedAgentTraces,\n compactBoundaries = EMPTY_BOUNDARIES,\n streamingMessageId,\n pendingPermission,\n expandedToolCallId,\n transcriptMode = 'compact',\n automaticToolCallId,\n toolExpansionOverrides,\n reducedMotion = false,\n screenReader = false,\n terminalWidth,\n terminalHeight,\n workspace,\n recentSessions,\n contentsPending,\n model,\n mode,\n commandCount = 0,\n skillCount = 0,\n retryPhase = 'none',\n showAllToolOutput = false,\n showAllToolOutputIds,\n showThinking = true,\n retryAttempt = 0,\n retryMax = 0,\n retryCountdownMs = 0,\n}: ChatPanelProps) {\n const density = useDensity();\n useDebugMount(uiLog, { model, mode, commandCount, skillCount });\n const timeline = useIncrementalTimeline(messages, compactBoundaries, streamingMessageId);\n const completedWindow = getCompletedTimelineWindow(terminalHeight);\n const [historyWindowSize, setHistoryWindowSize] = useState(completedWindow);\n const previousTimelineLengthRef = useRef(timeline.length);\n const notifyLayoutChange = useTranscriptLayoutChange();\n\n useEffect(() => {\n if (timeline.length < previousTimelineLengthRef.current) {\n setHistoryWindowSize(completedWindow);\n }\n previousTimelineLengthRef.current = timeline.length;\n }, [completedWindow, timeline.length]);\n\n useLayoutEffect(() => {\n notifyLayoutChange?.();\n }, [historyWindowSize, notifyLayoutChange]);\n\n const activeWindowSize = streamingMessageId\n ? getStreamingTimelineWindow(terminalHeight)\n : historyWindowSize;\n const hiddenTimelineEntries = Math.max(0, timeline.length - activeWindowSize);\n const windowedTimeline = useMemo(\n () => (hiddenTimelineEntries > 0 ? timeline.slice(hiddenTimelineEntries) : timeline),\n [hiddenTimelineEntries, timeline],\n );\n // The compact transcript folds runs of quiet tool calls (reads, searches,\n // lookups) into one summary row, across consecutive messages as well as\n // within one. The fold happens here, on the data, so the virtual transcript\n // sizes one entry per drawn row instead of hiding merged entries (each would\n // still count as a row). Ctrl+O's detailed transcript and screen readers see\n // every call.\n const quietCollapserRef = useRef<ReturnType<typeof createQuietCollapser> | null>(null);\n quietCollapserRef.current ??= createQuietCollapser();\n const pendingToolId = pendingPermission?.toolCall.id;\n const quietTools = useMemo<QuietToolContext | undefined>(() => {\n if (transcriptMode !== 'compact' || screenReader) return undefined;\n // What the user singled out keeps its own row.\n const pinned = new Set<string>();\n for (const [id, expanded] of toolExpansionOverrides ?? []) if (expanded) pinned.add(id);\n if (expandedToolCallId) pinned.add(expandedToolCallId);\n return { pinned, pendingToolId, workspace };\n }, [\n expandedToolCallId,\n pendingToolId,\n screenReader,\n toolExpansionOverrides,\n transcriptMode,\n workspace,\n ]);\n const displayTimeline = useMemo(\n () =>\n quietTools\n ? quietCollapserRef.current!(windowedTimeline, quietTools, showThinking)\n : { entries: windowedTimeline, sourceIds: NO_SOURCE_IDS },\n [quietTools, showThinking, windowedTimeline],\n );\n const visibleTimeline = displayTimeline.entries;\n const getTimelineKey = useCallback(\n (entry: Message | CompactBoundary) =>\n 'transcriptOrdinal' in entry ? `boundary-${entry.id}` : entry.id,\n [],\n );\n const estimateRows = useCallback(\n (entry: Message | CompactBoundary) =>\n estimateTimelineRows(entry, terminalWidth ?? 80, quietTools, density),\n [quietTools, terminalWidth, density],\n );\n const hiddenHistoryRows = hiddenTimelineEntries > 0 ? (density === 'tight' ? 1 : 2) : 0;\n const virtualTimeline = useVirtualTranscript({\n items: visibleTimeline,\n // Keep completed history virtualized while a live response streams. The\n // active message remains in the virtual range and follows the bottom when\n // the user is not browsing history.\n enabled: !screenReader && visibleTimeline.length > 24,\n terminalWidth: terminalWidth ?? 80,\n leadingRows: hiddenHistoryRows,\n getKey: getTimelineKey,\n estimateRows,\n });\n const estimatedLayoutRows = virtualTimeline.estimatedTotalRows;\n useEffect(() => {\n // Re-measure only when the estimated row count changes. MarkdownBlock and\n // virtual rows also notify for content whose measured height differs from\n // this inexpensive estimate.\n notifyLayoutChange?.();\n }, [estimatedLayoutRows, notifyLayoutChange]);\n const loadOlderHistory = useCallback(\n (request: 'page' | 'all') => {\n if (streamingMessageId || hiddenTimelineEntries === 0) return false;\n setHistoryWindowSize((current) =>\n request === 'all' ? timeline.length : Math.min(timeline.length, current + completedWindow),\n );\n return true;\n },\n [completedWindow, hiddenTimelineEntries, streamingMessageId, timeline.length],\n );\n useTranscriptHistoryLoader(loadOlderHistory);\n const selectedToolCallId =\n expandedToolCallId === undefined ? selectExpandedToolId(messages) : expandedToolCallId;\n\n useDebugRender(renderLog, {\n total: timeline.length,\n active: streamingMessageId?.slice(-8) ?? null,\n isEmpty: timeline.length === 0,\n });\n\n if (timeline.length === 0) {\n // A managed child transcript must never fall back to the main welcome\n // banner; callers render their own empty/waiting state around this panel.\n if (mode === 'managed') return null;\n return (\n <WelcomeScreen\n terminalWidth={terminalWidth ?? 80}\n terminalHeight={terminalHeight ?? 24}\n workspace={workspace}\n model={model}\n mode={mode}\n commandCount={commandCount}\n skillCount={skillCount}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n animate={false}\n recentSessions={recentSessions}\n contentsPending={contentsPending}\n />\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n {hiddenTimelineEntries > 0 ? (\n <Box marginLeft={2} marginBottom={density === 'tight' ? 0 : 1}>\n <Text dimColor>\n {hiddenTimelineEntries} older transcript entries hidden\n {streamingMessageId ? ' while streaming' : ' · scroll to the top to load more'}\n </Text>\n </Box>\n ) : null}\n {virtualTimeline.topSpacerRows > 0 ? (\n <Box height={virtualTimeline.topSpacerRows} flexShrink={0} />\n ) : null}\n {virtualTimeline.entries.map(({ item: entry, index, key, measurementKey, reserveRows }) => {\n let row: React.ReactNode;\n if ('transcriptOrdinal' in entry) {\n row = (\n <CompactBoundaryRow\n terminalWidth={terminalWidth}\n spaced={index > 0 && density !== 'tight'}\n screenReader={screenReader}\n />\n );\n } else {\n const message = entry;\n const previous = visibleTimeline[index - 1];\n if (message.role === 'user') {\n row = (\n // Two blank rows, like the space before a new section: one left\n // your turn reading as another paragraph of the reply above it.\n <Box flexDirection=\"column\" marginTop={index > 0 && density !== 'tight' ? 2 : 0}>\n {screenReader ? (\n <ScreenReaderRoleLabel role=\"user\" timestamp={message.timestamp} />\n ) : null}\n <UserMessage\n content={message.content}\n attachments={message.attachments}\n terminalWidth={terminalWidth}\n timestamp={message.timestamp}\n screenReader={screenReader}\n />\n </Box>\n );\n } else {\n // A merged entry keeps its first message's id; it is live while any\n // message folded into it is.\n const isStreaming =\n message.id === streamingMessageId ||\n Boolean(\n streamingMessageId &&\n displayTimeline.sourceIds.get(message.id)?.includes(streamingMessageId),\n );\n const rowExpandedToolCallId = messageOwnsTool(message, selectedToolCallId)\n ? selectedToolCallId\n : undefined;\n const rowAutomaticToolCallId = messageOwnsTool(message, automaticToolCallId)\n ? automaticToolCallId\n : undefined;\n const rowPendingPermission =\n pendingPermission && messageOwnsTool(message, pendingPermission.toolCall.id)\n ? pendingPermission\n : undefined;\n const next = visibleTimeline[index + 1];\n const nextEntryIsUser = Boolean(next && 'role' in next && next.role === 'user');\n const followsToolCall = Boolean(\n previous &&\n 'role' in previous &&\n previous.role === 'assistant' &&\n previous.toolCalls?.length,\n );\n row = (\n <Box\n flexDirection=\"column\"\n marginTop={\n followsToolCall ||\n // A boundary takes a blank row above it, so the reply that\n // follows one keeps the blank row below it too.\n (previous && 'transcriptOrdinal' in previous && density !== 'tight') ||\n (density !== 'tight' &&\n previous &&\n // A slash command's output answers no prompt row of its\n // own, so without this a run of them read as one block\n // glued to the reply above.\n (message.kind === 'local' || ('role' in previous && previous.role === 'user')))\n ? 1\n : 0\n }\n >\n {screenReader ? (\n <ScreenReaderRoleLabel role=\"assistant\" timestamp={message.timestamp} />\n ) : null}\n <AgentMessage\n message={message}\n managedAgentTraces={managedAgentTraces}\n isStreaming={isStreaming}\n pendingPermission={rowPendingPermission}\n expandedToolCallId={rowExpandedToolCallId}\n transcriptMode={transcriptMode}\n automaticToolCallId={rowAutomaticToolCallId}\n toolExpansionOverrides={toolExpansionOverrides}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n terminalWidth={terminalWidth}\n retryPhase={isStreaming ? retryPhase : 'none'}\n retryAttempt={isStreaming ? retryAttempt : 0}\n retryMax={isStreaming ? retryMax : 0}\n retryCountdownMs={isStreaming ? retryCountdownMs : 0}\n hideStreamingSpinner={isStreaming}\n showAllToolOutput={showAllToolOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n showThinking={showThinking}\n trimTrailingSpacing={nextEntryIsUser}\n quietTools={quietTools}\n />\n </Box>\n );\n }\n }\n\n if (!virtualTimeline.virtualized) {\n return <React.Fragment key={key}>{row}</React.Fragment>;\n }\n return (\n <VirtualTranscriptRow\n key={key}\n measurementKey={measurementKey}\n onMeasure={virtualTimeline.measure}\n reserveRows={reserveRows}\n >\n {row}\n </VirtualTranscriptRow>\n );\n })}\n {virtualTimeline.bottomSpacerRows > 0 ? (\n <Box height={virtualTimeline.bottomSpacerRows} flexShrink={0} />\n ) : null}\n </Box>\n );\n}\n\nexport const ChatPanel = React.memo(ChatPanelInner, (previous, next) => {\n if (\n previous.messages !== next.messages ||\n previous.compactBoundaries !== next.compactBoundaries ||\n previous.streamingMessageId !== next.streamingMessageId ||\n previous.pendingPermission !== next.pendingPermission ||\n previous.expandedToolCallId !== next.expandedToolCallId ||\n previous.transcriptMode !== next.transcriptMode ||\n previous.automaticToolCallId !== next.automaticToolCallId ||\n previous.toolExpansionOverrides !== next.toolExpansionOverrides ||\n previous.reducedMotion !== next.reducedMotion ||\n previous.screenReader !== next.screenReader ||\n previous.terminalWidth !== next.terminalWidth ||\n previous.terminalHeight !== next.terminalHeight ||\n previous.workspace !== next.workspace ||\n previous.recentSessions !== next.recentSessions ||\n previous.contentsPending !== next.contentsPending ||\n previous.model !== next.model ||\n previous.mode !== next.mode ||\n previous.commandCount !== next.commandCount ||\n previous.skillCount !== next.skillCount ||\n previous.retryPhase !== next.retryPhase ||\n previous.showAllToolOutput !== next.showAllToolOutput ||\n previous.showAllToolOutputIds !== next.showAllToolOutputIds ||\n previous.showThinking !== next.showThinking ||\n previous.retryAttempt !== next.retryAttempt ||\n previous.retryMax !== next.retryMax ||\n previous.retryCountdownMs !== next.retryCountdownMs\n ) {\n return false;\n }\n\n if (previous.managedAgentTraces === next.managedAgentTraces) return true;\n if (!previous.managedAgentTraces?.size && !next.managedAgentTraces?.size) return true;\n return previous.messages.every((message) =>\n managedAgentTracesEqualForMessage(\n message,\n previous.managedAgentTraces,\n next.managedAgentTraces,\n ),\n );\n});\n\ninterface TimelineCache {\n messages?: Message[];\n streamingMessageId?: string | null;\n prefixLength: number;\n prefixLast?: Message;\n boundaries?: CompactBoundary[];\n prefix: Array<Message | CompactBoundary>;\n trailing?: CompactBoundary[];\n composed?: Array<Message | CompactBoundary>;\n composedActive?: Message;\n}\n\nfunction useIncrementalTimeline(\n messages: Message[],\n boundaries: CompactBoundary[],\n streamingMessageId?: string | null,\n): Array<Message | CompactBoundary> {\n const cache = useRef<TimelineCache>({ prefixLength: -1, prefix: [] });\n if (!streamingMessageId) {\n if (cache.current.messages !== messages || cache.current.boundaries !== boundaries) {\n cache.current = {\n messages,\n streamingMessageId,\n prefixLength: messages.length,\n prefixLast: messages.at(-1),\n boundaries,\n prefix: buildTimeline(messages, boundaries, streamingMessageId),\n };\n }\n return cache.current.prefix;\n }\n const streamingIndex = messages.findIndex((message) => message.id === streamingMessageId);\n if (streamingIndex < 0 || streamingIndex !== messages.length - 1) {\n return buildTimeline(messages, boundaries, streamingMessageId);\n }\n\n const prefixLast = streamingIndex > 0 ? messages[streamingIndex - 1] : undefined;\n if (\n cache.current.streamingMessageId !== streamingMessageId ||\n cache.current.prefixLength !== streamingIndex ||\n cache.current.prefixLast !== prefixLast ||\n cache.current.boundaries !== boundaries\n ) {\n cache.current = {\n streamingMessageId,\n prefixLength: streamingIndex,\n prefixLast,\n boundaries,\n prefix: buildTimeline(\n messages.slice(0, streamingIndex),\n // Only the boundaries this prefix can place: the ones past the streaming message are\n // drawn after it, from `trailing`.\n boundaries.filter((boundary) => boundary.transcriptOrdinal <= streamingIndex),\n streamingMessageId,\n ),\n // A compaction that committed behind the streaming message's output sits below it until the\n // turn's next output opens a message of its own: draw it meanwhile, not when the turn ends.\n trailing: boundaries\n .filter((boundary) => boundary.transcriptOrdinal > streamingIndex)\n .sort((a, b) => a.timestamp - b.timestamp),\n };\n }\n const active = messages[streamingIndex];\n if (active.kind === 'agent-notification') {\n const trailing = cache.current.trailing ?? [];\n return trailing.length ? [...cache.current.prefix, ...trailing] : cache.current.prefix;\n }\n // Reuse the composed array while the active message object is unchanged so\n // re-renders without new deltas keep a stable timeline identity downstream.\n if (cache.current.composedActive !== active) {\n cache.current.composed = [...cache.current.prefix, active, ...(cache.current.trailing ?? [])];\n cache.current.composedActive = active;\n }\n return cache.current.composed!;\n}\n\nfunction buildTimeline(\n messages: Message[],\n boundaries: CompactBoundary[],\n streamingMessageId?: string | null,\n): Array<Message | CompactBoundary> {\n const byOrdinal = new Map<number, CompactBoundary[]>();\n for (const boundary of boundaries) {\n const group = byOrdinal.get(boundary.transcriptOrdinal) ?? [];\n group.push(boundary);\n byOrdinal.set(boundary.transcriptOrdinal, group);\n }\n const timeline: Array<Message | CompactBoundary> = [];\n let segment: Message[] = [];\n const flush = () => {\n if (!segment.length) return;\n timeline.push(...mergeAssistantMessages(segment, streamingMessageId));\n segment = [];\n };\n for (let index = 0; index <= messages.length; index++) {\n const markers = byOrdinal.get(index);\n if (markers?.length) {\n flush();\n timeline.push(...markers.sort((a, b) => a.timestamp - b.timestamp));\n }\n if (index < messages.length) {\n // A notification opens a new turn: the agent's reply to it never folds\n // into the answer that closed the turn before.\n if (messages[index].kind === 'agent-notification') flush();\n else segment.push(messages[index]);\n }\n }\n // A row placed past the last message, for a streaming message whose append never landed,\n // still shows: at the end.\n const beyond = boundaries.filter((boundary) => boundary.transcriptOrdinal > messages.length);\n if (beyond.length) {\n flush();\n timeline.push(...beyond.sort((a, b) => a.timestamp - b.timestamp));\n }\n flush();\n return timeline;\n}\n\n/**\n * The point the conversation was compacted, set like a tool row: its mark on the column every tool\n * row's status mark uses, a blank row above and below it except in tight density.\n */\nfunction CompactBoundaryRow({\n terminalWidth = 80,\n spaced,\n screenReader,\n}: {\n terminalWidth?: number;\n spaced: boolean;\n screenReader: boolean;\n}) {\n const theme = useTheme();\n const text = indentedGrid(transcriptGrid(terminalWidth)).content;\n return (\n <Box\n marginTop={spaced ? 1 : 0}\n marginLeft={screenReader ? 0 : CONTENT_COLUMN}\n width={GUTTER_WIDTH + text}\n >\n <Text color={theme.inactive}>✓ </Text>\n <Text color={theme.text}>{truncateDisplay('Compact conversation', text)}</Text>\n </Box>\n );\n}\n","import { Text, Box } from 'ink';\nimport React, { useMemo } from 'react';\nimport { Spinner } from './Spinner.js';\nimport { MetaText, TargetText, ToolCallBlock } from './ToolCallBlock.js';\nimport { DiffBlock, isUnifiedDiffLike } from './Diff.js';\nimport { MarkdownBlock, useThrottledValue } from './MarkdownBlock.js';\nimport { CommandPanel } from './CommandPanel.js';\nimport { ThemeContext, useTheme } from '../theme.js';\nimport { useDensityMetrics } from '../density.js';\nimport {\n CONTENT_COLUMN,\n GUTTER_WIDTH,\n indentedGrid,\n transcriptGrid,\n withLabelColumn,\n} from '../layout.js';\nimport { composeToolRow, toolLabelColumnWidth, toolRowLabel } from '../tool-presentation.js';\nimport type { Message } from '../../types/messages.js';\nimport type { RetryPhase } from '../../types/runtime.js';\nimport type { PendingPermissionRequest } from '../../session/agent-interactions.js';\nimport { createRenderDebugLogger } from '../../debug-log.js';\nimport { splitReasoningParts } from '../../reasoning-tags.js';\nimport {\n countNestedToolInvocations,\n indexNestedToolInvocations,\n type NestedToolChildren,\n} from '../tool-traces.js';\nimport {\n getFileMutationDisplaySummary,\n type FileMutationDisplaySummary,\n} from '../file-mutation-display.js';\nimport {\n shouldDefaultExpandTool,\n shouldExpandTool,\n type TranscriptMode,\n} from '../tool-presentation.js';\nimport type { ManagedAgentTrace } from '../managed-agent-transcript.js';\nimport { ManagedAgentActivityBlock } from './ManagedAgentActivityBlock.js';\nimport { QuietToolRun } from './QuietToolRun.js';\nimport {\n groupQuietInvocations,\n summarizeQuietRun,\n type QuietRunSummary,\n type QuietToolContext,\n} from '../quiet-tools.js';\nimport { useDebugRender } from '../debug.js';\nimport { isWorkStep } from './transcript-messages.js';\n\nconst renderLog = createRenderDebugLogger('tui:agentmsg');\n\ninterface AgentMessageProps {\n message: Message;\n managedAgentTraces?: ReadonlyMap<string, ManagedAgentTrace>;\n isStreaming: boolean;\n pendingPermission?: PendingPermissionRequest | null;\n expandedToolCallId?: string | null;\n transcriptMode?: TranscriptMode;\n automaticToolCallId?: string | null;\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\n reducedMotion?: boolean;\n screenReader?: boolean;\n /** Terminal width in columns — passed down to MarkdownBlock for word-wrap. */\n terminalWidth?: number;\n /** Retry state — shown in the spinner line when active. */\n retryPhase?: RetryPhase;\n retryAttempt?: number;\n retryMax?: number;\n retryCountdownMs?: number;\n /** Hide the inline streaming spinner when an external working indicator owns activity state. */\n hideStreamingSpinner?: boolean;\n /** When true, expanded tool results show the larger output cap instead of a short preview. */\n showAllToolOutput?: boolean;\n /** Tool-specific full-output expansion used by compact transcript mode. */\n showAllToolOutputIds?: ReadonlySet<string>;\n /** Whether provider-native and embedded model thinking should be shown. */\n showThinking?: boolean;\n /** Remove the final markdown block's margin before the next user turn. */\n trimTrailingSpacing?: boolean;\n /**\n * When set, runs of quiet tool calls (reads, searches, lookups) collapse into\n * one summary row. ChatPanel sets it for the compact transcript only; the\n * detailed transcript and screen readers get every row.\n */\n quietTools?: QuietToolContext;\n}\n\nconst NO_EXPANSION_OVERRIDES = new Map<string, boolean>();\nconst NO_SHOW_ALL_TOOL_OUTPUT_IDS: ReadonlySet<string> = new Set<string>();\nfunction NestedToolRows({\n childrenByParent,\n parentTraceId,\n depth,\n transcriptMode,\n automaticToolCallId,\n toolExpansionOverrides,\n reducedMotion,\n screenReader,\n showAllToolOutput,\n showAllToolOutputIds,\n terminalWidth,\n toolRowGap,\n}: {\n childrenByParent: NestedToolChildren;\n parentTraceId: string;\n depth: number;\n transcriptMode: TranscriptMode;\n automaticToolCallId?: string | null;\n toolExpansionOverrides: ReadonlyMap<string, boolean>;\n reducedMotion: boolean;\n screenReader: boolean;\n showAllToolOutput: boolean;\n showAllToolOutputIds: ReadonlySet<string>;\n terminalWidth?: number;\n toolRowGap: 0 | 1;\n}) {\n const children = childrenByParent.get(parentTraceId) ?? [];\n return children.map((invocation) => {\n return (\n <Box\n key={invocation.traceId}\n flexDirection=\"column\"\n marginLeft={screenReader ? 2 : depth * 2}\n marginTop={toolRowGap}\n >\n <ToolCallBlock\n toolId={invocation.traceId}\n name={invocation.call.name}\n args={invocation.call.arguments}\n unparsedArguments={invocation.call.unparsedArguments}\n result={invocation.result}\n isExpanded={shouldExpandTool({\n mode: transcriptMode,\n toolId: invocation.traceId,\n automaticToolId: automaticToolCallId,\n defaultExpanded: shouldDefaultExpandTool(invocation.call.name, invocation.result),\n expansionOverrides: toolExpansionOverrides,\n screenReader,\n })}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n showAllToolOutput={showAllToolOutput || showAllToolOutputIds.has(invocation.traceId)}\n terminalWidth={terminalWidth ? Math.max(12, terminalWidth - depth * 2) : undefined}\n />\n <NestedToolRows\n childrenByParent={childrenByParent}\n parentTraceId={invocation.traceId}\n depth={depth + 1}\n transcriptMode={transcriptMode}\n automaticToolCallId={automaticToolCallId}\n toolExpansionOverrides={toolExpansionOverrides}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n showAllToolOutput={showAllToolOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n terminalWidth={terminalWidth}\n toolRowGap={toolRowGap}\n />\n </Box>\n );\n });\n}\n\n/**\n * Strip trailing partial markdown code-fence closings from streaming text.\n *\n * While streaming, the LLM may emit incomplete closing fences (e.g. `` after a\n * ```rust block). These partial markers cause rendered code blocks to visually\n * jitter as the fence opens/closes. This function detects when the last line is\n * a non-empty prefix of a closing fence marker and strips it.\n */\nexport function trimPartialClosingFences(text: string): string {\n const lines = text.split('\\n');\n let lastOpenIdx = -1;\n for (let i = lines.length - 2; i >= 0; i--) {\n if (/^```/.test(lines[i])) {\n lastOpenIdx = i;\n break;\n }\n }\n\n if (lastOpenIdx === -1) return text;\n\n let hasClose = false;\n for (let i = lastOpenIdx + 1; i < lines.length; i++) {\n if (/^```\\s*$/.test(lines[i])) {\n hasClose = true;\n break;\n }\n }\n\n if (hasClose) return text;\n\n const lastLine = lines[lines.length - 1];\n if (lastLine === '') return text;\n\n const closeMarker = '```';\n if (lastLine !== closeMarker && closeMarker.startsWith(lastLine)) {\n return lines.slice(0, -1).join('\\n') + (lines.length > 1 ? '\\n' : '');\n }\n\n return text;\n}\n\n/** Build the spinner label based on retry state. Exported for testing. */\nexport function getRetryLabel(\n retryPhase: RetryPhase,\n retryAttempt: number,\n retryMax: number,\n retryCountdownMs: number,\n): string | undefined {\n const countdown = Math.max(0, Math.ceil(retryCountdownMs / 1000));\n const attemptStr =\n retryMax > 0 ? `attempt ${retryAttempt}/${retryMax}` : `attempt ${retryAttempt}`;\n if (retryPhase === 'transport') {\n return `Retrying in ${countdown}s · ${attemptStr}`;\n }\n if (retryPhase === 'continue') {\n return `Continuing past the output limit · ${attemptStr}`;\n }\n if (retryPhase === 'reissue') {\n return `Re-sending the turn in ${countdown}s · ${attemptStr}`;\n }\n if (retryPhase === 'stalled') {\n return `Waiting for API response · will retry in ${countdown}s · check your network`;\n }\n if (retryPhase === 'watchdog') {\n return `Retrying (watchdog) · attempt ${retryAttempt}`;\n }\n return undefined;\n}\n\n/**\n * Reasoning-tag splitting lives in `src/reasoning-tags.ts` so the agent loop can\n * apply the same rule when deciding whether a turn produced an answer. It is\n * re-exported under the renderer's own name because that is what the transcript\n * calls these blocks.\n */\nexport const splitThinkBlocks = splitReasoningParts;\n\nfunction reasoningLines(text: string): string[] {\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n}\n\nexport function countReasoningLines(text: string): number {\n return reasoningLines(text).length;\n}\n\n/**\n * Rows a completed thought would occupy if it were expanded.\n *\n * The collapsed row advertises what expanding costs, so it has to count\n * *rendered* rows. Counting source lines put `Thought - 2 lines` above four\n * wrapped rows, which read as a bug in the count rather than a wrap.\n */\nexport function countReasoningRows(text: string, width?: number): number {\n const lines = reasoningLines(text);\n if (!width || width <= 0) return lines.length;\n const measure = Math.max(8, Math.floor(width));\n return lines.reduce((rows, line) => rows + Math.max(1, Math.ceil(line.length / measure)), 0);\n}\n\nfunction ThinkBlock({\n text,\n terminalWidth,\n reducedMotion,\n active = true,\n expanded = false,\n screenReader = false,\n}: {\n text: string;\n terminalWidth?: number;\n reducedMotion?: boolean;\n active?: boolean;\n /** Detailed transcript mode keeps a finished thought open. */\n expanded?: boolean;\n screenReader?: boolean;\n}) {\n const theme = useTheme();\n // Keep the complete thought readable while avoiding a terminal redraw for every delta.\n const streamedText = useThrottledValue(text, 80);\n // The body sits two gutters in from the block's own width: the rail plus its\n // padding, then the indent under the header.\n const bodyWidth =\n terminalWidth === undefined || screenReader\n ? terminalWidth\n : Math.max(12, Math.floor(terminalWidth) - GUTTER_WIDTH * 2);\n const rowCount = countReasoningRows(text, bodyWidth);\n const rowLabel = `${rowCount} ${rowCount === 1 ? 'line' : 'lines'}`;\n\n // A finished thought collapses to one row.\n //\n // Watching reasoning arrive is the point of showing it; re-reading it in\n // scrollback is not. Expanded by default it put the least important content\n // of a turn in the most prominent position — several rows of it above the\n // first sentence of the answer. Detailed mode (Ctrl+O) reopens it, so\n // nothing becomes unreachable.\n if (!active && !expanded && !screenReader) {\n return (\n <Box>\n {/* `mdThinkText` plus the terminal's faint attribute put this row near\n 2.5:1 — below any reading threshold. The colour already steps it\n down; the faint attribute on top of it only made it unreadable. */}\n <Text color={theme.inactive}>{`▸ thought · ${rowLabel}`}</Text>\n </Box>\n );\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderLeft={!screenReader}\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeftColor={theme.mdThinkBorder}\n paddingLeft={screenReader ? 0 : 1}\n >\n <Box>\n {active && !screenReader ? (\n <Spinner active color={theme.mdThinkText} reducedMotion={reducedMotion} />\n ) : null}\n {/* A finished thought is set like a collapsed one: grey at reading\n weight. The faint attribute on top of an already-muted grey put this\n header near 2.5:1, and it is the one row the expanded view cannot\n skip past. */}\n <Text color={active ? theme.mdThinkText : theme.inactive} bold={active}>\n {active ? 'Thinking' : 'Thought'}\n </Text>\n {!active ? <Text color={theme.inactive}>{` - ${rowLabel}`}</Text> : null}\n </Box>\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN}>\n {active ? (\n <Text color={theme.mdThinkText} dimColor>\n {streamedText}\n </Text>\n ) : (\n <MarkdownBlock content={text} terminalWidth={bodyWidth} />\n )}\n </Box>\n </Box>\n );\n}\n\n/**\n * Heading for a run of consecutive file mutations, laid out like a tool row so\n * its verb, target and churn land on the same columns as everything else.\n */\nfunction MutationGroupRow({\n createdOnly,\n fileCount,\n addedLines,\n removedLines,\n grid,\n screenReader,\n}: {\n createdOnly: boolean;\n fileCount: number;\n addedLines: number;\n removedLines: number;\n grid: ReturnType<typeof transcriptGrid>;\n screenReader: boolean;\n}) {\n const theme = useTheme();\n const row = composeToolRow(\n {\n title: createdOnly ? 'Create' : 'Edit',\n target: `${fileCount} ${fileCount === 1 ? 'file' : 'files'}`,\n metadata: [`+${addedLines}`, `-${removedLines}`],\n },\n grid,\n );\n if (screenReader) {\n return (\n <Box>\n <Text>\n {createdOnly ? 'Created' : 'Edited'} {fileCount} {fileCount === 1 ? 'file' : 'files'} (+\n {addedLines} -{removedLines})\n </Text>\n </Box>\n );\n }\n return (\n <Box height={1} marginLeft={CONTENT_COLUMN}>\n {/* The same mark as every other finished tool row: a mutation group is\n work that completed, not a list item. Grey, because success is the\n default and the exception is what takes colour. */}\n <Text color={theme.inactive}>{'✓ '}</Text>\n {row.label ? <Text color={theme.inactive}>{row.label} </Text> : null}\n <TargetText target={row.target} failed={false} />\n <Text>{row.gap}</Text>\n <MetaText meta={row.meta} failed={false} />\n </Box>\n );\n}\n\n/**\n * Marks where reasoning ends and the answer begins.\n *\n * Visually this is a blank row: a finished thought already collapses to a\n * single line, so a labelled rule on top of it was chrome announcing chrome.\n * Screen readers still get the spoken boundary, which they cannot infer from\n * spacing.\n */\nfunction AnswerDivider({ screenReader }: { screenReader: boolean }) {\n if (!screenReader) return <Box marginTop={1} />;\n return (\n <Box>\n <Text>Answer:</Text>\n </Box>\n );\n}\n\n/**\n * Claude Code-style agent message block.\n *\n * Each assistant turn renders as:\n * 1. Spinner line — shows thinking tips, or retry countdown during retries\n * 2. Streaming text content\n * 3. One tool row per invocation, with Task subagent tools nested below their parent\n *\n * During retries, the spinner line shows Claude Code-style messages:\n * - Transport retry: \"Retrying in 4s · attempt 3/10\"\n * - Stream stall: \"Waiting for API response · will retry in 8s · check your network\"\n * - Watchdog: \"Retrying (watchdog) · attempt 47\"\n *\n * When screenReader mode is enabled, all decorations (spinners,\n * box borders, expand/collapse toggles) are stripped for flat,\n * accessible rendering.\n */\nexport function AgentMessageInner({\n message,\n managedAgentTraces,\n isStreaming,\n pendingPermission,\n expandedToolCallId,\n transcriptMode = 'compact',\n automaticToolCallId,\n toolExpansionOverrides = NO_EXPANSION_OVERRIDES,\n reducedMotion = false,\n screenReader = false,\n terminalWidth,\n retryPhase = 'none',\n retryAttempt = 0,\n retryMax = 0,\n retryCountdownMs = 0,\n hideStreamingSpinner = false,\n showAllToolOutput = false,\n showAllToolOutputIds = NO_SHOW_ALL_TOOL_OUTPUT_IDS,\n showThinking = true,\n trimTrailingSpacing = false,\n quietTools,\n}: AgentMessageProps) {\n const theme = useTheme();\n const { toolRowGap, toolBlockGap } = useDensityMetrics();\n const toolCalls = message.toolCalls ?? [];\n const suppressDelegationNarration = toolCalls.some((call) => {\n if (call.name !== 'AgentSpawn') return false;\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\n return !result || result.status === 'success';\n });\n // AgentSpawn has its own activity row. Keep the model text in history/context,\n // but avoid showing duplicated delegation narration in the user transcript.\n const rawDisplayContent = useMemo(\n () => (isStreaming ? trimPartialClosingFences(message.content) : message.content),\n [isStreaming, message.content],\n );\n const displayContent = suppressDelegationNarration ? '' : rawDisplayContent;\n const reasoningContent = message.reasoningContent;\n\n useDebugRender(renderLog, {\n id: message.id.slice(-8),\n streaming: isStreaming,\n contentLen: displayContent.length,\n toolCalls: (message.toolCalls ?? []).length,\n toolResults: (message.toolResults ?? []).length,\n retry: retryPhase,\n });\n\n const childrenByParent = useMemo(\n () => indexNestedToolInvocations(message.nestedToolInvocations ?? []),\n [message.nestedToolInvocations],\n );\n\n const spinnerLabel = useMemo(\n () => getRetryLabel(retryPhase, retryAttempt, retryMax, retryCountdownMs),\n [retryPhase, retryAttempt, retryMax, retryCountdownMs],\n );\n\n const isRetrying = retryPhase !== 'none';\n\n // Prose sits on the transcript content column, the same one tool rows and the\n // status line use. Activity labels render on their own row so they never\n // steal horizontal space from markdown or diffs.\n const grid = useMemo(() => transcriptGrid(terminalWidth ?? 80), [terminalWidth]);\n const contentWidth = terminalWidth ? grid.content : undefined;\n const mdWidth = contentWidth;\n // Once a turn has spoken its last — settled, and holding no tool call to\n // continue through — a reasoning tag the provider never closed must not be\n // allowed to swallow the answer into a collapsed thought. A turn that did call\n // a tool keeps the strict reading; see `splitReasoningParts`.\n //\n // An empty reasoning block is dropped outright. Routers that inline thinking\n // as `<think></think>` emit one on every tool-call turn, and each rendered as\n // a `thought · 0 lines` row: a toggle that expands to nothing.\n const contentParts = useMemo(\n () =>\n splitThinkBlocks(displayContent, {\n concluded: !isStreaming && toolCalls.length === 0,\n }).filter((part) => part.kind !== 'think' || part.text.length > 0),\n [displayContent, isStreaming, toolCalls.length],\n );\n // Whether the content box draws anything. An empty `<think></think>` draws\n // nothing, so it must not buy the tool block below it a blank row either.\n const showsContent = contentParts.some((part) =>\n part.kind === 'markdown' ? part.text.trim().length > 0 : showThinking,\n );\n const renderAsUnifiedDiff = useMemo(\n () => displayContent.length > 0 && isUnifiedDiffLike(displayContent),\n [displayContent],\n );\n const embeddedThinking = useMemo(\n () => contentParts.some((part) => part.kind === 'think'),\n [contentParts],\n );\n const topLevelInvocations = useMemo(\n () =>\n toolCalls.map((call) => {\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\n return {\n id: call.id,\n name: call.name,\n call,\n result,\n mutation: getFileMutationDisplaySummary(call.name, call.arguments, result),\n };\n }),\n [message.toolResults, toolCalls],\n );\n // Which rows this turn draws: a run of quiet calls folds into one summary.\n const quietRows = useMemo(() => {\n if (!quietTools || screenReader) return undefined;\n const byIndex = new Map<number, { head: boolean; summary: QuietRunSummary }>();\n for (const row of groupQuietInvocations(topLevelInvocations, message, quietTools)) {\n if (row.kind !== 'quiet') continue;\n const summary = summarizeQuietRun(row.indices.map((index) => topLevelInvocations[index]!));\n row.indices.forEach((index, position) =>\n byIndex.set(index, { head: position === 0, summary }),\n );\n }\n return byIndex.size > 0 ? byIndex : undefined;\n }, [message, quietTools, screenReader, topLevelInvocations]);\n // Size the label column to this turn's own rows. A turn of `Bash` / `Read`\n // rows padded to fit a hypothetical `Git status` puts seven dead columns\n // between every verb and its target. Only rows actually drawn count: a call\n // folded into a summary contributes the summary's label, once.\n const labelWidth = useMemo(\n () =>\n toolLabelColumnWidth(\n topLevelInvocations.flatMap((invocation, index) => {\n const quiet = quietRows?.get(index);\n if (quiet) return quiet.head ? [quiet.summary.title] : [];\n return [toolRowLabel(invocation.name, invocation.result)];\n }),\n ),\n [quietRows, topLevelInvocations],\n );\n // The heading sits on the same indented grid as the tool rows it heads.\n const mutationGrid = useMemo(\n () => indentedGrid(withLabelColumn(grid, labelWidth)),\n [grid, labelWidth],\n );\n const selectedAutomaticToolId = automaticToolCallId ?? expandedToolCallId;\n\n // A step of work reads as one quiet unit: its thought, the sentence it says\n // before acting, and the tool rows sit together with no blank row between\n // them. The compact transcript only — the detailed transcript expands every\n // block and keeps the blank rows between them, which is what keeps one call's\n // output from running into the next call's header. Screen readers keep every\n // mark, since a spoken stream has no whitespace to carry the distinction. A\n // turn whose call waits for your approval is not a step either: that sentence\n // is what you are being asked to judge.\n const awaitsApproval = Boolean(\n pendingPermission && toolCalls.some((call) => call.id === pendingPermission.toolCall.id),\n );\n const workStep =\n !screenReader && transcriptMode !== 'detailed' && !awaitsApproval && isWorkStep(message);\n // A step's narration speaks in the secondary voice: every run of its prose\n // takes `subtle`, so the answer is the only full-ink text in a turn. Its\n // code blocks follow, keyword and string hues included — a snippet the step\n // shows to explain itself is still the step. Memoized, because\n // MarkdownRenderer is memoized on the theme object.\n const stepTheme = useMemo(\n () => ({\n ...theme,\n text: theme.subtle,\n mdHeadingH1: theme.subtle,\n mdHeadingH2: theme.subtle,\n mdHeading: theme.subtle,\n mdInlineCodeText: theme.subtle,\n mdLink: theme.subtle,\n mdCodeText: theme.subtle,\n mdCodeKeyword: theme.subtle,\n mdCodeString: theme.subtle,\n mdCodeFunction: theme.subtle,\n mdCodeNumber: theme.subtle,\n mdListMarker: theme.subtle,\n mdBlockquoteText: theme.subtle,\n mdCheckboxChecked: theme.subtle,\n }),\n [theme],\n );\n\n // A local note that opens with a status mark (`✕ Could not save…`, `✓\n // Background shell … exited`) is an event, so it is set like a tool row: the\n // mark in its colour, then the text in ink. As plain prose it read as a stray\n // line of white text. Only a failure takes colour: a check is the default\n // state of the row, the same as on a tool row.\n const localEvent =\n message.kind === 'local' && !message.localCommand && !screenReader\n ? /^([✕✓]) ([\\s\\S]+)$/.exec(displayContent)\n : null;\n if (localEvent) {\n return (\n <Box\n marginLeft={CONTENT_COLUMN}\n width={Math.max(8, (terminalWidth ?? 80) - CONTENT_COLUMN - 1)}\n >\n <Text color={localEvent[1] === '✕' ? theme.error : theme.inactive}>{localEvent[1]} </Text>\n <Box flexGrow={1} flexShrink={1}>\n <Text color={theme.text} wrap=\"wrap\">\n {localEvent[2]}\n </Text>\n </Box>\n </Box>\n );\n }\n\n if (message.localCommand) {\n return (\n <CommandPanel\n display={message.localCommand}\n fallback={displayContent}\n terminalWidth={terminalWidth}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n />\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n {/* Spinner line: shows thinking tips, or retry countdown during retries */}\n {isStreaming &&\n !hideStreamingSpinner &&\n !displayContent &&\n !(showThinking && reasoningContent) &&\n !message.toolCalls?.length ? (\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN}>\n {isRetrying && spinnerLabel ? (\n <Box>\n <Text color={theme.error}>Retrying: </Text>\n <Text color={theme.error}>{spinnerLabel}</Text>\n </Box>\n ) : (\n <Spinner active reducedMotion={reducedMotion} showTips={true} />\n )}\n </Box>\n ) : null}\n\n {showThinking && reasoningContent ? (\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN} flexDirection=\"column\">\n <ThinkBlock\n text={reasoningContent}\n terminalWidth={mdWidth}\n reducedMotion={reducedMotion}\n active={isStreaming && !displayContent}\n expanded={transcriptMode === 'detailed'}\n screenReader={screenReader}\n />\n </Box>\n ) : null}\n\n {/* Activity and content use separate rows so markdown keeps its full budget. */}\n {displayContent ? (\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN} flexDirection=\"column\">\n {showThinking && reasoningContent && !embeddedThinking && !workStep ? (\n <AnswerDivider screenReader={screenReader} />\n ) : null}\n {isStreaming && !hideStreamingSpinner && !isRetrying ? (\n <Box>\n <Spinner active reducedMotion={reducedMotion} />\n </Box>\n ) : null}\n {isRetrying && !hideStreamingSpinner && spinnerLabel ? (\n <Box>\n <Text color={theme.error}>Retrying: </Text>\n <Text color={theme.error}>{spinnerLabel}</Text>\n </Box>\n ) : null}\n {renderAsUnifiedDiff ? (\n <DiffBlock output={displayContent} terminalWidth={contentWidth} />\n ) : (\n <ThemeContext.Provider value={workStep ? stepTheme : theme}>\n <Box flexDirection=\"column\">\n {contentParts.map((part, i) => {\n if (part.kind === 'think') {\n if (!showThinking) return null;\n const answerHasStarted = contentParts\n .slice(i + 1)\n .some((candidate) => candidate.kind === 'markdown' && candidate.text.trim());\n return (\n <ThinkBlock\n key={`think-${i}`}\n text={part.text}\n terminalWidth={mdWidth}\n reducedMotion={reducedMotion}\n active={isStreaming && !answerHasStarted}\n expanded={transcriptMode === 'detailed'}\n screenReader={screenReader}\n />\n );\n }\n const hasEarlierThinking = contentParts\n .slice(0, i)\n .some((candidate) => candidate.kind === 'think');\n return (\n <React.Fragment key={`md-${i}`}>\n {showThinking && hasEarlierThinking && !workStep ? (\n <AnswerDivider screenReader={screenReader} />\n ) : null}\n <MarkdownBlock\n content={part.text}\n terminalWidth={mdWidth}\n isStreaming={isStreaming}\n trimTrailingMargin={trimTrailingSpacing && i === contentParts.length - 1}\n />\n </React.Fragment>\n );\n })}\n </Box>\n </ThemeContext.Provider>\n )}\n </Box>\n ) : null}\n\n {/* Every invocation gets its own row, except that a run of quiet calls folds\n into one summary in the compact transcript. Task subagent tools stay\n display-only and nest below it. */}\n {topLevelInvocations.map((invocation, index) => {\n // The detailed transcript expands every call, so each row carries a block\n // of output; a blank row between blocks keeps one call's output from\n // running into the next call's header.\n const marginTop =\n index === 0\n ? workStep\n ? 0\n : showsContent || (showThinking && reasoningContent)\n ? toolBlockGap\n : 0\n : transcriptMode === 'detailed' && !screenReader\n ? 1\n : toolRowGap;\n const tc = invocation.call;\n const result = invocation.result;\n const mutation = invocation.mutation;\n const previousMutation = topLevelInvocations[index - 1]?.mutation;\n let mutationGroup:\n | {\n summaries: FileMutationDisplaySummary[];\n fileCount: number;\n addedLines: number;\n removedLines: number;\n createdOnly: boolean;\n }\n | undefined;\n if (mutation && !previousMutation) {\n const summaries: FileMutationDisplaySummary[] = [];\n for (let groupIndex = index; groupIndex < topLevelInvocations.length; groupIndex++) {\n const summary = topLevelInvocations[groupIndex].mutation;\n if (!summary) break;\n summaries.push(summary);\n }\n mutationGroup = {\n summaries,\n fileCount: summaries.some((summary) => (summary.fileCount ?? 1) > 1)\n ? summaries.reduce((total, summary) => total + (summary.fileCount ?? 1), 0)\n : new Set(summaries.map((summary) => summary.filePath)).size,\n addedLines: summaries.reduce((total, summary) => total + summary.addedLines, 0),\n removedLines: summaries.reduce((total, summary) => total + summary.removedLines, 0),\n createdOnly: summaries.every((summary) => summary.kind === 'create'),\n };\n }\n const isPending = pendingPermission?.toolCall.id === tc.id;\n const managedAgentTrace = managedAgentTraces?.get(tc.id);\n const quiet = quietRows?.get(index);\n if (quiet) {\n if (!quiet.head) return null;\n return (\n <Box key={tc.id || `tool-${index}`} flexDirection=\"column\" marginTop={marginTop}>\n <QuietToolRun\n summary={quiet.summary}\n grid={mutationGrid}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n />\n </Box>\n );\n }\n return (\n <Box\n key={tc.id || `tool-${index}`}\n flexDirection=\"column\"\n marginTop={mutation && previousMutation ? 0 : marginTop}\n >\n {mutationGroup ? (\n <MutationGroupRow\n createdOnly={mutationGroup.createdOnly}\n fileCount={mutationGroup.fileCount}\n addedLines={mutationGroup.addedLines}\n removedLines={mutationGroup.removedLines}\n grid={mutationGrid}\n screenReader={screenReader}\n />\n ) : null}\n {managedAgentTrace ? (\n <ManagedAgentActivityBlock\n trace={managedAgentTrace}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n terminalWidth={terminalWidth}\n />\n ) : (\n <ToolCallBlock\n toolId={tc.id}\n name={tc.name}\n args={tc.arguments}\n unparsedArguments={tc.unparsedArguments}\n result={result}\n isExpanded={shouldExpandTool({\n mode: transcriptMode,\n toolId: tc.id,\n automaticToolId: selectedAutomaticToolId,\n defaultExpanded: shouldDefaultExpandTool(tc.name, result),\n expansionOverrides: toolExpansionOverrides,\n screenReader,\n })}\n isPending={isPending}\n nestedActivityCount={countNestedToolInvocations(childrenByParent, tc.id)}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n showAllToolOutput={showAllToolOutput || showAllToolOutputIds.has(tc.id)}\n summaryVariant={mutation ? 'file-child' : 'default'}\n terminalWidth={terminalWidth}\n labelWidth={labelWidth}\n />\n )}\n {!managedAgentTrace && childrenByParent.has(tc.id) ? (\n <NestedToolRows\n childrenByParent={childrenByParent}\n parentTraceId={tc.id}\n depth={1}\n transcriptMode={transcriptMode}\n automaticToolCallId={selectedAutomaticToolId}\n toolExpansionOverrides={toolExpansionOverrides}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n showAllToolOutput={showAllToolOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n terminalWidth={terminalWidth}\n toolRowGap={toolRowGap}\n />\n ) : null}\n </Box>\n );\n })}\n </Box>\n );\n}\n\nfunction managedAgentTraceEqual(\n left: ManagedAgentTrace | undefined,\n right: ManagedAgentTrace | undefined,\n): boolean {\n if (left === right) return true;\n if (!left || !right) return false;\n if (\n left.agentId !== right.agentId ||\n left.parentToolCallId !== right.parentToolCallId ||\n left.profile !== right.profile ||\n left.purpose !== right.purpose ||\n left.status !== right.status ||\n left.startedAt !== right.startedAt ||\n left.finishedAt !== right.finishedAt ||\n left.openable !== right.openable ||\n left.blocking !== right.blocking ||\n left.toolUses.length !== right.toolUses.length\n ) {\n return false;\n }\n return left.toolUses.every((tool, index) => {\n const candidate = right.toolUses[index];\n return (\n candidate !== undefined &&\n tool.id === candidate.id &&\n tool.call === candidate.call &&\n tool.result === candidate.result &&\n tool.status === candidate.status &&\n tool.startedAt === candidate.startedAt &&\n tool.finishedAt === candidate.finishedAt\n );\n });\n}\n\nexport function managedAgentTracesEqualForMessage(\n message: Message,\n left: ReadonlyMap<string, ManagedAgentTrace> | undefined,\n right: ReadonlyMap<string, ManagedAgentTrace> | undefined,\n): boolean {\n if (left === right) return true;\n for (const call of message.toolCalls ?? []) {\n // A background child is traced under its AgentSpawn call, a foreground one under its Task call.\n if (!managedAgentTraceEqual(left?.get(call.id), right?.get(call.id))) return false;\n }\n return true;\n}\n\n/**\n * Memoized agent message with a custom comparator.\n *\n * Scalar props are compared first (fast path). Message arrays use reference\n * equality because every streaming append/result update replaces its array.\n *\n */\nexport const AgentMessage = React.memo(AgentMessageInner, (prev, next) => {\n // Fast path: same references for the most common props.\n if (\n prev.isStreaming === next.isStreaming &&\n prev.expandedToolCallId === next.expandedToolCallId &&\n prev.transcriptMode === next.transcriptMode &&\n prev.automaticToolCallId === next.automaticToolCallId &&\n prev.toolExpansionOverrides === next.toolExpansionOverrides &&\n prev.pendingPermission?.toolCall?.id === next.pendingPermission?.toolCall?.id &&\n prev.retryPhase === next.retryPhase &&\n prev.retryAttempt === next.retryAttempt &&\n prev.retryMax === next.retryMax &&\n prev.retryCountdownMs === next.retryCountdownMs &&\n prev.hideStreamingSpinner === next.hideStreamingSpinner &&\n prev.showAllToolOutput === next.showAllToolOutput &&\n prev.showAllToolOutputIds === next.showAllToolOutputIds &&\n prev.showThinking === next.showThinking &&\n prev.trimTrailingSpacing === next.trimTrailingSpacing &&\n prev.quietTools === next.quietTools &&\n prev.reducedMotion === next.reducedMotion &&\n prev.screenReader === next.screenReader &&\n prev.terminalWidth === next.terminalWidth\n ) {\n // Check message identity.\n const pm = prev.message;\n const nm = next.message;\n if (\n pm.id === nm.id &&\n pm.content === nm.content &&\n pm.reasoningContent === nm.reasoningContent &&\n pm.localCommand === nm.localCommand &&\n pm.toolCalls === nm.toolCalls &&\n pm.toolResults === nm.toolResults &&\n pm.nestedToolInvocations === nm.nestedToolInvocations &&\n managedAgentTracesEqualForMessage(nm, prev.managedAgentTraces, next.managedAgentTraces)\n ) {\n return true; // skip re-render\n }\n }\n return false;\n});\n","import { Text, Box } from 'ink';\nimport { useState, useEffect, useMemo, useRef } from 'react';\nimport { useGradientSpinner, type SpinnerStyle } from '../hooks/useAnimation.js';\nimport { useTheme } from '../theme.js';\n\nexport const SPINNER_TIPS = [\n 'Press Ctrl+/ for keyboard shortcuts',\n 'Use @filename to include file contents',\n 'Start with ! to run a shell command',\n 'Press Esc or Ctrl+C to cancel the current operation',\n 'Type /help for available commands',\n 'Alt+M to cycle permission modes',\n 'Alt+P to open the model picker',\n 'Alt+V to attach a clipboard image',\n 'Use /compact when context is getting long',\n 'Use /theme to choose and save a color theme',\n \"Ctrl+T to show the agent's steps\",\n 'Sessions auto-save — use -c to resume',\n 'Ctrl+J or Shift+Enter for multiline input',\n 'Type /task <subject> to add a task',\n 'The model can use multiple tools per turn',\n 'Use /new to start fresh; /resume returns to saved conversations',\n 'Use PageUp/PageDown to review earlier messages',\n 'Tab to accept suggestions in the input bar',\n 'Up/Down arrows for input history',\n 'Ctrl+L to redraw the screen',\n];\n\ninterface SpinnerProps {\n active?: boolean;\n style?: SpinnerStyle;\n color?: string;\n reducedMotion?: boolean;\n showTips?: boolean;\n /** Custom tip strings to override the defaults. */\n tips?: string[];\n /** If true, only show custom tips (no defaults mixed in). */\n excludeDefaultTips?: boolean;\n}\n\n/**\n * Book's quill spinner (see quill.ts), with rotating tips.\n *\n * During long operations, the spinner cycles through a list of tips every 4\n * seconds, shown inline next to the spinner frame. The tip list is\n * configurable via the `tips` and `excludeDefaultTips` props.\n */\nexport function Spinner({\n active = true,\n style = 'quill',\n color,\n reducedMotion = false,\n showTips = false,\n tips,\n excludeDefaultTips = false,\n}: SpinnerProps) {\n const theme = useTheme();\n const spinner = useGradientSpinner(active, style, reducedMotion);\n const [tipIndex, setTipIndex] = useState(0);\n const tipTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const effectiveTips = useMemo(() => {\n if (tips && excludeDefaultTips) return tips;\n if (tips) return [...SPINNER_TIPS, ...tips];\n return SPINNER_TIPS;\n }, [tips, excludeDefaultTips]);\n\n useEffect(() => {\n if (!active || !showTips) {\n if (tipTimerRef.current) {\n clearInterval(tipTimerRef.current);\n tipTimerRef.current = null;\n }\n return;\n }\n // Reset tip index when starting.\n setTipIndex(0);\n tipTimerRef.current = setInterval(() => {\n setTipIndex((i) => (i + 1) % effectiveTips.length);\n }, 4000);\n return () => {\n if (tipTimerRef.current) {\n clearInterval(tipTimerRef.current);\n tipTimerRef.current = null;\n }\n };\n }, [active, showTips, effectiveTips.length]);\n\n const tip = effectiveTips[tipIndex];\n\n return (\n <Box>\n <SpinnerGlyphs frame={spinner.frame} colors={spinner.colors} color={color} />\n <Text> </Text>\n {showTips && active && tip ? (\n <Text color={theme.subtle} dimColor>\n {tip}\n </Text>\n ) : null}\n </Box>\n );\n}\n\n/**\n * A spinner frame, each cell in its own colour: the quill's ink is fresh at\n * the nib and dry behind it. `color` paints every cell one colour instead, for\n * a caller that wants the spinner in a status colour.\n */\nexport function SpinnerGlyphs({\n frame,\n colors,\n color,\n}: {\n frame: string;\n colors: readonly string[];\n color?: string;\n}) {\n const cells = [...frame];\n if (color || colors.length < cells.length) {\n return <Text color={color ?? colors[0]}>{frame}</Text>;\n }\n return (\n <Text>\n {cells.map((cell, index) => (\n <Text key={index} color={colors[index]}>\n {cell}\n </Text>\n ))}\n </Text>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { createRenderDebugLogger } from '../../debug-log.js';\nimport { isTranscriptScrollActive } from '../scroll-activity.js';\nimport { useUiClock } from '../ui-clock.js';\nimport { mixColor, shimmerColor } from '../shimmer.js';\nimport { QUILL_FRAMES, QUILL_STILL, quillColors } from '../quill.js';\nimport { useTheme } from '../theme.js';\n\nconst animLog = createRenderDebugLogger('tui:animation');\n\nconst BRAILLE_FRAMES = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];\n\n/** Frames of the wording's breath at the quill's 50ms clock: one a second, as at 100ms. */\nconst QUILL_BREATH_STEPS = 20;\n\n/**\n * Ten frames at the 100ms clock: one revolution per second, and one shimmer\n * breath per revolution.\n */\nconst DOT_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n/**\n * The spinner.\n *\n * Colour comes from the active theme's `shimmerPair` and eases across it over\n * a full revolution. It used to be a hardcoded `cyan`/`#5cf` pair swapped every\n * frame, which put an off-palette 5Hz strobe in front of the user on every turn\n * regardless of theme.\n *\n * When reducedMotion is true, returns a static frame in a static colour.\n */\nexport function useGradientSpinner(\n active: boolean,\n style: SpinnerStyle = 'quill',\n reducedMotion = false,\n): SpinnerFrame {\n const theme = useTheme();\n const animating = active && !reducedMotion;\n const quill = style === 'quill';\n const tick = useUiClock(quill ? 'cinematic' : 'fast', animating);\n\n if (quill) {\n const frame = animating ? QUILL_FRAMES[tick % QUILL_FRAMES.length]! : QUILL_STILL;\n return {\n frame: frame.text,\n // The ink takes the rubric while it is fresh and dries to the greys.\n colors: quillColors(\n frame,\n { fresh: theme.brand, wet: theme.brandShimmer, drying: theme.subtle, dry: theme.inactive },\n mixColor,\n ),\n // The wording beside the pen breathes in ink.\n color: animating\n ? shimmerColor(theme.shimmerPair, tick, QUILL_BREATH_STEPS)\n : theme.shimmerPair[0],\n markColor: theme.brand,\n };\n }\n\n const frames = style === 'braille' ? BRAILLE_FRAMES : DOT_FRAMES;\n const markColor = animating ? shimmerColor([theme.brand, theme.brandShimmer], tick) : theme.brand;\n const frame = frames[animating ? tick % frames.length : 0]!;\n return {\n frame,\n colors: [markColor],\n color: animating ? shimmerColor(theme.shimmerPair, tick) : theme.shimmerPair[0],\n markColor,\n };\n}\n\nexport type SpinnerStyle = 'quill' | 'braille' | 'dots';\n\n/** One frame of the spinner, ready to draw. */\nexport interface SpinnerFrame {\n /** The glyphs, one terminal cell each. */\n frame: string;\n /** One colour per cell of `frame`. */\n colors: readonly string[];\n /** The breathing colour of the wording beside the spinner. */\n color: string;\n /** The spinner's single colour, where one colour stands for all its cells. */\n markColor: string;\n}\n\nexport function useStaggeredReveal(\n count: number,\n active: boolean,\n intervalMs = 120,\n reducedMotion = false,\n): number {\n const [visibleCount, setVisibleCount] = useState(reducedMotion ? count : 0);\n\n useEffect(() => {\n if (!active || reducedMotion) {\n setVisibleCount(count);\n return;\n }\n setVisibleCount(0);\n let current = 0;\n const interval = setInterval(() => {\n if (isTranscriptScrollActive()) return;\n current++;\n setVisibleCount(Math.min(count, current));\n if (current >= count) {\n clearInterval(interval);\n }\n }, intervalMs);\n return () => clearInterval(interval);\n }, [active, count, intervalMs, reducedMotion]);\n\n return visibleCount;\n}\n\nexport function useTimedFlash(triggerValue: unknown, durationMs = 220, disabled = false): boolean {\n const [on, setOn] = useState(false);\n const firstRun = useRef(true);\n\n useEffect(() => {\n if (disabled) {\n setOn(false);\n firstRun.current = false;\n return;\n }\n if (firstRun.current) {\n firstRun.current = false;\n return;\n }\n setOn(true);\n const timer = setTimeout(() => setOn(false), durationMs);\n return () => clearTimeout(timer);\n }, [triggerValue, durationMs, disabled]);\n\n return on;\n}\n\nexport function usePulse(active: boolean, interval = 500): boolean {\n const [on, setOn] = useState(false);\n\n useEffect(() => {\n if (!active) {\n setOn(false);\n return;\n }\n animLog.event('pulse:start', { interval });\n const timer = setInterval(() => {\n if (isTranscriptScrollActive()) return;\n setOn((o) => !o);\n }, interval);\n return () => {\n clearInterval(timer);\n animLog.event('pulse:stop', { interval });\n };\n }, [active, interval]);\n\n return on;\n}\n\n/** Time-based pending progress; callers must render 100% from a real completion signal. */\nexport function useAnimatedProgress(\n active: boolean,\n durationMs = 2_400,\n reducedMotion = false,\n maximum = 95,\n): number {\n const [progress, setProgress] = useState(0);\n const safeMaximum = Math.max(0, Math.min(99, maximum));\n const startedAtRef = useRef(Date.now());\n const tick = useUiClock('fast', active && !reducedMotion && progress < safeMaximum);\n\n useEffect(() => {\n startedAtRef.current = Date.now();\n setProgress(0);\n }, [active, durationMs, reducedMotion, safeMaximum]);\n\n useEffect(() => {\n if (!active || reducedMotion) return;\n const safeDuration = Math.max(1, durationMs);\n setProgress(\n Math.min(safeMaximum, Math.floor(((Date.now() - startedAtRef.current) / safeDuration) * 100)),\n );\n }, [active, durationMs, reducedMotion, safeMaximum, tick]);\n\n return progress;\n}\n","export const TRANSCRIPT_SCROLL_IDLE_MS = 150;\n\nlet activeUntil = 0;\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\n\nexport function markTranscriptScrollActivity(now = Date.now()): void {\n activeUntil = Math.max(activeUntil, now + TRANSCRIPT_SCROLL_IDLE_MS);\n if (idleTimer !== null) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n idleTimer = null;\n if (Date.now() >= activeUntil) activeUntil = 0;\n }, TRANSCRIPT_SCROLL_IDLE_MS);\n}\n\nexport function isTranscriptScrollActive(now = Date.now()): boolean {\n return activeUntil > now;\n}\n","import { useCallback, useSyncExternalStore } from 'react';\nimport { isTranscriptScrollActive } from './scroll-activity.js';\n\nexport type UiClockRate = 'cinematic' | 'fast' | 'slow';\n\ninterface ClockState {\n revision: number;\n timer: ReturnType<typeof setInterval> | null;\n listeners: Set<() => void>;\n}\n\nconst CLOCK_INTERVAL_MS: Record<UiClockRate, number> = {\n cinematic: 50,\n fast: 100,\n slow: 1000,\n};\n\nconst clocks: Record<UiClockRate, ClockState> = {\n cinematic: { revision: 0, timer: null, listeners: new Set() },\n fast: { revision: 0, timer: null, listeners: new Set() },\n slow: { revision: 0, timer: null, listeners: new Set() },\n};\n\nfunction startClock(rate: UiClockRate): void {\n const clock = clocks[rate];\n if (clock.timer !== null) return;\n clock.timer = setInterval(() => {\n if (rate !== 'slow' && isTranscriptScrollActive()) return;\n clock.revision++;\n for (const listener of clock.listeners) listener();\n }, CLOCK_INTERVAL_MS[rate]);\n}\n\nexport function subscribeUiClock(rate: UiClockRate, listener: () => void): () => void {\n const clock = clocks[rate];\n clock.listeners.add(listener);\n startClock(rate);\n return () => {\n clock.listeners.delete(listener);\n if (clock.listeners.size === 0 && clock.timer !== null) {\n clearInterval(clock.timer);\n clock.timer = null;\n }\n };\n}\n\nfunction subscribeNoop(): () => void {\n return () => {};\n}\n\nexport function useUiClock(rate: UiClockRate, enabled = true): number {\n const subscribe = useCallback(\n (listener: () => void) => (enabled ? subscribeUiClock(rate, listener) : subscribeNoop()),\n [enabled, rate],\n );\n const getSnapshot = useCallback(() => clocks[rate].revision, [rate]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","/**\n * Spinner shimmer.\n *\n * The spinner is the most-watched pixel in the TUI, so it gets the most care.\n * Two rules:\n *\n * - It uses the theme's `shimmerPair`, never a literal colour. The gradient\n * used to be hardcoded `['cyan', '#5cf']`, which put a bright blue strobe on\n * a warm editorial palette in every theme.\n * - It eases between the pair over a full revolution instead of swapping on\n * every frame. Alternating two colours at the frame rate is a 5Hz strobe;\n * easing across {@link SHIMMER_STEPS} frames reads as a breath.\n */\n\n/** Frames in one shimmer cycle. Matches the spinner's revolution. */\nexport const SHIMMER_STEPS = 10;\n\ninterface Rgb {\n r: number;\n g: number;\n b: number;\n}\n\n/** Last-resort colour when a theme supplies no usable shimmer pair. */\nconst FALLBACK_SHIMMER = '#64D2FF';\n\n/**\n * Parse a hex colour, tolerating anything a custom theme might supply.\n *\n * The parameter is `unknown` on purpose: theme tokens are merged from\n * unvalidated JSON, so the declared `string` was a claim rather than a fact.\n */\nfunction parseHex(color: unknown): Rgb | null {\n if (typeof color !== 'string') return null;\n const match = /^#?([0-9a-f]{6})$/i.exec(color.trim());\n if (!match) return null;\n const value = Number.parseInt(match[1], 16);\n return { r: (value >> 16) & 0xff, g: (value >> 8) & 0xff, b: value & 0xff };\n}\n\nfunction toHex({ r, g, b }: Rgb): string {\n const channel = (value: number) =>\n Math.max(0, Math.min(255, Math.round(value)))\n .toString(16)\n .padStart(2, '0');\n return `#${channel(r)}${channel(g)}${channel(b)}`;\n}\n\n/**\n * Position within the breath for a frame index: 0 at the start, 1 at the\n * midpoint, back to 0 — a raised cosine, so the turn at each end is gradual\n * rather than a hard bounce.\n */\nexport function shimmerPhase(tick: number, steps = SHIMMER_STEPS): number {\n const period = Math.max(1, Math.floor(steps));\n const position = ((Math.floor(tick) % period) + period) % period;\n return (1 - Math.cos((2 * Math.PI * position) / period)) / 2;\n}\n\n/**\n * Blend a theme's shimmer pair at `tick`.\n *\n * Falls back to the first colour when either end is not a plain hex value —\n * custom themes may use Ink's named or `ansi256` colours, which cannot be\n * interpolated.\n */\nexport function shimmerColor(\n pair: readonly [string, string],\n tick: number,\n steps = SHIMMER_STEPS,\n): string {\n // `loadCustomTheme` merges arbitrary `.book/themes/*.json` into the token set\n // without validating it, so this pair can be short, empty, or not an array at\n // all. It reaches here on the spinner's first frame, where throwing takes the\n // whole TUI down.\n const [from, to] = Array.isArray(pair) ? (pair as readonly unknown[]) : [];\n const start = parseHex(from);\n const end = parseHex(to);\n if (!start) return typeof from === 'string' && from ? from : FALLBACK_SHIMMER;\n if (!end) return from as string;\n const t = shimmerPhase(tick, steps);\n return toHex({\n r: start.r + (end.r - start.r) * t,\n g: start.g + (end.g - start.g) * t,\n b: start.b + (end.b - start.b) * t,\n });\n}\n\n/**\n * `from` blended towards `to` by `t` (0 is `from`, 1 is `to`). Returns `to`\n * unchanged when either end is not a plain hex colour, since a custom theme's\n * named or `ansi256` colours cannot be interpolated.\n */\nexport function mixColor(from: string, to: string, t: number): string {\n const start = parseHex(from);\n const end = parseHex(to);\n if (!start || !end) return to;\n const amount = Math.max(0, Math.min(1, t));\n return toHex({\n r: start.r + (end.r - start.r) * amount,\n g: start.g + (end.g - start.g) * amount,\n b: start.b + (end.b - start.b) * amount,\n });\n}\n","/**\n * Book's spinner: the quill.\n *\n * A nib writes a flourish, a lemniscate (∞), across four braille cells one dot\n * at a time. It touches down at the left, climbs over the left lobe, dives\n * through the knot, rounds the right lobe and comes back through the knot to\n * close where it began, slowing through the tight turns the way a hand does.\n * The ink is wet at the nib, rubric red just behind it, and dries to grey as it\n * ages; once the pen lifts the mark dries faster, then the ink lifts off in the\n * order it was laid down, and the next stroke touches down beside the last\n * speck of the old one. Forty-eight frames at the 50ms clock: 2.4 seconds.\n *\n * The frames carry each cell's ink state (how old its freshest ink is, and how\n * much of the nib's wet glow reaches it) rather than colours, so the palette\n * comes from the theme at render time.\n *\n * It replaced a hedera fleuron that had three poses: Unicode holds that\n * ornament in three orientations and no angles between them.\n */\n\n/** The ink in one cell of a frame. */\nexport interface QuillInk {\n /** Frames since the freshest ink in the cell was laid, dry time included; `null` when bare. */\n age: number | null;\n /** How much of the nib's wet glow reaches the cell, 0–1. */\n wet: number;\n}\n\nexport interface QuillFrame {\n /** Four braille cells. */\n text: string;\n ink: readonly QuillInk[];\n}\n\n/** The colours ink is drawn in, from the theme. */\nexport interface QuillPalette {\n /** Fresh ink: the rubric. */\n fresh: string;\n /** Ink under the nib: the rubric's lighter shimmer. */\n wet: string;\n /** Ink part dry. */\n drying: string;\n /** Dry ink, and bare cells. */\n dry: string;\n}\n\nexport const QUILL_CELLS = 4;\nexport const QUILL_FRAME_COUNT = 48;\n\n/** Frames the nib spends writing, eased and slower through tight turns. */\nconst WRITE_FRAMES = 30;\n/**\n * The ink lifts oldest first, two specks a frame (one to begin); the last speck\n * goes on the frame the next stroke touches down, so no frame is blank.\n */\nconst LIFT_START = QUILL_FRAME_COUNT - 8;\n/** Extra dwell per radian of turn, like a hand in a curve. */\nconst TURN_COST = 0.75;\n/** Blend of linear and smoothstep timing: a slow start and finish. */\nconst WRITE_EASE = 0.35;\n/** Once the pen lifts, the whole mark dries this much faster. */\nconst DRY_BOOST = 1.2;\n/** Dots past its own cell that the nib's wet glow reaches. */\nconst NIB_REACH = 2;\n/** Frames the glow takes to go once the pen lifts. */\nconst NIB_FADE = 4;\n/** Frames the ink takes to start flowing after touchdown. */\nconst NIB_RAMP = 6;\n\n/**\n * The flourish on the 8×4 dot canvas, in pen order:\n *\n * . X X . . X X .\n * X . . X X . . X\n * X . . X X . . X\n * . X X . . X X .\n */\nconst STROKE: readonly (readonly [number, number])[] = [\n [0, 2],\n [0, 1],\n [1, 0],\n [2, 0],\n [3, 1],\n [4, 2],\n [5, 3],\n [6, 3],\n [7, 2],\n [7, 1],\n [6, 0],\n [5, 0],\n [4, 1],\n [3, 2],\n [2, 3],\n [1, 3],\n];\n\n/** Braille dot bit for a dot in column 0..1, row 0..3 of one cell. */\nconst DOT_BIT: readonly (readonly number[])[] = [\n [0x01, 0x02, 0x04, 0x40],\n [0x08, 0x10, 0x20, 0x80],\n];\n\nconst smoothstep = (t: number) => t * t * (3 - 2 * t);\nconst clamp01 = (t: number) => Math.max(0, Math.min(1, t));\n\ninterface TimedDot {\n x: number;\n y: number;\n /** Frame the nib lays it. */\n laid: number;\n /** Frame it lifts off. */\n lifted: number;\n}\n\nfunction timeStroke(): TimedDot[] {\n // A unit of travel per dot, plus dwell where the stroke turns.\n const costs = STROKE.map(([x, y], index) => {\n if (index === 0 || index === STROKE.length - 1) return 1;\n const [px, py] = STROKE[index - 1]!;\n const [nx, ny] = STROKE[index + 1]!;\n let turn = Math.abs(Math.atan2(ny - y, nx - x) - Math.atan2(y - py, x - px));\n if (turn > Math.PI) turn = 2 * Math.PI - turn;\n return 1 + TURN_COST * turn;\n });\n const reached: number[] = [];\n let travelled = 0;\n for (const cost of costs) {\n reached.push(travelled);\n travelled += cost;\n }\n const end = reached[reached.length - 1]!;\n const eased = (t: number) => (1 - WRITE_EASE) * t + WRITE_EASE * smoothstep(t);\n // Invert the easing: the time at which the eased journey reaches `progress`.\n const timeAt = (progress: number) => {\n let low = 0;\n let high = 1;\n for (let step = 0; step < 40; step++) {\n const mid = (low + high) / 2;\n if (eased(mid) < progress) low = mid;\n else high = mid;\n }\n return (low + high) / 2;\n };\n return STROKE.map(([x, y], index) => ({\n x,\n y,\n laid: reached[index] === 0 ? 0 : WRITE_FRAMES * timeAt(reached[index]! / end),\n lifted: LIFT_START + Math.ceil(index / 2),\n }));\n}\n\nfunction buildFrames(): QuillFrame[] {\n const dots = timeStroke();\n const penUp = dots[dots.length - 1]!.laid;\n const nibX = (tau: number) => {\n for (let index = 0; index < dots.length - 1; index++) {\n const here = dots[index]!;\n const next = dots[index + 1]!;\n if (tau < next.laid) {\n const k = clamp01((tau - here.laid) / (next.laid - here.laid));\n return here.x + (next.x - here.x) * k;\n }\n }\n return dots[dots.length - 1]!.x;\n };\n const nibStrength = (tau: number) => {\n if (tau < 0) return 0;\n if (tau <= penUp) return 0.35 + 0.65 * smoothstep(clamp01(tau / NIB_RAMP));\n return clamp01(1 - (tau - penUp) / NIB_FADE);\n };\n\n const frames: QuillFrame[] = [];\n for (let frame = 0; frame < QUILL_FRAME_COUNT; frame++) {\n const bits = new Array<number>(QUILL_CELLS).fill(0);\n const age = new Array<number>(QUILL_CELLS).fill(Infinity);\n const wet = new Array<number>(QUILL_CELLS).fill(0);\n // This cycle's stroke and its neighbours', so the loop has no seam.\n for (const tau of [frame, frame + QUILL_FRAME_COUNT, frame - QUILL_FRAME_COUNT]) {\n let inked = false;\n for (const dot of dots) {\n if (tau < dot.laid || tau >= dot.lifted) continue;\n inked = true;\n const cell = Math.floor(dot.x / 2);\n bits[cell]! |= DOT_BIT[dot.x % 2]![dot.y]!;\n const dried = tau - dot.laid + DRY_BOOST * Math.max(0, tau - penUp);\n age[cell] = Math.min(age[cell]!, dried);\n }\n if (!inked) continue;\n const strength = nibStrength(tau);\n const x = nibX(tau);\n for (let cell = 0; cell < QUILL_CELLS; cell++) {\n const distance = Math.max(0, 2 * cell - 0.5 - x, x - (2 * cell + 1.5));\n wet[cell] = Math.max(wet[cell]!, strength * smoothstep(clamp01(1 - distance / NIB_REACH)));\n }\n }\n frames.push({\n text: bits.map((bit) => String.fromCodePoint(0x2800 + bit)).join(''),\n ink: age.map((cellAge, cell) =>\n Number.isFinite(cellAge) ? { age: cellAge, wet: wet[cell]! } : { age: null, wet: 0 },\n ),\n });\n }\n return frames;\n}\n\n/** The spinner's frames, in order. */\nexport const QUILL_FRAMES: readonly QuillFrame[] = buildFrames();\n\n/** The finished flourish in fresh ink: the still frame, for reduced motion. */\nexport const QUILL_STILL: QuillFrame = {\n text: (() => {\n const bits = new Array<number>(QUILL_CELLS).fill(0);\n for (const [x, y] of STROKE) bits[Math.floor(x / 2)]! |= DOT_BIT[x % 2]![y]!;\n return bits.map((bit) => String.fromCodePoint(0x2800 + bit)).join('');\n })(),\n ink: new Array<QuillInk>(QUILL_CELLS).fill({ age: 0, wet: 0 }),\n};\n\n/** Frames ink stays fresh, is part dry, and is dry. */\nconst FRESH_FOR = 9;\nconst HALF_DRY_AT = 22;\nconst DRY_AT = 34;\n\n/**\n * The colour of each cell of `frame`. `mix(from, to, t)` blends two colours;\n * it is passed in so this module stays free of the theme's colour parsing.\n */\nexport function quillColors(\n frame: QuillFrame,\n palette: QuillPalette,\n mix: (from: string, to: string, t: number) => string,\n): string[] {\n const inkAt = (age: number) => {\n if (age <= FRESH_FOR) return palette.fresh;\n if (age <= HALF_DRY_AT) {\n return mix(\n palette.fresh,\n palette.drying,\n smoothstep((age - FRESH_FOR) / (HALF_DRY_AT - FRESH_FOR)),\n );\n }\n if (age <= DRY_AT) {\n return mix(\n palette.drying,\n palette.dry,\n smoothstep((age - HALF_DRY_AT) / (DRY_AT - HALF_DRY_AT)),\n );\n }\n return palette.dry;\n };\n return frame.ink.map((cell) => {\n if (cell.age === null) return palette.dry;\n const base = inkAt(cell.age);\n return cell.wet > 0 ? mix(base, palette.wet, cell.wet) : base;\n });\n}\n","import { Text, Box, type DOMElement } from 'ink';\nimport React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport { Spinner } from './Spinner.js';\nimport { useTheme } from '../theme.js';\nimport { DiffBlock } from './Diff.js';\nimport { MarkdownBlock } from './MarkdownBlock.js';\nimport { highlightCode } from './syntax-highlight.js';\nimport { prepareToolOutputDisplay } from './tool-output.js';\nimport { truncateDisplay } from './word-wrap.js';\nimport {\n getFileMutationDisplaySummary,\n isRenderableFileMutationDiff,\n} from '../file-mutation-display.js';\nimport {\n composeToolRow,\n deriveToolPresentation,\n type ToolPresentationStatus,\n} from '../tool-presentation.js';\nimport {\n CONTENT_COLUMN,\n GUTTER_WIDTH,\n indentedGrid,\n nestedGrid,\n transcriptGrid,\n withLabelColumn,\n} from '../layout.js';\nimport { formatElapsedDuration } from './SubagentRow.js';\nimport { foldControlCharacters, stripTerminalControls } from '../../control-characters.js';\nimport { useToolRowInteractionRegistry } from './tool-row-interactions.js';\nimport { useUiClock } from '../ui-clock.js';\nimport type { ToolResult } from '../../types/tools.js';\nimport { networkPolicyRefusal } from '../../tools/web-policy.js';\n\n/**\n * A blocked result shows its reason only for a network-policy refusal or a stopped cross-origin\n * redirect, which the user needs to understand. `networkPolicyRefusal` classifies both, and the\n * loop's stop message uses the same classifier.\n */\nfunction showsErrorMessage(result: ToolResult | undefined): boolean {\n if (!result?.structuredError) return false;\n return result.status !== 'blocked' || networkPolicyRefusal(result) !== undefined;\n}\n\ninterface ToolCallBlockProps {\n toolId?: string;\n name: string;\n args: Record<string, unknown>;\n /** The argument text of a call the provider could not parse; its `args` are empty. */\n unparsedArguments?: { raw: string; error: string };\n result?: ToolResult;\n isExpanded: boolean;\n isPending?: boolean;\n nestedActivityCount?: number;\n agentColor?: string;\n reducedMotion?: boolean;\n /** When true, renders flat, complete text without decorations. */\n screenReader?: boolean;\n /** When true, expanded tool results show the large rendering ceiling. */\n showAllToolOutput?: boolean;\n /** Render a file path as a child row under an aggregate mutation heading. */\n summaryVariant?: 'default' | 'file-child';\n /** Available terminal width, including this block's outer indentation. */\n terminalWidth?: number;\n /**\n * Width of the label column, measured across the sibling rows of this turn.\n * Omitted, the row uses the grid's default column.\n */\n labelWidth?: number;\n}\n\n/** Compatibility export used by existing consumers and tests. */\nfunction getResultLabel(result?: ToolResult): { label: string; color: string } {\n if (!result) return { label: '', color: 'gray' };\n if (result.status === 'blocked') return { label: '[SKIPPED]', color: 'yellow' };\n if (result.status !== 'success') return { label: '[ERR]', color: 'red' };\n return { label: '[OK]', color: 'green' };\n}\n\nfunction isDiffOutput(toolName: string, result: ToolResult | undefined): boolean {\n return isRenderableFileMutationDiff(toolName, result);\n}\n\nfunction toolLabel(name: string): string {\n const labels: Record<string, string> = {\n Read: 'Read file',\n ApplyPatch: 'Apply patch',\n Write: 'Write file',\n Edit: 'Edit file',\n MultiEdit: 'Edit file',\n NotebookEdit: 'Edit notebook',\n Bash: 'Run command',\n BashOutput: 'Read shell output',\n KillShell: 'Kill shell',\n Glob: 'Find files',\n Grep: 'Search files',\n WebFetch: 'Fetch URL',\n WebSearch: 'Search web',\n Task: 'Run subagent',\n InvokeSkill: 'Use skill',\n };\n return labels[name] ?? name;\n}\n\nfunction statusColor(status: ToolPresentationStatus, theme: ReturnType<typeof useTheme>): string {\n // A column of green checks beside one rose `×` made every row shout. Success\n // is the default, so it is the exception — a failure or a pending row — that\n // takes colour.\n if (status === 'success') return theme.inactive;\n if (status === 'failure') return theme.error;\n if (status === 'skipped' || status === 'pending') return theme.warning;\n return theme.brand;\n}\n\nfunction statusSymbol(status: ToolPresentationStatus): string {\n if (status === 'success') return '✓';\n if (status === 'failure') return '×';\n if (status === 'skipped') return '–';\n if (status === 'pending') return '?';\n return '◌';\n}\n\nfunction useRunningElapsed(isRunning: boolean): number {\n const startedAtRef = useRef(Date.now());\n // The 1s clock keeps a running row to one re-render per second; the fast\n // clock forced 10 renders + full Yoga layouts per second for every running\n // tool. Second granularity in the label (formatElapsedDuration) matches.\n const tick = useUiClock('slow', isRunning);\n\n useEffect(() => {\n startedAtRef.current = Date.now();\n }, [isRunning]);\n\n void tick;\n return isRunning ? Date.now() - startedAtRef.current : 0;\n}\n\nfunction ScreenReaderTool({\n presentation,\n result,\n}: {\n presentation: ReturnType<typeof deriveToolPresentation>;\n result?: ToolResult;\n}) {\n const status =\n presentation.status === 'running'\n ? '[Running]'\n : presentation.status === 'pending'\n ? '[needs approval]'\n : presentation.status === 'success'\n ? '[OK]'\n : presentation.status === 'skipped'\n ? '[SKIPPED]'\n : '[ERR]';\n const accessibleSummary =\n presentation.previewType === 'diff' || presentation.canonicalName.startsWith('mcp__')\n ? presentation.summary\n : `${toolLabel(presentation.canonicalName)}${presentation.target ? ` ${presentation.target}` : ''}${\n presentation.metadata.length > 0 ? ` · ${presentation.metadata.join(' ')}` : ''\n }`;\n return (\n <Box flexDirection=\"column\">\n <Text>\n {status} {accessibleSummary}\n </Text>\n {result?.content ? <Text>{stripTerminalControls(result.content)}</Text> : null}\n {result?.structuredError && showsErrorMessage(result) ? (\n <Text>Error: {foldControlCharacters(result.structuredError.message)}</Text>\n ) : null}\n </Box>\n );\n}\n\n/**\n * Render a target so the part that identifies it carries the weight.\n *\n * Two ramps at once. Across the row: a path's directory is context and its\n * basename is the thing being acted on, and in a column of twenty rows the\n * directories are largely identical. Against the rest of the turn: a tool row\n * is machinery, and it sits a step below prose so the answer is the brightest\n * thing on screen rather than one more row of the same weight.\n */\nexport function TargetText({\n target,\n failed,\n path = false,\n}: {\n target: string;\n failed: boolean;\n /** Split the directory prefix off. Only meaningful for filesystem paths. */\n path?: boolean;\n}) {\n const theme = useTheme();\n if (failed) return <Text color={theme.error}>{target}</Text>;\n const split = path ? target.lastIndexOf('/') : -1;\n // A trailing slash leaves no basename, which would paint the whole target in\n // the dim prefix colour and make the row's only content the faintest thing\n // on screen.\n if (split < 0 || split === target.length - 1) {\n return <Text color={theme.subtle}>{target}</Text>;\n }\n return (\n <Text>\n <Text color={theme.inactive}>{target.slice(0, split + 1)}</Text>\n <Text color={theme.subtle}>{target.slice(split + 1)}</Text>\n </Text>\n );\n}\n\n/** `+12` / `-3`: churn counts, which read faster in the diff colours. */\nconst CHURN_TOKEN = /^([+-])(\\d+)$/;\n\n/**\n * Render right-aligned metadata, colouring churn counts.\n *\n * Everything else stays recessive — the figures a reader scans for are the\n * lines added and removed, and an error.\n */\nexport function MetaText({ meta, failed }: { meta: string; failed: boolean }) {\n const theme = useTheme();\n if (failed) return <Text color={theme.error}>{meta}</Text>;\n if (!CHURN_TOKEN.test(meta.split(' ')[0] ?? '')) {\n return <Text color={theme.inactive}>{meta}</Text>;\n }\n return (\n <Text>\n {meta.split(' ').map((token, index) => {\n const churn = CHURN_TOKEN.exec(token);\n const color = !churn ? theme.inactive : churn[1] === '+' ? theme.success : theme.error;\n return (\n <Text key={index} color={color}>\n {index > 0 ? ' ' : ''}\n {token}\n </Text>\n );\n })}\n </Text>\n );\n}\n\nfunction ToolCallBlockInner({\n toolId,\n name,\n args,\n unparsedArguments,\n result,\n isExpanded,\n isPending = false,\n nestedActivityCount = 0,\n agentColor,\n reducedMotion = false,\n screenReader = false,\n showAllToolOutput = false,\n summaryVariant = 'default',\n terminalWidth = 80,\n labelWidth,\n}: ToolCallBlockProps) {\n const theme = useTheme();\n const registry = useToolRowInteractionRegistry();\n const summaryRef = useRef<DOMElement>(null);\n const grid = useMemo(() => {\n const base = transcriptGrid(terminalWidth);\n return labelWidth === undefined ? base : withLabelColumn(base, labelWidth);\n }, [labelWidth, terminalWidth]);\n // The row nests one gutter under the prose it belongs to, so its own grid is\n // the indented one; `grid` stays the message-level measure the label column\n // was negotiated against.\n const rowGrid = useMemo(() => indentedGrid(grid), [grid]);\n const blockWidth = rowGrid.content;\n const presentation = useMemo(\n () =>\n deriveToolPresentation(name, args, result, {\n isPending,\n nestedActivityCount,\n unparsedArguments,\n }),\n [args, isPending, name, nestedActivityCount, result, unparsedArguments],\n );\n const isRunning = presentation.status === 'running';\n // Under reducedMotion the row must not tick at all: the spinner is frozen,\n // so a changing elapsed label would be the only remaining animation.\n const runningElapsedMs = useRunningElapsed(isRunning && !reducedMotion);\n const elapsed =\n isRunning && !reducedMotion\n ? formatElapsedDuration(Math.floor(runningElapsedMs / 1000))\n : undefined;\n const inlineError = showsErrorMessage(result) ? result?.structuredError?.message : undefined;\n const mutationSummary = useMemo(\n () => getFileMutationDisplaySummary(name, args, result),\n [args, name, result],\n );\n const isFileChild = summaryVariant === 'file-child';\n // A child row sits under an aggregate heading that already named the verb, so\n // it drops the label column and renders on the nested grid.\n const row = useMemo(() => {\n if (isFileChild && mutationSummary) {\n return composeToolRow(\n {\n title: '',\n target: mutationSummary.filePath,\n metadata: [`+${mutationSummary.addedLines}`, `-${mutationSummary.removedLines}`],\n },\n nestedGrid(rowGrid),\n { error: inlineError },\n );\n }\n return composeToolRow(presentation, isFileChild ? nestedGrid(rowGrid) : rowGrid, {\n elapsed,\n error: inlineError,\n });\n }, [elapsed, rowGrid, inlineError, isFileChild, mutationSummary, presentation]);\n\n useLayoutEffect(() => {\n if (!registry || !toolId) return;\n return registry.register({\n id: toolId,\n element: summaryRef,\n expandable: presentation.hasHiddenContent,\n expanded: isExpanded,\n });\n }, [isExpanded, presentation.hasHiddenContent, registry, toolId]);\n\n if (screenReader) {\n return (\n <Box flexDirection=\"column\" marginLeft={CONTENT_COLUMN} width={blockWidth}>\n <ScreenReaderTool presentation={presentation} result={result} />\n </Box>\n );\n }\n\n return (\n <Box\n flexDirection=\"column\"\n marginLeft={isFileChild ? CONTENT_COLUMN + GUTTER_WIDTH : CONTENT_COLUMN}\n >\n <Box ref={summaryRef} height={1}>\n {/* The gutter carries status; content always begins on the next column. */}\n {isFileChild ? (\n <Text color={theme.toolRail}>└ </Text>\n ) : isRunning ? (\n <>\n {/* Spinner emits its own trailing space, so the gutter stays two\n columns wide and the verb does not shift when the tool ends. */}\n <Spinner\n active\n style=\"dots\"\n color={agentColor ?? theme.assistantAccent}\n reducedMotion={reducedMotion}\n />\n </>\n ) : (\n <Text color={statusColor(presentation.status, theme)}>\n {statusSymbol(presentation.status)}{' '}\n </Text>\n )}\n {/* Recessive, but never faint: SGR 2 on an already-muted grey left the\n verb nearly invisible on a dark background. */}\n {row.label ? <Text color={theme.inactive}>{row.label} </Text> : null}\n <TargetText\n target={row.target}\n failed={presentation.status === 'failure'}\n path={Boolean(presentation.filePath) || isFileChild}\n />\n <Text>{row.gap}</Text>\n <MetaText meta={row.meta} failed={Boolean(inlineError)} />\n </Box>\n {isExpanded && result && isDiffOutput(name, result) ? (\n <DiffBlock\n output={result.content}\n filePath={presentation.filePath}\n terminalWidth={blockWidth}\n />\n ) : isExpanded && result?.content ? (\n <OutputBlock\n output={result.content}\n success={result.status === 'success'}\n theme={theme}\n showAllToolOutput={showAllToolOutput}\n toolName={presentation.canonicalName}\n terminalWidth={blockWidth}\n />\n ) : null}\n </Box>\n );\n}\n\nexport const ToolCallBlock = React.memo(ToolCallBlockInner);\n\nfunction looksLikeMarkdown(output: string, toolName: string): boolean {\n if (toolName === 'WebFetch' || toolName === 'WebSearch') return true;\n return /(^|\\n)\\s{0,3}(#{1,6}\\s|[-*+]\\s|\\d+\\.\\s|>\\s|```|\\|.+\\|)/.test(output);\n}\n\nfunction inferLanguage(output: string, toolName: string): string | undefined {\n if (toolName !== 'Read') return undefined;\n const firstLine = output.split('\\n', 1)[0] ?? '';\n const match = firstLine.match(/\\.(ts|tsx|js|jsx|json|py|rs|go|sh|bash|yml|yaml|css|html|sql)\\b/i);\n return match?.[1]?.toLowerCase();\n}\n\nfunction OutputBlock({\n output,\n success,\n theme,\n showAllToolOutput,\n toolName,\n terminalWidth,\n}: {\n output: string;\n success: boolean;\n theme: ReturnType<typeof useTheme>;\n showAllToolOutput: boolean;\n toolName: string;\n terminalWidth: number;\n}) {\n // The rail's border plus its padding occupy the nested gutter.\n const contentWidth = Math.max(8, Math.floor(terminalWidth) - CONTENT_COLUMN - 2);\n const footerWidth = contentWidth;\n const display = useMemo(\n () =>\n prepareToolOutputDisplay(output, {\n maxLines: showAllToolOutput ? 2000 : success ? 6 : 10,\n maxLineWidth: contentWidth,\n hint: showAllToolOutput ? undefined : 'Ctrl+E shows all',\n strategy: showAllToolOutput ? 'head' : success ? 'head-tail' : 'tail',\n }),\n [contentWidth, output, showAllToolOutput, success],\n );\n const language = inferLanguage(output, toolName);\n const displayText = display.lines.join('\\n');\n const highlighted = useMemo(\n () => (language ? highlightCode(displayText, language, theme) : undefined),\n [displayText, language, theme],\n );\n // The markdown sniff regex scans the whole output string; memoize it so an\n // expanded multi-MB result pays that once per output, not once per render.\n const renderAsMarkdown = useMemo(\n () => !language && looksLikeMarkdown(output, toolName),\n [language, output, toolName],\n );\n\n if (renderAsMarkdown) {\n return (\n <Box\n marginLeft={CONTENT_COLUMN}\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderLeft\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeftColor={theme.toolRail}\n paddingLeft={1}\n paddingRight={1}\n >\n <MarkdownBlock content={display.lines.join('\\n')} terminalWidth={contentWidth} />\n {display.footer ? (\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(display.footer, footerWidth)}\n </Text>\n ) : null}\n </Box>\n );\n }\n\n return (\n <Box\n marginLeft={CONTENT_COLUMN}\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderLeft\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeftColor={theme.toolRail}\n paddingLeft={1}\n paddingRight={1}\n >\n {display.lines.map((line, index) => (\n <Box key={index}>\n {highlighted ? (\n <Text>\n {highlighted[index]?.map((segment, segmentIndex) => (\n <Text\n key={segmentIndex}\n color={segment.color}\n bold={segment.bold}\n italic={segment.italic}\n dimColor\n >\n {segment.text}\n </Text>\n ))}\n </Text>\n ) : (\n <Text color={theme.text} dimColor>\n {line}\n </Text>\n )}\n </Box>\n ))}\n {display.footer ? (\n <Box>\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(display.footer, footerWidth)}\n </Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n\nexport { isDiffOutput, getResultLabel, toolLabel };\n","import { Text, Box } from 'ink';\nimport { Fragment, useMemo } from 'react';\nimport { useTheme } from '../theme.js';\nimport { displayWidth, hardWrapLine, padDisplay, truncateDisplay } from './word-wrap.js';\nimport { highlightCode, type StyledSegment } from './syntax-highlight.js';\n\ninterface DiffProps {\n output: string;\n filePath?: string;\n /** When true, render a change-focused preview across all hunks. */\n collapsed?: boolean;\n /** Row budget for the collapsed preview; defaults to the transcript's. */\n maxRows?: number;\n /** Key hint appended to the omission footer while collapsed. */\n expandHint?: string;\n terminalWidth?: number;\n}\n\nconst COLLAPSED_ROWS = 80;\nconst COLLAPSED_CONTEXT_ROWS = 2;\nconst MAX_WORD_TOKENS = 200;\nconst MAX_WORD_LINE_LENGTH = 2000;\n\nexport function isUnifiedDiffLike(output: string): boolean {\n const hasHunk = /^@@\\s+-\\d+(?:,\\d+)?\\s+\\+\\d+(?:,\\d+)?\\s+@@/m.test(output);\n const hasChangedLine = /^(?:\\+(?!\\+\\+)|-(?!--))/m.test(output);\n return hasHunk && hasChangedLine;\n}\n\nexport type DiffLineKind = 'add' | 'del' | 'hunk' | 'ctx' | 'meta';\nexport type DiffSpanKind = 'plain' | 'addedWord' | 'removedWord';\n\nexport interface DiffSpan {\n text: string;\n kind: DiffSpanKind;\n}\n\nexport interface ParsedDiffLine {\n /** Original source row, retained for exact byte accounting and compatibility. */\n text: string;\n content: string;\n marker: '+' | '-' | ' ' | '@' | '\\\\';\n kind: DiffLineKind;\n oldLineNumber?: number;\n newLineNumber?: number;\n spans?: DiffSpan[];\n}\n\ninterface HunkPosition {\n oldLine: number;\n newLine: number;\n}\n\nfunction parseHunkPosition(line: string): HunkPosition | undefined {\n const match = /^@@\\s+-(\\d+)(?:,\\d+)?\\s+\\+(\\d+)(?:,\\d+)?\\s+@@/.exec(line);\n if (!match) return undefined;\n return { oldLine: Number(match[1]), newLine: Number(match[2]) };\n}\n\n/** Parse Claude-style embedded word markers such as `{+new+}` when present. */\nfunction parseEmbeddedWordMarkers(content: string): DiffSpan[] | undefined {\n const spans: DiffSpan[] = [];\n const combined = /\\{(\\+|\\-)(.+?)\\1\\}/gs;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = combined.exec(content)) !== null) {\n const before = content.slice(lastIndex, match.index);\n if (before) spans.push({ text: before, kind: 'plain' });\n spans.push({\n text: match[2],\n kind: match[1] === '+' ? 'addedWord' : 'removedWord',\n });\n lastIndex = combined.lastIndex;\n }\n\n if (spans.length === 0) return undefined;\n const after = content.slice(lastIndex);\n if (after) spans.push({ text: after, kind: 'plain' });\n return spans;\n}\n\nfunction tokenizeForDiff(value: string): string[] {\n return value.match(/\\s+|[\\p{L}\\p{N}_]+|[^\\s\\p{L}\\p{N}_]/gu) ?? [];\n}\n\nfunction mergeSpans(spans: DiffSpan[]): DiffSpan[] {\n const merged: DiffSpan[] = [];\n for (const span of spans) {\n const previous = merged[merged.length - 1];\n if (previous?.kind === span.kind) previous.text += span.text;\n else if (span.text) merged.push({ ...span });\n }\n return merged;\n}\n\n/** Bounded token LCS for adjacent one-line replacements. */\nfunction calculateReplacementSpans(\n removed: string,\n added: string,\n): { removed: DiffSpan[]; added: DiffSpan[] } | undefined {\n if (removed.length > MAX_WORD_LINE_LENGTH || added.length > MAX_WORD_LINE_LENGTH)\n return undefined;\n const oldTokens = tokenizeForDiff(removed);\n const newTokens = tokenizeForDiff(added);\n if (\n oldTokens.length === 0 ||\n newTokens.length === 0 ||\n oldTokens.length > MAX_WORD_TOKENS ||\n newTokens.length > MAX_WORD_TOKENS\n ) {\n return undefined;\n }\n\n const table = Array.from(\n { length: oldTokens.length + 1 },\n () => new Uint16Array(newTokens.length + 1),\n );\n for (let oldIndex = oldTokens.length - 1; oldIndex >= 0; oldIndex--) {\n for (let newIndex = newTokens.length - 1; newIndex >= 0; newIndex--) {\n table[oldIndex][newIndex] =\n oldTokens[oldIndex] === newTokens[newIndex]\n ? table[oldIndex + 1][newIndex + 1] + 1\n : Math.max(table[oldIndex + 1][newIndex], table[oldIndex][newIndex + 1]);\n }\n }\n\n const removedSpans: DiffSpan[] = [];\n const addedSpans: DiffSpan[] = [];\n let oldIndex = 0;\n let newIndex = 0;\n let commonTokens = 0;\n while (oldIndex < oldTokens.length || newIndex < newTokens.length) {\n if (\n oldIndex < oldTokens.length &&\n newIndex < newTokens.length &&\n oldTokens[oldIndex] === newTokens[newIndex]\n ) {\n removedSpans.push({ text: oldTokens[oldIndex], kind: 'plain' });\n addedSpans.push({ text: newTokens[newIndex], kind: 'plain' });\n oldIndex++;\n newIndex++;\n commonTokens++;\n } else if (\n newIndex < newTokens.length &&\n (oldIndex >= oldTokens.length ||\n table[oldIndex][newIndex + 1] >= table[oldIndex + 1][newIndex])\n ) {\n addedSpans.push({ text: newTokens[newIndex], kind: 'addedWord' });\n newIndex++;\n } else {\n removedSpans.push({ text: oldTokens[oldIndex], kind: 'removedWord' });\n oldIndex++;\n }\n }\n\n // Unrelated long lines are clearer with whole-line highlighting.\n if (commonTokens === 0 && Math.max(oldTokens.length, newTokens.length) > 8) return undefined;\n return { removed: mergeSpans(removedSpans), added: mergeSpans(addedSpans) };\n}\n\nexport function parseDiffLines(output: string): ParsedDiffLine[] {\n if (output.length === 0) return [];\n\n let oldLine: number | undefined;\n let newLine: number | undefined;\n let inHunk = false;\n const rows = output.split('\\n').map((text): ParsedDiffLine => {\n const hunk = parseHunkPosition(text);\n if (hunk) {\n inHunk = true;\n oldLine = hunk.oldLine;\n newLine = hunk.newLine;\n return { text, content: text, marker: '@', kind: 'hunk' };\n }\n if (text.startsWith('diff ')) {\n inHunk = false;\n oldLine = undefined;\n newLine = undefined;\n return { text, content: text, marker: ' ', kind: 'meta' };\n }\n if (!inHunk && (text.startsWith('---') || text.startsWith('+++'))) {\n return { text, content: text, marker: ' ', kind: 'meta' };\n }\n if (text.startsWith('\\\')) {\n return { text, content: text.slice(2), marker: '\\\\', kind: 'meta' };\n }\n if (text.startsWith('-')) {\n const row = {\n text,\n content: text.slice(1),\n marker: '-' as const,\n kind: 'del' as const,\n oldLineNumber: oldLine,\n spans: parseEmbeddedWordMarkers(text.slice(1)),\n };\n if (oldLine !== undefined) oldLine++;\n return row;\n }\n if (text.startsWith('+')) {\n const row = {\n text,\n content: text.slice(1),\n marker: '+' as const,\n kind: 'add' as const,\n newLineNumber: newLine,\n spans: parseEmbeddedWordMarkers(text.slice(1)),\n };\n if (newLine !== undefined) newLine++;\n return row;\n }\n\n const content = text.startsWith(' ') ? text.slice(1) : text;\n const row = {\n text,\n content,\n marker: ' ' as const,\n kind: 'ctx' as const,\n oldLineNumber: oldLine,\n newLineNumber: newLine,\n };\n if (oldLine !== undefined) oldLine++;\n if (newLine !== undefined) newLine++;\n return row;\n });\n\n for (let index = 0; index < rows.length;) {\n if (rows[index].kind !== 'del') {\n index++;\n continue;\n }\n const deletedStart = index;\n while (index < rows.length && rows[index].kind === 'del') index++;\n const addedStart = index;\n while (index < rows.length && rows[index].kind === 'add') index++;\n const pairCount = Math.min(addedStart - deletedStart, index - addedStart);\n for (let pairIndex = 0; pairIndex < pairCount; pairIndex++) {\n const removed = rows[deletedStart + pairIndex];\n const added = rows[addedStart + pairIndex];\n if (removed.spans || added.spans) continue;\n const replacement = calculateReplacementSpans(removed.content, added.content);\n if (!replacement) continue;\n removed.spans = replacement.removed;\n added.spans = replacement.added;\n }\n }\n return rows;\n}\n\nexport function inferDiffLanguage(filePath: string | undefined): string | undefined {\n const extension = filePath?.split('.').pop()?.toLowerCase();\n const languages: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n py: 'python',\n rs: 'rust',\n go: 'go',\n sh: 'bash',\n bash: 'bash',\n json: 'json',\n yml: 'yaml',\n yaml: 'yaml',\n css: 'css',\n html: 'html',\n sql: 'sql',\n };\n return extension ? languages[extension] : undefined;\n}\n\nexport function expandTabs(value: string, tabSize = 4): string {\n let column = 0;\n let result = '';\n for (const character of value) {\n if (character === '\\t') {\n const spaces = tabSize - (column % tabSize);\n result += ' '.repeat(spaces);\n column += spaces;\n } else {\n result += character;\n column += displayWidth(character);\n }\n }\n return result;\n}\n\nfunction expandSpanTabs(spans: readonly DiffSpan[], tabSize = 4): DiffSpan[] {\n const output: DiffSpan[] = [];\n let column = 0;\n for (const span of spans) {\n let text = '';\n for (const character of span.text) {\n if (character === '\\t') {\n const spaces = tabSize - (column % tabSize);\n text += ' '.repeat(spaces);\n column += spaces;\n } else {\n text += character;\n column += displayWidth(character);\n }\n }\n if (text) output.push({ ...span, text });\n }\n return output;\n}\n\nfunction wrapSpans(spans: readonly DiffSpan[], width: number): DiffSpan[][] {\n const lines: DiffSpan[][] = [[]];\n let lineWidth = 0;\n\n for (const span of expandSpanTabs(spans)) {\n for (const character of span.text) {\n const characterWidth = displayWidth(character);\n if (lines[lines.length - 1].length > 0 && lineWidth + characterWidth > width) {\n lines.push([]);\n lineWidth = 0;\n }\n\n const line = lines[lines.length - 1];\n const previous = line[line.length - 1];\n if (previous?.kind === span.kind) previous.text += character;\n else line.push({ text: character, kind: span.kind });\n lineWidth += characterWidth;\n }\n }\n\n return lines;\n}\n\nfunction rowByteSize(row: ParsedDiffLine, index: number, total: number): number {\n return Buffer.byteLength(`${row.text}${index < total - 1 ? '\\n' : ''}`, 'utf8');\n}\n\nfunction selectPreviewIndices(rows: readonly ParsedDiffLine[], limit: number): number[] {\n if (rows.length <= limit) return rows.map((_, index) => index);\n const changedIndices = rows\n .map((row, index) => (row.kind === 'add' || row.kind === 'del' ? index : -1))\n .filter((index) => index >= 0);\n if (changedIndices.length === 0) return Array.from({ length: limit }, (_, index) => index);\n\n const hunkHeaders = rows\n .map((row, index) => (row.kind === 'hunk' ? index : -1))\n .filter((index) => index >= 0);\n const priority = new Set([...hunkHeaders, ...changedIndices]);\n\n // Context is useful, but changed rows and hunk boundaries always win the budget.\n const contextCandidates = new Map<number, number>();\n for (const changedIndex of changedIndices) {\n for (let distance = 1; distance <= COLLAPSED_CONTEXT_ROWS; distance++) {\n for (const candidate of [changedIndex - distance, changedIndex + distance]) {\n if (candidate < 0 || candidate >= rows.length || priority.has(candidate)) continue;\n if (rows[candidate].kind !== 'ctx') continue;\n const previousDistance = contextCandidates.get(candidate);\n if (previousDistance === undefined || distance < previousDistance) {\n contextCandidates.set(candidate, distance);\n }\n }\n }\n }\n\n const priorityIndices = [...priority].sort((a, b) => a - b);\n if (priorityIndices.length >= limit) {\n const headCount = Math.ceil(limit / 2);\n return [...priorityIndices.slice(0, headCount), ...priorityIndices.slice(-(limit - headCount))];\n }\n\n const contextIndices = [...contextCandidates.entries()]\n .sort(([leftIndex, leftDistance], [rightIndex, rightDistance]) =>\n leftDistance === rightDistance ? leftIndex - rightIndex : leftDistance - rightDistance,\n )\n .slice(0, limit - priorityIndices.length)\n .map(([index]) => index);\n\n return [...priorityIndices, ...contextIndices].sort((a, b) => a - b);\n}\n\ninterface SelectedDiffRow {\n row: ParsedDiffLine;\n sourceIndex: number;\n}\n\nfunction selectRenderedRows(\n rows: readonly ParsedDiffLine[],\n collapsed: boolean,\n limit: number,\n): { rows: SelectedDiffRow[]; hiddenRows: number; hiddenBytes: number } {\n const rowBytes = rows.map((row, index) => rowByteSize(row, index, rows.length));\n const indices = collapsed\n ? selectPreviewIndices(rows, Math.max(1, Math.floor(limit)))\n : rows.map((_, index) => index);\n const selected = new Set(indices);\n const hiddenBytes = rowBytes.reduce(\n (total, bytes, index) => total + (selected.has(index) ? 0 : bytes),\n 0,\n );\n return {\n rows: indices.map((sourceIndex) => ({ row: rows[sourceIndex], sourceIndex })),\n hiddenRows: rows.length - indices.length,\n hiddenBytes,\n };\n}\n\nfunction lineNumber(value: number | undefined, width: number): string {\n if (value === undefined) return ' '.repeat(width);\n const text = String(value);\n return text.length <= width ? padDisplay(text, width, 'right') : text.slice(-width);\n}\n\nfunction syntaxSegments(\n content: string,\n language: string | undefined,\n theme: ReturnType<typeof useTheme>,\n): StyledSegment[] | undefined {\n if (!language || !content) return undefined;\n return highlightCode(content, language, theme)[0];\n}\n\nexport function DiffBlock({\n output,\n filePath,\n collapsed = false,\n maxRows = COLLAPSED_ROWS,\n expandHint = 'Ctrl+E shows all',\n terminalWidth = 80,\n}: DiffProps) {\n const theme = useTheme();\n const parsed = useMemo(() => parseDiffLines(output), [output]);\n const selected = useMemo(\n () => selectRenderedRows(parsed, collapsed, maxRows),\n [collapsed, maxRows, parsed],\n );\n const language = inferDiffLanguage(filePath);\n const maxOld = Math.max(1, ...parsed.map((row) => row.oldLineNumber ?? 0));\n const maxNew = Math.max(1, ...parsed.map((row) => row.newLineNumber ?? 0));\n const narrow = terminalWidth < 36;\n const oldWidth = Math.max(1, Math.min(String(maxOld).length, narrow ? 3 : 6));\n const newWidth = Math.max(1, Math.min(String(maxNew).length, narrow ? 3 : 6));\n // marginLeft(2) + `│` + gutters + marker remain visible before wrapped content.\n const fixedWidth = 2 + 1 + oldWidth + 1 + newWidth + 1 + 2;\n const contentWidth = Math.max(1, Math.floor(terminalWidth) - fixedWidth);\n\n return (\n <Box flexDirection=\"column\">\n {selected.rows.map(({ row, sourceIndex }, index) => {\n const previousSourceIndex = selected.rows[index - 1]?.sourceIndex;\n const gapRows =\n previousSourceIndex === undefined ? sourceIndex : sourceIndex - previousSourceIndex - 1;\n const backgroundColor =\n row.kind === 'add' ? theme.diffAdded : row.kind === 'del' ? theme.diffRemoved : undefined;\n // A hunk header is a signpost, not content: quiet, and never the accent.\n const foregroundColor = row.kind === 'hunk' ? theme.inactive : theme.text;\n const rawContent = expandTabs(row.content);\n const wrappedSpans = row.spans ? wrapSpans(row.spans, contentWidth) : undefined;\n const wrappedContent = wrappedSpans\n ? wrappedSpans.map((spans) => spans.map((span) => span.text).join(''))\n : hardWrapLine(rawContent, contentWidth);\n\n return (\n <Fragment key={`${sourceIndex}-${row.text}`}>\n {gapRows > 0 ? (\n <Box marginLeft={2}>\n <Text color={theme.subtle} dimColor>\n │{' '}\n {truncateDisplay(\n `⋮ ${gapRows} ${gapRows === 1 ? 'row' : 'rows'} omitted`,\n Math.max(4, terminalWidth - 4),\n )}\n </Text>\n </Box>\n ) : null}\n {wrappedContent.map((content, visualIndex) => {\n const spans = wrappedSpans?.[visualIndex];\n const highlighted =\n !spans && (row.kind === 'add' || row.kind === 'del' || row.kind === 'ctx')\n ? syntaxSegments(content, language, theme)\n : undefined;\n const visibleWidth = spans\n ? spans.reduce((total, span) => total + displayWidth(span.text), 0)\n : displayWidth(content);\n const padding = backgroundColor\n ? ' '.repeat(Math.max(0, contentWidth - visibleWidth))\n : '';\n const continuation = visualIndex > 0;\n\n return (\n <Box key={visualIndex} marginLeft={2}>\n <Text color={theme.toolRail}>│</Text>\n <Text color={theme.subtle} dimColor>\n {lineNumber(continuation ? undefined : row.oldLineNumber, oldWidth)}{' '}\n {lineNumber(continuation ? undefined : row.newLineNumber, newWidth)}{' '}\n </Text>\n <Text\n color={\n row.kind === 'add'\n ? theme.success\n : row.kind === 'del'\n ? theme.error\n : foregroundColor\n }\n backgroundColor={backgroundColor}\n >\n {/* `@@ -6 +6 @@` already starts with its marker; a second\n `@` in the marker column read as a rendering glitch. */}\n {continuation || row.kind === 'hunk' ? ' ' : row.marker}{' '}\n </Text>\n <Text color={foregroundColor} backgroundColor={backgroundColor}>\n {spans\n ? spans.map((span, spanIndex) => (\n <Text\n key={spanIndex}\n backgroundColor={\n span.kind === 'addedWord'\n ? theme.diffAddedWord\n : span.kind === 'removedWord'\n ? theme.diffRemovedWord\n : backgroundColor\n }\n bold={span.kind !== 'plain'}\n >\n {span.text}\n </Text>\n ))\n : highlighted\n ? highlighted.map((segment, segmentIndex) => (\n <Text\n key={segmentIndex}\n color={segment.color}\n bold={segment.bold}\n italic={segment.italic}\n dimColor={segment.dimColor}\n >\n {segment.text}\n </Text>\n ))\n : content}\n {padding}\n </Text>\n </Box>\n );\n })}\n </Fragment>\n );\n })}\n {selected.hiddenRows > 0 || selected.hiddenBytes > 0 ? (\n <Box marginLeft={2}>\n <Text color={theme.subtle} dimColor>\n │{' '}\n {truncateDisplay(\n `… ${selected.hiddenRows} ${selected.hiddenRows === 1 ? 'row' : 'rows'} and ${selected.hiddenBytes} B omitted${collapsed && expandHint ? `; ${expandHint}` : ''}`,\n Math.max(4, terminalWidth - 4),\n )}\n </Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n","/**\n * Soft word-boundary text wrapping utility.\n *\n * Unlike Ink's built-in wrap-ansi (which uses `hard: true` and breaks at any\n * character position), this wraps only at word boundaries (spaces). Words\n * longer than maxWidth are kept intact — Ink's hard wrap handles those as\n * a safety net.\n *\n * ANSI escape sequences are stripped before measuring width so that colored\n * text is not mismeasured.\n */\n\n/**\n * Strip ANSI escape sequences from a string for accurate width measurement.\n */\nexport function stripAnsi(text: string): string {\n return text.replace(/\\x1B\\[[0-?]*[ -/]*[@-~]/g, '');\n}\n\n/**\n * Unicode zero-width character ranges.\n * Characters in these ranges contribute 0 to terminal display width.\n */\nconst ZERO_WIDTH_RANGES: [number, number][] = [\n [0x0300, 0x036f], // Combining Diacritical Marks\n [0x0483, 0x0489], // Cyrillic combining marks\n [0x0591, 0x05bd], // Hebrew combining marks\n [0x05bf, 0x05bf],\n [0x05c1, 0x05c2],\n [0x05c4, 0x05c5],\n [0x05c7, 0x05c7],\n [0x0610, 0x061a], // Arabic combining marks\n [0x064b, 0x065f],\n [0x0670, 0x0670],\n [0x06d6, 0x06dc],\n [0x06df, 0x06e4],\n [0x06e7, 0x06e8],\n [0x06ea, 0x06ed],\n [0x0711, 0x0711],\n [0x0730, 0x074a],\n [0x07a6, 0x07b0],\n [0x0900, 0x0902], // Devanagari combining\n [0x093a, 0x093c],\n [0x0941, 0x0948],\n [0x094d, 0x094d],\n [0x0951, 0x0957],\n [0x0962, 0x0963],\n [0x0981, 0x0981],\n [0x09bc, 0x09bc],\n [0x09c1, 0x09c4],\n [0x09cd, 0x09cd],\n [0x09e2, 0x09e3],\n [0x0a01, 0x0a02],\n [0x0a3c, 0x0a3c],\n [0x0a41, 0x0a42],\n [0x0a47, 0x0a48],\n [0x0a4b, 0x0a4d],\n [0x0a70, 0x0a71],\n [0x0a81, 0x0a82],\n [0x0abc, 0x0abc],\n [0x0ac1, 0x0ac5],\n [0x0ac7, 0x0ac8],\n [0x0acd, 0x0acd],\n [0x0ae2, 0x0ae3],\n [0x0b01, 0x0b01],\n [0x0b3c, 0x0b3c],\n [0x0b3f, 0x0b3f],\n [0x0b41, 0x0b44],\n [0x0b4d, 0x0b4d],\n [0x0b56, 0x0b56],\n [0x0b62, 0x0b63],\n [0x0b82, 0x0b82],\n [0x0bc0, 0x0bc0],\n [0x0bcd, 0x0bcd],\n [0x0c00, 0x0c00],\n [0x0c3e, 0x0c40],\n [0x0c46, 0x0c48],\n [0x0c4a, 0x0c4d],\n [0x0c55, 0x0c56],\n [0x0c62, 0x0c63],\n [0x0c81, 0x0c81],\n [0x0cbc, 0x0cbc],\n [0x0ccc, 0x0ccd],\n [0x0ce2, 0x0ce3],\n [0x0d01, 0x0d01],\n [0x0d41, 0x0d44],\n [0x0d4d, 0x0d4d],\n [0x0d62, 0x0d63],\n [0x0dca, 0x0dca],\n [0x0dd2, 0x0dd4],\n [0x0dd6, 0x0dd6],\n [0x0e31, 0x0e31], // Thai\n [0x0e34, 0x0e3a],\n [0x0e47, 0x0e4e],\n [0x0eb1, 0x0eb1], // Lao\n [0x0eb4, 0x0eb9],\n [0x0ebb, 0x0ebc],\n [0x0ec8, 0x0ecd],\n [0x0f18, 0x0f19], // Tibetan\n [0x0f35, 0x0f35],\n [0x0f37, 0x0f37],\n [0x0f39, 0x0f39],\n [0x0f71, 0x0f7e],\n [0x0f80, 0x0f84],\n [0x0f86, 0x0f87],\n [0x0f90, 0x0f97],\n [0x0f99, 0x0fbc],\n [0x0fc6, 0x0fc6],\n [0x1031, 0x1031], // Myanmar\n [0x103b, 0x103c],\n [0x103d, 0x103e],\n [0x1056, 0x1057],\n [0x1058, 0x1059],\n [0x105e, 0x1060],\n [0x1062, 0x1064],\n [0x1067, 0x106d],\n [0x1071, 0x1074],\n [0x1082, 0x1082],\n [0x1085, 0x1086],\n [0x108d, 0x108d],\n [0x109d, 0x109d],\n [0x135d, 0x135f], // Ethiopic\n [0x1712, 0x1714], // Tagalog\n [0x1732, 0x1734], // Hanunoo\n [0x1752, 0x1753], // Buhid\n [0x1772, 0x1773], // Tagbanwa\n [0x17b4, 0x17b5], // Khmer\n [0x17b7, 0x17bd],\n [0x17c6, 0x17c6],\n [0x17c9, 0x17d3],\n [0x17dd, 0x17dd],\n [0x180b, 0x180d], // Mongolian\n [0x18a9, 0x18a9],\n [0x1920, 0x1922], // Limbu\n [0x1927, 0x1928],\n [0x1932, 0x1932],\n [0x1939, 0x193b],\n [0x1a17, 0x1a18], // Buginese\n [0x1a56, 0x1a56], // Tai Tham\n [0x1a58, 0x1a5e],\n [0x1a60, 0x1a60],\n [0x1a62, 0x1a62],\n [0x1a65, 0x1a6c],\n [0x1a73, 0x1a7c],\n [0x1a7f, 0x1a7f],\n [0x1ab0, 0x1abe], // Combining Diacritical Marks Extended\n [0x1b00, 0x1b03], // Balinese\n [0x1b34, 0x1b34],\n [0x1b36, 0x1b3a],\n [0x1b3c, 0x1b3c],\n [0x1b42, 0x1b42],\n [0x1b6b, 0x1b73],\n [0x1b80, 0x1b81], // Sundanese\n [0x1ba2, 0x1ba5],\n [0x1ba8, 0x1ba9],\n [0x1bab, 0x1bad],\n [0x1be6, 0x1be6],\n [0x1be8, 0x1be9],\n [0x1bed, 0x1bed],\n [0x1bef, 0x1bf1],\n [0x1c2c, 0x1c33], // Lepcha\n [0x1c36, 0x1c37],\n [0x1cd0, 0x1cd2], // Vedic Extensions\n [0x1cd4, 0x1ce0],\n [0x1ce2, 0x1ce8],\n [0x1ced, 0x1ced],\n [0x1cf4, 0x1cf4],\n [0x1cf8, 0x1cf9],\n [0x1dc0, 0x1df5], // Combining Diacritical Marks Supplement\n [0x1dfc, 0x1dff],\n [0x200b, 0x200f], // ZWSP, ZWNJ, ZWJ, LRM, RLM\n [0x2028, 0x2029], // Line/Paragraph separator\n [0x202a, 0x202e], // Bidi control chars\n [0x2060, 0x2064], // Word joiner, invisible operators\n [0x2066, 0x206f], // Bidi override chars\n [0x20d0, 0x20f0], // Combining Diacritical Marks for Symbols\n [0x2cef, 0x2cf1], // Coptic combining\n [0x2d7f, 0x2d7f], // Tifinagh combining\n [0x2de0, 0x2dff], // Cyrillic Extended-A combining\n [0xa66f, 0xa672],\n [0xa674, 0xa67d],\n [0xa69e, 0xa69f],\n [0xa6f0, 0xa6f1], // Bamum\n [0xa802, 0xa802], // Syloti Nagri\n [0xa806, 0xa806],\n [0xa80b, 0xa80b],\n [0xa825, 0xa826],\n [0xa8c4, 0xa8c4], // Saurashtra\n [0xa8e0, 0xa8f1], // Devanagari Extended combining\n [0xa926, 0xa92d], // Kayah Li\n [0xa947, 0xa951], // Rejang\n [0xa980, 0xa982], // Javanese\n [0xa9b3, 0xa9b3],\n [0xa9b6, 0xa9b9],\n [0xa9bc, 0xa9bc],\n [0xa9e5, 0xa9e5],\n [0xaa29, 0xaa2e], // Cham\n [0xaa31, 0xaa32],\n [0xaa35, 0xaa36],\n [0xaa43, 0xaa43],\n [0xaa4c, 0xaa4c],\n [0xaa7c, 0xaa7c],\n [0xaab0, 0xaab0], // Tai Viet\n [0xaab2, 0xaab4],\n [0xaab7, 0xaab8],\n [0xaabe, 0xaabf],\n [0xaac1, 0xaac1],\n [0xaaec, 0xaaed], // Meetei Mayek\n [0xaaf6, 0xaaf6],\n [0xabe5, 0xabe5], // Meetei Mayek Ext\n [0xabe8, 0xabe8],\n [0xabed, 0xabed],\n [0xfb1e, 0xfb1e], // Hebrew presentation forms\n [0xfe00, 0xfe0f], // Variation selectors\n [0xfe20, 0xfe2f], // Combining Half Marks\n [0xfeff, 0xfeff], // BOM / ZWNBSP\n [0xfff9, 0xfffb], // Interlinear annotation anchors\n [0x101fd, 0x101fd], // Phaistos Disc\n [0x102e0, 0x102e0], // Coptic Epact Numbers\n [0x10376, 0x1037a], // Combining Old Permic\n [0x10a01, 0x10a03], // Kharoshthi\n [0x10a05, 0x10a06],\n [0x10a0c, 0x10a0f],\n [0x10a38, 0x10a3a],\n [0x10a3f, 0x10a3f],\n [0x10ae5, 0x10ae6], // Manichaean\n [0x11001, 0x11001], // Brahmi\n [0x11038, 0x11046],\n [0x1107f, 0x11081],\n [0x110b3, 0x110b6],\n [0x110b9, 0x110ba],\n [0x11100, 0x11102], // Chakma\n [0x11127, 0x1112b],\n [0x1112d, 0x11134],\n [0x11173, 0x11173],\n [0x11180, 0x11181], // Sharada\n [0x111b6, 0x111be],\n [0x111c9, 0x111cc],\n [0x1122f, 0x11231], // Khojki\n [0x11234, 0x11234],\n [0x11236, 0x11237],\n [0x112df, 0x112df], // Khudawadi\n [0x112e3, 0x112ea],\n [0x11300, 0x11301], // Grantha\n [0x1133c, 0x1133c],\n [0x11340, 0x11340],\n [0x11366, 0x1136c],\n [0x11370, 0x11374],\n [0x114b3, 0x114b8], // Tirhuta\n [0x114ba, 0x114ba],\n [0x114bf, 0x114c0],\n [0x114c2, 0x114c3],\n [0x115b2, 0x115b5], // Siddham\n [0x115bc, 0x115bd],\n [0x115bf, 0x115c0],\n [0x115dc, 0x115dd],\n [0x11633, 0x1163a], // Modi\n [0x1163d, 0x1163d],\n [0x1163f, 0x11640],\n [0x116ab, 0x116ab], // Takri\n [0x116ad, 0x116ad],\n [0x116b0, 0x116b5],\n [0x116b7, 0x116b7],\n [0x1171d, 0x1171f], // Ahom\n [0x11722, 0x11725],\n [0x11727, 0x1172b],\n [0x11a01, 0x11a06], // Zanabazar Square\n [0x11a09, 0x11a0a],\n [0x11a33, 0x11a38],\n [0x11a3b, 0x11a3e],\n [0x11a47, 0x11a47],\n [0x11a51, 0x11a56],\n [0x11a59, 0x11a5b],\n [0x11a8a, 0x11a96],\n [0x11a98, 0x11a99],\n [0x11c30, 0x11c36], // Bhaiksuki\n [0x11c38, 0x11c3d],\n [0x11c3f, 0x11c3f],\n [0x11c92, 0x11ca7], // Marchen\n [0x11caa, 0x11cb0],\n [0x11cb2, 0x11cb3],\n [0x11cb5, 0x11cb6],\n [0x11d31, 0x11d36], // Masaram Gondi\n [0x11d3a, 0x11d3a],\n [0x11d3c, 0x11d3d],\n [0x11d3f, 0x11d45],\n [0x11d47, 0x11d47],\n [0x16af0, 0x16af4], // Bassa Vah\n [0x16b30, 0x16b36], // Pahawh Hmong\n [0x16f8f, 0x16f92], // Miao\n [0x1bc9d, 0x1bc9e], // Duployan\n [0x1bca0, 0x1bca3],\n [0x1d167, 0x1d169], // Musical symbols combining\n [0x1d173, 0x1d182],\n [0x1d185, 0x1d18b],\n [0x1d1aa, 0x1d1ad],\n [0x1d242, 0x1d244], // Combining music symbols\n [0x1da00, 0x1da36], // SignWriting\n [0x1da3b, 0x1da6c],\n [0x1da75, 0x1da75],\n [0x1da84, 0x1da84],\n [0x1da9b, 0x1da9f],\n [0x1daa1, 0x1daaf],\n [0x1e000, 0x1e006], // Glagolitic supplement combining\n [0x1e008, 0x1e018],\n [0x1e01b, 0x1e021],\n [0x1e023, 0x1e024],\n [0x1e026, 0x1e02a],\n [0x1e8d0, 0x1e8d6], // Mende Kikakui\n [0x1e944, 0x1e94a], // Adlam\n [0xe0001, 0xe0001], // Language tags\n [0xe0020, 0xe007f], // Tag characters\n [0xe0100, 0xe01ef], // Variation Selectors Supplement\n];\n\n/**\n * Unicode wide-character ranges (2 columns in terminal).\n * Covers CJK, Hangul, fullwidth forms, and emoji/pictographs.\n */\nconst WIDE_RANGES: [number, number][] = [\n // CJK / Hangul / fullwidth forms\n [0x1100, 0x115f], // Hangul Jamo\n [0x2e80, 0xa4cf], // CJK Radicals, Yi, Kangxi, etc.\n [0xac00, 0xd7a3], // Hangul Syllables\n [0xf900, 0xfaff], // CJK Compatibility Ideographs\n [0xfe30, 0xfe6f], // CJK Compatibility Forms\n [0xff01, 0xff60], // Fullwidth Forms\n [0xffe0, 0xffe6], // Fullwidth Signs\n [0x20000, 0x2fffd], // CJK Extension B+\n [0x30000, 0x3fffd], // CJK Extension G+\n // Emoji and pictographs (many terminals render these as 2-wide)\n [0x1f300, 0x1f5ff], // Misc Symbols and Pictographs\n [0x1f600, 0x1f64f], // Emoticons\n [0x1f680, 0x1f6ff], // Transport and Map Symbols\n [0x1f700, 0x1f77f], // Alchemical Symbols\n [0x1f780, 0x1f7ff], // Geometric Shapes Extended\n [0x1f800, 0x1f8ff], // Supplemental Arrows-C\n [0x1f900, 0x1f9ff], // Supplemental Symbols and Pictographs\n [0x1fa00, 0x1fa6f], // Chess Symbols\n [0x1fa70, 0x1faff], // Symbols and Pictographs Extended-A\n // Dingbats, emoji-presentation subset only. The block also holds\n // East-Asian *ambiguous* marks — U+2713 ✓, U+2717 ✗ and friends — which\n // terminals and Ink's own layout render one column wide. Measuring the whole\n // block as wide put our width math one column out from the renderer for the\n // check mark used on every successful tool row.\n [0x2705, 0x2705], // White heavy check mark\n [0x270a, 0x270b], // Raised fist, raised hand\n [0x2728, 0x2728], // Sparkles\n [0x274c, 0x274c], // Cross mark\n [0x274e, 0x274e], // Negative squared cross mark\n [0x2753, 0x2755], // Question and exclamation ornaments\n [0x2757, 0x2757], // Heavy exclamation mark\n [0x2795, 0x2797], // Heavy plus, minus, division\n [0x27b0, 0x27b0], // Curly loop\n [0x27bf, 0x27bf], // Double curly loop\n [0x2300, 0x23ff], // Misc Technical (many 2-wide symbols)\n [0x2b50, 0x2b55], // Star, circle\n [0x2b05, 0x2b07], // Direction arrows\n [0x2b1b, 0x2b1c], // Large squares\n [0x2934, 0x2935], // Curved arrows\n [0x25aa, 0x25ab], // Small squares\n [0x25fb, 0x25fe], // Medium squares\n [0x231a, 0x231b], // Watch, hourglass\n [0x2328, 0x2328], // Keyboard\n [0x23e9, 0x23f3], // Double triangles, hourglass\n [0x23f8, 0x23fa], // Power symbols\n [0x24c2, 0x24c2], // Circled M\n [0x25b6, 0x25b6], // Play\n [0x25c0, 0x25c0], // Reverse\n [0x3030, 0x3030], // Wavy dash\n [0x303d, 0x303d], // Part alternation mark\n [0x3297, 0x3297], // Circled ideograph\n [0x3299, 0x3299], // Circled ideograph secret\n];\n\nfunction mergeRanges(ranges: [number, number][]): [number, number][] {\n const sorted = [...ranges].sort((left, right) => left[0] - right[0]);\n const merged: [number, number][] = [];\n for (const [low, high] of sorted) {\n const previous = merged[merged.length - 1];\n if (!previous || low > previous[1] + 1) {\n merged.push([low, high]);\n } else {\n previous[1] = Math.max(previous[1], high);\n }\n }\n return merged;\n}\n\nconst SORTED_ZERO_WIDTH_RANGES = mergeRanges(ZERO_WIDTH_RANGES);\nconst SORTED_WIDE_RANGES = mergeRanges(WIDE_RANGES);\n\n/**\n * Misc Symbols (U+2600–U+26FF) is wide only where a character is emoji by\n * default (☔, ⚡, ⛔). The rest (☙, ☆, ♠, ☐) render one column wide in the\n * terminal and in Ink's own layout. Measuring the whole block as wide put this\n * width math a column out from the renderer, as the Dingbats block once did\n * for the check mark.\n */\nconst MISC_SYMBOLS: [number, number] = [0x2600, 0x26ff];\nconst EMOJI_PRESENTATION = /\\p{Emoji_Presentation}/u;\nconst ASCII_PRINTABLE = /^[\\x20-\\x7e]*$/;\n\n/**\n * Check if a code point falls within any range in the given list.\n */\nfunction inRanges(cp: number, ranges: [number, number][]): boolean {\n let low = 0;\n let high = ranges.length - 1;\n while (low <= high) {\n const middle = (low + high) >>> 1;\n const [rangeLow, rangeHigh] = ranges[middle]!;\n if (cp < rangeLow) {\n high = middle - 1;\n } else if (cp > rangeHigh) {\n low = middle + 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Get the display width of a string (accounting for wide chars).\n *\n * - CJK, Hangul, fullwidth, and emoji characters → 2 columns\n * - Combining marks, zero-width chars, control chars → 0 columns\n * - Everything else → 1 column\n *\n * ANSI escape sequences are stripped before measurement.\n */\nexport function displayWidth(text: string): number {\n if (text.length === 0) return 0;\n // Fast path for the per-character calls from wrap/truncate loops.\n if (text.length === 1) {\n const code = text.charCodeAt(0);\n if (code >= 0x20 && code < 0x7f) return 1;\n }\n // Skip the regex replace when no ANSI escape can be present.\n const plain = text.indexOf('\\u001B') === -1 ? text : stripAnsi(text);\n if (ASCII_PRINTABLE.test(plain)) return plain.length;\n\n let width = 0;\n for (const ch of plain) {\n const cp = ch.codePointAt(0) ?? 0;\n if (inRanges(cp, SORTED_ZERO_WIDTH_RANGES)) {\n // width += 0\n } else if (cp >= MISC_SYMBOLS[0] && cp <= MISC_SYMBOLS[1]) {\n width += EMOJI_PRESENTATION.test(ch) ? 2 : 1;\n } else if (inRanges(cp, SORTED_WIDE_RANGES)) {\n width += 2;\n } else {\n width += 1;\n }\n }\n return width;\n}\n\n/** Build a terminal divider that never underflows on tiny widths. */\nexport function makeDivider(width: number, padding = 0, char = '─'): string {\n return char.repeat(Math.max(5, Math.floor(width) - padding));\n}\n\n/** True when `text` fits within `maxWidth` terminal display columns. */\nexport function fitsDisplayWidth(text: string, maxWidth: number): boolean {\n return displayWidth(text) <= Math.max(0, maxWidth);\n}\n\n/**\n * Truncate a string by terminal display columns.\n *\n * ANSI SGR sequences are preserved without counting toward width. Wide and\n * zero-width Unicode characters use the same width model as `displayWidth`.\n */\nexport function truncateDisplay(text: string, maxWidth: number, suffix = '…'): string {\n const limit = Math.max(0, Math.floor(maxWidth));\n if (limit === 0) return '';\n if (fitsDisplayWidth(text, limit)) return text;\n\n const suffixWidth = displayWidth(suffix);\n const contentLimit = Math.max(0, limit - suffixWidth);\n if (contentLimit === 0) return suffixWidth <= limit ? suffix : '';\n\n let width = 0;\n let out = '';\n for (let i = 0; i < text.length;) {\n if (text.charCodeAt(i) === 0x1b) {\n const match = text.slice(i).match(/^\\x1B\\[[0-?]*[ -/]*[@-~]/);\n if (match) {\n out += match[0];\n i += match[0].length;\n continue;\n }\n }\n\n const cp = text.codePointAt(i);\n if (cp === undefined) break;\n const ch = String.fromCodePoint(cp);\n const chWidth = displayWidth(ch);\n if (width + chWidth > contentLimit) break;\n out += ch;\n width += chWidth;\n i += ch.length;\n }\n\n return out + suffix;\n}\n\n/** Clip ANSI-stripped text to a display-column budget without adding an ellipsis. */\nexport function sliceDisplayWidth(text: string, maxWidth: number): string {\n const limit = Math.max(0, Math.floor(maxWidth));\n const plain = stripAnsi(text);\n if (limit === 0) return '';\n if (displayWidth(plain) <= limit) return plain;\n\n let width = 0;\n let out = '';\n for (const ch of plain) {\n const chWidth = displayWidth(ch);\n if (width + chWidth > limit) break;\n out += ch;\n width += chWidth;\n }\n return out;\n}\n\n/**\n * Split text into chunks that each fit within `maxWidth` display columns.\n *\n * Breaks mid-word when needed. Wide characters (CJK/emoji) never split a\n * grapheme cluster produced by `for...of` (code-point safe). A single\n * character wider than `maxWidth` is still emitted alone so content is never\n * dropped. Combining marks stay attached to the preceding base when they are\n * zero-width and fit in the same iteration budget.\n */\nexport function hardWrap(text: string, maxWidth: number): string {\n if (maxWidth <= 0 || !text) return text;\n return text\n .split('\\n')\n .map((line) => hardWrapLine(line, maxWidth).join('\\n'))\n .join('\\n');\n}\n\n/** Display-width-aware hard wrap for a single line (no embedded newlines). */\nexport function hardWrapLine(text: string, maxWidth: number): string[] {\n if (maxWidth <= 0 || !text) return text ? [text] : [''];\n if (fitsDisplayWidth(text, maxWidth)) return [text];\n\n const lines: string[] = [];\n let current = '';\n let currentWidth = 0;\n\n for (const ch of text) {\n const chWidth = displayWidth(ch);\n if (current && currentWidth + chWidth > maxWidth) {\n lines.push(current);\n current = ch;\n currentWidth = chWidth;\n continue;\n }\n current += ch;\n currentWidth += chWidth;\n }\n\n if (current) lines.push(current);\n return lines.length > 0 ? lines : [''];\n}\n\n/**\n * Soft-wrap text at word boundaries to fit within `maxWidth` columns.\n *\n * Words longer than maxWidth are hard-wrapped by display width (CJK/emoji\n * safe). Multiple consecutive spaces are collapsed when wrapping. Paragraph\n * breaks (blank lines / double-newline) are preserved.\n *\n * @param text The text to wrap\n * @param maxWidth Maximum columns per line\n * @returns Wrapped text with newlines inserted at word boundaries\n */\nexport function wordWrap(text: string, maxWidth: number): string {\n if (maxWidth <= 0 || !text) return text;\n\n const paragraphs = text.split('\\n');\n const wrapped: string[] = [];\n\n for (const paragraph of paragraphs) {\n // Preserve blank lines (paragraph separators).\n if (paragraph.trim().length === 0) {\n wrapped.push('');\n continue;\n }\n\n const words = paragraph.split(' ');\n const lines: string[] = [];\n let current = '';\n let currentWidth = 0;\n\n const pushWordChunks = (word: string) => {\n const chunks = hardWrapLine(word, maxWidth);\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i]!;\n const chunkWidth = displayWidth(chunk);\n if (!current) {\n current = chunk;\n currentWidth = chunkWidth;\n } else if (currentWidth + 1 + chunkWidth <= maxWidth && i === 0) {\n // Only the first chunk of a hard-broken word can share a line with\n // previous content; continuation chunks always start a new line.\n current = `${current} ${chunk}`;\n currentWidth = currentWidth + 1 + chunkWidth;\n } else {\n lines.push(current);\n current = chunk;\n currentWidth = chunkWidth;\n }\n }\n };\n\n for (const word of words) {\n if (word === '') {\n // Consecutive spaces — add one space to current line if not empty.\n if (current) {\n current += ' ';\n currentWidth += 1;\n }\n continue;\n }\n\n const wordWidth = displayWidth(word);\n const candidateWidth = current ? currentWidth + 1 + wordWidth : wordWidth;\n\n if (wordWidth > maxWidth) {\n // Long token: flush current line, then hard-wrap the word.\n if (current) {\n lines.push(current);\n current = '';\n currentWidth = 0;\n }\n pushWordChunks(word);\n } else if (candidateWidth > maxWidth) {\n // This word would overflow — start a new line.\n if (current) {\n lines.push(current);\n current = word;\n currentWidth = wordWidth;\n } else {\n pushWordChunks(word);\n }\n } else {\n current = current ? `${current} ${word}` : word;\n currentWidth = candidateWidth;\n }\n }\n\n if (current) lines.push(current);\n wrapped.push(lines.join('\\n'));\n }\n\n return wrapped.join('\\n');\n}\n\n/**\n * Pad `text` to `width` display columns (not string length).\n * Truncates with ellipsis when text is wider than `width`.\n */\nexport function padDisplay(\n text: string,\n width: number,\n align: 'left' | 'right' | 'center' = 'left',\n): string {\n const limit = Math.max(0, Math.floor(width));\n if (limit === 0) return '';\n const clipped = fitsDisplayWidth(text, limit) ? text : truncateDisplay(text, limit);\n const pad = Math.max(0, limit - displayWidth(clipped));\n if (pad === 0) return clipped;\n if (align === 'right') return `${' '.repeat(pad)}${clipped}`;\n if (align === 'center') {\n const left = Math.floor(pad / 2);\n return `${' '.repeat(left)}${clipped}${' '.repeat(pad - left)}`;\n }\n return `${clipped}${' '.repeat(pad)}`;\n}\n","import type { ThemeTokens } from '../../types/theme.js';\n\nexport interface StyledSegment {\n text: string;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n dimColor?: boolean;\n}\n\nexport type StyledLine = StyledSegment[];\n\nconst cache = new Map<string, StyledLine[]>();\nconst MAX_CACHE_ENTRIES = 80;\n\nfunction normalizeLang(lang?: string): string {\n const normalized = (lang ?? '').toLowerCase().trim();\n if (normalized === 'js') return 'javascript';\n if (normalized === 'jsx') return 'javascript';\n if (normalized === 'ts') return 'typescript';\n if (normalized === 'tsx') return 'typescript';\n if (normalized === 'py') return 'python';\n if (normalized === 'sh' || normalized === 'shell') return 'bash';\n if (normalized === 'yml') return 'yaml';\n return normalized;\n}\n\nfunction pushSegment(line: StyledLine, text: string, segment: Omit<StyledSegment, 'text'> = {}) {\n if (!text) return;\n const previous = line[line.length - 1];\n if (\n previous &&\n previous.color === segment.color &&\n previous.bold === segment.bold &&\n previous.italic === segment.italic &&\n previous.dimColor === segment.dimColor\n ) {\n previous.text += text;\n return;\n }\n line.push({ text, ...segment });\n}\n\nfunction keywordPattern(lang: string): RegExp | null {\n if (['javascript', 'typescript'].includes(lang)) {\n return /\\b(?:async|await|break|case|catch|class|const|continue|default|delete|else|export|extends|false|finally|for|from|function|if|import|in|instanceof|interface|let|new|null|of|return|switch|throw|true|try|type|typeof|undefined|var|void|while|yield)\\b/y;\n }\n if (lang === 'python') {\n return /\\b(?:and|as|assert|async|await|break|class|continue|def|elif|else|except|False|finally|for|from|if|import|in|is|lambda|None|not|or|pass|raise|return|True|try|while|with|yield)\\b/y;\n }\n if (lang === 'rust') {\n return /\\b(?:as|async|await|break|const|continue|crate|else|enum|extern|false|fn|for|if|impl|in|let|loop|match|mod|move|mut|pub|ref|return|self|Self|static|struct|super|trait|true|type|unsafe|use|where|while)\\b/y;\n }\n if (lang === 'go') {\n return /\\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go|goto|if|import|interface|map|package|range|return|select|struct|switch|type|var)\\b/y;\n }\n if (lang === 'bash') {\n return /\\b(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)\\b/y;\n }\n if (lang === 'sql') {\n return /\\b(?:SELECT|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|ON|GROUP|BY|ORDER|INSERT|INTO|UPDATE|DELETE|CREATE|ALTER|DROP|TABLE|INDEX|VIEW|VALUES|SET|AND|OR|NOT|NULL|AS|LIMIT|OFFSET|HAVING)\\b/iy;\n }\n if (lang === 'css') {\n return /\\b(?:display|position|absolute|relative|fixed|grid|flex|block|inline|color|background|border|padding|margin|width|height|content|media|import|keyframes)\\b/y;\n }\n return null;\n}\n\nfunction highlightLine(raw: string, lang: string, theme: ThemeTokens): StyledLine {\n const line: StyledLine = [];\n const keyword = keywordPattern(lang);\n let i = 0;\n\n while (i < raw.length) {\n const rest = raw.slice(i);\n\n const commentStart = lang === 'python' || lang === 'bash' || lang === 'yaml' ? '#' : '//';\n if (rest.startsWith(commentStart)) {\n pushSegment(line, rest, { color: theme.mdCodeComment, italic: true, dimColor: true });\n break;\n }\n if (rest.startsWith('/*')) {\n const end = raw.indexOf('*/', i + 2);\n const text = end === -1 ? rest : raw.slice(i, end + 2);\n pushSegment(line, text, { color: theme.mdCodeComment, italic: true, dimColor: true });\n i += text.length;\n continue;\n }\n\n const stringMatch = rest.match(/^(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`)/);\n if (stringMatch) {\n pushSegment(line, stringMatch[0], { color: theme.mdCodeString });\n i += stringMatch[0].length;\n continue;\n }\n\n const numberMatch = rest.match(/^\\b\\d+(?:\\.\\d+)?\\b/);\n if (numberMatch) {\n pushSegment(line, numberMatch[0], { color: theme.mdCodeNumber });\n i += numberMatch[0].length;\n continue;\n }\n\n const functionMatch = rest.match(/^([A-Za-z_$][\\w$-]*)(?=\\s*\\()/);\n if (functionMatch) {\n pushSegment(line, functionMatch[1], { color: theme.mdCodeFunction });\n i += functionMatch[1].length;\n continue;\n }\n\n if (keyword) {\n keyword.lastIndex = i;\n const match = keyword.exec(raw);\n if (match && match.index === i) {\n pushSegment(line, match[0], { color: theme.mdCodeKeyword, bold: true });\n i += match[0].length;\n continue;\n }\n }\n\n pushSegment(line, raw[i], { color: theme.mdCodeText });\n i += 1;\n }\n\n return line.length > 0 ? line : [{ text: '', color: theme.mdCodeText }];\n}\n\nexport function highlightCode(\n code: string,\n lang: string | undefined,\n theme: ThemeTokens,\n): StyledLine[] {\n const normalized = normalizeLang(lang);\n const key = `${normalized}\\0${code}\\0${JSON.stringify({\n keyword: theme.mdCodeKeyword,\n string: theme.mdCodeString,\n comment: theme.mdCodeComment,\n number: theme.mdCodeNumber,\n function: theme.mdCodeFunction,\n text: theme.mdCodeText,\n })}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n const lines = code.split('\\n').map((line) => highlightLine(line, normalized, theme));\n cache.set(key, lines);\n if (cache.size > MAX_CACHE_ENTRIES) {\n const oldest = cache.keys().next().value;\n if (oldest) cache.delete(oldest);\n }\n return lines;\n}\n","import { Text, Box } from 'ink';\nimport React, { useLayoutEffect, useMemo, useRef, useState, useEffect } from 'react';\nimport { marked, Tokens, Token } from 'marked';\nimport { useTheme } from '../theme.js';\nimport { useDensity } from '../density.js';\nimport { useTranscriptLayoutChange } from '../transcript-layout.js';\nimport { displayWidth, wordWrap } from './word-wrap.js';\nimport { highlightCode, type StyledLine } from './syntax-highlight.js';\nimport {\n layoutCodeBlock,\n layoutHeadingChrome,\n layoutHorizontalRule,\n layoutTable,\n markdownBlockGap,\n nestedContentWidth,\n sliceStyledLine,\n tableRowText,\n} from './markdown-layout.js';\n\n/** Columns a list is indented from the surrounding prose. */\nconst LIST_INDENT = 2;\n\ninterface MarkdownBlockProps {\n /** Raw markdown string to render. */\n content: string;\n /** Terminal width in columns for word-boundary wrapping. */\n terminalWidth?: number;\n /** While streaming, keep expensive final-pass decoration such as syntax highlighting disabled. */\n isStreaming?: boolean;\n /** Remove the final block's bottom margin when another transcript turn follows immediately. */\n trimTrailingMargin?: boolean;\n}\n\ntype InlineStyle = {\n color?: string;\n bold?: boolean;\n italic?: boolean;\n strikethrough?: boolean;\n underline?: boolean;\n dimColor?: boolean;\n};\n\ntype InlineRun = InlineStyle & { text: string };\n\ninterface RenderContext {\n textColor?: string;\n depth: number;\n isStreaming: boolean;\n /** Nested blockquote depth for width budgeting. */\n blockquoteDepth: number;\n}\n\nexport function wrapParagraphLines(rawText: string, terminalWidth: number): string[] {\n if (terminalWidth <= 0) return rawText.split('\\n');\n // wordWrap already hard-wraps overlong tokens with displayWidth semantics;\n // scanning every completed line a second time doubles paragraph render cost.\n return wordWrap(rawText, terminalWidth).split('\\n');\n}\n\n/**\n * Throttle a rapidly-changing value onto a fixed cadence, with an immediate\n * first render and a guaranteed trailing emit.\n *\n * Why: during streaming, `content` grows ~every 16ms (the accumulator flush).\n * `marked.lexer(content)` on every flush re-parses the whole string ~60×/sec\n * — the main CPU sink while a large assistant reply streams in. Throttling the\n * value React actually parses caps re-lex work to ~17×/sec regardless of how\n * fast `content` changes, and the trailing emit guarantees the final, complete\n * markdown always renders.\n *\n * Semantics:\n * - First value passed is emitted synchronously (no delayed first frame).\n * - A change while within `interval` of the last emit is held; it is flushed\n * on a trailing timer so the newest value always wins.\n * - A change after `interval` emits immediately.\n *\n * `ponytail:` no leading-edge coalesce on the very first call. If a future\n * caller streams a value that changes mid-first-frame and needs the leading\n * edge deferred too, pass an explicit `startPending` flag. Ceiling: none —\n * this is the standard throttle shape.\n */\nexport function useThrottledValue<T>(next: T, intervalMs: number, onEmit?: () => void): T {\n const [value, setValue] = useState<T>(next);\n const lastEmitRef = useRef<number | null>(null);\n const mountedRef = useRef(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const nextRef = useRef<T>(next);\n const onEmitRef = useRef(onEmit);\n const notifiedValueRef = useRef(value);\n onEmitRef.current = onEmit;\n\n useEffect(() => {\n nextRef.current = next;\n if (!mountedRef.current) {\n mountedRef.current = true;\n lastEmitRef.current = Date.now();\n return;\n }\n if (next === value) return;\n const now = Date.now();\n const elapsed = now - (lastEmitRef.current ?? now);\n if (elapsed >= intervalMs) {\n lastEmitRef.current = now;\n setValue(next);\n return;\n }\n if (timerRef.current === null) {\n const remaining = intervalMs - elapsed;\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n lastEmitRef.current = Date.now();\n setValue(nextRef.current);\n }, remaining);\n }\n }, [next, intervalMs]);\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n }, []);\n\n useLayoutEffect(() => {\n if (value === notifiedValueRef.current) return;\n notifiedValueRef.current = value;\n onEmitRef.current?.();\n }, [value]);\n\n return value;\n}\n\nfunction mergeStyle(base: InlineStyle, next: InlineStyle): InlineStyle {\n return { ...base, ...next };\n}\n\nfunction appendRun(runs: InlineRun[], text: string, style: InlineStyle) {\n if (!text) return;\n const previous = runs[runs.length - 1];\n if (\n previous &&\n previous.color === style.color &&\n previous.bold === style.bold &&\n previous.italic === style.italic &&\n previous.strikethrough === style.strikethrough &&\n previous.underline === style.underline &&\n previous.dimColor === style.dimColor\n ) {\n previous.text += text;\n return;\n }\n // Style first, then text — callers may pass an InlineRun as `style`, and the\n // sliced `text` argument must win over any previous `style.text`.\n runs.push({ ...style, text });\n}\n\nfunction plainTextFromTokens(tokens: Token[]): string {\n const runs = inlineRunsFromTokens(tokens, { color: undefined }, undefined);\n return runs.map((run) => run.text).join('');\n}\n\nfunction inlineRunsFromTokens(\n tokens: Token[],\n style: InlineStyle,\n theme: ReturnType<typeof useTheme> | undefined,\n): InlineRun[] {\n const runs: InlineRun[] = [];\n for (const token of tokens) {\n switch (token.type) {\n case 'text': {\n const t = token as Tokens.Text & { tokens?: Token[] };\n if (t.tokens?.length) {\n runs.push(...inlineRunsFromTokens(t.tokens, style, theme));\n } else {\n appendRun(runs, t.text, style);\n }\n break;\n }\n case 'strong': {\n const t = token as Tokens.Strong;\n runs.push(...inlineRunsFromTokens(t.tokens, mergeStyle(style, { bold: true }), theme));\n break;\n }\n case 'em': {\n const t = token as Tokens.Em;\n runs.push(...inlineRunsFromTokens(t.tokens, mergeStyle(style, { italic: true }), theme));\n break;\n }\n case 'del': {\n const t = token as Tokens.Del;\n runs.push(\n ...inlineRunsFromTokens(\n t.tokens,\n mergeStyle(style, {\n strikethrough: true,\n color: theme?.subtle ?? style.color,\n }),\n theme,\n ),\n );\n break;\n }\n case 'codespan': {\n // Colour alone marks inline code. A background pill on every span\n // turned an ordinary paragraph into a row of highlighted badges, which\n // is exactly the noise the quiet palette removes everywhere else.\n const t = token as Tokens.Codespan;\n appendRun(\n runs,\n t.text,\n mergeStyle(style, { color: theme?.mdInlineCodeText ?? style.color }),\n );\n break;\n }\n case 'link': {\n const t = token as Tokens.Link;\n const linkRuns = inlineRunsFromTokens(\n t.tokens,\n mergeStyle(style, { color: theme?.mdLink ?? style.color, underline: true }),\n theme,\n );\n runs.push(...linkRuns);\n const label = linkRuns.map((run) => run.text).join('');\n if (t.href && t.href !== label) {\n appendRun(\n runs,\n ` (${t.href})`,\n mergeStyle(style, { color: theme?.mdLink ?? style.color }),\n );\n }\n break;\n }\n case 'image': {\n const t = token as Tokens.Image;\n appendRun(\n runs,\n `[Image: ${t.text || t.href}]`,\n mergeStyle(style, { color: theme?.mdLink ?? style.color, dimColor: true }),\n );\n break;\n }\n case 'br':\n appendRun(runs, '\\n', style);\n break;\n case 'escape': {\n const t = token as Tokens.Escape;\n appendRun(runs, t.text, style);\n break;\n }\n case 'html': {\n const t = token as Tokens.HTML;\n if (t.text && !t.block) appendRun(runs, t.text, mergeStyle(style, { dimColor: true }));\n break;\n }\n default:\n break;\n }\n }\n return runs;\n}\n\nfunction wrappedInlineRuns(runs: InlineRun[], terminalWidth: number): InlineRun[][] {\n const rawText = runs.map((run) => run.text).join('');\n const lines = wrapParagraphLines(rawText, terminalWidth);\n let searchOffset = 0;\n let runIndex = 0;\n let runOffset = 0;\n return lines.map((line) => {\n // wordWrap may collapse spaces or replace an original newline with a visual\n // line break. Locate each rendered slice in the source instead of assuming\n // every break consumed exactly one space; otherwise style offsets drift and\n // later lines can lose their final character.\n const locatedOffset = rawText.indexOf(line, searchOffset);\n const lineOffset = locatedOffset === -1 ? searchOffset : locatedOffset;\n const lineRuns: InlineRun[] = [];\n while (runIndex < runs.length && runOffset + runs[runIndex]!.text.length <= lineOffset) {\n runOffset += runs[runIndex]!.text.length;\n runIndex++;\n }\n\n let localIndex = runIndex;\n let localOffset = runOffset;\n const lineEnd = lineOffset + line.length;\n while (localIndex < runs.length && localOffset < lineEnd) {\n const run = runs[localIndex]!;\n const overlapStart = Math.max(localOffset, lineOffset);\n const overlapEnd = Math.min(localOffset + run.text.length, lineEnd);\n if (overlapStart < overlapEnd) {\n appendRun(\n lineRuns,\n run.text.slice(overlapStart - localOffset, overlapEnd - localOffset),\n run,\n );\n }\n localOffset += run.text.length;\n localIndex++;\n }\n searchOffset = lineOffset + line.length;\n return lineRuns;\n });\n}\n\ninterface FenceContext {\n marker: string;\n info: string;\n}\n\nfunction fenceOpening(context: FenceContext): string {\n return `${context.marker}${context.info}`;\n}\n\n/** The fence state after one more line: `open` unchanged, a fence it opens, or none it closes. */\nfunction nextFenceContext(\n open: FenceContext | undefined,\n rawLine: string,\n): FenceContext | undefined {\n const match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(rawLine.replace(/\\r$/, ''));\n if (!match) return open;\n const marker = match[2]!;\n const rest = match[3]!;\n // Backtick fences cannot contain backticks in their info string.\n if (marker[0] === '`' && rest.includes('`')) return open;\n if (!open) return { marker, info: rest.trim() };\n return marker[0] === open.marker[0] && marker.length >= open.marker.length && rest.trim() === ''\n ? undefined\n : open;\n}\n\nfunction fenceContextAt(content: string, offset: number): FenceContext | undefined {\n let open: FenceContext | undefined;\n let lineStart = 0;\n\n while (lineStart < offset) {\n const lineEnd = content.indexOf('\\n', lineStart);\n if (lineEnd === -1 || lineEnd > offset) break;\n\n open = nextFenceContext(open, content.slice(lineStart, lineEnd));\n\n lineStart = lineEnd + 1;\n }\n\n return open;\n}\n\nfunction standaloneBlockStart(content: string, offset: number): number | undefined {\n let lineStart = content.indexOf('\\n', offset);\n if (lineStart === -1) return undefined;\n lineStart++;\n\n while (lineStart < content.length) {\n const lineEnd = content.indexOf('\\n', lineStart);\n const line = content.slice(lineStart, lineEnd === -1 ? content.length : lineEnd);\n if (\n /^( {0,3})(?:#{1,6}(?:\\s|$)|>|(?:[-+*]|\\d+[.)])\\s|`{3,}|~{3,}|(?:[-*_]\\s*){3,}$)/.test(line)\n ) {\n return lineStart;\n }\n if (lineEnd === -1) return undefined;\n lineStart = lineEnd + 1;\n }\n\n return undefined;\n}\n\n/** A prose word that would open a Markdown block (heading, list item, quote) at a tail's start. */\nconst BLOCK_MARKER_WORD = /^(?:#{1,6}|[-+*>]|\\d{1,9}[.)])(?:\\s|$)/;\n\n/**\n * The rest of a line that is a dash thematic break (`---`, `-- -`, `- - -`, `-----`), trailing\n * spaces allowed. Only dashes: the prose fallback already drops a tail holding `*` or `_`.\n */\nconst DASH_THEMATIC_BREAK_REST = /^(?:-[ \\t]*){3,}\\r?$/;\n\n/** Whether a prose tail starting at `start` would open a block instead of a paragraph. */\nfunction opensBlockAt(content: string, start: number): boolean {\n if (BLOCK_MARKER_WORD.test(content.slice(start, start + 12))) return true;\n if (content[start] !== '-') return false;\n const lineEnd = content.indexOf('\\n', start);\n return DASH_THEMATIC_BREAK_REST.test(\n content.slice(start, lineEnd === -1 ? content.length : lineEnd),\n );\n}\n\n/** The first word start at or after `offset` and before `limit`, if there is one. */\nfunction wordStartAfter(content: string, offset: number, limit: number): number | undefined {\n const match = content.slice(offset - 1, limit).search(/\\s\\S/);\n return match === -1 ? undefined : offset + match;\n}\n\n/**\n * Where the prose fallback tail starts. The cutoff rounds up to a multiple of `step`, so the\n * start stays fixed while the response grows and the tail only gains text at its end between\n * jumps. It then moves to the first word that does not read as a heading, list item or quote\n * marker, or as a dash thematic break that ends its line, any of which would turn the tail\n * into that block. With no such word within one step, the rounded cutoff is used as is.\n */\nfunction proseTailStart(content: string, cutoff: number, step: number): number {\n const rounded = Math.ceil(cutoff / step) * step;\n const limit = rounded + step;\n let start = wordStartAfter(content, rounded, limit);\n while (start !== undefined && opensBlockAt(content, start)) {\n start = wordStartAfter(content, start + 1, limit);\n }\n return start ?? rounded;\n}\n\n/**\n * The fence delimiter line the cutoff falls on, from its first character through its newline,\n * and whether it opens a fence (it closes one otherwise). The fence check reads only whole lines\n * before the cutoff, so it misses a delimiter line the cutoff splits: an opening line split there\n * starts the tail inside the code as prose, and a closing one leaves the fence open over the\n * prose after it.\n */\nfunction fenceLineAt(\n content: string,\n offset: number,\n): { start: number; end: number; opens: boolean } | undefined {\n const start = content.lastIndexOf('\\n', offset - 1) + 1;\n const end = content.indexOf('\\n', offset);\n if (end === -1 || !/^ {0,3}(?:`{3,}|~{3,})/.test(content.slice(start, end))) return undefined;\n const before = fenceContextAt(content, start);\n const after = nextFenceContext(before, content.slice(start, end));\n const openBefore = before !== undefined;\n const openAfter = after !== undefined;\n // A delimiter-shaped line that changes nothing, such as a backtick line inside a tilde\n // fence, is only code.\n if (openBefore === openAfter) return undefined;\n return { start, end, opens: openAfter };\n}\n\n/**\n * The start of the first line after `offset` and before `limit` that opens a fence, when the text at\n * `offset` is outside one.\n */\nfunction fenceOpeningBefore(content: string, offset: number, limit: number): number | undefined {\n let lineStart = content.indexOf('\\n', offset) + 1;\n while (lineStart > 0 && lineStart < limit) {\n const lineEnd = content.indexOf('\\n', lineStart);\n const line = content.slice(lineStart, lineEnd === -1 ? content.length : lineEnd);\n if (nextFenceContext(undefined, line)) return lineStart;\n if (lineEnd === -1) return undefined;\n lineStart = lineEnd + 1;\n }\n return undefined;\n}\n\nfunction contextualStreamingTail(content: string, maxCharacters: number, step: number): string {\n let desiredStart = content.length - maxCharacters;\n if (desiredStart <= 0) return content;\n\n // A cutoff inside a fence delimiter line moves to that line's outer edge: the start of an\n // opening line, which then opens the tail, or the newline that ends a closing one.\n const fenceLine = fenceLineAt(content, desiredStart);\n if (fenceLine?.opens) return content.slice(fenceLine.start);\n if (fenceLine) desiredStart = fenceLine.end;\n\n const context = fenceContextAt(content, desiredStart);\n if (context) {\n return `${fenceOpening(context)}\\n${content.slice(desiredStart)}`;\n }\n\n // Start complete Markdown blocks whenever possible. This avoids turning a\n // truncated table/list/paragraph prefix into a misleading partial block.\n const blankLine = content.indexOf('\\n\\n', desiredStart);\n // A fence that opens before that blank line starts the tail. Searching past it would skip the\n // whole block, then bring it back from the cutoff once the cutoff entered it.\n const fenceStart =\n blankLine >= 0 ? fenceOpeningBefore(content, desiredStart, blankLine) : undefined;\n const start =\n fenceStart ?? (blankLine >= 0 ? blankLine + 2 : standaloneBlockStart(content, desiredStart));\n if (start === undefined) {\n const tail = content.slice(proseTailStart(content, desiredStart, step));\n return /[*_`~[\\]<>|\\\\]/.test(tail) ? '' : tail;\n }\n // Every start found above lies outside a fence: the cutoff was outside one, and each search\n // stops at the first line that could open one.\n return content.slice(start);\n}\n\nexport function streamingMarkdownWindow(content: string, terminalWidth?: number): string {\n const width = Math.max(20, Math.floor(terminalWidth ?? 80));\n // Keep enough history for the live tail to feel continuous without making\n // every throttled Markdown parse scale with the full assistant response.\n const maxCharacters = width * 24;\n const step = width * 4;\n if (content.length <= maxCharacters) return content;\n return `… earlier response hidden while streaming\\n\\n${contextualStreamingTail(content, maxCharacters, step)}`;\n}\n\nfunction InlineRuns({ runs }: { runs: InlineRun[] }) {\n // Parent already soft/hard-wrapped to terminal width — disable Ink re-wrap.\n return (\n <Text wrap=\"truncate\">\n {runs.map((run, i) => (\n <Text\n key={i}\n color={run.color}\n bold={run.bold}\n italic={run.italic}\n strikethrough={run.strikethrough}\n underline={run.underline}\n dimColor={run.dimColor}\n >\n {run.text}\n </Text>\n ))}\n </Text>\n );\n}\n\nfunction renderStyledLine(line: StyledLine, keyPrefix: string) {\n return (\n <Text>\n {line.map((segment, i) => (\n <Text\n key={`${keyPrefix}-${i}`}\n color={segment.color}\n bold={segment.bold}\n italic={segment.italic}\n dimColor={segment.dimColor}\n >\n {segment.text}\n </Text>\n ))}\n </Text>\n );\n}\n\nfunction renderTableCells(\n cells: string[],\n key: string,\n theme: ReturnType<typeof useTheme>,\n header = false,\n) {\n return (\n <Box key={key} flexDirection=\"row\">\n <Text bold={header} color={header ? theme.mdHeading : theme.text}>\n {tableRowText(cells)}\n </Text>\n </Box>\n );\n}\n\n/**\n * Render a block-level token into an Ink Box/Text component tree.\n */\nfunction renderBlockToken(\n token: Token,\n theme: ReturnType<typeof useTheme>,\n index: number,\n terminalWidth: number | undefined,\n context: RenderContext,\n): React.ReactNode {\n switch (token.type) {\n case 'heading': {\n const t = token as Tokens.Heading;\n const text = plainTextFromTokens(t.tokens);\n const chrome = layoutHeadingChrome(text, t.depth, terminalWidth);\n if (t.depth === 1) {\n return (\n <Box key={`h-${index}`} flexDirection=\"column\">\n <Text bold color={theme.mdHeadingH1}>\n <Text color={theme.brand}>{chrome.prefix}</Text>\n {chrome.text}\n {chrome.suffix}\n </Text>\n </Box>\n );\n }\n if (t.depth === 2) {\n return (\n <Box key={`h-${index}`} flexDirection=\"column\">\n <Text bold color={theme.mdHeadingH2}>\n <Text color={theme.brand}>{chrome.prefix}</Text>\n {chrome.text}\n {chrome.suffix}\n </Text>\n </Box>\n );\n }\n return (\n <Box key={`h-${index}`} flexDirection=\"column\">\n <Text bold={t.depth <= 4} color={theme.mdHeading} dimColor={t.depth >= 5}>\n {chrome.prefix}\n {chrome.text}\n </Text>\n </Box>\n );\n }\n\n case 'paragraph': {\n const t = token as Tokens.Paragraph;\n const runs = inlineRunsFromTokens(\n t.tokens,\n { color: context.textColor ?? theme.text },\n theme,\n );\n if (terminalWidth) {\n const wrappedLines = wrappedInlineRuns(runs, terminalWidth);\n return (\n <Box key={`p-${index}`} flexDirection=\"column\" flexGrow={1}>\n {wrappedLines.map((lineRuns, li) => (\n <Box key={`pw-${index}-${li}`} flexDirection=\"row\">\n <InlineRuns runs={lineRuns} />\n </Box>\n ))}\n </Box>\n );\n }\n return (\n <Box key={`p-${index}`} flexDirection=\"row\" flexGrow={1}>\n <InlineRuns runs={runs} />\n </Box>\n );\n }\n\n case 'code': {\n const t = token as Tokens.Code;\n const lines = t.text.split('\\n');\n const displayLines =\n lines.length > 0 && lines[lines.length - 1] === '' ? lines.slice(0, -1) : lines;\n const layout = layoutCodeBlock(displayLines, terminalWidth, {\n lang: t.lang,\n preferLineNumbers: displayLines.length > 5,\n });\n const highlighted = context.isStreaming\n ? undefined\n : highlightCode(displayLines.join('\\n'), t.lang, theme);\n\n const widthProp =\n terminalWidth && terminalWidth > 0 ? { width: Math.max(1, Math.floor(terminalWidth)) } : {};\n\n // A left rail plus the code tint, never a four-sided box: the border used\n // to be the heaviest element in an answer, wrapped around its smallest.\n const boxProps = layout.showRail\n ? {\n ...widthProp,\n paddingLeft: 1 as const,\n borderLeft: true,\n borderTop: false,\n borderRight: false,\n borderBottom: false,\n borderStyle: 'single' as const,\n borderColor: theme.mdCodeBorder,\n backgroundColor: theme.mdCodeBackground,\n }\n : {\n ...widthProp,\n backgroundColor: theme.mdCodeBackground,\n };\n\n return (\n <Box key={`code-${index}`} flexDirection=\"column\">\n {layout.langLabel ? (\n // On the rail, not floating above it. A bare dim word at the prose\n // indent with nothing joining it to the block below reads as a\n // one-word paragraph — `js` sitting in the answer as if the model\n // had said it. Sharing the rail makes it a caption on the block.\n <Box {...(layout.showRail ? railCaptionProps(theme) : {})}>\n <Text color={theme.inactive}>{layout.langLabel}</Text>\n </Box>\n ) : null}\n <Box flexDirection=\"column\" {...boxProps}>\n {layout.lines.map((visual, vi) => {\n const highlightedLine = highlighted?.[visual.sourceLineIndex];\n const segments: StyledLine = highlightedLine\n ? sliceStyledLine(highlightedLine, visual.sourceStart, visual.sourceEnd)\n : [{ text: visual.text, color: theme.mdCodeText }];\n const safeSegments: StyledLine =\n segments.length > 0 ? segments : [{ text: visual.text, color: theme.mdCodeText }];\n\n return (\n <Box key={`code-${index}-v${vi}`}>\n {layout.showLineNumbers ? (\n <Text color={theme.mdCodeLineNumber} dimColor>\n {visual.gutter}\n </Text>\n ) : null}\n {highlighted ? (\n renderStyledLine(safeSegments, `code-${index}-${vi}`)\n ) : (\n <Text color={theme.mdCodeText}>{visual.text}</Text>\n )}\n </Box>\n );\n })}\n </Box>\n </Box>\n );\n }\n\n case 'blockquote': {\n const t = token as Tokens.Blockquote;\n // Incremental budget: border + paddingLeft ≈ 2 columns per quote level.\n const childWidth =\n terminalWidth !== undefined ? Math.max(1, Math.floor(terminalWidth) - 2) : undefined;\n return (\n <Box\n key={`bq-${index}`}\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderLeft\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeftColor={theme.mdBlockquoteBorder}\n paddingLeft={1}\n >\n {t.tokens.map((childToken, ci) =>\n renderBlockToken(childToken, theme, index * 1000 + ci, childWidth, {\n ...context,\n textColor: theme.mdBlockquoteText,\n blockquoteDepth: context.blockquoteDepth + 1,\n }),\n )}\n </Box>\n );\n }\n\n case 'list': {\n const t = token as Tokens.List;\n const markerFor = (item: Tokens.ListItem, ii: number): string =>\n item.task\n ? item.checked\n ? '[x]'\n : '[ ]'\n : t.ordered\n ? `${(typeof t.start === 'number' ? t.start : 1) + ii}.`\n : '•';\n // One marker column for the whole list, sized to its widest marker: a\n // per-item width shears the text column between items 9 and 10, and a\n // fixed width leaves a dead column after every bullet.\n const markerWidth =\n Math.max(...t.items.map((item, ii) => displayWidth(markerFor(item, ii))), 1) + 1;\n return (\n <Box key={`list-${index}`} flexDirection=\"column\" marginLeft={context.depth > 0 ? 2 : 0}>\n {t.items.map((item, ii) => {\n const marker = markerFor(item, ii);\n const markerColor = item.task\n ? item.checked\n ? theme.mdCheckboxChecked\n : theme.mdCheckboxUnchecked\n : theme.mdListMarker;\n // Incremental: marker column + margins. Nested lists receive an already-reduced width.\n const itemWidth = nestedContentWidth(terminalWidth, {\n depth: 0,\n listGutter: LIST_INDENT + markerWidth,\n blockquoteDepth: 0,\n });\n return (\n <Box key={`li-${index}-${ii}`} flexDirection=\"row\" marginLeft={LIST_INDENT}>\n <Box width={markerWidth} flexShrink={0}>\n <Text color={markerColor}>{marker}</Text>\n </Box>\n <Box flexDirection=\"column\" flexGrow={1}>\n {item.tokens.map((childToken, ci) => {\n if (childToken.type === 'text') {\n const textToken = childToken as Tokens.Text & { tokens?: Token[] };\n const childRuns = textToken.tokens?.length\n ? inlineRunsFromTokens(\n textToken.tokens,\n { color: context.textColor ?? theme.text },\n theme,\n )\n : [{ text: textToken.text, color: context.textColor ?? theme.text }];\n if (itemWidth) {\n const wrapped = wrappedInlineRuns(childRuns, itemWidth);\n return (\n <Box key={`lit-${index}-${ii}-${ci}`} flexDirection=\"column\">\n {wrapped.map((lineRuns, li) => (\n <Box key={`lit-${index}-${ii}-${ci}-l${li}`}>\n <InlineRuns runs={lineRuns} />\n </Box>\n ))}\n </Box>\n );\n }\n return (\n <Box key={`lit-${index}-${ii}-${ci}`}>\n <InlineRuns runs={childRuns} />\n </Box>\n );\n }\n return renderBlockToken(\n childToken,\n theme,\n index * 1000 + ii * 100 + ci,\n itemWidth,\n { ...context, depth: context.depth + 1 },\n );\n })}\n </Box>\n </Box>\n );\n })}\n </Box>\n );\n }\n\n case 'hr': {\n const rule = layoutHorizontalRule(terminalWidth);\n return (\n <Box key={`hr-${index}`}>\n <Text color={theme.mdHr} dimColor>\n {rule}\n </Text>\n </Box>\n );\n }\n\n case 'table': {\n const t = token as Tokens.Table;\n if (t.header.length === 0 && t.rows.length === 0) return null;\n\n const layout = layoutTable({\n header: t.header.map((cell) => ({ text: plainTextFromTokens(cell.tokens) })),\n rows: t.rows.map((row) => row.map((cell) => ({ text: plainTextFromTokens(cell.tokens) }))),\n align: t.align ?? [],\n terminalWidth: terminalWidth ?? 80,\n });\n\n if (layout.mode === 'stacked') {\n return (\n <Box key={`table-${index}`} flexDirection=\"column\">\n {layout.lines.map((line, li) => (\n <Text key={`table-${index}-s${li}`} color={theme.text}>\n {line}\n </Text>\n ))}\n </Box>\n );\n }\n\n return (\n <Box key={`table-${index}`} flexDirection=\"column\">\n <Text color={theme.mdTableBorder}>{layout.top}</Text>\n {layout.headerRows.map((row, ri) =>\n renderTableCells(row, `tr-${index}-h${ri}`, theme, true),\n )}\n <Text color={theme.mdTableBorder}>{layout.middle}</Text>\n {layout.bodyRows.map((row, ri) => renderTableCells(row, `tr-${index}-${ri}`, theme))}\n <Text color={theme.mdTableBorder}>{layout.bottom}</Text>\n </Box>\n );\n }\n\n case 'space':\n return null;\n\n case 'html': {\n const t = token as Tokens.HTML;\n if (t.block && t.text) {\n return (\n <Box key={`html-${index}`}>\n <Text color={theme.subtle} dimColor>\n {t.text}\n </Text>\n </Box>\n );\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Renders markdown content into Ink components.\n *\n * Uses marked.lexer() to tokenize the markdown string, then maps each\n * block-level token to Ink Box/Text components with appropriate styling\n * from the current theme (mdCodeBackground, mdHeading, mdLink, etc.).\n */\ninterface MarkdownRendererProps {\n content: string;\n terminalWidth?: number;\n isStreaming: boolean;\n theme: ReturnType<typeof useTheme>;\n density: ReturnType<typeof useDensity>;\n}\n\nconst MarkdownRenderer = React.memo(function MarkdownRenderer({\n content,\n terminalWidth,\n isStreaming,\n theme,\n density,\n}: MarkdownRendererProps) {\n const tokens = useMemo(\n // A link definition draws nothing, so it must never be the neighbour a gap\n // is measured from.\n () => marked.lexer(content).filter((token) => token.type !== 'space' && token.type !== 'def'),\n [content],\n );\n\n return (\n <Box flexDirection=\"column\">\n {tokens.map((token, i) => {\n const gap = markdownBlockGap(tokens[i - 1]?.type, token.type, density);\n return (\n <React.Fragment key={`block-${i}`}>\n {gap > 0 ? <Box height={gap} /> : null}\n {renderBlockToken(token, theme, i, terminalWidth, {\n depth: 0,\n isStreaming,\n blockquoteDepth: 0,\n })}\n </React.Fragment>\n );\n })}\n </Box>\n );\n});\n\n/** The rail a code block draws down its left edge, for its caption to share. */\nfunction railCaptionProps(theme: ReturnType<typeof useTheme>) {\n return {\n paddingLeft: 1 as const,\n borderLeft: true,\n borderTop: false,\n borderRight: false,\n borderBottom: false,\n borderStyle: 'single' as const,\n borderColor: theme.mdCodeBorder,\n };\n}\n\nexport function MarkdownBlock({ content, terminalWidth, isStreaming = false }: MarkdownBlockProps) {\n const theme = useTheme();\n const density = useDensity();\n const notifyLayoutChange = useTranscriptLayoutChange();\n\n const parsedContent = useThrottledValue(content, 60, notifyLayoutChange ?? undefined);\n // Completed content should never wait for the streaming throttle. This also\n // ensures the final render highlights the complete response immediately.\n const effectiveContent = isStreaming ? parsedContent || content : content;\n // Keep the live view bounded, but use the same Markdown tree as the final\n // view. This avoids a visible raw-text-to-Markdown layout swap when a large\n // response completes; streaming only disables expensive code highlighting.\n const displayContent = useMemo(\n () =>\n isStreaming ? streamingMarkdownWindow(effectiveContent, terminalWidth) : effectiveContent,\n [effectiveContent, isStreaming, terminalWidth],\n );\n\n if (!displayContent) return null;\n\n return (\n <MarkdownRenderer\n content={displayContent}\n terminalWidth={terminalWidth}\n isStreaming={isStreaming}\n theme={theme}\n density={density}\n />\n );\n}\n","/* Hallmark pre-emit critique: P5 H5 E5 S5 R5 V4 */\n\nimport { createContext, useContext } from 'react';\n\nexport type TuiDensity = 'compact' | 'tight';\n\nexport interface DensityMetrics {\n panelMarginY: 0;\n turnMarginY: 0;\n userPaddingX: 1;\n userPaddingY: 0;\n headingGapBefore: 0 | 1;\n majorBlockGap: 0 | 1;\n /** Blank rows between consecutive tool rows. Zero: they read as one column. */\n toolRowGap: 0 | 1;\n /** Blank rows between prose and the tool block that follows it. */\n toolBlockGap: 0 | 1;\n paragraphGap: 1;\n showOptionalHelp: boolean;\n}\n\nconst COMPACT_METRICS: DensityMetrics = {\n panelMarginY: 0,\n turnMarginY: 0,\n userPaddingX: 1,\n userPaddingY: 0,\n headingGapBefore: 1,\n majorBlockGap: 1,\n toolRowGap: 0,\n toolBlockGap: 1,\n paragraphGap: 1,\n showOptionalHelp: true,\n};\n\nconst TIGHT_METRICS: DensityMetrics = {\n ...COMPACT_METRICS,\n headingGapBefore: 0,\n majorBlockGap: 0,\n toolRowGap: 0,\n toolBlockGap: 0,\n showOptionalHelp: false,\n};\n\nexport const DensityContext = createContext<TuiDensity>('compact');\n\nexport function resolveTuiDensity(rows: number): TuiDensity {\n return Math.floor(rows) < 18 ? 'tight' : 'compact';\n}\n\nexport function densityMetrics(density: TuiDensity): DensityMetrics {\n return density === 'tight' ? TIGHT_METRICS : COMPACT_METRICS;\n}\n\nexport function useDensity(): TuiDensity {\n return useContext(DensityContext);\n}\n\nexport function useDensityMetrics(): DensityMetrics {\n return densityMetrics(useDensity());\n}\n","import { createContext, useContext, useEffect, useSyncExternalStore } from 'react';\n\nexport type TranscriptLayoutChange = () => void;\nexport type TranscriptHistoryRequest = 'page' | 'all';\nexport type TranscriptHistoryLoader = (request: TranscriptHistoryRequest) => boolean;\n\ninterface TranscriptHistoryRegistry {\n register: (loader: TranscriptHistoryLoader) => () => void;\n}\n\nexport interface TranscriptViewportSnapshot {\n scrollTop: number;\n viewportRows: number;\n followBottom: boolean;\n}\n\nexport interface TranscriptViewportStore {\n subscribe: (listener: () => void) => () => void;\n getRevision: () => number;\n getSnapshot: () => TranscriptViewportSnapshot;\n /**\n * Keeps the rows in view where they are when a row above them changes height. The virtual\n * transcript sizes rows it has not mounted from an estimate; when one scrolls into its window it\n * reports its measured height, and if the whole row is above the first visible row, everything\n * under it would slide by the difference. `endRow` is the content row just past the row as it was\n * laid out, and `deltaRows` is its measured height minus the height it was laid out with.\n */\n anchorRowsAbove?: (endRow: number, deltaRows: number) => void;\n}\n\nexport const TranscriptLayoutContext = createContext<TranscriptLayoutChange | null>(null);\nexport const TranscriptHistoryContext = createContext<TranscriptHistoryRegistry | null>(null);\nexport const TranscriptViewportContext = createContext<TranscriptViewportStore | null>(null);\n\nexport function useTranscriptLayoutChange(): TranscriptLayoutChange | null {\n return useContext(TranscriptLayoutContext);\n}\n\nexport function useTranscriptHistoryLoader(loader: TranscriptHistoryLoader): void {\n const registry = useContext(TranscriptHistoryContext);\n useEffect(() => registry?.register(loader), [loader, registry]);\n}\n\nexport function useTranscriptViewport(): TranscriptViewportSnapshot | null {\n const store = useContext(TranscriptViewportContext);\n useSyncExternalStore(\n store?.subscribe ?? subscribeNoop,\n store?.getRevision ?? getZeroRevision,\n getZeroRevision,\n );\n return store?.getSnapshot() ?? null;\n}\n\nfunction subscribeNoop(): () => void {\n return () => {};\n}\n\nfunction getZeroRevision(): number {\n return 0;\n}\n","/**\n * The rubricator's marks.\n *\n * Rubricated manuscripts set the body in black ink and the marks a reader\n * navigates by in red. The TUI does the same: these are the only glyphs that\n * take the accent, and each has one job.\n */\n\n/** Opens a user turn, and prompts the composer you write the next one in. */\nexport const PILCROW = '¶';\n\n/** Precedes an H1 or H2 heading in an answer. */\nexport const SECTION_SIGN = '§';\n","/**\n * Pure layout helpers for MarkdownBlock: tables, fenced code chrome, and\n * nested block width budgets. All measurements use displayWidth (CJK/emoji\n * safe). No React imports — unit-testable without Ink.\n */\n\nimport {\n displayWidth,\n hardWrapLine,\n makeDivider,\n padDisplay,\n truncateDisplay,\n wordWrap,\n} from './word-wrap.js';\nimport type { TuiDensity } from '../density.js';\nimport { SECTION_SIGN } from '../marks.js';\n\nexport function markdownBlockGap(\n previous: string | undefined,\n next: string,\n density: TuiDensity,\n): 0 | 1 {\n if (!previous) return 0;\n if (previous === 'heading') return 0;\n if (next === 'heading') return density === 'compact' ? 1 : 0;\n if (previous === 'paragraph' && next === 'paragraph') return 1;\n // A closing paragraph is a new thought, not one more bullet: with no gap\n // \"All 3 tests pass.\" read as the last item of the list above it. The other\n // direction keeps its 0 — a paragraph that leads into a list belongs with\n // what follows.\n if (previous === 'list' && next === 'paragraph') return 1;\n\n const major = new Set(['code', 'table', 'blockquote', 'hr']);\n if (major.has(previous) || major.has(next)) return density === 'compact' ? 1 : 0;\n\n return 0;\n}\n\nexport type TableAlign = 'left' | 'right' | 'center' | null | undefined;\n\nexport interface TableCellInput {\n text: string;\n}\n\nexport interface TableLayoutInput {\n header: TableCellInput[];\n rows: TableCellInput[][];\n align?: TableAlign[];\n /** Available terminal columns for the whole table, rules and outer air included. */\n terminalWidth: number;\n}\n\nexport interface TableGridLayout {\n mode: 'grid';\n /** Display widths of cell content (excluding padding/borders). */\n colWidths: number[];\n /** Full border/body line width (display columns). */\n totalWidth: number;\n top: string;\n middle: string;\n bottom: string;\n /** First visual header row (padded cells). */\n headerCells: string[];\n /** Full multi-line header rows (padded cells). */\n headerRows: string[][];\n bodyRows: string[][];\n}\n\nexport interface TableStackedLayout {\n mode: 'stacked';\n /** Lines like \"Header: value\", already hard-wrapped to terminalWidth. */\n lines: string[];\n}\n\nexport type TableLayout = TableGridLayout | TableStackedLayout;\n\nexport interface CodeLineLayout {\n /** Gutter prefix for this visual line (line number + separator, or continuation spaces). */\n gutter: string;\n /** Hard-wrapped content segment for this visual line. */\n text: string;\n /** 0-based source line index in the original fenced block. */\n sourceLineIndex: number;\n /** Character offset into the original source line where `text` starts. */\n sourceStart: number;\n /** Character offset into the original source line where `text` ends (exclusive). */\n sourceEnd: number;\n /** True when this is a continuation of a previous hard-wrap for the same source line. */\n isContinuation: boolean;\n}\n\nexport interface CodeBlockLayout {\n /** Render the left rail (a border column plus one column of padding). */\n showRail: boolean;\n showLineNumbers: boolean;\n /** Content columns available after border/padding/gutter. */\n contentWidth: number;\n /** Full outer width budget used for border lines. */\n outerWidth: number;\n /** Language label, truncated to contentWidth when present. */\n langLabel: string | null;\n /** Flattened visual lines ready to render. */\n lines: CodeLineLayout[];\n}\n\nconst MIN_CELL = 1;\n\n/** Narrower than this, a cell that had to be cut reads as fragments. */\nconst MIN_READABLE_CELL = 4;\n// Row format: │ + \" \" + cell + \" \" + │ ... → per column: 3 chrome chars + width,\n// plus one final │. Equivalently: 1 + sum(width_i + 3) for n columns?\n// Actual: \"│ \" + cell + \" │ \" + cell + \" │\"\n// Between cells: \" │ \" (3), left edge \"│ \" (2), right edge \"│\" (1).\n// total = 1 (left │) + n * (1 space + width + 1 space) + (n-1) * 1 (│ between) + 1?\n// Looking at current MarkdownBlock: `│ ` + cell + ` │ ` between + final via same pattern.\n// renderTableRow: <Text>│ </Text> then for each cell: cell + ` │ `\n// So: \"│ \" + cell0 + \" │ \" + cell1 + \" │ \" ... = 2 + sum(width_i + 3) for each cell\n// = 2 + n*width + 3n = n*width + 3n + 2\n// Border: ┌ + ─.repeat(w+2) joined by ┬ + ┐\n// = 1 + sum(w+2) + (n-1) + 1 = n*w + 2n + n + 1? join('┬') adds n-1 seps of 1\n// = 1 + sum(w_i+2) + (n-1) + 1 = sum(w_i) + 2n + n - 1 + 2 = sum(w) + 3n + 1\n// Row body: \"│ \" (2) + for each: cell + \" │ \" (width+3) = 2 + sum(w)+3n = sum(w)+3n+2\n// Off-by-one: border is sum(w)+3n+1, body is sum(w)+3n+2\n// Looking at existing code:\n// const separator = colWidths.map((width) => '─'.repeat(width + 2));\n// const top = `┌${separator.join('┬')}┐`;\n// For widths [3,3]: sep = ['─────','─────'] join ┬ → ┌─────┬─────┐ length = 1+5+1+5+1=13\n// Body: │ + space + 3 + space + │ + space + 3 + space + │ = 2+3+3+2+3+3?\n// \"│ \" + \"aaa\" + \" │ \" + \"bbb\" + \" │\" = 2+3+3+3+3+2 wait\n// \"│ \" = 2, cell=3, \" │ \" = 3, cell=3, \" │\" = 2 → 2+3+3+3+2 = 13. Yes!\n// So totalWidth = sum(w_i + 2) + (n - 1) + 2 = sum(w) + 2n + n - 1 + 2 = sum(w) + 3n + 1\n// With the trailing \" │\" being 2 chars (space+│) not 3.\n// Formula: 1 + sum(width_i + 2) + (n-1) = sum(width) + 3n\n\n/**\n * Width of a table row and of its rules: the cells, a {@link TABLE_COLUMN_GAP}\n * between each two, and a column of air at each end (`sum + 3n - 1`). It used\n * to count the boxed grid's vertical borders as well (`sum + 3n + 1`), so after\n * the borders went a table that fit was still squeezed or stacked.\n */\nfunction tableChromeWidth(colWidths: number[]): number {\n if (colWidths.length === 0) return 0;\n return (\n colWidths.reduce((sum, w) => sum + w, 0) + (colWidths.length - 1) * TABLE_COLUMN_GAP.length + 2\n );\n}\n\nfunction normalizeAlign(align: TableAlign): 'left' | 'right' | 'center' {\n if (align === 'right' || align === 'center') return align;\n return 'left';\n}\n\n/**\n * Allocate column content widths that fit inside `terminalWidth`.\n * Prefers natural content widths; shrinks proportionally when needed.\n * Returns null when even minimum columns cannot fit (caller should stack).\n */\nexport function allocateTableColumns(\n naturalWidths: number[],\n terminalWidth: number,\n): number[] | null {\n const n = naturalWidths.length;\n if (n === 0) return [];\n\n const minTotal = tableChromeWidth(Array<number>(n).fill(MIN_CELL));\n if (terminalWidth < minTotal) return null;\n\n const natural = naturalWidths.map((w) => Math.max(MIN_CELL, Math.ceil(w)));\n const naturalTotal = tableChromeWidth(natural);\n if (naturalTotal <= terminalWidth) return natural;\n\n // Everything but the cells: total = sum(w) + tableChromeWidth(zeros).\n const sumTarget = terminalWidth - tableChromeWidth(Array<number>(n).fill(0));\n if (sumTarget < n * MIN_CELL) return null;\n\n // Start from natural, shrink largest columns first until sum fits.\n const widths = [...natural];\n let sum = widths.reduce((a, b) => a + b, 0);\n while (sum > sumTarget) {\n let maxIdx = 0;\n for (let i = 1; i < n; i++) {\n if (widths[i]! > widths[maxIdx]!) maxIdx = i;\n }\n if (widths[maxIdx]! <= MIN_CELL) break;\n widths[maxIdx]! -= 1;\n sum -= 1;\n }\n\n if (sum > sumTarget) return null;\n // Distribute any leftover to the widest natural columns for readability.\n let leftover = sumTarget - sum;\n while (leftover > 0) {\n let maxIdx = 0;\n for (let i = 1; i < n; i++) {\n if (natural[i]! > natural[maxIdx]!) maxIdx = i;\n }\n // Prefer columns that are still below natural width.\n let growIdx = -1;\n for (let i = 0; i < n; i++) {\n if (widths[i]! < natural[i]!) {\n if (growIdx < 0 || natural[i]! > natural[growIdx]!) growIdx = i;\n }\n }\n if (growIdx < 0) growIdx = maxIdx;\n widths[growIdx]! += 1;\n leftover -= 1;\n }\n\n return widths;\n}\n\nfunction wrapCellLines(text: string, width: number): string[] {\n if (width <= 0) return [''];\n const soft = wordWrap(text, width);\n const out: string[] = [];\n for (const line of soft.split('\\n')) {\n out.push(...hardWrapLine(line, width));\n }\n return out.length > 0 ? out : [''];\n}\n\n/** Spaces between two table columns. Columns are divided by space, not by rules. */\nexport const TABLE_COLUMN_GAP = ' ';\n\n/**\n * One table row as text: cells separated by {@link TABLE_COLUMN_GAP}, with one\n * column of air at each end so the text sits inside the rules above and below.\n */\nexport function tableRowText(cells: readonly string[]): string {\n return ` ${cells.join(TABLE_COLUMN_GAP)} `;\n}\n\n/**\n * A full-width table rule.\n *\n * Tables are ruled the way a book sets them (booktabs): a heavy rule above and\n * below, a light one under the header, and no vertical lines at all. The old\n * grid drew a box around every cell, which made a three-row comparison the\n * heaviest object in the answer.\n */\nfunction buildRule(colWidths: number[], char: '━' | '─'): string {\n return char.repeat(Math.max(0, tableChromeWidth(colWidths)));\n}\n\n/**\n * Layout a markdown table for the given terminal width.\n * Falls back to stacked \"Header: value\" lines when the grid cannot fit.\n */\nexport function layoutTable(input: TableLayoutInput): TableLayout {\n const { header, rows, align = [], terminalWidth } = input;\n const colCount = Math.max(header.length, ...rows.map((r) => r.length), 0);\n if (colCount === 0) {\n return { mode: 'stacked', lines: [] };\n }\n\n const normalizedHeader = Array.from({ length: colCount }, (_, i) => header[i]?.text ?? '');\n const normalizedRows = rows.map((row) =>\n Array.from({ length: colCount }, (_, i) => row[i]?.text ?? ''),\n );\n\n const naturalWidths: number[] = Array.from({ length: colCount }, () => MIN_CELL);\n for (let ci = 0; ci < colCount; ci++) {\n naturalWidths[ci] = Math.max(naturalWidths[ci]!, displayWidth(normalizedHeader[ci]!));\n for (const row of normalizedRows) {\n naturalWidths[ci] = Math.max(naturalWidths[ci]!, displayWidth(row[ci]!));\n }\n }\n\n const widthBudget = Math.max(0, Math.floor(terminalWidth));\n const colWidths = allocateTableColumns(naturalWidths, widthBudget);\n\n // Prefer stacked layout when a column had to be cut below a readable width\n // (four columns, or its whole content if that is shorter), or allocation\n // failed (too many columns / tiny terminal). A `fo`/`o` cell is not a table.\n const tooNarrow =\n colWidths === null ||\n colWidths.some((w, i) => w < Math.min(MIN_READABLE_CELL, naturalWidths[i]!)) ||\n (colCount >= 4 && widthBudget < colCount * 8);\n\n if (tooNarrow || colWidths === null) {\n return {\n mode: 'stacked',\n lines: layoutStackedTable(normalizedHeader, normalizedRows, widthBudget),\n };\n }\n\n // Wrap header + body cells; expand multi-line cells into stacked visual rows.\n const headerLineGroups = normalizedHeader.map((text, ci) => wrapCellLines(text, colWidths[ci]!));\n const headerHeight = Math.max(1, ...headerLineGroups.map((lines) => lines.length));\n const headerRows: string[][] = [];\n for (let li = 0; li < headerHeight; li++) {\n headerRows.push(\n headerLineGroups.map((lines, ci) =>\n padDisplay(lines[li] ?? '', colWidths[ci]!, normalizeAlign(align[ci])),\n ),\n );\n }\n\n const bodyRows: string[][] = [];\n for (const row of normalizedRows) {\n const cellLines = row.map((text, ci) => wrapCellLines(text, colWidths[ci]!));\n const height = Math.max(1, ...cellLines.map((lines) => lines.length));\n for (let li = 0; li < height; li++) {\n bodyRows.push(\n cellLines.map((lines, ci) =>\n padDisplay(lines[li] ?? '', colWidths[ci]!, normalizeAlign(align[ci])),\n ),\n );\n }\n }\n\n const top = buildRule(colWidths, '━');\n return {\n mode: 'grid',\n colWidths,\n totalWidth: displayWidth(top),\n top,\n middle: buildRule(colWidths, '─'),\n bottom: buildRule(colWidths, '━'),\n // First visual header row kept as headerCells for simple consumers;\n // full multi-line header is in headerRows.\n headerCells: headerRows[0] ?? Array(colCount).fill(''.padEnd(0)),\n headerRows,\n bodyRows,\n };\n}\n\nfunction layoutStackedTable(header: string[], rows: string[][], terminalWidth: number): string[] {\n const width = Math.max(1, terminalWidth);\n const lines: string[] = [];\n for (const row of rows) {\n if (lines.length > 0) lines.push(''); // blank separator between records\n for (let ci = 0; ci < header.length; ci++) {\n const label = header[ci]?.trim() || `Col ${ci + 1}`;\n const value = row[ci] ?? '';\n const combined = `${label}: ${value}`;\n const wrapped = wordWrap(combined, width).split('\\n');\n for (const line of wrapped) {\n lines.push(...hardWrapLine(line, width));\n }\n }\n }\n // If there are headers but no body rows, still show headers.\n if (rows.length === 0 && header.some((h) => h.length > 0)) {\n for (const h of header) {\n lines.push(...hardWrapLine(h, width));\n }\n }\n return lines;\n}\n\n/** Nested content budget after list markers / blockquote bars. */\nexport function nestedContentWidth(\n terminalWidth: number | undefined,\n options: { depth?: number; listGutter?: number; blockquoteDepth?: number } = {},\n): number | undefined {\n if (terminalWidth === undefined) return undefined;\n const depth = options.depth ?? 0;\n const listGutter = options.listGutter ?? 5; // marker column + margins\n const bq = options.blockquoteDepth ?? 0;\n // Each list depth: +2 marginLeft on list + 2 on item ≈ 4, plus marker width ~3.\n // Keep a conservative clamp matching previous Math.max(10, terminalWidth - 5 - depth*2).\n const listDeduction = listGutter + depth * 2;\n const bqDeduction = bq * 2; // border + paddingLeft\n return Math.max(1, Math.floor(terminalWidth) - listDeduction - bqDeduction);\n}\n\n/** Clamp decorative heading chrome so it fits `terminalWidth`. */\nexport function layoutHeadingChrome(\n text: string,\n depth: number,\n terminalWidth: number | undefined,\n): { prefix: string; text: string; suffix: string } {\n // Headings are bold and brightness-ranked by depth (see MarkdownBlock). The\n // two that structure an answer open with a rubricated section sign, the only\n // chrome they carry: `=== TEXT ===` side rules competed with the transcript's\n // own boundaries for the eye.\n const prefix = depth <= 2 ? `${SECTION_SIGN} ` : '';\n const budget =\n terminalWidth && terminalWidth > 0\n ? Math.max(1, Math.floor(terminalWidth) - displayWidth(prefix))\n : null;\n return {\n prefix,\n text: budget === null || fitsIn(text, budget) ? text : truncateDisplay(text, budget),\n suffix: '',\n };\n}\n\nfunction fitsIn(text: string, width: number): boolean {\n return displayWidth(text) <= width;\n}\n\n/** Horizontal rule that respects terminal width (min 5, max 60). */\nexport function layoutHorizontalRule(terminalWidth: number | undefined): string {\n const width = terminalWidth && terminalWidth > 0 ? Math.floor(terminalWidth) : 40;\n return makeDivider(Math.min(width, 60), 0, '─');\n}\n\n/**\n * Layout a fenced code block.\n *\n * Accounts for the left rail (1) + its padding (1) + an optional line-number\n * gutter. Hard-wraps unbroken source lines; continuation lines use a blank\n * gutter so the numbering stays readable.\n */\nexport function layoutCodeBlock(\n sourceLines: string[],\n terminalWidth: number | undefined,\n options: { lang?: string; preferLineNumbers?: boolean } = {},\n): CodeBlockLayout {\n const preferLineNumbers = options.preferLineNumbers ?? sourceLines.length > 5;\n const lang = options.lang?.trim() || null;\n\n // Without a known width, keep full chrome and do not wrap (Ink may hard-wrap).\n if (!terminalWidth || terminalWidth <= 0) {\n const gutterWidth = String(Math.max(sourceLines.length, 1)).length;\n const showLineNumbers = preferLineNumbers;\n const lines: CodeLineLayout[] = sourceLines.map((text, i) => {\n const gutter = showLineNumbers ? `${String(i + 1).padStart(gutterWidth, ' ')} │ ` : '';\n return {\n gutter,\n text,\n sourceLineIndex: i,\n sourceStart: 0,\n sourceEnd: text.length,\n isContinuation: false,\n };\n });\n return {\n showRail: true,\n showLineNumbers,\n contentWidth: Number.POSITIVE_INFINITY,\n outerWidth: terminalWidth ?? 0,\n langLabel: lang,\n lines,\n };\n }\n\n const outerWidth = Math.max(1, Math.floor(terminalWidth));\n\n // Rail cost: one border column on the left, plus one column of padding\n // inside it. A code block is content, not a panel, so it never pays for a\n // four-sided box — that chrome outweighed the code it wrapped.\n const BORDER = 1;\n const PADDING_X = 1;\n\n type Chrome = { border: boolean; lineNumbers: boolean };\n const candidates: Chrome[] = [\n { border: true, lineNumbers: preferLineNumbers },\n { border: true, lineNumbers: false },\n { border: false, lineNumbers: preferLineNumbers },\n { border: false, lineNumbers: false },\n ];\n\n const gutterWidth = String(Math.max(sourceLines.length, 1)).length;\n // \"N │ \" → gutterWidth + 3\n const lineNumberGutterCols = gutterWidth + 3;\n\n let chosen: Chrome = { border: false, lineNumbers: false };\n let contentWidth = Math.max(1, outerWidth);\n\n for (const candidate of candidates) {\n const chrome =\n (candidate.border ? BORDER + PADDING_X : 0) +\n (candidate.lineNumbers ? lineNumberGutterCols : 0);\n const available = outerWidth - chrome;\n if (available >= 1) {\n chosen = candidate;\n contentWidth = available;\n break;\n }\n }\n\n // Final clamp: always leave at least 1 content column.\n contentWidth = Math.max(1, contentWidth);\n\n const langLabel =\n lang === null ? null : fitsIn(lang, contentWidth) ? lang : truncateDisplay(lang, contentWidth);\n\n const lines: CodeLineLayout[] = [];\n for (let i = 0; i < sourceLines.length; i++) {\n const source = sourceLines[i] ?? '';\n const chunks = hardWrapLine(source, contentWidth);\n let charOffset = 0;\n for (let ci = 0; ci < chunks.length; ci++) {\n const chunk = chunks[ci]!;\n // hardWrapLine splits by code points; concatenation of chunks equals source.\n const start = charOffset;\n const end = start + chunk.length;\n charOffset = end;\n\n const isContinuation = ci > 0;\n let gutter = '';\n if (chosen.lineNumbers) {\n gutter = isContinuation\n ? `${' '.repeat(gutterWidth)} │ `\n : `${String(i + 1).padStart(gutterWidth, ' ')} │ `;\n }\n\n lines.push({\n gutter,\n text: chunk,\n sourceLineIndex: i,\n sourceStart: start,\n sourceEnd: end,\n isContinuation,\n });\n }\n }\n\n return {\n showRail: chosen.border,\n showLineNumbers: chosen.lineNumbers,\n contentWidth,\n outerWidth,\n langLabel,\n lines,\n };\n}\n\n/**\n * Slice a styled segment line by character offsets (not display width).\n * Preserves segment styles for hard-wrapped code visual lines.\n */\nexport function sliceStyledLine<T extends { text: string }>(\n segments: T[],\n start: number,\n end: number,\n): T[] {\n if (end <= start) return [];\n const out: T[] = [];\n let cursor = 0;\n for (const seg of segments) {\n const segStart = cursor;\n const segEnd = cursor + seg.text.length;\n const overlapStart = Math.max(segStart, start);\n const overlapEnd = Math.min(segEnd, end);\n if (overlapStart < overlapEnd) {\n const text = seg.text.slice(overlapStart - segStart, overlapEnd - segStart);\n if (text) out.push({ ...seg, text });\n }\n cursor = segEnd;\n if (cursor >= end) break;\n }\n return out;\n}\n","import { displayWidth, truncateDisplay } from './word-wrap.js';\n\nexport interface ToolOutputDisplayOptions {\n maxLines: number;\n maxLineWidth: number;\n /** Optional hint appended to the footer when output is hidden. */\n hint?: string;\n /** Select initial lines, final lines, or a balanced initial/final preview. */\n strategy?: 'head' | 'tail' | 'head-tail';\n}\n\nexport interface ToolOutputDisplay {\n lines: string[];\n totalLines: number;\n totalChars: number;\n totalBytes: number;\n hiddenLines: number;\n hiddenBytes: number;\n truncatedLines: number;\n truncated: boolean;\n footer?: string;\n}\n\nexport function formatByteSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n const kib = bytes / 1024;\n if (kib < 1024) return `${kib.toFixed(kib >= 10 ? 0 : 1)} KB`;\n const mib = kib / 1024;\n return `${mib.toFixed(mib >= 10 ? 0 : 1)} MB`;\n}\n\n/**\n * Prepare tool output for terminal display without mutating the underlying result.\n * Counts the original output, then returns a bounded, display-width-aware preview.\n */\nexport function prepareToolOutputDisplay(\n output: string,\n { maxLines, maxLineWidth, hint, strategy = 'head' }: ToolOutputDisplayOptions,\n): ToolOutputDisplay {\n const rawLines = output.length === 0 ? [] : output.split('\\n');\n const lineLimit = Math.max(0, Math.floor(maxLines));\n const widthLimit = Math.max(0, Math.floor(maxLineWidth));\n const visibleIndices = selectVisibleLineIndices(rawLines.length, lineLimit, strategy);\n const visibleRawLines = visibleIndices.map((index) => rawLines[index] ?? '');\n // Measure the whole output in one call and only the visible lines\n // individually — a per-line map allocates a string and a Buffer measurement\n // for every line of a potentially huge output just to fill in the footer.\n const totalBytes = Buffer.byteLength(output, 'utf8');\n let visibleBytes = 0;\n for (const index of visibleIndices) {\n visibleBytes +=\n Buffer.byteLength(rawLines[index] ?? '', 'utf8') + (index < rawLines.length - 1 ? 1 : 0);\n }\n let truncatedLines = 0;\n const lines = visibleRawLines.map((line) => {\n const next = truncateDisplay(line, widthLimit);\n if (displayWidth(next) < displayWidth(line) || next !== line) truncatedLines++;\n return next;\n });\n const hiddenLines = Math.max(0, rawLines.length - visibleRawLines.length);\n const hiddenBytes = Math.max(0, totalBytes - visibleBytes);\n const truncated = hiddenLines > 0 || truncatedLines > 0;\n const footer = truncated\n ? formatToolOutputFooter({\n totalLines: rawLines.length,\n totalBytes,\n hiddenLines,\n hiddenBytes,\n truncatedLines,\n hint,\n })\n : undefined;\n\n return {\n lines,\n totalLines: rawLines.length,\n totalChars: output.length,\n totalBytes,\n hiddenLines,\n hiddenBytes,\n truncatedLines,\n truncated,\n footer,\n };\n}\n\nfunction selectVisibleLineIndices(\n totalLines: number,\n maxLines: number,\n strategy: NonNullable<ToolOutputDisplayOptions['strategy']>,\n): number[] {\n if (maxLines <= 0 || totalLines <= 0) return [];\n if (totalLines <= maxLines) return Array.from({ length: totalLines }, (_, index) => index);\n if (strategy === 'tail') {\n return Array.from({ length: maxLines }, (_, index) => totalLines - maxLines + index);\n }\n if (strategy === 'head-tail' && maxLines > 1) {\n const headLines = Math.ceil(maxLines / 2);\n const tailLines = maxLines - headLines;\n return [\n ...Array.from({ length: headLines }, (_, index) => index),\n ...Array.from({ length: tailLines }, (_, index) => totalLines - tailLines + index),\n ];\n }\n return Array.from({ length: maxLines }, (_, index) => index);\n}\n\nfunction formatToolOutputFooter({\n totalLines,\n totalBytes,\n hiddenLines,\n hiddenBytes,\n truncatedLines,\n hint,\n}: {\n totalLines: number;\n totalBytes: number;\n hiddenLines: number;\n hiddenBytes: number;\n truncatedLines: number;\n hint?: string;\n}): string {\n const parts: string[] = [];\n if (hiddenLines > 0)\n parts.push(\n `${hiddenLines} more ${hiddenLines === 1 ? 'line' : 'lines'} hidden, ${hiddenBytes} B`,\n );\n if (truncatedLines > 0)\n parts.push(`${truncatedLines} long ${truncatedLines === 1 ? 'line' : 'lines'} shortened`);\n const summary = `${totalLines} ${totalLines === 1 ? 'line' : 'lines'}, ${formatByteSize(totalBytes)} total`;\n return `… ${parts.join(', ')} (${summary}${hint ? `; ${hint}` : ''})`;\n}\n","import type { ToolResult } from '../types/tools.js';\nimport { canonicalToolName } from '../tools/aliases.js';\nimport { getPrimaryArg } from '../tools/primary-arg.js';\nimport { isFileMutatingTool } from '../tools/tool-capabilities.js';\nimport { isUnifiedDiffLike } from './components/Diff.js';\n\nexport interface FileMutationDisplaySummary {\n filePath: string;\n kind: 'create' | 'update' | 'delete';\n addedLines: number;\n removedLines: number;\n fileCount?: number;\n}\n\nexport function isRenderableFileMutationDiff(\n toolName: string,\n result: ToolResult | undefined,\n): boolean {\n if (result?.status !== 'success' || !result.content) return false;\n return isFileMutatingTool(canonicalToolName(toolName)) && isUnifiedDiffLike(result.content);\n}\n\nexport function getFileMutationDisplaySummary(\n toolName: string,\n args: Record<string, unknown>,\n result: ToolResult | undefined,\n): FileMutationDisplaySummary | undefined {\n if (!isRenderableFileMutationDiff(toolName, result)) return undefined;\n\n const mutations = result?.artifacts?.fileMutations ?? [];\n if (mutations.length > 1) {\n const kinds = new Set(mutations.map((mutation) => mutation.kind));\n return {\n filePath: `${mutations.length} files`,\n kind: kinds.size === 1 ? mutations[0].kind : 'update',\n addedLines: mutations.reduce((total, mutation) => total + mutation.addedLines, 0),\n removedLines: mutations.reduce((total, mutation) => total + mutation.removedLines, 0),\n fileCount: new Set(mutations.map((mutation) => mutation.filePath)).size,\n };\n }\n const mutation = result?.artifacts?.fileMutation;\n const filePath =\n mutation?.filePath ??\n ['filePath', 'file_path', 'notebook_path', 'path']\n .map((key) => args[key])\n .find((value): value is string => typeof value === 'string' && value.length > 0) ??\n getPrimaryArg(args) ??\n '(unknown file)';\n const lines = result?.content.split('\\n') ?? [];\n const addedLines =\n mutation?.addedLines ??\n lines.filter((line) => line.startsWith('+') && !line.startsWith('+++')).length;\n const removedLines =\n mutation?.removedLines ??\n lines.filter((line) => line.startsWith('-') && !line.startsWith('---')).length;\n\n return {\n filePath,\n kind: mutation?.kind ?? 'update',\n addedLines,\n removedLines,\n fileCount: 1,\n };\n}\n","import type { Todo } from '../tools/todo.js';\n\n/** Most step rows the Steps sheet lists before it folds the rest into counts. */\nexport const STEP_SHEET_ROWS = 8;\n\nexport interface StepWindow {\n /** Steps above the window, folded into one row. */\n before: Todo[];\n /** Steps listed row by row. */\n rows: Todo[];\n /** How many steps sit below the window. */\n after: number;\n}\n\n/**\n * The steps a sheet of `limit` rows lists.\n *\n * The window follows the step in flight, keeping one step of context above it,\n * and shifts up only when it would otherwise run past the end. The first five\n * steps used to be listed whatever the progress, with the active step swapped\n * into the last row, so a long plan spent its rows on finished work and hid the\n * steps in between.\n */\nexport function stepWindow(todos: readonly Todo[], limit = STEP_SHEET_ROWS): StepWindow {\n if (todos.length <= limit) return { before: [], rows: [...todos], after: 0 };\n const active = todos.findIndex((todo) => todo.status === 'in_progress');\n const unfinished = todos.findIndex((todo) => todo.status !== 'completed');\n const focus = active >= 0 ? active : unfinished >= 0 ? unfinished : todos.length - 1;\n let from = Math.max(0, Math.min(focus - 1, todos.length - limit));\n let to = from + limit;\n // A fold row takes the row its one step would have filled, so a lone step\n // is listed rather than folded.\n if (from === 1) from = 0;\n if (todos.length - to === 1) to = todos.length;\n return { before: todos.slice(0, from), rows: todos.slice(from, to), after: todos.length - to };\n}\n\n/** Where a plan stands: `2 of 7 done`. */\nexport function stepProgress(todos: readonly Todo[]): string {\n const done = todos.filter((todo) => todo.status === 'completed').length;\n return `${done} of ${todos.length} done`;\n}\n\n/**\n * The status line's note on the plan: `step 3/7` while a step is in flight,\n * `2/7 done` between steps, and nothing once the plan is finished or absent.\n */\nexport function statusStepLabel(todos: readonly Todo[]): string | undefined {\n if (todos.length === 0) return undefined;\n const done = todos.filter((todo) => todo.status === 'completed').length;\n if (done === todos.length) return undefined;\n const active = todos.findIndex((todo) => todo.status === 'in_progress');\n return active >= 0 ? `step ${active + 1}/${todos.length}` : `${done}/${todos.length} done`;\n}\n","import type { ToolResult } from '../types/tools.js';\nimport { foldControlCharacters as foldShared } from '../control-characters.js';\nimport { canonicalToolName } from '../tools/aliases.js';\nimport { getPrimaryArg } from '../tools/primary-arg.js';\nimport { isFileMutatingTool } from '../tools/tool-capabilities.js';\nimport { grepResultMetadata, readResultMetadata } from '../tools/result.js';\nimport { normalizePersistedTodos } from '../tools/todo.js';\nimport { stepProgress } from './steps.js';\nimport { displayWidth, truncateDisplay } from './components/word-wrap.js';\nimport { LABEL_COLUMN_WIDTH, MIN_TARGET_WIDTH, type TranscriptGrid } from './layout.js';\nimport { isRenderableFileMutationDiff } from './file-mutation-display.js';\n\nexport type TranscriptMode = 'compact' | 'detailed';\nexport type TranscriptShortcutAction = 'enter-detailed' | 'exit-detailed' | 'expand-output';\nexport type ToolPresentationStatus = 'running' | 'pending' | 'success' | 'failure' | 'skipped';\nexport type ToolPreviewType = 'none' | 'text' | 'markdown' | 'diff';\n\nexport interface ToolPresentation {\n canonicalName: string;\n status: ToolPresentationStatus;\n title: string;\n target?: string;\n metadata: string[];\n summary: string;\n previewType: ToolPreviewType;\n hasDetails: boolean;\n hasHiddenContent: boolean;\n filePath?: string;\n}\n\nexport interface ToolPresentationOptions {\n isPending?: boolean;\n nestedActivityCount?: number;\n /**\n * The argument text of a call the provider could not parse. Its `arguments` are\n * `{}`, so this is the only text there is to show for the row.\n */\n unparsedArguments?: { raw: string; error: string };\n}\n\nexport function getTranscriptShortcutAction(\n mode: TranscriptMode,\n input: string,\n key: { ctrl?: boolean; meta?: boolean; escape?: boolean },\n): TranscriptShortcutAction | null {\n if (\n mode === 'detailed' &&\n (key.escape || (!key.ctrl && !key.meta && input.toLowerCase() === 'q'))\n ) {\n return 'exit-detailed';\n }\n if (key.ctrl && (input === 'o' || input.charCodeAt(0) === 15)) {\n return mode === 'detailed' ? 'exit-detailed' : 'enter-detailed';\n }\n if (key.ctrl && (input === 'e' || input.charCodeAt(0) === 5)) return 'expand-output';\n return null;\n}\n\n/**\n * True for the keypress that toggles the keyboard-shortcut reference.\n *\n * A terminal sends US (`0x1f`) for Ctrl+/, and Ink's `parseKeypress` reports\n * that byte as `{ name: '', ctrl: false }` — the sequence reaches `useInput` as\n * `input`, with no `ctrl` flag to gate on. Testing only `key.ctrl && input ===\n * '/'` therefore never matched, so the one shortcut advertised on the welcome\n * screen could not be pressed, while a unit test synthesizing `{ ctrl: true }`\n * passed. Match the raw byte first and keep the flag form for terminals that do\n * report it.\n */\nexport function isShortcutsToggleKey(\n input: string,\n key: { ctrl?: boolean; meta?: boolean },\n): boolean {\n if (input.charCodeAt(0) === 31) return true;\n return Boolean(key.ctrl) && !key.meta && (input === '/' || input === '_');\n}\n\nexport interface PresentableToolInvocation<TCall = unknown> {\n id: string;\n name: string;\n call: TCall;\n result?: ToolResult;\n}\n\nexport type CompactToolGroup<TCall = unknown> =\n | { kind: 'tool'; invocation: PresentableToolInvocation<TCall> }\n | {\n kind: 'mcp-group';\n id: string;\n server: string;\n invocations: PresentableToolInvocation<TCall>[];\n };\n\n/** Group adjacent successful, completed MCP calls from the same server. */\nexport function groupConsecutiveMcpCalls<TCall>(\n invocations: readonly PresentableToolInvocation<TCall>[],\n): CompactToolGroup<TCall>[] {\n const groups: CompactToolGroup<TCall>[] = [];\n for (let index = 0; index < invocations.length;) {\n const current = invocations[index];\n const mcp = parseMcpToolName(current.name);\n if (!mcp || current.result?.status !== 'success') {\n groups.push({ kind: 'tool', invocation: current });\n index++;\n continue;\n }\n\n const consecutive: PresentableToolInvocation<TCall>[] = [current];\n let nextIndex = index + 1;\n while (nextIndex < invocations.length) {\n const next = invocations[nextIndex];\n const nextMcp = parseMcpToolName(next.name);\n if (!nextMcp || nextMcp.server !== mcp.server || next.result?.status !== 'success') break;\n consecutive.push(next);\n nextIndex++;\n }\n\n if (consecutive.length === 1) groups.push({ kind: 'tool', invocation: current });\n else {\n groups.push({\n kind: 'mcp-group',\n id: `mcp-group:${consecutive.map((item) => item.id).join(',')}`,\n server: mcp.server,\n invocations: consecutive,\n });\n }\n index = nextIndex;\n }\n return groups;\n}\nconst LABELS: Record<string, string> = {\n Read: 'Read',\n ApplyPatch: 'Apply patch',\n Write: 'Write',\n Edit: 'Edit',\n MultiEdit: 'Edit',\n NotebookEdit: 'Edit notebook',\n Bash: 'Bash',\n BashOutput: 'Shell output',\n KillShell: 'Kill shell',\n Glob: 'Glob',\n Grep: 'Grep',\n WebFetch: 'Fetch',\n WebSearch: 'Search web',\n GitStatus: 'Git status',\n GitDiff: 'Git diff',\n GitLog: 'Git log',\n GitCommit: 'Git commit',\n GitBranch: 'Git branch',\n TodoWrite: 'Steps',\n Task: 'Task',\n InvokeSkill: 'Skill',\n AskUserQuestion: 'Ask',\n ExitPlanMode: 'Plan',\n EnterPlanMode: 'Plan mode',\n};\n\nexport function formatDuration(durationMs: number | undefined): string | undefined {\n if (durationMs === undefined || durationMs < 0) return undefined;\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`;\n if (durationMs < 60_000) return `${(durationMs / 1000).toFixed(1)}s`;\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.floor((durationMs % 60_000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function parseMcpToolName(name: string): { server: string; tool: string } | undefined {\n const match = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(name);\n if (!match) return undefined;\n return { server: match[1], tool: match[2].replace(/_/g, ' ') };\n}\n\n/**\n * Fold a display target onto one line: every run of control characters (C0\n * such as tab, CR and LF, DEL, C1, and the bidi marks and separators) becomes\n * one space. Ordinary spaces are kept as they are, because the row shows what\n * the call acted on: a Grep pattern `^ def ` or a commit message's double\n * space is part of it. One linear pass, so a long raw argument costs its\n * length.\n */\nfunction foldControlCharacters(value: string | undefined): string | undefined {\n return value === undefined ? undefined : foldShared(value);\n}\n\nfunction stringArg(args: Record<string, unknown>, ...names: string[]): string | undefined {\n for (const name of names) {\n const value = args[name];\n if (typeof value === 'string' && value.length > 0) return value;\n }\n return undefined;\n}\n\nfunction countOutputLines(output: string | undefined): number {\n if (!output) return 0;\n return output.split('\\n').length;\n}\n\nfunction countNonEmptyOutputLines(output: string | undefined): number {\n if (!output) return 0;\n return output.split('\\n').filter((line) => line.trim().length > 0).length;\n}\n\nfunction outputSizeMetadata(result: ToolResult | undefined): string | undefined {\n if (!result?.content) return undefined;\n // Line count only. The byte size rode along on every row that produced any\n // output and told the reader nothing they would act on.\n const lines = countOutputLines(result.content);\n return `${lines} ${lines === 1 ? 'line' : 'lines'}`;\n}\n\nfunction statusFor(result: ToolResult | undefined, isPending: boolean): ToolPresentationStatus {\n if (isPending) return 'pending';\n if (!result) return 'running';\n if (result.status === 'blocked') return 'skipped';\n return result.status === 'success' ? 'success' : 'failure';\n}\n\nfunction resultStatusMetadata(status: ToolPresentationStatus): string | undefined {\n if (status === 'failure') return 'failed';\n if (status === 'skipped') return 'skipped';\n if (status === 'pending') return 'needs approval';\n return undefined;\n}\n\nfunction fileMutationPresentation(\n canonicalName: string,\n args: Record<string, unknown>,\n result: ToolResult | undefined,\n status: ToolPresentationStatus,\n): Pick<ToolPresentation, 'title' | 'target' | 'metadata' | 'previewType' | 'filePath'> {\n const filePath =\n result?.artifacts?.fileMutation?.filePath ??\n stringArg(args, 'filePath', 'file_path', 'notebook_path', 'path') ??\n getPrimaryArg(args);\n const action =\n result?.artifacts?.fileMutation?.kind === 'create'\n ? 'Create'\n : result?.artifacts?.fileMutation?.kind === 'delete'\n ? 'Delete'\n : 'Edit';\n const metadata: string[] = [];\n const mutation =\n result?.artifacts?.fileMutation ??\n (result?.status === 'success' && /^@@/m.test(result.content)\n ? {\n kind: 'update' as const,\n filePath,\n addedLines: result.content\n .split('\\n')\n .filter((line) => line.startsWith('+') && !line.startsWith('+++')).length,\n removedLines: result.content\n .split('\\n')\n .filter((line) => line.startsWith('-') && !line.startsWith('---')).length,\n }\n : undefined);\n if (result?.status === 'success' && mutation) {\n if (mutation.addedLines > 0) metadata.push(`+${mutation.addedLines}`);\n if (mutation.removedLines > 0) metadata.push(`-${mutation.removedLines}`);\n if (mutation.addedLines === 0 && mutation.removedLines === 0) metadata.push('no changes');\n } else {\n const statusLabel = resultStatusMetadata(status);\n if (statusLabel) metadata.push(statusLabel);\n }\n const previewType = result?.status === 'success' && /^@@/m.test(result.content) ? 'diff' : 'none';\n return {\n title: action,\n target: filePath,\n metadata,\n previewType,\n filePath,\n };\n}\n\nfunction readMetadata(args: Record<string, unknown>, result: ToolResult | undefined): string[] {\n return result?.status === 'success' ? readResultMetadata(args, result.content) : [];\n}\n\nfunction domainFor(value: string | undefined): string | undefined {\n if (!value) return undefined;\n try {\n return new URL(value).hostname || value;\n } catch {\n return value;\n }\n}\n\n/**\n * A TodoWrite row's columns: the step the call set in flight and where the plan\n * stands, `Reproduce the bug with a failing test 2 of 7 done`. Read from the\n * arguments, so the row says it while the call runs, and scrolling back reads\n * how the plan moved. A call that failed or was refused shows only its status:\n * its arguments are a plan that never happened.\n */\nfunction todoWriteColumns(\n args: Record<string, unknown>,\n status: ToolPresentationStatus,\n): { target: string | undefined; metadata: string[] } {\n if (status === 'failure' || status === 'skipped') return { target: undefined, metadata: [] };\n const todos = normalizePersistedTodos(\n Array.isArray(args.todos)\n ? (args.todos as Parameters<typeof normalizePersistedTodos>[0])\n : undefined,\n );\n return {\n target: todos.find((todo) => todo.status === 'in_progress')?.content,\n metadata: todos.length > 0 ? [stepProgress(todos)] : [],\n };\n}\n\n/** Derive all concise tool-row text without depending on Ink rendering. */\nexport function deriveToolPresentation(\n name: string,\n args: Record<string, unknown>,\n result?: ToolResult,\n options: ToolPresentationOptions = {},\n): ToolPresentation {\n const canonicalName = canonicalToolName(name);\n const status = statusFor(result, Boolean(options.isPending));\n // TodoWrite's row comes from its arguments, in both paths below.\n const todoColumns = canonicalName === 'TodoWrite' ? todoWriteColumns(args, status) : undefined;\n const primary = getPrimaryArg(args);\n const mcp = parseMcpToolName(name);\n let title = LABELS[canonicalName] ?? canonicalName;\n let target = primary || undefined;\n let metadata: string[] = [];\n let previewType: ToolPreviewType = result?.content ? 'text' : 'none';\n let filePath: string | undefined;\n\n if (result?.version === 2 && result.presentation) {\n const structured = result.presentation;\n target = structured.target ?? target;\n metadata = [...(structured.metadata ?? [])];\n if (todoColumns) ({ target, metadata } = todoColumns);\n previewType =\n structured.kind === 'diff'\n ? 'diff'\n : structured.kind === 'markdown' || structured.kind === 'search'\n ? 'markdown'\n : structured.details\n ? 'text'\n : 'none';\n const mutation = result.artifacts?.fileMutation;\n if (mutation) {\n title =\n mutation.kind === 'create' ? 'Create' : mutation.kind === 'delete' ? 'Delete' : 'Edit';\n filePath = mutation.filePath;\n target = mutation.filePath;\n }\n const statusMetadata = resultStatusMetadata(status);\n if (statusMetadata && !metadata.includes(statusMetadata)) metadata.unshift(statusMetadata);\n // Writing the plan down takes no time worth reading; `0ms` was only noise.\n const duration = todoColumns ? undefined : formatDuration(result.metrics?.durationMs);\n if (duration) metadata.push(duration);\n const retryAttempt = result.metrics?.retryAttempt;\n if (retryAttempt && retryAttempt > 1) metadata.push(`attempt ${retryAttempt}`);\n target = foldControlCharacters(target);\n const hasDetails = Boolean(structured.details);\n return {\n canonicalName,\n status,\n title,\n target,\n metadata,\n summary:\n todoColumns || !structured.summary\n ? `${title}${target ? `(${target})` : ''}`\n : structured.summary,\n previewType,\n hasDetails,\n hasHiddenContent: hasDetails,\n filePath,\n };\n }\n\n if (isFileMutatingTool(canonicalName)) {\n const mutation = fileMutationPresentation(canonicalName, args, result, status);\n title = mutation.title;\n target = mutation.target;\n metadata = mutation.metadata;\n previewType = mutation.previewType;\n filePath = mutation.filePath;\n } else if (canonicalName === 'Read') {\n target = stringArg(args, 'filePath', 'file_path', 'path') ?? target;\n metadata = readMetadata(args, result);\n } else if (canonicalName === 'Glob') {\n target = stringArg(args, 'pattern') ?? target;\n if (result?.status === 'success') {\n const files = /^(?:No files found|No matches found)$/i.test(result.content.trim())\n ? 0\n : countNonEmptyOutputLines(result.content.replace(/\\n\\.\\.\\. \\(truncated[\\s\\S]*$/, ''));\n metadata = [`${files} ${files === 1 ? 'file' : 'files'}`];\n }\n } else if (canonicalName === 'Grep') {\n target = stringArg(args, 'pattern') ?? target;\n if (result?.status === 'success') {\n // Grep counts from its own data, which the text cannot be counted back\n // into; only a result persisted by a build that did not have it needs the\n // text fallback (#311).\n const own = result.presentation?.metadata;\n metadata = own?.length ? [...own] : [grepResultMetadata(args, result.content)];\n }\n } else if (canonicalName === 'WebFetch') {\n target = domainFor(stringArg(args, 'url'));\n previewType = result?.content ? 'markdown' : 'none';\n } else if (canonicalName === 'WebSearch') {\n target = stringArg(args, 'query') ?? target;\n previewType = result?.content ? 'markdown' : 'none';\n } else if (canonicalName === 'AskUserQuestion') {\n // `Ask Fallback, Scope 2 questions`, not the tool's name and nothing else.\n const questions = Array.isArray(args.questions) ? (args.questions as unknown[]) : [];\n const headers = questions\n .map((question) =>\n question &&\n typeof question === 'object' &&\n typeof (question as { header?: unknown }).header === 'string'\n ? (question as { header: string }).header.trim()\n : '',\n )\n .filter(Boolean);\n target = headers.join(', ') || undefined;\n if (questions.length > 0) {\n metadata = [`${questions.length} ${questions.length === 1 ? 'question' : 'questions'}`];\n }\n } else if (canonicalName === 'ExitPlanMode') {\n // `Plan Fix the timeout fallback 3 steps`: the plan's own title, not its\n // raw markdown squeezed onto one line.\n const plan = stringArg(args, 'plan') ?? '';\n const lines = plan.split('\\n').map((line) => line.trim());\n const heading = lines.find((line) => /^#{1,6}\\s+\\S/.test(line))?.replace(/^#{1,6}\\s+/, '');\n target = heading ?? lines.find((line) => line.length > 0);\n const steps = lines.filter((line) => /^\\d+[.)]\\s/.test(line)).length;\n if (steps > 0) metadata = [`${steps} ${steps === 1 ? 'step' : 'steps'}`];\n } else if (todoColumns) {\n ({ target, metadata } = todoColumns);\n } else if (canonicalName === 'Task') {\n target = stringArg(args, 'agent', 'subject', 'description', 'prompt') ?? target;\n if ((options.nestedActivityCount ?? 0) > 0) {\n const count = options.nestedActivityCount ?? 0;\n metadata.push(`${count} ${count === 1 ? 'activity' : 'activities'}`);\n }\n } else if (mcp) {\n const groupCount = Number(args.__groupCount ?? 0);\n title =\n Number.isSafeInteger(groupCount) && groupCount > 1\n ? `Called ${mcp.server} ${groupCount} times`\n : `Called ${mcp.server}`;\n target = groupCount > 1 ? undefined : mcp.tool;\n previewType = result?.content ? 'markdown' : 'none';\n } else if (\n canonicalName === 'Bash' ||\n canonicalName.startsWith('Git') ||\n canonicalName === 'BashOutput'\n ) {\n const size = outputSizeMetadata(result);\n if (size) metadata.push(size);\n }\n\n const statusMetadata = resultStatusMetadata(status);\n if (statusMetadata && !metadata.includes(statusMetadata)) metadata.unshift(statusMetadata);\n // Writing the plan down takes no time worth reading; `0ms` was only noise.\n const duration = todoColumns ? undefined : formatDuration(result?.metrics?.durationMs);\n if (duration) metadata.push(duration);\n if (result?.metrics?.retryAttempt && result.metrics.retryAttempt > 1)\n metadata.push(`attempt ${result.metrics.retryAttempt}`);\n\n // A target is shown on one line, in the row and in the summary. A call whose\n // arguments were not valid JSON shows its raw text here, newlines and all — the\n // typed field's text now, the `{__raw}` sentinel's through `getPrimaryArg`.\n target = target || options.unparsedArguments?.raw;\n target = foldControlCharacters(target);\n const targetText = target ? `(${target})` : '';\n const metadataText = metadata.length > 0 ? ` · ${metadata.join(' ')}` : '';\n const summary = `${title}${targetText}${metadataText}`;\n const hasDetails = Boolean(result?.content);\n\n return {\n canonicalName,\n status,\n title,\n target,\n metadata,\n summary,\n previewType,\n hasDetails,\n hasHiddenContent: hasDetails,\n filePath,\n };\n}\n\nexport interface ToolExpansionPolicyInput {\n mode: TranscriptMode;\n toolId: string;\n automaticToolId?: string | null;\n defaultExpanded?: boolean;\n expansionOverrides: ReadonlyMap<string, boolean>;\n screenReader?: boolean;\n}\n\n/** Successful file mutations stay visible until the user explicitly collapses them. */\nexport function shouldDefaultExpandTool(name: string, result?: ToolResult): boolean {\n return isRenderableFileMutationDiff(name, result);\n}\n\n/** Centralized expansion policy shared by top-level and nested tool rows. */\nexport function shouldExpandTool({\n mode,\n toolId,\n automaticToolId,\n defaultExpanded = false,\n expansionOverrides,\n screenReader = false,\n}: ToolExpansionPolicyInput): boolean {\n if (screenReader) return true;\n const override = expansionOverrides.get(toolId);\n if (override !== undefined) return override;\n return mode === 'detailed' || automaticToolId === toolId || defaultExpanded;\n}\n\n/**\n * Widest a failure message may grow the metadata column.\n *\n * Long enough for the shell errors that actually occur — `'tail' is not\n * recognized as an internal or external command` is 57 — without letting a\n * pathological message crowd out the target it failed on.\n */\nconst ERROR_META_MAX = 64;\n\n/** MCP rows are titled `Called <server>` by {@link deriveToolPresentation}. */\nconst MCP_TITLE_PREFIX = 'Called ';\n\n/** `+12` / `-3`: churn counts that belong together as one figure. */\nconst CHURN = /^[+-]\\d+$/;\n\n/**\n * Join metadata parts with `·`, except adjacent churn counts, which join with a\n * space so `+3 -2` reads as one number rather than two facts.\n */\nfunction joinMetadata(parts: readonly string[]): string {\n return parts.reduce((joined, part, index) => {\n if (index === 0) return part;\n const separator = CHURN.test(part) && CHURN.test(parts[index - 1]!) ? ' ' : ' · ';\n return `${joined}${separator}${part}`;\n }, '');\n}\n\n/**\n * Shorten a presentation title for the aligned label column.\n *\n * An MCP row's title reads `Called <server>`; inside the column the verb is\n * redundant and the server name is what the reader scans for.\n */\nexport function shortLabel(title: string): string {\n const stripped = title.startsWith(MCP_TITLE_PREFIX)\n ? title.slice(MCP_TITLE_PREFIX.length)\n : title;\n return SHORT_LABELS[stripped] ?? stripped;\n}\n\n/**\n * The label a row will show, derived without scanning result content.\n *\n * Callers measuring a column across many rows must not pay for a full\n * {@link deriveToolPresentation} per row: that regex-scans result bodies, which\n * is real cost on a multi-megabyte tool result. This reads only the cheap\n * fields and is allowed to be wrong — an under-measured column costs one row\n * its alignment, never its content.\n */\nexport function toolRowLabel(name: string, result?: ToolResult): string {\n const mutation = result?.artifacts?.fileMutation;\n if (mutation) {\n return mutation.kind === 'create' ? 'Create' : mutation.kind === 'delete' ? 'Delete' : 'Edit';\n }\n const mcp = parseMcpToolName(name);\n if (mcp) return mcp.server;\n const canonical = canonicalToolName(name);\n return shortLabel(LABELS[canonical] ?? canonical);\n}\n\n/**\n * Standard label-column widths.\n *\n * Nearly every verb is four (`Read`, `Bash`, `Grep`, `Edit`) or six (`Create`,\n * `Delete`); snapping to these means two turns in a row almost always land on\n * the same column, which exact per-turn sizing did not.\n */\nconst LABEL_COLUMN_STEPS = [4, 6, LABEL_COLUMN_WIDTH] as const;\n\n/** Widest standard label column a run of rows needs, in columns. */\nexport function toolLabelColumnWidth(labels: readonly string[]): number {\n const widest = labels.reduce((max, label) => Math.max(max, displayWidth(label)), 1);\n return LABEL_COLUMN_STEPS.find((step) => step >= widest) ?? LABEL_COLUMN_WIDTH;\n}\n\n/** Labels short enough for the aligned row's fixed label column. */\nconst SHORT_LABELS: Record<string, string> = {\n 'Apply patch': 'Patch',\n 'Edit notebook': 'Notebook',\n 'Shell output': 'Shell',\n};\n\n/** The three aligned columns of a tool row, already padded to the grid. */\nexport interface ToolRowColumns {\n /** Verb, padded to the grid's label column. Empty when labels are inline. */\n label: string;\n /** What the tool acted on, truncated to fit. */\n target: string;\n /** Spaces that push `meta` flush against the right edge. */\n gap: string;\n /** Right-aligned result metadata, or the error message on a failure. */\n meta: string;\n}\n\n/**\n * Lay a tool row out as `[label][target] … [meta]`.\n *\n * The label and meta columns are fixed so the eye can scan straight down a\n * column of rows; only the target flexes. Below the grid's label threshold the\n * label column collapses and the verb runs inline, because a fixed column would\n * leave nothing for the path.\n */\nexport function composeToolRow(\n presentation: Pick<ToolPresentation, 'title' | 'target' | 'metadata'>,\n grid: TranscriptGrid,\n extra: { elapsed?: string; error?: string } = {},\n): ToolRowColumns {\n const title = shortLabel(presentation.title);\n // Never truncate the verb. A row whose label does not fit the column runs\n // inline instead: `Read sr…` is unreadable in a way `Read src/a.ts` is not.\n const useLabelColumn = grid.label > 0 && displayWidth(title) <= grid.label;\n // Both strings reaching the layout are someone else's: the target is a\n // tool argument, and the error is the model's own or a tool's — it may hold a\n // newline, an ESC, or a bidi override, none of which survive a one-line row.\n const error = foldControlCharacters(extra.error);\n const metaSource = error\n ? [error]\n : [...presentation.metadata, ...(extra.elapsed ? [extra.elapsed] : [])];\n\n const label = useLabelColumn ? title.padEnd(grid.label) : '';\n const labelWidth = useLabelColumn ? grid.label + 1 : 0;\n const inlinePrefix = useLabelColumn || !title ? '' : `${title} `;\n\n // Aligned rows lay out inside the grid's bounded row measure even when the\n // prose around them takes the whole terminal. Right-aligning `67ms` against\n // column 197 does not align it with the command it timed -- it just puts it\n // far away, with a gap of pure padding rebuilt on every streamed frame in\n // between. The bound lives on the grid so it narrows with nesting.\n const measure = grid.row;\n\n // An error message outranks the target it failed on, so a failing row takes\n // as much as the message needs — capped, and never so much that the target\n // drops below a width worth reading.\n const metaBudget = error\n ? Math.max(\n grid.meta,\n Math.min(\n ERROR_META_MAX,\n measure - labelWidth - displayWidth(inlinePrefix) - MIN_TARGET_WIDTH - 1,\n ),\n )\n : grid.meta;\n const meta = metaBudget > 0 ? truncateDisplay(joinMetadata(metaSource), metaBudget) : '';\n\n const metaWidth = displayWidth(meta);\n // The budget covers the whole truncated string, prefix included — subtracting\n // the prefix here as well clipped an inline-label row by exactly the width of\n // its own verb, and `gap` then padded those columns back with spaces.\n const targetBudget = Math.max(4, measure - labelWidth - metaWidth - (metaWidth > 0 ? 1 : 0));\n const target = truncateDisplay(\n `${inlinePrefix}${foldControlCharacters(presentation.target) ?? ''}`,\n targetBudget,\n );\n\n const used = labelWidth + displayWidth(target) + metaWidth;\n const gap = ' '.repeat(Math.max(metaWidth > 0 ? 1 : 0, measure - used));\n return { label, target, gap, meta };\n}\n","import { Text } from 'ink';\nimport type { AgentSummary } from '../../agents/types.js';\nimport { useTheme } from '../theme.js';\nimport { truncateDisplay } from './word-wrap.js';\nimport { useUiClock } from '../ui-clock.js';\n\nfunction statusGlyph(status: AgentSummary['status'], reducedMotion: boolean): string {\n if (status === 'completed') return '✓';\n if (status === 'failed') return '✕';\n if (status === 'stopped' || status === 'interrupted') return '■';\n if (status === 'waiting_input' || status === 'waiting_permission') return '?';\n return reducedMotion ? '*' : '●';\n}\n\nfunction terminalActivity(agent: AgentSummary): string {\n if (agent.status === 'completed') return agent.summary?.split(/\\r?\\n/, 1)[0] ?? 'Completed';\n if (agent.status === 'failed') return agent.error?.split(/\\r?\\n/, 1)[0] ?? 'Failed';\n if (agent.status === 'stopped') return 'Stopped';\n if (agent.status === 'interrupted') return 'Interrupted';\n return agent.currentActivity?.label ?? agent.status.replace('_', ' ');\n}\n\nexport function formatElapsedDuration(totalSeconds: number): string {\n const seconds = Math.max(0, Math.floor(totalSeconds));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${minutes % 60}m ${remainingSeconds}s`;\n}\n\nfunction useCurrentTime(active: boolean, fixedNow?: number): number {\n const tick = useUiClock('slow', active && fixedNow === undefined);\n void tick;\n return fixedNow ?? Date.now();\n}\n\nexport function SubagentRow({\n agent,\n selected = false,\n width = 80,\n reducedMotion = false,\n screenReader = false,\n now,\n}: {\n agent: AgentSummary;\n selected?: boolean;\n width?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n now?: number;\n}) {\n const theme = useTheme();\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(agent.status);\n const currentTime = useCurrentTime(!terminal, now);\n const activity = terminal\n ? terminalActivity(agent)\n : (agent.currentActivity?.label ?? agent.status.replace('_', ' '));\n const elapsed = Math.max(\n 0,\n Math.floor(((agent.finishedAt ?? currentTime) - (agent.startedAt ?? agent.createdAt)) / 1000),\n );\n const color =\n agent.status === 'failed'\n ? theme.error\n : agent.status === 'completed'\n ? theme.success\n : agent.status === 'waiting_input' || agent.status === 'waiting_permission'\n ? theme.warning\n : theme.brand;\n\n if (screenReader) {\n return (\n <Text>\n {agent.displayName}. {agent.profile}. {agent.resolvedModel}. {agent.status}. {activity}.\n </Text>\n );\n }\n\n const elapsedLabel = formatElapsedDuration(elapsed);\n const elapsedSuffix = ` | ${elapsedLabel}`;\n const displayNameWidth = Math.max(1, width - 8 - elapsedSuffix.length);\n return (\n <Text color={selected ? theme.text : color} bold={selected}>\n {selected ? '› ' : ' '}\n {statusGlyph(agent.status, reducedMotion)}{' '}\n {truncateDisplay(agent.displayName, displayNameWidth)}\n <Text color={theme.subtle}>{elapsedSuffix}</Text>\n </Text>\n );\n}\n","import { createContext, useContext, type RefObject } from 'react';\nimport type { DOMElement } from 'ink';\n\nexport interface ToolSummaryRowRegistration {\n id: string;\n element: RefObject<DOMElement | null>;\n expandable: boolean;\n expanded: boolean;\n}\n\nexport interface ToolRowInteractionRegistry {\n register: (registration: ToolSummaryRowRegistration) => () => void;\n}\n\nexport const ToolRowInteractionContext = createContext<ToolRowInteractionRegistry | null>(null);\n\nexport function useToolRowInteractionRegistry(): ToolRowInteractionRegistry | null {\n return useContext(ToolRowInteractionContext);\n}\n","/* Hallmark · component: command instrument panel · genre: modern-minimal · theme: existing TUI\n * states: default · narrow · empty · warning · reduced-motion · screen-reader\n * contrast: pass (40–41; inherited from ThemeTokens)\n * Hallmark · pre-emit critique: P5 H5 E4 S5 R5 V5\n */\nimport { Box, Text } from 'ink';\nimport { useMemo } from 'react';\nimport type {\n ConfigCommandDisplay,\n ContextCommandDisplay,\n LocalCommandDisplay,\n UsageCommandDisplay,\n} from '../../types/messages.js';\nimport { useStaggeredReveal } from '../hooks/useAnimation.js';\nimport { panelGrid, sheetContentWidth } from '../layout.js';\nimport { SECTION_SIGN } from '../marks.js';\nimport { useTheme } from '../theme.js';\nimport { SheetRule } from './chrome.js';\nimport { failureTotal, formatFailureCounts, trafficTokens } from '../../pricing.js';\nimport { sourceLabel } from '../../context-report.js';\nimport { padDisplay, truncateDisplay, wordWrap } from './word-wrap.js';\n\ninterface CommandPanelProps {\n display: LocalCommandDisplay;\n fallback: string;\n terminalWidth?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n}\n\ninterface ConfigEntry {\n path: string;\n value: string;\n}\n\ninterface Metric {\n label: string;\n value: string;\n color?: string;\n}\n\nconst REVEAL_STEPS = 10;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction compactNumber(value: number): string {\n const absolute = Math.abs(value);\n if (absolute >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(absolute >= 10_000_000 ? 0 : 1)}m`;\n }\n if (absolute >= 1_000) {\n return `${(value / 1_000).toFixed(absolute >= 100_000 ? 0 : 1)}k`;\n }\n return value.toLocaleString();\n}\n\nfunction formatDuration(durationMs: number): string {\n if (durationMs <= 0) return '—';\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`;\n return `${(durationMs / 1000).toFixed(durationMs >= 10_000 ? 0 : 1)}s`;\n}\n\nfunction formatConfigValue(value: unknown): string {\n if (value === undefined) return '—';\n if (value === null) return 'null';\n if (typeof value === 'string') return value || '(empty)';\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n\nfunction flattenConfigValue(\n value: unknown,\n path: string,\n entries: ConfigEntry[],\n depth: number,\n): void {\n if (depth > 7) {\n entries.push({ path, value: formatConfigValue(value) });\n return;\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n entries.push({ path, value: '[]' });\n return;\n }\n if (value.every((item) => item === null || typeof item !== 'object')) {\n entries.push({ path, value: value.map(formatConfigValue).join(', ') });\n return;\n }\n value.forEach((item, index) => {\n flattenConfigValue(item, `${path}[${index}]`, entries, depth + 1);\n });\n return;\n }\n\n if (value && typeof value === 'object') {\n const objectEntries = Object.entries(value as Record<string, unknown>);\n if (objectEntries.length === 0) {\n entries.push({ path, value: '{}' });\n return;\n }\n for (const [key, nested] of objectEntries) {\n flattenConfigValue(nested, path ? `${path}.${key}` : key, entries, depth + 1);\n }\n return;\n }\n\n entries.push({ path, value: formatConfigValue(value) });\n}\n\nexport function flattenConfigSnapshot(snapshot: Record<string, unknown>): ConfigEntry[] {\n const entries: ConfigEntry[] = [];\n for (const [key, value] of Object.entries(snapshot)) {\n flattenConfigValue(value, key, entries, 0);\n }\n return entries;\n}\n\nfunction revealProgress(step: number, startAt = 1): number {\n return clamp((step - startAt) / Math.max(1, REVEAL_STEPS - startAt), 0, 1);\n}\n\nfunction PanelHeader({\n command,\n title,\n subtitle,\n width,\n step,\n}: {\n command: string;\n title: string;\n subtitle: string;\n width: number;\n step: number;\n}) {\n const theme = useTheme();\n const ready = step >= REVEAL_STEPS;\n // The same head as every other reference panel: a rule led by a section sign.\n // The note names the command that printed it (this is a transcript entry, not\n // an overlay Esc could close) once the figures have finished arriving.\n return (\n <Box flexDirection=\"column\">\n <SheetRule\n mark={SECTION_SIGN}\n label={title}\n tone={theme.text}\n meta={ready ? command : 'reading…'}\n width={width}\n />\n <Box paddingX={2}>\n <Text color={theme.inactive}>{truncateDisplay(subtitle, sheetContentWidth(width))}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction MetricGrid({\n metrics,\n contentWidth,\n narrow,\n illuminated,\n}: {\n metrics: Metric[];\n contentWidth: number;\n narrow: boolean;\n illuminated: boolean;\n}) {\n const theme = useTheme();\n\n if (narrow) {\n const labelWidth = Math.min(12, Math.max(8, Math.floor(contentWidth * 0.34)));\n const valueWidth = Math.max(8, contentWidth - labelWidth - 1);\n return (\n <Box flexDirection=\"column\">\n {metrics.map((metric) => (\n <Box key={metric.label} flexWrap=\"nowrap\">\n <Text color={theme.subtle} dimColor>\n {padDisplay(metric.label, labelWidth)}\n </Text>\n <Text color={illuminated ? (metric.color ?? theme.text) : theme.subtle} bold>\n {truncateDisplay(metric.value, valueWidth)}\n </Text>\n </Box>\n ))}\n </Box>\n );\n }\n\n const columnWidth = Math.max(10, Math.floor(contentWidth / metrics.length));\n return (\n <Box flexDirection=\"row\" flexWrap=\"nowrap\">\n {metrics.map((metric) => (\n <Box key={metric.label} width={columnWidth} flexDirection=\"column\">\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(metric.label, columnWidth - 1)}\n </Text>\n <Text color={illuminated ? (metric.color ?? theme.text) : theme.subtle} bold>\n {truncateDisplay(metric.value, columnWidth - 1)}\n </Text>\n </Box>\n ))}\n </Box>\n );\n}\n\nfunction Meter({\n fraction,\n width,\n progress,\n color,\n}: {\n fraction: number;\n width: number;\n progress: number;\n color: string;\n}) {\n const theme = useTheme();\n const safeWidth = Math.max(5, width);\n const target = Math.round(clamp(fraction, 0, 1) * safeWidth);\n const filled = Math.round(target * clamp(progress, 0, 1));\n\n return (\n <Box flexWrap=\"nowrap\">\n <Text color={color}>{'•'.repeat(filled)}</Text>\n <Text color={theme.subtle} dimColor>\n {'·'.repeat(Math.max(0, safeWidth - filled))}\n </Text>\n </Box>\n );\n}\n\nfunction StackedUsageMeter({\n promptTokens,\n cacheTokens,\n completionTokens,\n totalTokens,\n width,\n progress,\n}: {\n promptTokens: number;\n cacheTokens: number;\n completionTokens: number;\n totalTokens: number;\n width: number;\n progress: number;\n}) {\n const theme = useTheme();\n const safeWidth = Math.max(8, width);\n const safeTotal = Math.max(1, totalTokens, promptTokens + cacheTokens + completionTokens);\n const promptTarget = Math.round((promptTokens / safeTotal) * safeWidth);\n const cacheTarget = Math.min(\n safeWidth - promptTarget,\n Math.round((cacheTokens / safeTotal) * safeWidth),\n );\n const completionTarget = Math.min(\n safeWidth - promptTarget - cacheTarget,\n Math.round((completionTokens / safeTotal) * safeWidth),\n );\n const promptFilled = Math.round(promptTarget * progress);\n const cacheFilled = Math.round(cacheTarget * progress);\n const completionFilled = Math.round(completionTarget * progress);\n const remainder = Math.max(0, safeWidth - promptFilled - cacheFilled - completionFilled);\n\n return (\n <Box flexWrap=\"nowrap\">\n <Text color={theme.usageMeter}>{'•'.repeat(promptFilled)}</Text>\n <Text color={theme.subtle}>{'•'.repeat(cacheFilled)}</Text>\n <Text color={theme.success}>{'•'.repeat(completionFilled)}</Text>\n <Text color={theme.subtle} dimColor>\n {'·'.repeat(remainder)}\n </Text>\n </Box>\n );\n}\n\nfunction SectionLabel({ children }: { children: string }) {\n const theme = useTheme();\n return (\n <Text color={theme.subtle} dimColor>\n {children}\n </Text>\n );\n}\n\nfunction ConfigPanelBody({\n data,\n contentWidth,\n narrow,\n step,\n}: {\n data: ConfigCommandDisplay;\n contentWidth: number;\n narrow: boolean;\n step: number;\n}) {\n const theme = useTheme();\n const entries = useMemo(() => flattenConfigSnapshot(data.snapshot), [data.snapshot]);\n const groups = useMemo(() => {\n const counts = new Map<string, number>();\n for (const entry of entries) {\n const dotIndex = entry.path.indexOf('.');\n const bracketIndex = entry.path.indexOf('[');\n const boundaries = [dotIndex, bracketIndex].filter((index) => index >= 0);\n const boundary = boundaries.length > 0 ? Math.min(...boundaries) : entry.path.length;\n const group = entry.path.slice(0, boundary) || 'root';\n counts.set(group, (counts.get(group) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, narrow ? 3 : 5);\n }, [entries, narrow]);\n const maxGroup = Math.max(1, ...groups.map(([, count]) => count));\n const labelWidth = narrow ? Math.min(16, Math.floor(contentWidth * 0.42)) : 24;\n const valueWidth = Math.max(8, contentWidth - labelWidth - 1);\n const barWidth = Math.max(8, Math.min(narrow ? 16 : 28, contentWidth - 18));\n const progress = revealProgress(step, 2);\n const metrics: Metric[] = [\n { label: 'Model', value: data.runtime.model, color: theme.usageMeter },\n { label: 'Provider', value: data.runtime.provider },\n { label: 'Mode', value: data.runtime.mode },\n { label: 'Budget', value: compactNumber(data.runtime.maxTokens) },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <MetricGrid\n metrics={metrics}\n contentWidth={contentWidth}\n narrow={narrow}\n illuminated={step >= 3}\n />\n <Box flexDirection=\"column\">\n <SectionLabel>configuration signal map</SectionLabel>\n {groups.map(([group, count], index) => (\n <Box key={group} flexWrap=\"nowrap\">\n <Text color={step >= 4 + index ? theme.text : theme.subtle}>\n {padDisplay(group, Math.min(14, Math.max(8, contentWidth - barWidth - 5)))}\n </Text>\n <Text> </Text>\n <Meter\n fraction={count / maxGroup}\n width={barWidth}\n progress={progress}\n color={index === 0 ? theme.usageMeter : theme.subtle}\n />\n <Text color={theme.subtle}> {count}</Text>\n </Box>\n ))}\n </Box>\n <Box flexDirection=\"column\">\n <SectionLabel>resolved values</SectionLabel>\n {entries.map((entry, index) => {\n const active = step >= Math.min(REVEAL_STEPS, 5 + (index % 4));\n const wrappedValue = wordWrap(entry.value, valueWidth);\n return narrow ? (\n <Box key={`${entry.path}-${index}`} flexDirection=\"column\">\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(entry.path, contentWidth)}\n </Text>\n <Text color={active ? theme.text : theme.subtle}>{wrappedValue}</Text>\n </Box>\n ) : (\n <Box key={`${entry.path}-${index}`} flexDirection=\"row\">\n <Text color={theme.subtle} dimColor>\n {padDisplay(entry.path, labelWidth)}\n </Text>\n <Text> </Text>\n <Box width={valueWidth}>\n <Text color={active ? theme.text : theme.subtle}>{wrappedValue}</Text>\n </Box>\n </Box>\n );\n })}\n </Box>\n <Text color={theme.subtle} dimColor>\n {entries.length} resolved fields · sensitive provider values redacted\n </Text>\n </Box>\n );\n}\n\nfunction ContextPanelBody({\n data,\n contentWidth,\n narrow,\n step,\n}: {\n data: ContextCommandDisplay;\n contentWidth: number;\n narrow: boolean;\n step: number;\n}) {\n const theme = useTheme();\n const usageFraction = data.maxTokens > 0 ? data.estimatedTokens / data.maxTokens : 0;\n const percent = Math.round(clamp(usageFraction, 0, 1) * 100);\n const meterColor = percent >= 95 ? theme.error : percent >= 80 ? theme.warning : theme.usageMeter;\n const roleTotal = Math.max(1, data.userTokens + data.assistantTokens);\n const meterWidth = Math.max(8, contentWidth - (narrow ? 18 : 24));\n const windowSource = sourceLabel(data.windowSource, data.windowDeclared);\n const metrics: Metric[] = [\n {\n label: 'Window',\n value:\n windowSource && windowSource !== 'declared'\n ? `${compactNumber(data.maxTokens)} (${windowSource})`\n : compactNumber(data.maxTokens),\n color: theme.usageMeter,\n },\n { label: 'Estimate', value: compactNumber(data.estimatedTokens) },\n { label: 'Messages', value: String(data.totalMessages) },\n { label: 'Tools', value: `${data.toolCalls}/${data.toolResults}` },\n ];\n const ambient = [\n `commands ${data.ambient.commandCount}`,\n data.ambient.skillCount === undefined ? null : `skills ${data.ambient.skillCount}`,\n data.ambient.subagentCount === undefined ? null : `agents ${data.ambient.subagentCount}`,\n `memory ${data.ambient.hasMemoryIndex ? 'loaded' : 'none'}`,\n `rules ${data.ambient.hasClaudeMdLoader ? 'loaded' : 'none'}`,\n ].filter((item): item is string => Boolean(item));\n\n return (\n <Box flexDirection=\"column\">\n <MetricGrid\n metrics={metrics}\n contentWidth={contentWidth}\n narrow={narrow}\n illuminated={step >= 3}\n />\n <Box flexDirection=\"column\">\n <Box justifyContent=\"space-between\">\n <SectionLabel>conversation pressure</SectionLabel>\n <Text bold color={meterColor}>\n {percent}%\n </Text>\n </Box>\n <Meter\n fraction={usageFraction}\n width={contentWidth}\n progress={revealProgress(step, 2)}\n color={meterColor}\n />\n <Text color={theme.subtle} dimColor>\n {compactNumber(data.estimatedTokens)} estimated / {compactNumber(data.maxTokens)} tokens\n </Text>\n </Box>\n <Box flexDirection=\"column\">\n <SectionLabel>role split</SectionLabel>\n <Box flexWrap=\"nowrap\">\n <Text>{padDisplay('user', narrow ? 10 : 12)}</Text>\n <Meter\n fraction={data.userTokens / roleTotal}\n width={meterWidth}\n progress={revealProgress(step, 4)}\n color={theme.subtle}\n />\n <Text color={theme.subtle}> {compactNumber(data.userTokens)}</Text>\n </Box>\n <Box flexWrap=\"nowrap\">\n <Text>{padDisplay('assistant', narrow ? 10 : 12)}</Text>\n <Meter\n fraction={data.assistantTokens / roleTotal}\n width={meterWidth}\n progress={revealProgress(step, 5)}\n color={theme.success}\n />\n <Text color={theme.subtle}> {compactNumber(data.assistantTokens)}</Text>\n </Box>\n </Box>\n <Box flexDirection=\"column\">\n <SectionLabel>ambient context injected each turn</SectionLabel>\n <Text color={step >= 8 ? theme.text : theme.subtle}>{ambient.join(' · ')}</Text>\n </Box>\n <Text color={theme.subtle} dimColor>\n Estimate uses chars/4; provider usage remains authoritative.\n </Text>\n </Box>\n );\n}\n\nfunction UsagePanelBody({\n data,\n contentWidth,\n narrow,\n step,\n}: {\n data: UsageCommandDisplay;\n contentWidth: number;\n narrow: boolean;\n step: number;\n}) {\n const theme = useTheme();\n const usage = data.usage;\n const delegated = data.delegatedAgents ?? 0;\n const cacheRead = usage?.cacheReadInputTokens ?? 0;\n const cacheWrite = usage?.cacheCreationInputTokens ?? 0;\n const metrics: Metric[] = [\n { label: 'Turn', value: String(data.currentTurn), color: theme.usageMeter },\n { label: 'Messages', value: String(data.messageCount) },\n { label: 'Latency', value: formatDuration(data.turnDurationMs) },\n {\n label: 'Est. cost',\n value: data.estimatedCostUsd === undefined ? '—' : `$${data.estimatedCostUsd.toFixed(4)}`,\n color: data.estimatedCostUsd === undefined ? theme.subtle : theme.success,\n },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <MetricGrid\n metrics={metrics}\n contentWidth={contentWidth}\n narrow={narrow}\n illuminated={step >= 3}\n />\n {usage ? (\n <>\n <Box flexDirection=\"column\">\n <Box justifyContent=\"space-between\">\n <SectionLabel>token traffic</SectionLabel>\n <Text bold color={theme.usageMeter}>\n {trafficTokens(usage).toLocaleString()}\n </Text>\n </Box>\n <StackedUsageMeter\n promptTokens={usage.promptTokens}\n cacheTokens={cacheRead + cacheWrite}\n completionTokens={usage.completionTokens}\n totalTokens={trafficTokens(usage)}\n width={contentWidth}\n progress={revealProgress(step, 2)}\n />\n <Box flexDirection={narrow ? 'column' : 'row'} justifyContent=\"space-between\">\n <Text color={theme.usageMeter}>• input {usage.promptTokens.toLocaleString()}</Text>\n <Text color={theme.success}>• output {usage.completionTokens.toLocaleString()}</Text>\n {cacheRead + cacheWrite > 0 ? (\n <Text color={theme.subtle}>\n {`• cache ${[\n cacheRead > 0 ? cacheRead.toLocaleString() : '',\n cacheWrite > 0 ? `${cacheWrite.toLocaleString()} written` : '',\n ]\n .filter(Boolean)\n .join(' · ')}`}\n </Text>\n ) : null}\n </Box>\n </Box>\n <Box flexDirection=\"column\">\n <SectionLabel>active model</SectionLabel>\n <Text color={step >= 8 ? theme.text : theme.subtle}>{data.model}</Text>\n <Text color={theme.subtle} dimColor>\n {data.rate\n ? `$${data.rate.inputPerMillion}/M input · $${data.rate.outputPerMillion}/M output`\n : 'Pricing is not configured for this model.'}\n </Text>\n </Box>\n {delegated ? (\n <Text color={theme.subtle}>\n {`incl. ${delegated} delegated agent${delegated === 1 ? '' : 's'}`}\n </Text>\n ) : null}\n </>\n ) : (\n <Box flexDirection=\"column\">\n <SectionLabel>token traffic</SectionLabel>\n <Meter fraction={0} width={contentWidth} progress={1} color={theme.usageMeter} />\n <Text color={theme.subtle}>No model response recorded in this session yet.</Text>\n </Box>\n )}\n {data.toolCallStats && data.toolCallStats.length > 0 ? (\n <Box flexDirection=\"column\">\n <SectionLabel>tool calls</SectionLabel>\n <Text color={theme.subtle}>\n {`${data.toolCallStats.reduce((sum, entry) => sum + entry.calls, 0)} total`}\n {(() => {\n const failed = data.toolCallStats.reduce(\n (sum, entry) => sum + failureTotal(entry.failures),\n 0,\n );\n return failed > 0 ? ` · ${failed} failed` : '';\n })()}\n {data.toolCallStats.length > 8\n ? ` · showing 8 of ${data.toolCallStats.length} tools`\n : ''}\n </Text>\n {data.toolCallStats.slice(0, 8).map((entry) => {\n const failed = failureTotal(entry.failures);\n return (\n <Box key={entry.tool} flexWrap=\"nowrap\">\n <Text color={step >= 8 ? theme.text : theme.subtle}>\n {padDisplay(entry.tool, narrow ? 12 : 16)}\n {String(entry.calls)}\n </Text>\n {failed > 0 ? (\n <Text color={theme.error}> · {formatFailureCounts(entry.failures)}</Text>\n ) : null}\n </Box>\n );\n })}\n </Box>\n ) : null}\n <Text color={theme.subtle} dimColor>\n {delegated\n ? 'Cost is a local estimate across every model this session ran on, not a billing statement.'\n : 'Cost is a local estimate for the active model, not a billing statement.'}\n </Text>\n </Box>\n );\n}\n\nexport function CommandPanel({\n display,\n fallback,\n terminalWidth = 80,\n reducedMotion = false,\n screenReader = false,\n}: CommandPanelProps) {\n const motionDisabled = reducedMotion || screenReader;\n const step = useStaggeredReveal(REVEAL_STEPS, true, 55, motionDisabled);\n\n if (screenReader) {\n return (\n <Box marginLeft={0} flexDirection=\"column\">\n <Text>{fallback}</Text>\n </Box>\n );\n }\n\n // The sheet sits on the panel grid like /help and /status; its rule spans the\n // sheet and the figures sit two columns in from either end.\n const panelWidth = Math.max(28, Math.min(100, panelGrid(terminalWidth).width));\n const contentWidth = sheetContentWidth(panelWidth, 18);\n const narrow = panelWidth < 58;\n const header =\n display.kind === 'config'\n ? {\n command: '/config',\n title: 'Runtime map',\n subtitle: `${display.runtime.provider} · ${display.runtime.workspace}`,\n }\n : display.kind === 'context'\n ? {\n command: '/context',\n title: 'Context',\n subtitle: `${display.model} · estimated conversation load before ambient injection`,\n }\n : {\n command: '/usage',\n title: 'Usage',\n subtitle: `${display.model} · cumulative provider-reported activity`,\n };\n\n return (\n // No top margin of its own: ChatPanel spaces every slash-command entry.\n <Box width={panelWidth} flexDirection=\"column\">\n <PanelHeader {...header} width={panelWidth} step={step} />\n <Box flexDirection=\"column\" paddingX={2} marginTop={1}>\n {display.kind === 'config' ? (\n <ConfigPanelBody data={display} contentWidth={contentWidth} narrow={narrow} step={step} />\n ) : display.kind === 'context' ? (\n <ContextPanelBody\n data={display}\n contentWidth={contentWidth}\n narrow={narrow}\n step={step}\n />\n ) : (\n <UsagePanelBody data={display} contentWidth={contentWidth} narrow={narrow} step={step} />\n )}\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useTheme } from '../theme.js';\nimport { panelGrid } from '../layout.js';\nimport { PILCROW, SECTION_SIGN } from '../marks.js';\nimport { displayWidth, padDisplay, truncateDisplay } from './word-wrap.js';\n\nexport type PanelTone = 'neutral' | 'brand' | 'permission' | 'plan' | 'error';\n\nfunction toneColor(tone: PanelTone, theme: ReturnType<typeof useTheme>): string {\n switch (tone) {\n case 'brand':\n return theme.brand;\n case 'permission':\n return theme.permission;\n case 'plan':\n return theme.planMode;\n case 'error':\n return theme.error;\n default:\n return theme.border;\n }\n}\n\n/**\n * A reference surface (a picker, a settings list, a panel of facts), set under\n * a rule instead of inside a box.\n *\n * `─ § Settings ───────────────────────────────── Esc to close ─`\n *\n * The section sign marks it as something to consult; the pilcrow of a\n * {@link DecisionSheet} marks something that waits on you. With no `title` the\n * rule is a bare hairline. Either way there are no walls: one extra column of\n * padding stands in for each, so callers that size rows as `width - 4` keep the\n * geometry they had inside the box.\n *\n * `attached` draws the panel as part of the composer right below it (the\n * command and mention menus), so it takes no row of air above.\n */\nexport function SoftPanel({\n children,\n tone = 'neutral',\n width,\n marginX = 0,\n paddingX = 1,\n attached = false,\n title,\n meta,\n}: {\n children: ReactNode;\n tone?: PanelTone;\n width?: number;\n marginX?: number;\n paddingX?: number;\n attached?: boolean;\n /** Set in the rule after a section sign. */\n title?: string;\n /** A short note at the rule's right end. */\n meta?: string;\n}) {\n const theme = useTheme();\n const labelTone = tone === 'neutral' || tone === 'brand' ? theme.text : toneColor(tone, theme);\n if (title && width !== undefined) {\n return (\n <Box flexDirection=\"column\" width={width} marginX={marginX} marginTop={attached ? 0 : 1}>\n <SheetRule mark={SECTION_SIGN} label={title} tone={labelTone} meta={meta} width={width} />\n <Box flexDirection=\"column\" paddingX={paddingX + 1}>\n {children}\n </Box>\n </Box>\n );\n }\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderLeft={false}\n borderRight={false}\n borderBottom={false}\n borderColor={theme.border}\n paddingX={paddingX + 1}\n width={width}\n marginX={marginX}\n marginTop={attached ? 0 : 1}\n >\n {title ? (\n <Text bold color={labelTone}>\n {title}\n </Text>\n ) : null}\n {children}\n </Box>\n );\n}\n\n/**\n * One row of a list the cursor moves through. The selected row is bold and\n * bright, and the caller's own `›` marks it; there is no highlight bar behind\n * it, which made every picker look like a menu from another program.\n */\nexport function SelectionRow({\n selected,\n children,\n width,\n}: {\n selected: boolean;\n children: ReactNode;\n width?: number;\n}) {\n const theme = useTheme();\n return (\n <Box width={width}>\n <Text color={selected ? theme.selectionText : theme.text} bold={selected}>\n {children}\n </Text>\n </Box>\n );\n}\n\n/**\n * One row of a composer menu (`@file`, `$skill`): a steady rubric `›` on the\n * selected row, the name in ink and bold when selected, a quiet badge, and the\n * description a step quieter, cut to fit. The command menu composes its own\n * rows, since it aligns a name column and shows syntax, but draws them alike.\n */\nexport function MenuRow({\n selected,\n name,\n badge = '',\n desc = '',\n width,\n screenReader = false,\n}: {\n selected: boolean;\n name: string;\n badge?: string;\n desc?: string;\n width: number;\n screenReader?: boolean;\n}) {\n const theme = useTheme();\n const marker = screenReader ? (selected ? 'selected ' : '') : selected ? '› ' : ' ';\n const shownName = truncateDisplay(\n name,\n Math.max(1, width - displayWidth(marker) - displayWidth(badge)),\n );\n const room = width - displayWidth(marker + shownName + badge) - 2;\n const tail = desc && room >= 8 ? ` ${truncateDisplay(desc, room)}` : '';\n return (\n <Box width={width}>\n <Text color={theme.brand}>{marker}</Text>\n <Text bold={selected} color={selected ? theme.selectionText : theme.text}>\n {shownName}\n </Text>\n <Text color={theme.inactive}>{badge}</Text>\n <Text color={selected ? theme.text : theme.inactive}>{tail}</Text>\n </Box>\n );\n}\n\n/**\n * @deprecated Prefer {@link panelGrid} directly. Kept so every floating surface\n * keeps a single call site while they migrate to the grid.\n *\n * Note this is {@link panelGrid}, not {@link frameGrid}: everything that reaches\n * here floats over the transcript, so it is bounded. The composer is the one\n * bordered surface that spans the transcript, and it calls `frameGrid` itself.\n */\nexport function floatingFrameMetrics(terminalWidth: number): { width: number; marginX: number } {\n return panelGrid(terminalWidth);\n}\n\n/**\n * The head of a surface that is waiting on you: a hairline across its width,\n * opened by a rubricated pilcrow and a label, with a short note at the far end.\n *\n * `─ ¶ Permission required ──────────────────────────── shell command ─`\n *\n * The pilcrow is the composer's mark and means the same thing here: the next\n * move is yours. The label carries the surface's one tone (amber for a write,\n * rose for a shell command); the line itself stays a quiet hairline, so the\n * tone reads as a word, not as a frame.\n */\nexport function DecisionRule(props: {\n label: string;\n tone: string;\n width: number;\n /** A short note set at the right end of the rule, in a quiet grey. */\n meta?: string;\n /** The line's own colour; a hairline grey unless a caller asks otherwise. */\n lineTone?: string;\n}) {\n return <SheetRule mark={PILCROW} {...props} />;\n}\n\n/** A rule led by a rubricated mark and a label: the head of every sheet. */\nexport function SheetRule({\n mark: markGlyph,\n label,\n tone,\n width,\n meta = '',\n lineTone,\n}: {\n mark: string;\n label: string;\n tone: string;\n width: number;\n meta?: string;\n lineTone?: string;\n}) {\n const theme = useTheme();\n const line = lineTone ?? theme.border;\n const lead = '─ ';\n const mark = `${markGlyph} `;\n // When the row is tight the note leaves the rule for a row of its own under\n // the label, rather than vanishing: some sheets keep their only copy of a\n // fact there (the risk of a shell command, \"2 of 3\", servers still waiting).\n const room = (tail: string) => width - displayWidth(lead + mark + tail) - 2;\n const inline = Boolean(meta) && room(` ${meta} ─`) >= displayWidth(label);\n const tail = inline ? ` ${meta} ─` : '';\n const text = truncateDisplay(label, Math.max(1, room(tail)));\n const fill = Math.max(1, width - displayWidth(lead + mark + text) - 1 - displayWidth(tail));\n const indent = displayWidth(lead + mark);\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color={line}>{lead}</Text>\n <Text color={theme.brand}>{mark}</Text>\n <Text color={tone} bold>\n {text}\n </Text>\n <Text color={line}>{` ${'─'.repeat(fill)}`}</Text>\n {tail ? (\n <>\n <Text color={theme.inactive}> {meta}</Text>\n <Text color={line}> ─</Text>\n </>\n ) : null}\n </Box>\n {meta && !inline ? (\n <Text color={theme.inactive}>\n {' '.repeat(indent)}\n {truncateDisplay(meta, Math.max(1, width - indent))}\n </Text>\n ) : null}\n </Box>\n );\n}\n\n/**\n * A surface that is waiting on you, set under a {@link DecisionRule} instead of\n * inside a box.\n *\n * Every decision the TUI asks for (a permission, a question, a plan, an MCP\n * server) shares this anatomy: a blank row of air, the rule, then the body two\n * columns in, so its text lands on the transcript's content column. Two columns\n * of padding stand in for each wall a box would have drawn, so a body sized as\n * `width - PANEL_CHROME` keeps the geometry it had inside the box.\n */\nexport function DecisionSheet({\n label,\n tone,\n meta,\n width,\n marginX = 0,\n children,\n}: {\n label: string;\n tone: string;\n meta?: string;\n width: number;\n marginX?: number;\n children: ReactNode;\n}) {\n return (\n <Box flexDirection=\"column\" width={width} marginX={marginX} marginTop={1}>\n <DecisionRule label={label} tone={tone} meta={meta} width={width} />\n <Box flexDirection=\"column\" paddingX={2}>\n {children}\n </Box>\n </Box>\n );\n}\n\nexport interface Choice {\n label: string;\n /** Set after the labels, in one column, in a quiet grey. */\n detail?: string;\n /** Whether this choice is ticked, or is the answer already given; drawn when `marks` is on. */\n checked?: boolean;\n /** Replaces the row's number, as `+` does for \"Other\". */\n numeral?: string;\n}\n\n/**\n * The choices a decision offers, one per row.\n *\n * `› 1 The default (1000) Treat an empty value like a missing one.`\n * ` 2 Disable timeouts Keep today's behaviour.`\n *\n * The chosen row is marked by a rubricated `›` and a bold label, and nothing\n * else: a highlight bar behind it made the list look like a menu from another\n * program. Labels share one column, so details start on the same column. Rows\n * are numbered only when number keys choose them.\n */\nexport function ChoiceList({\n choices,\n selected,\n width,\n numbered = true,\n marks = false,\n active = true,\n}: {\n choices: readonly Choice[];\n /** The row the cursor is on; -1 for none. */\n selected: number;\n width: number;\n numbered?: boolean;\n /** Keep a column for a `✓` beside each row: ticked choices, or the answer already given. */\n marks?: boolean;\n /** False while another part of the surface has the keys: no cursor is drawn. */\n active?: boolean;\n}) {\n const theme = useTheme();\n const compact = width < 56;\n const numeralWidth = numbered\n ? Math.max(...choices.map((choice, index) => displayWidth(choice.numeral ?? `${index + 1}`))) +\n 2\n : 0;\n const prefixWidth = 2 + (marks ? 2 : 0) + numeralWidth;\n const labelColumn = Math.min(\n Math.max(...choices.map((choice) => displayWidth(choice.label)), 4),\n Math.max(8, Math.floor((width - prefixWidth) * 0.45)),\n );\n return (\n <Box flexDirection=\"column\">\n {choices.map((choice, index) => {\n const current = active && index === selected;\n const numeral = choice.numeral ?? `${index + 1}`;\n const label = compact\n ? truncateDisplay(choice.label, Math.max(4, width - prefixWidth))\n : padDisplay(truncateDisplay(choice.label, labelColumn), labelColumn);\n const detailRoom = compact\n ? Math.max(4, width - prefixWidth)\n : Math.max(4, width - prefixWidth - labelColumn - 3);\n const detail = choice.detail ? truncateDisplay(choice.detail, detailRoom) : '';\n return (\n <Box key={`${index}-${choice.label}`} flexDirection=\"column\">\n <Box>\n <Text color={theme.brand}>{current ? '› ' : ' '}</Text>\n {marks ? <Text color={theme.brand}>{choice.checked ? '✓ ' : ' '}</Text> : null}\n {numbered ? (\n <Text color={theme.brand}>{padDisplay(numeral, numeralWidth)}</Text>\n ) : null}\n <Text\n bold={current || Boolean(choice.checked)}\n color={current ? theme.selectionText : theme.text}\n >\n {label}\n </Text>\n {!compact && detail ? (\n <Text color={current ? theme.subtle : theme.inactive}>{` ${detail}`}</Text>\n ) : null}\n </Box>\n {compact && detail ? (\n <Text color={theme.inactive}>{`${' '.repeat(prefixWidth)}${detail}`}</Text>\n ) : null}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n/**\n * Facts set as two columns: a quiet key, then its value.\n *\n * `model mock-model`\n * `workspace C:\\Users\\zain\\…\\ws`\n *\n * Keys share one column sized to the widest; a long value wraps under itself,\n * never back under the keys. `ink` keys are for rows where the key is the thing\n * you press or type (shortcuts), and read louder than their explanation.\n */\nexport function KeyValueList({\n rows,\n width,\n keys = 'quiet',\n}: {\n rows: ReadonlyArray<{ key: string; value: string }>;\n width: number;\n keys?: 'quiet' | 'ink';\n}) {\n const theme = useTheme();\n const keyWidth = Math.min(\n Math.max(...rows.map((row) => displayWidth(row.key)), 1),\n Math.max(6, Math.floor(width * 0.4)),\n );\n const valueWidth = Math.max(8, width - keyWidth - 2);\n return (\n <Box flexDirection=\"column\">\n {rows.map((row, index) => (\n <Box key={`${index}-${row.key}`}>\n <Box width={keyWidth + 2} flexShrink={0}>\n <Text color={keys === 'ink' ? theme.text : theme.inactive} bold={keys === 'ink'}>\n {truncateDisplay(row.key, keyWidth)}\n </Text>\n </Box>\n <Box width={valueWidth}>\n <Text color={keys === 'ink' ? theme.subtle : theme.text} wrap=\"wrap\">\n {row.value}\n </Text>\n </Box>\n </Box>\n ))}\n </Box>\n );\n}\n","import type { Message } from '../types/messages.js';\nimport type { NestedToolInvocation } from '../types/tools.js';\n\nexport type NestedToolChildren = ReadonlyMap<string, readonly NestedToolInvocation[]>;\n\nexport function indexNestedToolInvocations(\n invocations: readonly NestedToolInvocation[],\n): Map<string, NestedToolInvocation[]> {\n const children = new Map<string, NestedToolInvocation[]>();\n for (const invocation of invocations) {\n const siblings = children.get(invocation.parentTraceId);\n if (siblings) siblings.push(invocation);\n else children.set(invocation.parentTraceId, [invocation]);\n }\n return children;\n}\n\nexport function countNestedToolInvocations(\n childrenByParent: NestedToolChildren,\n parentTraceId: string,\n): number {\n let count = 0;\n const visited = new Set<string>();\n const stack = [...(childrenByParent.get(parentTraceId) ?? [])];\n while (stack.length > 0) {\n const invocation = stack.pop()!;\n if (visited.has(invocation.traceId)) continue;\n visited.add(invocation.traceId);\n count++;\n stack.push(...(childrenByParent.get(invocation.traceId) ?? []));\n }\n return count;\n}\n\nexport function selectActiveToolId(message: Message | undefined): string | null {\n if (!message || message.role !== 'assistant') return null;\n\n const nested = message.nestedToolInvocations ?? [];\n for (let index = nested.length - 1; index >= 0; index--) {\n if (!nested[index].result) return nested[index].traceId;\n }\n\n const calls = message.toolCalls ?? [];\n const results = new Set((message.toolResults ?? []).map((result) => result.toolCallId));\n for (let index = calls.length - 1; index >= 0; index--) {\n if (!results.has(calls[index].id)) return calls[index].id;\n }\n\n return null;\n}\n\n/** Select the newest action for explicit output expansion when none is active. */\nexport function selectLatestToolId(messages: readonly Message[]): string | null {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role !== 'assistant') continue;\n const nested = message.nestedToolInvocations ?? [];\n if (nested.length > 0) return nested[nested.length - 1].traceId;\n const calls = message.toolCalls ?? [];\n if (calls.length > 0) return calls[calls.length - 1].id;\n }\n return null;\n}\n\n/**\n * Select the one tool row whose body should be visible in the transcript.\n *\n * This selects the latest unfinished invocation. Completed file mutations use\n * the separate default-expansion policy in tool-presentation.\n */\nexport function selectExpandedToolId(messages: readonly Message[]): string | null {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role !== 'assistant') continue;\n const hasToolActivity =\n (message.toolCalls?.length ?? 0) > 0 || (message.nestedToolInvocations?.length ?? 0) > 0;\n if (!hasToolActivity) continue;\n const activeToolId = selectActiveToolId(message);\n if (activeToolId) return activeToolId;\n }\n\n return null;\n}\n","import { Box, Text } from 'ink';\nimport { useUiClock } from '../ui-clock.js';\nimport type { ManagedAgentTrace, ManagedAgentToolUse } from '../managed-agent-transcript.js';\nimport { formatDuration, deriveToolPresentation } from '../tool-presentation.js';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, GUTTER_WIDTH, indentedGrid, transcriptGrid } from '../layout.js';\nimport { truncateDisplay } from './word-wrap.js';\nimport { Spinner } from './Spinner.js';\n\nconst MAX_VISIBLE_TOOL_USES = 1;\nconst TERMINAL_STATUSES = new Set(['completed', 'failed', 'stopped', 'interrupted']);\n\nfunction useCurrentTime(active: boolean): number {\n const tick = useUiClock('slow', active);\n void tick;\n return Date.now();\n}\n\nfunction statusGlyph(status: ManagedAgentToolUse['status'] | ManagedAgentTrace['status']): string {\n if (status === 'completed') return '✓';\n if (status === 'failed') return '✕';\n if (status === 'stopped' || status === 'interrupted') return '■';\n return '›';\n}\n\nfunction resultPreview(tool: ManagedAgentToolUse): string | undefined {\n const content =\n tool.result?.structuredError?.message ||\n tool.result?.presentation?.details ||\n tool.result?.content;\n if (!content) return undefined;\n const line = content\n .split(/\\r?\\n/)\n .map((value) => value.trim())\n .find(Boolean);\n return line ? truncateDisplay(line, 72) : undefined;\n}\n\nfunction durationFor(trace: ManagedAgentTrace, now: number): string | undefined {\n const end = trace.finishedAt ?? now;\n return formatDuration(Math.max(0, end - trace.startedAt));\n}\n\nfunction toolDuration(tool: ManagedAgentToolUse): string | undefined {\n if (!tool.finishedAt) return undefined;\n return formatDuration(Math.max(0, tool.finishedAt - tool.startedAt));\n}\n\nexport function ManagedAgentActivityBlock({\n trace,\n reducedMotion = false,\n screenReader = false,\n terminalWidth = 80,\n}: {\n trace: ManagedAgentTrace;\n reducedMotion?: boolean;\n screenReader?: boolean;\n terminalWidth?: number;\n}) {\n const theme = useTheme();\n const terminal = TERMINAL_STATUSES.has(trace.status);\n const now = useCurrentTime(!terminal);\n const elapsed = durationFor(trace, now);\n const visible = trace.toolUses.slice(-MAX_VISIBLE_TOOL_USES);\n const hiddenCount = Math.max(0, trace.toolUses.length - visible.length);\n // A blocked lead is a different situation from a background spawn and reads\n // wrong under the same words: \"Running in background\" next to a stopped parent\n // tells the user work is proceeding alongside their turn when nothing is.\n // Tab opens a child only while it still has a Background-panel row.\n const tabHint = trace.openable === false ? '' : ' · Tab to open';\n const footer = terminal\n ? `Transcript retained${tabHint}`\n : trace.blocking\n ? `Lead paused · sidekick working${tabHint}`\n : `Running in background${tabHint}`;\n const grid = transcriptGrid(terminalWidth);\n // A managed-agent block fills the same transcript slot as a tool row — it is\n // the other branch of the same ternary — so it sits on the same indented\n // grid. Left on the bare grid it would be the only row still hanging its\n // status glyph a gutter to the left of the prose column.\n const rowGrid = indentedGrid(grid);\n const width = rowGrid.content;\n\n if (screenReader) {\n return (\n <Box flexDirection=\"column\" marginLeft={2} width={width}>\n <Text>\n Subagent {trace.profile}, {trace.purpose}. Status {trace.status}.{' '}\n {elapsed ? `Elapsed ${elapsed}.` : ''}\n </Text>\n {visible.map((tool) => {\n const presentation = deriveToolPresentation(\n tool.call.name,\n tool.call.arguments,\n tool.result,\n { unparsedArguments: tool.call.unparsedArguments },\n );\n return (\n <Text key={tool.id}>\n {presentation.summary}. {tool.status}. {resultPreview(tool) ?? ''}\n </Text>\n );\n })}\n {hiddenCount > 0 ? <Text>{hiddenCount} earlier tool uses hidden.</Text> : null}\n <Text>{footer}.</Text>\n {trace.openable === false ? null : (\n <Text>Press Tab to open the complete subagent transcript.</Text>\n )}\n </Box>\n );\n }\n\n const headerColor =\n trace.status === 'failed'\n ? theme.error\n : trace.status === 'completed'\n ? theme.success\n : trace.status === 'stopped' || trace.status === 'interrupted'\n ? theme.warning\n : theme.brand;\n return (\n <Box flexDirection=\"column\" marginLeft={CONTENT_COLUMN} width={width + GUTTER_WIDTH}>\n <Box>\n {terminal ? (\n <Text color={headerColor}>{statusGlyph(trace.status)} </Text>\n ) : (\n <Spinner active color={theme.assistantAccent} reducedMotion={reducedMotion} />\n )}\n <Text color={headerColor} bold>\n {trace.profile}\n </Text>\n <Text color={theme.text}>\n ({truncateDisplay(trace.purpose, Math.max(12, width - trace.profile.length - 18))})\n </Text>\n {elapsed ? <Text color={theme.subtle}> · {elapsed}</Text> : null}\n </Box>\n\n {visible.map((tool, index) => {\n const presentation = deriveToolPresentation(\n tool.call.name,\n tool.call.arguments,\n tool.result,\n { unparsedArguments: tool.call.unparsedArguments },\n );\n const running = tool.status === 'running';\n const connector = index === visible.length - 1 ? '└' : '├';\n const color = tool.status === 'failed' ? theme.error : running ? theme.brand : theme.text;\n const duration = toolDuration(tool);\n return (\n <Box key={tool.id} flexDirection=\"column\" marginLeft={CONTENT_COLUMN}>\n <Box>\n <Text color={theme.toolRail}>{connector} </Text>\n {running ? (\n <Spinner active color={theme.assistantAccent} reducedMotion={reducedMotion} />\n ) : (\n <Text color={color}>{statusGlyph(tool.status)} </Text>\n )}\n <Text color={color}>\n {truncateDisplay(presentation.summary, Math.max(12, width - 8))}\n </Text>\n {duration ? <Text color={theme.subtle}> · {duration}</Text> : null}\n </Box>\n {resultPreview(tool) ? (\n <Text color={theme.subtle} dimColor>\n {' '}└ {resultPreview(tool)}\n </Text>\n ) : null}\n </Box>\n );\n })}\n\n {hiddenCount > 0 ? (\n <Text color={theme.subtle}>\n {' '}… +{hiddenCount} tool {hiddenCount === 1 ? 'use' : 'uses'}\n </Text>\n ) : null}\n <Text color={theme.subtle} dimColor>\n {' '}\n {footer}\n </Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, type TranscriptGrid } from '../layout.js';\nimport { composeToolRow } from '../tool-presentation.js';\nimport type { QuietRunSummary } from '../quiet-tools.js';\nimport { Spinner } from './Spinner.js';\nimport { MetaText, TargetText } from './ToolCallBlock.js';\n\n/**\n * One row standing in for a run of quiet tool calls (reads, searches, lookups).\n *\n * It sits on the same indented grid as the tool rows around it, so its verb,\n * target and counts line up with theirs, and it is drawn a step quieter: the\n * check is grey rather than green, because nothing here changed anything. The\n * rows it replaces come back with Ctrl+O.\n */\nfunction QuietToolRunInner({\n summary,\n grid,\n reducedMotion = false,\n screenReader = false,\n}: {\n summary: QuietRunSummary;\n grid: TranscriptGrid;\n reducedMotion?: boolean;\n screenReader?: boolean;\n}) {\n const theme = useTheme();\n const row = composeToolRow(\n { title: summary.title, target: summary.target, metadata: summary.metadata },\n grid,\n );\n\n if (screenReader) {\n return (\n <Box>\n <Text>\n {summary.title} {summary.target} ({summary.metadata.join(', ')})\n </Text>\n </Box>\n );\n }\n\n return (\n <Box height={1} marginLeft={CONTENT_COLUMN}>\n {summary.running ? (\n // Spinner emits its own trailing space, keeping the gutter two wide.\n <Spinner active style=\"dots\" color={theme.assistantAccent} reducedMotion={reducedMotion} />\n ) : (\n <Text color={theme.inactive}>{'✓ '}</Text>\n )}\n {row.label ? <Text color={theme.inactive}>{row.label} </Text> : null}\n <TargetText target={row.target} failed={false} />\n <Text>{row.gap}</Text>\n <MetaText meta={row.meta} failed={false} />\n </Box>\n );\n}\n\nexport const QuietToolRun = React.memo(QuietToolRunInner);\n","import { basename, isAbsolute, relative, resolve } from 'path';\nimport { splitReasoningParts } from '../reasoning-tags.js';\nimport { canonicalToolName } from '../tools/aliases.js';\nimport type { Message } from '../types/messages.js';\nimport type { ToolCall, ToolResult } from '../types/tools.js';\n\n/**\n * Quiet tools: the reading an agent does on its way to a change.\n *\n * A turn that reads six files and runs two searches before one edit used to\n * draw nine rows, and the edit, which is the row the reader needs, sat at the\n * bottom of a column of reads. In the compact transcript a run of these\n * collapses into one summary row. What changes something, runs a command,\n * reaches the network, delegates, fails or waits on a permission prompt keeps\n * its own row.\n *\n * `Bash` is deliberately absent even when a command only reads (`git diff\n * --stat`): a shell command can change anything, and the transcript cannot tell\n * which ones did.\n */\nexport const QUIET_TOOLS: ReadonlySet<string> = new Set([\n 'Read',\n 'Glob',\n 'Grep',\n 'GitStatus',\n 'GitDiff',\n 'GitLog',\n 'GitBranch',\n 'ToolSearch',\n 'TaskList',\n 'TaskGet',\n 'BashOutput',\n 'SessionHistorySearch',\n 'SessionHistoryRead',\n 'ReadSkillResource',\n]);\n\n/** Tools that search rather than read, for the summary's wording. */\nconst SEARCH_TOOLS: ReadonlySet<string> = new Set(['Glob', 'Grep']);\n\nexport interface QuietToolContext {\n /**\n * Tools the user has singled out: an explicit expansion, or the row they\n * selected. A pinned tool always keeps its own row, so nothing they asked to\n * see can end up inside a summary.\n */\n pinned: ReadonlySet<string>;\n /** The tool a permission prompt is waiting on, which is never quiet. */\n pendingToolId?: string;\n /**\n * The session's workspace. A read or search that reaches outside it is the\n * kind of access a permission rule exists for, so it keeps its own row even\n * when no prompt was shown (bypass mode, or an allow rule).\n */\n workspace?: string;\n}\n\n/** Whether a read or search reaches outside the workspace. */\nfunction reachesOutside(call: ToolCall, workspace: string | undefined): boolean {\n if (!workspace) return false;\n const target = argString(call.arguments, 'file_path', 'path', 'filePath');\n if (!target) return false;\n const rel = relative(resolve(workspace), resolve(workspace, target));\n return rel.startsWith('..') || isAbsolute(rel);\n}\n\nfunction resultFor(message: Message, toolCallId: string): ToolResult | undefined {\n return message.toolResults?.find((result) => result.toolCallId === toolCallId);\n}\n\n/**\n * Whether one call may fold into a summary.\n *\n * A running call may: it joins the run and the summary carries the spinner, so\n * the row does not appear and then vanish when the call finishes. A finished\n * call must have succeeded; a failure, a refusal or a cancellation is news.\n */\nexport function isQuietInvocation(\n call: ToolCall,\n result: ToolResult | undefined,\n message: Message,\n context: QuietToolContext,\n): boolean {\n if (!QUIET_TOOLS.has(canonicalToolName(call.name))) return false;\n if (context.pinned.has(call.id) || context.pendingToolId === call.id) return false;\n if (reachesOutside(call, context.workspace)) return false;\n if (message.nestedToolInvocations?.some((nested) => nested.parentTraceId === call.id)) {\n return false;\n }\n return !result || result.status === 'success';\n}\n\n/**\n * Whether a message shows any text of its own.\n *\n * Judged the way AgentMessage renders it, not by `content.trim()`: routers that\n * inline reasoning put `<think></think>` in the content of nearly every\n * tool-call turn, and that renders as nothing. Reasoning only counts when the\n * reader has thinking display on.\n */\nexport function hasVisibleText(message: Message, showThinking: boolean): boolean {\n const parts = splitReasoningParts(message.content ?? '', { concluded: false });\n for (const part of parts) {\n if (part.kind === 'markdown' && part.text.trim()) return true;\n if (part.kind === 'think' && showThinking && part.text.trim()) return true;\n }\n return Boolean(showThinking && message.reasoningContent?.trim());\n}\n\n/**\n * An assistant message with no text of its own whose first call is quiet: it\n * continues a run begun before it.\n *\n * Only the first call has to be quiet. Book already folds a tool-only turn with\n * blank content into the turn before it, so the turn that ends a run of reads\n * often carries the edit that follows them, as `[Read, Edit]`. Requiring every\n * call to be quiet would leave that last read stranded on its own row. The\n * message joins whole; the rows it draws still keep the edit apart (see\n * {@link groupQuietInvocations}).\n */\nexport function continuesQuietRun(\n message: Message,\n context: QuietToolContext,\n showThinking: boolean,\n): boolean {\n if (message.role !== 'assistant' || message.localCommand) return false;\n const first = message.toolCalls?.[0];\n if (!first) return false;\n // Joining would put a spawn in the same entry as the narration before it,\n // and AgentMessage hides a delegating entry's narration.\n if (message.toolCalls!.some((call) => call.name === 'AgentSpawn')) return false;\n if (hasVisibleText(message, showThinking)) return false;\n return isQuietInvocation(first, resultFor(message, first.id), message, context);\n}\n\nfunction endsWithQuietCall(message: Message, context: QuietToolContext): boolean {\n if (message.role !== 'assistant' || message.localCommand) return false;\n const calls = message.toolCalls ?? [];\n const last = calls[calls.length - 1];\n return Boolean(last && isQuietInvocation(last, resultFor(message, last.id), message, context));\n}\n\nexport interface CollapsedTimeline<T> {\n entries: T[];\n /** For a merged entry, keyed by its (first) id: every message folded into it, in order. */\n sourceIds: ReadonlyMap<string, readonly string[]>;\n}\n\ntype TimelineEntry = Message | { transcriptOrdinal: unknown };\n\nfunction isMessage(entry: TimelineEntry | undefined): entry is Message {\n return Boolean(entry && 'role' in entry);\n}\n\n/**\n * Fold each message that continues a quiet run into the entry before it.\n *\n * An agent that reads one file per turn produces a run of messages that hold a\n * single Read each and no text. Collapsing inside each message would leave that\n * run untouched, so the fold happens on the timeline: a message that continues\n * a run joins the entry before it when that entry's last call is quiet too. The merged entry\n * keeps the first message's id, so it holds its place in the virtual transcript\n * as the run grows.\n *\n * Merged entries are cached by the identity of the messages they were built\n * from, so a run that did not change keeps the same object and its row is not\n * re-rendered on every streamed delta elsewhere in the transcript.\n */\nexport function createQuietCollapser(): <T extends TimelineEntry>(\n timeline: readonly T[],\n context: QuietToolContext,\n showThinking: boolean,\n) => CollapsedTimeline<T> {\n let cache = new Map<string, { members: readonly Message[]; merged: Message }>();\n return <T extends TimelineEntry>(\n timeline: readonly T[],\n context: QuietToolContext,\n showThinking: boolean,\n ): CollapsedTimeline<T> => {\n const runs: Array<T | Message[]> = [];\n for (const entry of timeline) {\n const previous = runs[runs.length - 1];\n const previousMessage = Array.isArray(previous)\n ? previous[previous.length - 1]\n : isMessage(previous)\n ? previous\n : undefined;\n if (\n isMessage(entry) &&\n previousMessage &&\n continuesQuietRun(entry, context, showThinking) &&\n endsWithQuietCall(previousMessage, context)\n ) {\n if (Array.isArray(previous)) previous.push(entry);\n else runs[runs.length - 1] = [previousMessage, entry];\n continue;\n }\n runs.push(entry);\n }\n\n const nextCache = new Map<string, { members: readonly Message[]; merged: Message }>();\n const sourceIds = new Map<string, readonly string[]>();\n const entries = runs.map((run) => {\n if (!Array.isArray(run)) return run;\n const head = run[0]!;\n const cached = cache.get(head.id);\n const merged =\n cached &&\n cached.members.length === run.length &&\n cached.members.every((member, index) => member === run[index])\n ? cached.merged\n : {\n ...head,\n reasoningContent:\n run\n .map((message) => message.reasoningContent)\n .filter((value): value is string => Boolean(value))\n .join('\\n\\n') || undefined,\n toolCalls: run.flatMap((message) => message.toolCalls ?? []),\n toolResults: run.flatMap((message) => message.toolResults ?? []),\n nestedToolInvocations: run.flatMap((message) => message.nestedToolInvocations ?? []),\n };\n nextCache.set(head.id, { members: run, merged });\n sourceIds.set(\n head.id,\n run.map((message) => message.id),\n );\n return merged as T;\n });\n cache = nextCache;\n return { entries, sourceIds };\n };\n}\n\nexport interface QuietInvocation {\n call: ToolCall;\n result?: ToolResult;\n}\n\n/**\n * Split a message's calls into rows: a run of two or more consecutive quiet\n * calls becomes one group; everything else, a lone quiet call included, stays\n * a row of its own. A one-call summary would say less than the row it replaced.\n */\nexport function groupQuietInvocations<T extends QuietInvocation>(\n invocations: readonly T[],\n message: Message,\n context: QuietToolContext,\n): Array<{ kind: 'single'; index: number } | { kind: 'quiet'; indices: number[] }> {\n const rows: Array<{ kind: 'single'; index: number } | { kind: 'quiet'; indices: number[] }> = [];\n let run: number[] = [];\n const flush = () => {\n if (run.length >= 2) rows.push({ kind: 'quiet', indices: run });\n else for (const index of run) rows.push({ kind: 'single', index });\n run = [];\n };\n invocations.forEach((invocation, index) => {\n if (isQuietInvocation(invocation.call, invocation.result, message, context)) {\n run.push(index);\n } else {\n flush();\n rows.push({ kind: 'single', index });\n }\n });\n flush();\n return rows;\n}\n\nexport interface QuietRunSummary {\n title: string;\n target: string;\n metadata: string[];\n running: boolean;\n}\n\nfunction argString(args: Record<string, unknown>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const value = args[key];\n if (typeof value === 'string' && value.trim()) return value.trim();\n }\n return undefined;\n}\n\nfunction plural(count: number, one: string, many: string): string {\n return `${count} ${count === 1 ? one : many}`;\n}\n\n/**\n * The one row a quiet run collapses to: what was read, then the counts.\n *\n * `Read config.ts, loader.ts, index.ts 3 files · 2 searches`. The target\n * names what the agent looked at, so the summary still says something; the\n * row truncates it to the column like any other target.\n */\nexport function summarizeQuietRun(invocations: readonly QuietInvocation[]): QuietRunSummary {\n const files: string[] = [];\n const patterns: string[] = [];\n const others: string[] = [];\n for (const { call } of invocations) {\n const name = canonicalToolName(call.name);\n if (name === 'Read') {\n const path = argString(call.arguments, 'file_path', 'path', 'filePath');\n const shown = path ? basename(path.replace(/\\\\/g, '/')) : 'file';\n if (!files.includes(shown)) files.push(shown);\n } else if (SEARCH_TOOLS.has(name)) {\n const pattern = argString(call.arguments, 'pattern', 'query', 'glob');\n patterns.push(pattern ?? name.toLowerCase());\n } else {\n others.push(name);\n }\n }\n\n const title = files.length > 0 ? 'Read' : patterns.length > 0 ? 'Search' : 'Check';\n const target =\n files.length > 0\n ? files.join(', ')\n : patterns.length > 0\n ? patterns.join(', ')\n : [...new Set(others)].join(', ');\n const metadata: string[] = [];\n if (files.length > 0) metadata.push(plural(files.length, 'file', 'files'));\n if (patterns.length > 0) metadata.push(plural(patterns.length, 'search', 'searches'));\n if (others.length > 0) metadata.push(plural(others.length, 'lookup', 'lookups'));\n return {\n title,\n target,\n metadata,\n running: invocations.some((invocation) => !invocation.result),\n };\n}\n","/**\n * Shared TUI debug helpers.\n *\n * Thin hooks and functions that wrap {@link ../debug-log.js} so components\n * don't get cluttered with repetitive `isUiDebugEnabled()` guards and manual\n * event formatting. They all resolve to no-ops when the corresponding debug\n * flag is off.\n *\n * Usage in a component:\n * import { useDebugMount, useDebugRender, debugInput } from '../debug.js';\n * const log = createUiDebugLogger('tui:mycomponent');\n * useDebugMount(log, { optional: 'info' });\n * useDebugRender(log, { count });\n * debugInput(log, 'Enter', 'submit-text');\n */\n\nimport { useRef, useEffect } from 'react';\nimport type { DebugLogger } from '../debug-log.js';\nimport { isUiDebugEnabled, isRenderDebugEnabled, isFlowDebugEnabled } from '../debug-log.js';\n\n// ---------------------------------------------------------------------------\n// Hooks — useDebug* helpers for components to use inside render/effect bodies.\n// ---------------------------------------------------------------------------\n\n/**\n * Log a component mount/unmount event once.\n *\n * Call unconditionally in the component body (not inside a condition/loop).\n * When `BOOK_DEBUG_UI=1` (or `BOOK_DEBUG=1`) this logs `mounted` on first render\n * and `unmounted` in the cleanup effect.\n */\nexport function useDebugMount(log: DebugLogger, info?: Record<string, unknown>): void {\n if (!isUiDebugEnabled()) return;\n\n const isMount = useRef(true);\n if (isMount.current) {\n log.event('mounted', info);\n }\n\n useEffect(() => {\n isMount.current = false;\n return () => {\n log.event('unmounted');\n };\n }, [log]);\n}\n\n/**\n * Log component render events.\n *\n * Call unconditionally at the top of the component body. Gated by\n * `BOOK_DEBUG_RENDER=1` to keep stderr readable. When enabled, logs\n * `render` with the supplied metadata every time the component renders.\n *\n * Uses a ref-based throttle so high-frequency renders (streaming) don't\n * flood stderr.\n */\nexport function useDebugRender(\n log: DebugLogger,\n info?: Record<string, unknown>,\n throttleMs = 250,\n): void {\n if (!isRenderDebugEnabled()) return;\n\n const lastRender = useRef(0);\n const now = Date.now();\n if (now - lastRender.current < throttleMs) return;\n lastRender.current = now;\n\n log.event('render', info);\n}\n\n/**\n * Log when a specific value changes between renders, showing old→new.\n *\n * Useful for tracking state transitions without adding verbose `useEffect`\n * observers for each value.\n */\nexport function useDebugValueChange(\n log: DebugLogger,\n label: string,\n value: unknown,\n toRepr?: (val: unknown) => string,\n): void {\n if (!isUiDebugEnabled()) return;\n\n const prevRef = useRef<{ stored: boolean; value: unknown }>({ stored: false, value: undefined });\n const { stored, value: prevVal } = prevRef.current;\n prevRef.current = { stored: true, value };\n\n if (!stored) return;\n\n const format = toRepr ?? String;\n if (value !== prevVal) {\n log.event(`${label}:change`, { from: format(prevVal), to: format(value) });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Plain functions — call outside React render cycles (e.g. callbacks).\n// ---------------------------------------------------------------------------\n\n/**\n * Log an input / keyboard event from a TUI component. Gated by UI debug.\n */\nexport function debugInput(\n log: DebugLogger,\n key: string,\n action: string,\n extra?: Record<string, unknown>,\n): void {\n if (!isUiDebugEnabled()) return;\n log.event(`input:${key}`, { action, ...extra });\n}\n\n/**\n * Log a layout / sizing decision. Gated by render debug (noisy).\n */\nexport function debugLayout(log: DebugLogger, info: Record<string, unknown>): void {\n if (!isRenderDebugEnabled()) return;\n log.event('layout', info);\n}\n\n/**\n * Log a flow enter/exit pair with timing.\n *\n * Call `debugFlowEnter` at the start of an operation and `debugFlowExit`\n * at the end. Gated by `BOOK_DEBUG_FLOW=1`.\n */\nlet flowSeq = 0;\nconst flowStack: Array<{ id: number; label: string; start: number }> = [];\n\nexport function debugFlowEnter(log: DebugLogger, label: string): number {\n if (!isFlowDebugEnabled()) return -1;\n const id = ++flowSeq;\n flowStack.push({ id, label, start: Date.now() });\n log.event('enter', { flow: label, id });\n return id;\n}\n\nexport function debugFlowExit(log: DebugLogger, label: string, id?: number): void {\n if (!isFlowDebugEnabled()) return;\n let entry: { id: number; label: string; start: number } | undefined;\n if (id !== undefined) {\n entry = flowStack.find((f) => f.id === id);\n } else {\n // Walk backwards to find the latest matching label (findLast replacement).\n for (let i = flowStack.length - 1; i >= 0; i--) {\n if (flowStack[i].label === label) {\n entry = flowStack[i];\n break;\n }\n }\n }\n if (!entry) {\n log.event('exit', { flow: label, durationMs: '?' });\n return;\n }\n const durationMs = Date.now() - entry.start;\n // remove from stack\n const idx = flowStack.indexOf(entry);\n if (idx >= 0) flowStack.splice(idx, 1);\n log.event('exit', { flow: label, id: entry.id, durationMs });\n}\n","import type { Message } from '../../types/messages.js';\nimport { splitReasoningParts } from '../../reasoning-tags.js';\nimport { categoryFor } from '../../tools/catalog.js';\n\n/**\n * Whether assistant content draws nothing.\n *\n * An empty reasoning block counts as blank. Routers that inline thinking emit\n * `<think></think>` ahead of every tool call, and treating that as content kept\n * each of those turns as a separate transcript entry with its own spacing: two\n * blank rows between every tool row of a run. A block with reasoning in it is\n * not blank, since it renders as a thought row.\n */\nexport function isBlankAssistantContent(content: string | undefined | null): boolean {\n if (!content || content.trim().length === 0) return true;\n return splitReasoningParts(content).every((part) => part.text.trim().length === 0);\n}\n\n/**\n * Whether a message delegates. AgentMessage hides a delegating message's\n * narration (the spawn has its own activity row), so a delegating turn must\n * never merge into one that carries narration, or that narration vanishes.\n */\nexport function delegatesWork(message: Message): boolean {\n return Boolean(message.toolCalls?.some((call) => call.name === 'AgentSpawn'));\n}\n\n/** Calls that hand the conversation back to you, or save a memory: not in a catalog category of their own. */\nconst HAND_BACK_TOOLS = new Set(['AskUserQuestion', 'ExitPlanMode', 'MemorySave']);\n\n/**\n * Whether a call leaves the prose before it an answer: task bookkeeping (by\n * catalog category, so a new task tool is covered without editing this list)\n * and the calls that hand the conversation back to you.\n */\nfunction isNonStepTool(name: string): boolean {\n return categoryFor(name) === 'tasks' || HAND_BACK_TOOLS.has(name);\n}\n\n/**\n * Whether an assistant entry is a step of work rather than an answer. The\n * bookkeeping and hand-back calls are classified by the tool catalog, which is\n * the same source the capability rules read. An answer that ends by updating\n * the plan is still the answer.\n */\nexport function isWorkStep(message: Message): boolean {\n if (message.role !== 'assistant' || message.kind === 'local' || message.localCommand)\n return false;\n return (message.toolCalls ?? []).some((call) => !isNonStepTool(call.name));\n}\n\n/** Merge completed tool-only assistant messages into the preceding assistant turn for display. */\nexport function mergeAssistantMessages(\n messages: Message[],\n streamingMessageId?: string | null,\n): Message[] {\n if (messages.length <= 1) return messages;\n\n const merged: Message[] = [];\n let index = 0;\n while (index < messages.length) {\n const current = messages[index];\n if (current.role !== 'assistant') {\n merged.push(current);\n index++;\n continue;\n }\n\n let mergedMessage: Message = { ...current };\n let nextIndex = index + 1;\n while (nextIndex < messages.length) {\n const next = messages[nextIndex];\n if (next.role !== 'assistant') break;\n if (!isBlankAssistantContent(next.content)) break;\n if (next.id === streamingMessageId) break;\n if (delegatesWork(next)) break;\n mergedMessage = {\n ...mergedMessage,\n reasoningContent:\n [mergedMessage.reasoningContent, next.reasoningContent]\n .filter((value): value is string => Boolean(value))\n .join('\\n\\n') || undefined,\n toolCalls: [...(mergedMessage.toolCalls ?? []), ...(next.toolCalls ?? [])],\n toolResults: [...(mergedMessage.toolResults ?? []), ...(next.toolResults ?? [])],\n nestedToolInvocations: [\n ...(mergedMessage.nestedToolInvocations ?? []),\n ...(next.nestedToolInvocations ?? []),\n ],\n };\n nextIndex++;\n }\n merged.push(mergedMessage);\n index = nextIndex;\n }\n\n return merged;\n}\n\n/**\n * Turns you wrote: the status line's folio counts one page for each. Subagent\n * and background-shell notifications arrive as user turns too\n * (`kind: 'agent-notification'`), and checkpoints and the carried ledger are\n * host text, so only conversation turns count.\n */\nexport function countWrittenTurns(messages: readonly Message[]): number {\n return messages.filter(\n (message) => message.role === 'user' && (message.kind ?? 'conversation') === 'conversation',\n ).length;\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\nimport { displayWidth, hardWrapLine } from './word-wrap.js';\nimport { PILCROW } from '../marks.js';\nimport { mentionTokenRanges } from '../../input/input-expansion.js';\nimport type { ImageAttachment } from '../../types/messages.js';\n\ninterface UserMessageProps {\n content: string;\n attachments?: ImageAttachment[];\n terminalWidth?: number;\n /** Turn start time, shown at the right edge of the turn rule. */\n timestamp?: number;\n screenReader?: boolean;\n}\n\n/** The turn's start time as the transcript prints it, in the system locale. */\nexport function formatTurnTime(timestamp?: number): string {\n if (!timestamp) return '';\n return new Date(timestamp).toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n}\n\n/**\n * Split content into text segments and @mention tokens.\n * Shares `findMentionTokens` with input-expansion, so the TUI never accents an\n * at-sign the agent loop would not expand — an at-sign inside fenced or inline\n * code is left as plain text. The ranges are the ones `mentionTokenRanges`\n * found in the *whole* prompt: a fence or a code span that spans lines only\n * reads as code when the lines are taken together (#261).\n */\nfunction parseMentionSegments(\n content: string,\n ranges: ReadonlyArray<[number, number]>,\n): Array<{ text: string; isMention: boolean }> {\n const segments: Array<{ text: string; isMention: boolean }> = [];\n let cursor = 0;\n\n for (const [start, end] of ranges) {\n if (start > cursor) segments.push({ text: content.slice(cursor, start), isMention: false });\n segments.push({ text: content.slice(start, end), isMention: true });\n cursor = end;\n }\n if (cursor < content.length) {\n segments.push({ text: content.slice(cursor), isMention: false });\n }\n\n return segments;\n}\n\n/**\n * Columns the prompt text wraps at.\n *\n * The row stops one column short of the terminal, spends the gutter on the\n * pilcrow, and keeps the time clear at the right edge when the turn has one.\n * The time is measured, not assumed: `19:13` is five columns, but the system\n * locale can make it `19 h 13`, and a fixed five pushed that onto a second row\n * of every turn. The transcript's row estimate uses the same measure, so a\n * wrapped prompt is sized before it mounts exactly as it renders.\n */\nexport function userTurnTextWidth(terminalWidth: number, time: string): number {\n const rowWidth = transcriptGrid(terminalWidth).width - 1;\n const timeColumn = time ? displayWidth(time) + 2 : 1;\n return Math.max(8, rowWidth - CONTENT_COLUMN - timeColumn);\n}\n\n/** A run of prompt text, accented when it is an @mention. */\nexport interface PromptPiece {\n text: string;\n isMention: boolean;\n}\n\nconst TAB = ' ';\n\n/**\n * Wraps one hard line of a prompt into rows of at most `width` columns.\n *\n * `mentionRanges` are this line's, already resolved against the whole prompt and\n * given in columns of `line`. The line's indentation is kept, on its first row\n * and on every row it wraps onto, so a pasted code block keeps its shape. Words\n * break at whitespace, and a run of spaces at a break is dropped rather than\n * carried to the end of a row where it would push it past `width`. An @mention is\n * one unbreakable word, so a quoted path that wraps keeps its accent; only a word\n * wider than a whole row is cut.\n */\nfunction wrapPromptLine(\n line: string,\n width: number,\n mentionRanges: ReadonlyArray<[number, number]>,\n): PromptPiece[][] {\n const lead = /^[ \\t]*/.exec(line)![0];\n const body = line.slice(lead.length);\n if (!body) return [[]];\n // The line's own columns, past the indent the rows open with.\n const bodyRanges = mentionRanges\n .filter(([start, end]) => start >= lead.length && end <= line.length)\n .map(([start, end]): [number, number] => [start - lead.length, end - lead.length]);\n // Leave at least half the row for text, however deep the indent.\n const indent = lead.replace(/\\t/g, TAB).slice(0, Math.floor(width / 2));\n const indentWidth = displayWidth(indent);\n const room = Math.max(1, width - indentWidth);\n\n const rows: PromptPiece[][] = [];\n let row: PromptPiece[] = [];\n let used = 0;\n let space = '';\n const startRow = () => {\n row = indent ? [{ text: indent, isMention: false }] : [];\n used = 0;\n };\n const place = (word: PromptPiece) => {\n const chunks = hardWrapLine(word.text, room);\n chunks.forEach((chunk, index) => {\n if (index > 0) {\n rows.push(row);\n startRow();\n }\n row.push({ text: chunk, isMention: word.isMention });\n used = displayWidth(chunk);\n });\n };\n\n startRow();\n for (const segment of parseMentionSegments(body, bodyRanges)) {\n const tokens = segment.isMention ? [segment.text] : segment.text.split(/(\\s+)/);\n for (const token of tokens) {\n if (!token) continue;\n if (!segment.isMention && /^\\s+$/.test(token)) {\n space = token.replace(/\\t/g, TAB);\n continue;\n }\n const word = { text: token, isMention: segment.isMention };\n const wordWidth = displayWidth(token);\n if (used === 0) {\n place(word);\n } else if (used + displayWidth(space) + wordWidth <= room) {\n if (space) row.push({ text: space, isMention: false });\n row.push(word);\n used += displayWidth(space) + wordWidth;\n } else {\n rows.push(row);\n startRow();\n place(word);\n }\n space = '';\n }\n }\n rows.push(row);\n return rows;\n}\n\n/** A prompt as the transcript sets it: one entry per row, each within `width`. */\nexport function wrapUserPrompt(content: string, width: number): PromptPiece[][] {\n if (!content) return [];\n // The whole prompt is scanned once, before it is split: a fence or a code span\n // that crosses a line break is only visible with the lines together (#261).\n const ranges = mentionTokenRanges(content);\n let offset = 0;\n return content.split('\\n').flatMap((line) => {\n const lineRanges = ranges\n .filter(([start, end]) => start >= offset && end <= offset + line.length)\n .map(([start, end]): [number, number] => [start - offset, end - offset]);\n offset += line.length + 1;\n return wrapPromptLine(line, width, lineRanges);\n });\n}\n\n/** Rows a user turn takes at `terminalWidth`, for the transcript's row estimate. */\nexport function userTurnRows(\n content: string,\n terminalWidth: number,\n timestamp?: number,\n attachmentCount = 0,\n): number {\n const width = userTurnTextWidth(terminalWidth, formatTurnTime(timestamp));\n return Math.max(1, wrapUserPrompt(content, width).length + (attachmentCount > 0 ? 1 : 0));\n}\n\n/**\n * A user turn, set the way a rubricated manuscript opens a paragraph.\n *\n * A red pilcrow hangs in the gutter and the prompt is set upright in the\n * brightest ink on screen, a step above the agent's prose, so your words read as\n * a different voice without a band, a box or a rule through the screen. The\n * pilcrow is what a long transcript is scanned by: it is the only red mark at\n * the margin, and it is the same mark as the composer's, so what you typed\n * lands in the transcript under the glyph you typed it after. The time sits at\n * the right edge of the first row. @mentions stay accented.\n */\nfunction UserMessageInner({\n content,\n attachments = [],\n terminalWidth = 80,\n timestamp,\n screenReader = false,\n}: UserMessageProps) {\n const theme = useTheme();\n const grid = transcriptGrid(terminalWidth);\n const width = grid.width;\n\n if (screenReader) {\n return (\n <Box width={width}>\n <Text wrap=\"wrap\">\n {content}\n {attachments.length > 0\n ? `${content ? '\\n' : ''}${attachments.length} image attachment${attachments.length === 1 ? '' : 's'}`\n : ''}\n </Text>\n </Box>\n );\n }\n\n const time = formatTurnTime(timestamp);\n // The row leaves the terminal's last column empty, like every other row.\n const rowWidth = width - 1;\n const textWidth = userTurnTextWidth(terminalWidth, time);\n const rows: Array<{ pieces: PromptPiece[]; attachment?: string }> = wrapUserPrompt(\n content,\n textWidth,\n ).map((pieces) => ({ pieces }));\n if (attachments.length > 0) {\n rows.push({\n pieces: [],\n attachment: attachments.map((_, index) => `[image ${index + 1}]`).join(' '),\n });\n }\n if (rows.length === 0) rows.push({ pieces: [] });\n\n return (\n <Box flexDirection=\"column\" width={rowWidth}>\n {rows.map((row, index) => {\n const rowText = row.attachment ?? row.pieces.map((piece) => piece.text).join('');\n const gap = Math.max(0, textWidth - displayWidth(rowText));\n return (\n <Box key={index} width={rowWidth}>\n <Text color={theme.userAccent}>{index === 0 ? `${PILCROW} ` : ' '}</Text>\n {row.attachment !== undefined ? (\n <Text color={theme.userAccent}>{row.attachment}</Text>\n ) : (\n row.pieces.map((piece, i) => (\n <Text key={i} color={piece.isMention ? theme.userAccent : theme.userText}>\n {piece.text}\n </Text>\n ))\n )}\n {index === 0 && time ? (\n <>\n <Text>{' '.repeat(gap)}</Text>\n <Text color={theme.inactive}> {time}</Text>\n </>\n ) : null}\n </Box>\n );\n })}\n </Box>\n );\n}\n\nexport const UserMessage = React.memo(UserMessageInner);\n","import { Box, Text } from 'ink';\nimport { basename } from 'path';\nimport { useLayoutEffect } from 'react';\nimport type React from 'react';\nimport { useStaggeredReveal } from '../hooks/useAnimation.js';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\nimport { useTranscriptLayoutChange, useTranscriptViewport } from '../transcript-layout.js';\nimport { PILCROW } from '../marks.js';\nimport { formatAge } from '../relative-age.js';\nimport { romanNumeral } from '../roman.js';\nimport { displaySessionName } from '../../session/name.js';\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\n\n/** A past session of this workspace, listed on the title page as a chapter. */\nexport interface RecentChapter {\n id: string;\n name?: string;\n updatedAt: number;\n messageCount: number;\n}\n\ninterface WelcomeScreenProps {\n terminalWidth: number;\n terminalHeight: number;\n workspace?: string;\n model?: string;\n mode?: string;\n commandCount?: number;\n skillCount?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n /** When false, the welcome renders directly in its settled state. */\n animate?: boolean;\n /** This workspace's recent sessions, newest first; the title page's contents. */\n recentSessions?: readonly RecentChapter[];\n /**\n * The sessions are still being listed. The page then leaves its contents\n * out, instead of showing the getting-started list a returning reader would\n * see flip to their chapters a moment later.\n */\n contentsPending?: boolean;\n /** The clock the chapter ages are measured against. Tests pin it. */\n now?: number;\n}\n\nexport interface WelcomeHint {\n /** What the user types. */\n key: string;\n /** What it does. */\n label: string;\n}\n\n/** What a first-run user most needs to know, in the order they need it. */\nexport const WELCOME_HINTS: readonly WelcomeHint[] = [\n { key: '/help', label: 'commands' },\n { key: '@file', label: 'context' },\n { key: '/skills', label: 'workflows' },\n { key: '!cmd', label: 'shell' },\n { key: 'Ctrl+/', label: 'shortcuts' },\n];\n\n/** The index row under a title page that lists past chapters. */\nconst CHAPTER_HINTS: readonly WelcomeHint[] = [\n { key: '/resume', label: 'open a chapter' },\n { key: '/help', label: 'commands' },\n { key: '@file', label: 'context' },\n { key: '!cmd', label: 'shell' },\n { key: 'Ctrl+/', label: 'shortcuts' },\n];\n\n/** Columns between one hint and the next. */\nconst HINT_GAP = 4;\n\nconst TAGLINE = 'Ask anything, or type / for a command.';\n\n/**\n * A tiny terminal gets the short form. The hint row below already reads\n * `/help commands`, so orientation survives losing the long sentence — and a\n * truncated tagline reads as breakage, not brevity.\n */\nconst TAGLINE_TINY = 'Ask anything.';\n\n/**\n * Choose the hints that fit the available width, whole.\n *\n * A hint is never partially rendered: the previous screen truncated each\n * segment against its own budget inside a row that also held fixed separators,\n * so a 50-column terminal advertised `/hel commands` — a command that does not\n * exist. Dropping the last hint is always better than inventing one.\n */\nexport function composeWelcomeHints(hints: readonly WelcomeHint[], width: number): WelcomeHint[] {\n const budget = Math.max(0, Math.floor(width));\n const chosen: WelcomeHint[] = [];\n let used = 0;\n for (const hint of hints) {\n const cost = displayWidth(`${hint.key} ${hint.label}`) + (chosen.length > 0 ? HINT_GAP : 0);\n if (used + cost > budget) break;\n chosen.push(hint);\n used += cost;\n }\n return chosen;\n}\n\nfunction workspaceName(workspace?: string): string {\n if (!workspace) return 'workspace';\n return basename(workspace) || workspace;\n}\n\nfunction WelcomeLine({ visible, children }: { visible: boolean; children: React.ReactNode }) {\n return <Box>{visible ? children : <Text> </Text>}</Box>;\n}\n\nfunction HintRow({ hints }: { hints: readonly WelcomeHint[] }) {\n const theme = useTheme();\n return (\n <Box>\n {hints.map((hint, index) => (\n <Text key={hint.key}>\n {index > 0 ? ' '.repeat(HINT_GAP) : ''}\n <Text color={theme.text}>{hint.key}</Text>\n <Text color={theme.inactive}> {hint.label}</Text>\n </Text>\n ))}\n </Box>\n );\n}\n\n/**\n * The drop cap the title page opens on.\n *\n * A B five rows tall, drawn in half blocks (an 8×10 pixel glyph, two pixels per\n * cell: `▀` top, `▄` bottom, `█` both) and set in rubric, the way an\n * illuminated manuscript opens its first chapter. The stem is two pixels wide\n * and the lower bowl a column wider than the upper, as a printed B is; a\n * narrower draft pinched the waist so deep it read as an E. The rest of the\n * word, the rule and the contents are set beside and below it on the\n * transcript grid. Keep the rows the same width, or the text beside the cap\n * shears.\n */\nexport const DROP_CAP = ['██▀▀▀█▄ ', '██ ▄█▀ ', '██▀▀▀▄▄ ', '██ ██', '██▄▄▄█▀ '] as const;\n\n/** Columns between the drop cap and the text set beside it. */\nconst DROP_CAP_GAP = 3;\n\n/**\n * Widest the title page is set, however wide the terminal. The transcript\n * takes the whole width; a page of contents with dot leaders running across\n * two hundred columns reads as a ruler, not a page.\n */\nconst PAGE_MEASURE = 96;\n\n/** Columns the chapter numeral takes: `iii.` and a space of air. */\nconst NUMERAL_WIDTH = 6;\n\n/** Fewest leader columns an entry keeps between its title and its page. */\nconst LEADER_MIN = 5;\n\n/** Most chapters the contents list. */\nexport const CONTENTS_MAX = 5;\n\n/**\n * What the contents list before a first session: the things a new reader\n * needs, set as a table of contents with the key to press where the page\n * number would be.\n */\nconst FIRST_RUN_CONTENTS: ReadonlyArray<{ title: string; page: string }> = [\n { title: 'Ask for a change in your own words', page: PILCROW },\n { title: 'Point at a file', page: '@path' },\n { title: 'Run a shell command', page: '!cmd' },\n { title: 'Use a skill', page: '/skills' },\n { title: 'See every command', page: '/help' },\n { title: 'Keyboard shortcuts', page: 'Ctrl+/' },\n];\n\n/**\n * Rows the composer and status line take below the transcript: the estimate\n * used until the transcript viewport has been measured.\n */\nexport const WELCOME_FOOTER_ROWS = 5;\n\n/**\n * A dot leader, as a printed table of contents sets one.\n *\n * Periods, not `·`: a leader repeats its glyph dozens of times, and `·` is\n * ambiguous-width, so a terminal that draws it two cells wide would wrap the\n * row. The dots sit on even absolute columns, so the leaders of every entry\n * line up down the page, and a space of air is kept at each end.\n */\nexport function dotLeader(startColumn: number, width: number): string {\n const size = Math.max(0, Math.floor(width));\n if (size < 3) return ' '.repeat(size);\n let leader = ' ';\n for (let offset = 1; offset < size - 1; offset++) {\n leader += (startColumn + offset) % 2 === 0 ? '.' : ' ';\n }\n return `${leader} `;\n}\n\ninterface ContentsEntry {\n numeral: string;\n title: string;\n page: string;\n /** Keys read as ink; ages read as a quiet margin figure. */\n pageTone: 'key' | 'age';\n}\n\nfunction contentsEntries(\n recentSessions: readonly RecentChapter[],\n now: number,\n): { entries: ContentsEntry[]; chapters: boolean } {\n if (recentSessions.length > 0) {\n return {\n chapters: true,\n entries: recentSessions.slice(0, CONTENTS_MAX).map((session, index) => ({\n numeral: `${romanNumeral(index + 1)}.`,\n title: displaySessionName(session.name),\n page: formatAge(session.updatedAt, now),\n pageTone: 'age',\n })),\n };\n }\n return {\n chapters: false,\n entries: FIRST_RUN_CONTENTS.map((entry, index) => ({\n numeral: `${romanNumeral(index + 1)}.`,\n title: entry.title,\n page: entry.page,\n pageTone: 'key',\n })),\n };\n}\n\n/**\n * How much of the title page fits in `availableRows`: all of it, or the drop\n * cap block alone. An open menu takes ten rows from the transcript; a page\n * that shed entries one at a time left a CONTENTS heading over nothing, so it\n * is the whole page or the cap. It never draws part of the cap. One row is kept\n * as slack, since the measured viewport can run a row past what shows.\n */\nexport function fitTitlePage(\n availableRows: number,\n entryCount: number,\n hasIndex: boolean,\n): { topPadding: number; entries: number; index: boolean; show: boolean } {\n const rows = Math.floor(availableRows) - 1;\n const capRows = DROP_CAP.length;\n const full = capRows + entryCount + (hasIndex ? 2 : 0);\n if (rows >= full) {\n return {\n topPadding: Math.floor((rows - full) * 0.35),\n entries: entryCount,\n index: hasIndex,\n show: true,\n };\n }\n if (rows >= capRows) return { topPadding: 0, entries: 0, index: false, show: true };\n return { topPadding: 0, entries: 0, index: false, show: false };\n}\n\nexport function WelcomeScreen({\n terminalWidth,\n terminalHeight,\n workspace,\n model = 'model',\n mode = 'default',\n reducedMotion = false,\n screenReader = false,\n animate = true,\n recentSessions = [],\n contentsPending = false,\n now = Date.now(),\n}: WelcomeScreenProps) {\n const theme = useTheme();\n const viewport = useTranscriptViewport();\n const grid = transcriptGrid(terminalWidth);\n const width = grid.width;\n const height = Math.max(8, Math.floor(terminalHeight));\n // The rows the transcript can actually show. An open menu takes ten rows from\n // it, and a title page padded for the closed footer would overflow and be cut\n // through the middle of the drop cap. Until the viewport is measured (it\n // starts at one row), estimate from the terminal height.\n const availableRows =\n viewport && viewport.viewportRows > 1 ? viewport.viewportRows : height - WELCOME_FOOTER_ROWS;\n const compact = width < 64 || height < 18;\n const tiny = width < 42 || height < 12;\n const motionDisabled = reducedMotion || screenReader || !animate;\n const reveal = useStaggeredReveal(tiny ? 2 : compact ? 3 : 4, animate, 110, motionDisabled);\n const tagline = tiny ? TAGLINE_TINY : TAGLINE;\n const contentWidth = grid.content;\n const meta = `${workspaceName(workspace)} · ${model} · ${mode}`;\n const hints = composeWelcomeHints(WELCOME_HINTS, contentWidth);\n\n if (screenReader) {\n const recent = recentSessions.slice(0, CONTENTS_MAX);\n return (\n <Box flexDirection=\"column\" paddingLeft={CONTENT_COLUMN} width={width}>\n <Text bold>Book</Text>\n <Text>{truncateDisplay(tagline, contentWidth)}</Text>\n {/* Prose, not the `·`-joined chip row: a screen reader reads a\n sentence far better than a list of separators. */}\n <Text>\n {truncateDisplay(\n `Workspace ${workspaceName(workspace)}. Model ${model}. Mode ${mode}.`,\n contentWidth,\n )}\n </Text>\n {recent.length > 0 ? (\n <Text>\n {`Recent sessions: ${recent\n .map(\n (session) =>\n `${displaySessionName(session.name)}, ${formatAge(session.updatedAt, now)}`,\n )\n .join('; ')}. Type /resume to open one.`}\n </Text>\n ) : null}\n <Text>\n {truncateDisplay(\n 'Type /help for commands, Ctrl+/ for shortcuts, @file for context, !cmd for shell.',\n contentWidth,\n )}\n </Text>\n </Box>\n );\n }\n\n if (tiny) {\n return (\n <Box flexDirection=\"column\" width={width}>\n <Box paddingLeft={CONTENT_COLUMN}>\n {/* The drop cap in miniature: a rubricated B, then the word in ink. */}\n <Text color={theme.brand} bold>\n B\n </Text>\n <Text color={theme.text} bold>\n ook{' '}\n </Text>\n <Text color={theme.text}>{truncateDisplay(tagline, contentWidth - 5)}</Text>\n </Box>\n <WelcomeLine visible={reveal >= 1}>\n <Box paddingLeft={CONTENT_COLUMN}>\n <HintRow hints={composeWelcomeHints(WELCOME_HINTS, contentWidth)} />\n </Box>\n </WelcomeLine>\n </Box>\n );\n }\n\n if (compact) {\n return (\n <Box flexDirection=\"column\" width={width}>\n <Box paddingLeft={CONTENT_COLUMN}>\n {/* The drop cap in miniature: a rubricated B, then the word in ink. */}\n <Text color={theme.brand} bold>\n B\n </Text>\n <Text color={theme.text} bold>\n ook{' '}\n </Text>\n <Text color={theme.text}>{truncateDisplay(tagline, contentWidth - 5)}</Text>\n </Box>\n <WelcomeLine visible={reveal >= 1}>\n <Box paddingLeft={CONTENT_COLUMN}>\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(meta, contentWidth)}\n </Text>\n </Box>\n </WelcomeLine>\n <WelcomeLine visible={reveal >= 2}>\n <Box paddingLeft={CONTENT_COLUMN}>\n <HintRow hints={hints} />\n </Box>\n </WelcomeLine>\n </Box>\n );\n }\n\n return (\n <TitlePage\n width={width}\n pageWidth={Math.min(contentWidth, PAGE_MEASURE)}\n availableRows={availableRows}\n workspace={workspace}\n model={model}\n recentSessions={recentSessions}\n contentsPending={contentsPending}\n now={now}\n />\n );\n}\n\n/**\n * The title page an empty session opens on, set like the first page of a book.\n *\n * ██▀▀▀█▄ O O K book · space-bunny-alpha\n * ██ ▄█▀ ─────────────────────────────────────────────────────────────────────\n * ██▀▀█▄ Pick up a chapter with /resume, or begin a new one below.\n * ██ ██\n * ██▄▄▄█▀ C O N T E N T S\n * i. Fix the timeout fallback in the config loader . . . . . 2h ago\n * ii. Add retry backoff to the fetch client . . . . . . . . 1d ago\n *\n * /resume open a chapter /help commands @file context …\n *\n * The contents are this workspace's recent sessions, with their age where a\n * book prints the page. Before a first session they list what a new reader\n * needs, with the key to press as the page. Left-aligned on the transcript\n * grid, so the page begins where the conversation will.\n */\nfunction TitlePage({\n width,\n pageWidth,\n availableRows,\n workspace,\n model,\n recentSessions,\n contentsPending,\n now,\n}: {\n width: number;\n pageWidth: number;\n availableRows: number;\n workspace?: string;\n model: string;\n recentSessions: readonly RecentChapter[];\n contentsPending: boolean;\n now: number;\n}) {\n const theme = useTheme();\n const notifyLayoutChange = useTranscriptLayoutChange();\n const { entries, chapters } = contentsPending\n ? { entries: [], chapters: false }\n : contentsEntries(recentSessions, now);\n const fit = fitTitlePage(availableRows, entries.length, chapters);\n // The page resizes itself to the viewport (a menu opening shrinks it to the\n // cap), and the transcript only re-measures its content when told.\n const fitKey = `${fit.show}:${fit.entries}:${fit.index}:${fit.topPadding}`;\n useLayoutEffect(() => {\n notifyLayoutChange?.();\n }, [fitKey, notifyLayoutChange]);\n if (!fit.show) return <Box />;\n\n const capWidth = displayWidth(DROP_CAP[0]);\n const textColumn = capWidth + DROP_CAP_GAP;\n const textWidth = Math.max(12, pageWidth - textColumn);\n const word = 'O O K';\n const runningHead = truncateDisplay(\n `${workspaceName(workspace)} · ${model}`,\n Math.max(0, textWidth - displayWidth(word) - 4),\n );\n const tagline = contentsPending\n ? ''\n : chapters\n ? 'Pick up a chapter with /resume, or begin a new one below.'\n : 'Your first chapter begins below.';\n const beside: React.ReactNode[] = [\n <Box key=\"title\" width={textWidth}>\n <Text color={theme.text} bold>\n {word}\n </Text>\n <Text>\n {' '.repeat(Math.max(1, textWidth - displayWidth(word) - displayWidth(runningHead)))}\n </Text>\n <Text color={theme.inactive}>{runningHead}</Text>\n </Box>,\n <Text key=\"rule\" color={theme.border}>\n {'─'.repeat(textWidth)}\n </Text>,\n <Text key=\"tagline\" color={theme.subtle} italic>\n {truncateDisplay(tagline, textWidth)}\n </Text>,\n null,\n fit.entries > 0 ? (\n <Text key=\"contents\" color={theme.inactive}>\n C O N T E N T S\n </Text>\n ) : null,\n ];\n\n return (\n <Box flexDirection=\"column\" width={width - 1} paddingLeft={CONTENT_COLUMN}>\n {fit.topPadding > 0 ? <Box height={fit.topPadding} /> : null}\n {DROP_CAP.map((row, index) => (\n <Box key={`cap-${index}`}>\n <Text color={theme.brand}>{row}</Text>\n <Text>{' '.repeat(DROP_CAP_GAP)}</Text>\n {beside[index]}\n </Box>\n ))}\n {entries.slice(0, fit.entries).map((entry) => {\n const pageWidthUsed = displayWidth(entry.page);\n const titleRoom = Math.max(4, textWidth - NUMERAL_WIDTH - pageWidthUsed - LEADER_MIN);\n const title = truncateDisplay(entry.title, titleRoom);\n const leaderStart = CONTENT_COLUMN + textColumn + NUMERAL_WIDTH + displayWidth(title);\n const leaderWidth = textWidth - NUMERAL_WIDTH - displayWidth(title) - pageWidthUsed;\n return (\n <Box key={`${entry.numeral}-${entry.title}`} paddingLeft={textColumn}>\n <Text color={theme.brand}>{entry.numeral.padEnd(NUMERAL_WIDTH)}</Text>\n <Text color={theme.text}>{title}</Text>\n <Text color={theme.border}>{dotLeader(leaderStart, leaderWidth)}</Text>\n <Text color={entry.pageTone === 'key' ? theme.text : theme.inactive}>{entry.page}</Text>\n </Box>\n );\n })}\n {fit.index ? (\n <>\n <Text> </Text>\n <Box paddingLeft={textColumn}>\n <HintRow hints={composeWelcomeHints(CHAPTER_HINTS, textWidth)} />\n </Box>\n </>\n ) : null}\n </Box>\n );\n}\n","/**\n * How long ago a timestamp was, in the short form every picker uses:\n * `just now`, `12m ago`, `3h ago`, `2d ago`. `now` is injectable so a test can\n * pin the clock.\n */\nexport function formatAge(timestamp: number, now: number = Date.now()): string {\n const seconds = Math.max(0, Math.floor((now - timestamp) / 1000));\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.floor(hours / 24)}d ago`;\n}\n","/**\n * A number the way a book prints it in its front matter: `i`, `iv`, `xii`.\n * Zero and negative numbers have no numeral.\n */\nexport function romanNumeral(value: number): string {\n let n = Math.floor(value);\n if (n <= 0) return '';\n const steps: Array<[number, string]> = [\n [1000, 'm'],\n [900, 'cm'],\n [500, 'd'],\n [400, 'cd'],\n [100, 'c'],\n [90, 'xc'],\n [50, 'l'],\n [40, 'xl'],\n [10, 'x'],\n [9, 'ix'],\n [5, 'v'],\n [4, 'iv'],\n [1, 'i'],\n ];\n let out = '';\n for (const [step, numeral] of steps) {\n while (n >= step) {\n out += numeral;\n n -= step;\n }\n }\n return out;\n}\n","import { Box, measureElement, type DOMElement } from 'ink';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n TranscriptViewportContext,\n useTranscriptLayoutChange,\n useTranscriptViewport,\n} from '../transcript-layout.js';\n\nconst DEFAULT_MAX_MOUNTED_ITEMS = 512;\n\nexport interface VirtualTranscriptRange {\n startIndex: number;\n endIndex: number;\n topSpacerRows: number;\n bottomSpacerRows: number;\n totalRows: number;\n}\n\ninterface UseVirtualTranscriptOptions<T> {\n items: readonly T[];\n enabled: boolean;\n terminalWidth: number;\n leadingRows?: number;\n getKey: (item: T) => string;\n estimateRows: (item: T) => number;\n}\n\nexport interface VirtualTranscriptWindow<T> extends VirtualTranscriptRange {\n entries: Array<{\n item: T;\n index: number;\n key: string;\n measurementKey: string;\n /** Pass to `VirtualTranscriptRow`'s `reserveRows`. */\n reserveRows: number | undefined;\n }>;\n measure: (measurementKey: string, rows: number) => void;\n virtualized: boolean;\n /** Sum of the pre-measurement row estimates for all items. */\n estimatedTotalRows: number;\n}\n\ninterface DerivedItemEntry {\n width: number;\n key: string;\n estimate: number;\n measurementKey: string;\n}\n\nfunction lowerBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if ((values[middle] ?? 0) < target) low = middle + 1;\n else high = middle;\n }\n return low;\n}\n\nexport function getVirtualTranscriptRange(\n heights: readonly number[],\n scrollTop: number,\n viewportRows: number,\n overscanRows: number,\n followBottom: boolean,\n maxMountedItems = DEFAULT_MAX_MOUNTED_ITEMS,\n): VirtualTranscriptRange {\n const offsets = new Array<number>(heights.length + 1);\n offsets[0] = 0;\n for (let index = 0; index < heights.length; index++) {\n offsets[index + 1] = offsets[index]! + Math.max(1, Math.floor(heights[index] ?? 1));\n }\n\n const totalRows = offsets[heights.length] ?? 0;\n if (heights.length === 0) {\n return { startIndex: 0, endIndex: 0, topSpacerRows: 0, bottomSpacerRows: 0, totalRows };\n }\n\n const viewport = Math.max(1, Math.floor(viewportRows));\n const overscan = Math.max(0, Math.floor(overscanRows));\n const maxScrollTop = Math.max(0, totalRows - viewport);\n const effectiveScrollTop = followBottom\n ? maxScrollTop\n : Math.max(0, Math.min(Math.floor(scrollTop), maxScrollTop));\n const firstRow = Math.max(0, effectiveScrollTop - overscan);\n const lastRow = Math.min(totalRows, effectiveScrollTop + viewport + overscan);\n\n let startIndex = Math.max(0, lowerBound(offsets, firstRow) - 1);\n let endIndex = Math.min(heights.length, Math.max(startIndex + 1, lowerBound(offsets, lastRow)));\n const mountedLimit = Math.max(1, Math.floor(maxMountedItems));\n if (endIndex - startIndex > mountedLimit) {\n if (followBottom) startIndex = endIndex - mountedLimit;\n else endIndex = startIndex + mountedLimit;\n }\n\n return {\n startIndex,\n endIndex,\n topSpacerRows: offsets[startIndex] ?? 0,\n bottomSpacerRows: totalRows - (offsets[endIndex] ?? totalRows),\n totalRows,\n };\n}\n\nexport function useVirtualTranscript<T>({\n items,\n enabled,\n terminalWidth,\n leadingRows = 0,\n getKey,\n estimateRows,\n}: UseVirtualTranscriptOptions<T>): VirtualTranscriptWindow<T> {\n const viewport = useTranscriptViewport();\n const notifyLayoutChange = useTranscriptLayoutChange();\n const heightCacheRef = useRef(new Map<string, number>());\n const [heightVersion, setHeightVersion] = useState(0);\n const width = Math.max(1, Math.floor(terminalWidth));\n\n // Cache per-item derived values by item identity so a streaming update only\n // recomputes the one message whose object changed, not the whole window.\n const derivedCacheRef = useRef(new WeakMap<object, DerivedItemEntry>());\n const derivedFnsRef = useRef({ getKey, estimateRows });\n if (\n derivedFnsRef.current.getKey !== getKey ||\n derivedFnsRef.current.estimateRows !== estimateRows\n ) {\n derivedCacheRef.current = new WeakMap();\n derivedFnsRef.current = { getKey, estimateRows };\n }\n const derived = useMemo(() => {\n const cache = derivedCacheRef.current;\n const itemKeys = new Array<string>(items.length);\n const estimatedRows = new Array<number>(items.length);\n const measurementKeys = new Array<string>(items.length);\n let estimatedTotalRows = 0;\n for (let index = 0; index < items.length; index++) {\n const item = items[index]!;\n const cacheable = typeof item === 'object' && item !== null;\n let entry = cacheable ? cache.get(item as object) : undefined;\n if (!entry || entry.width !== width) {\n const key = getKey(item);\n const estimate = Math.max(1, Math.ceil(estimateRows(item)));\n entry = { width, key, estimate, measurementKey: `${width}:${key}:${estimate}` };\n if (cacheable) cache.set(item as object, entry);\n }\n itemKeys[index] = entry.key;\n estimatedRows[index] = entry.estimate;\n measurementKeys[index] = entry.measurementKey;\n estimatedTotalRows += entry.estimate;\n }\n return { itemKeys, estimatedRows, measurementKeys, estimatedTotalRows };\n }, [estimateRows, getKey, items, width]);\n const { itemKeys, estimatedRows, measurementKeys, estimatedTotalRows } = derived;\n const heights = useMemo(\n () =>\n items.map((item, index) =>\n Math.max(1, heightCacheRef.current.get(measurementKeys[index]!) ?? estimatedRows[index]!),\n ),\n [estimatedRows, heightVersion, items, measurementKeys],\n );\n\n useEffect(() => {\n const activeKeys = new Set(measurementKeys);\n for (const key of heightCacheRef.current.keys()) {\n if (!activeKeys.has(key)) heightCacheRef.current.delete(key);\n }\n }, [measurementKeys]);\n\n useLayoutEffect(() => {\n if (heightVersion > 0) notifyLayoutChange?.();\n }, [heightVersion, notifyLayoutChange]);\n\n // What the last render laid out, for `measure` to find where a reporting row starts.\n const laidOutRef = useRef({ measurementKeys, heights, leadingRows });\n laidOutRef.current = { measurementKeys, heights, leadingRows };\n const viewportStore = useContext(TranscriptViewportContext);\n const viewportStoreRef = useRef(viewportStore);\n viewportStoreRef.current = viewportStore;\n\n const measure = useCallback((measurementKey: string, rows: number) => {\n const height = Math.max(1, Math.floor(rows));\n if (heightCacheRef.current.get(measurementKey) === height) return;\n heightCacheRef.current.set(measurementKey, height);\n // A row that mounted with an estimated height pushes everything under it by the difference.\n // When the whole row is above the view, the view has to move with it or the text being read\n // jumps. A row the view cuts through is left alone: it changed where the reader is looking.\n const laidOut = laidOutRef.current;\n const index = laidOut.measurementKeys.indexOf(measurementKey);\n const laidOutHeight = index >= 0 ? laidOut.heights[index] : undefined;\n if (laidOutHeight !== undefined && laidOutHeight !== height) {\n let endRow = Math.max(0, laidOut.leadingRows) + laidOutHeight;\n for (let item = 0; item < index; item++) endRow += laidOut.heights[item] ?? 1;\n viewportStoreRef.current?.anchorRowsAbove?.(endRow, height - laidOutHeight);\n }\n setHeightVersion((version) => version + 1);\n }, []);\n\n const shouldVirtualize = enabled && viewport !== null;\n const range = useMemo(() => {\n if (!shouldVirtualize) {\n const totalRows = heights.reduce((sum, rows) => sum + rows, 0);\n return {\n startIndex: 0,\n endIndex: items.length,\n topSpacerRows: 0,\n bottomSpacerRows: 0,\n totalRows,\n };\n }\n\n return getVirtualTranscriptRange(\n heights,\n Math.max(0, viewport.scrollTop - Math.max(0, leadingRows)),\n viewport.viewportRows,\n Math.max(12, viewport.viewportRows),\n viewport.followBottom,\n );\n }, [heights, items.length, leadingRows, shouldVirtualize, viewport]);\n\n // A row that has never been measured and mounts wholly above the view is held at the height it\n // was laid out with until it is measured (`VirtualTranscriptRow`'s `reserveRows`). Ink draws a\n // commit before its layout effects run, so without the hold the frame that mounts it would show\n // the text in view pushed by the row's estimate error, and only the next frame would anchor it back.\n const viewportTop = shouldVirtualize && !viewport.followBottom ? viewport.scrollTop : null;\n let rowTop = Math.max(0, leadingRows) + range.topSpacerRows;\n const entries = items.slice(range.startIndex, range.endIndex).map((item, offset) => {\n const index = range.startIndex + offset;\n const measurementKey = measurementKeys[index]!;\n const laidOutRows = heights[index]!;\n const reserveRows =\n viewportTop !== null &&\n rowTop + laidOutRows <= viewportTop &&\n !heightCacheRef.current.has(measurementKey)\n ? laidOutRows\n : undefined;\n rowTop += laidOutRows;\n return { item, index, key: itemKeys[index]!, measurementKey, reserveRows };\n });\n\n return {\n ...range,\n entries,\n measure,\n virtualized: shouldVirtualize,\n estimatedTotalRows,\n };\n}\n\nexport const VirtualTranscriptRow = React.memo(function VirtualTranscriptRow({\n measurementKey,\n onMeasure,\n reserveRows,\n children,\n}: {\n measurementKey: string;\n onMeasure: (measurementKey: string, rows: number) => void;\n /**\n * Hold the row at this many rows, clipped, until it is measured: set for a row that mounts\n * above the view, so its estimate error lands in the same commit that anchors the view.\n * Read on mount only.\n */\n reserveRows?: number;\n children: React.ReactNode;\n}) {\n const contentRef = useRef<DOMElement>(null);\n const [reserved, setReserved] = useState(reserveRows);\n\n useLayoutEffect(() => {\n if (!contentRef.current) return;\n onMeasure(measurementKey, measureElement(contentRef.current).height);\n // Released in the same commit as the measurement it reported, so the anchored scroll and the\n // row's real height are drawn together.\n if (reserved !== undefined) setReserved(undefined);\n }, [children, measurementKey, onMeasure, reserved]);\n\n // The inner box keeps its natural height inside a held outer one, so it measures the same\n // either way, and the tree keeps one shape so releasing the hold does not remount the row.\n return (\n <Box\n flexDirection=\"column\"\n flexShrink={0}\n height={reserved}\n overflow={reserved === undefined ? undefined : 'hidden'}\n >\n <Box ref={contentRef} flexDirection=\"column\" flexShrink={0}>\n {children}\n </Box>\n </Box>\n );\n});\n","import { Box, Text } from 'ink';\nimport { useState, useCallback, useEffect, useLayoutEffect, useRef, useMemo } from 'react';\nimport { useInput } from 'ink';\nimport { useTheme } from '../theme.js';\nimport { CommandMenu } from './CommandMenu.js';\nimport { FileMentionMenu } from './FileMentionMenu.js';\nimport { SkillMentionMenu } from './SkillMentionMenu.js';\nimport type { PermissionMode } from '../../types/runtime.js';\nimport type { ImageAttachment } from '../../types/messages.js';\nimport type { SlashCommand } from '../../types/commands.js';\nimport type { Skill } from '../../skills.js';\nimport { isShortcutsToggleKey } from '../tool-presentation.js';\nimport { CONTENT_COLUMN, frameGrid } from '../layout.js';\nimport { PILCROW } from '../marks.js';\nimport {\n findActiveFileMention,\n getFileMentionCandidates,\n replaceActiveFileMention,\n type ActiveFileMention,\n type FileMentionCandidate,\n} from '../../input/file-mentions.js';\nimport {\n findActiveSkillMention,\n getSkillMentionCandidates,\n replaceActiveSkillMention,\n type ActiveSkillMention,\n type SkillMentionCandidate,\n} from '../../input/skill-mentions.js';\nimport { recordCommandUse } from '../../commands/recent.js';\nimport {\n getCommandsForEmptyQuery,\n getCommandsForQuery,\n type CommandItem,\n} from '../../commands/filter.js';\nimport { createUiDebugLogger } from '../../debug-log.js';\nimport { useDebugMount } from '../debug.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\nimport { COMPOSER_EDIT_KEYS, COMPOSER_PAGER_KEYS, InputBox } from './InputBox.js';\nimport { displayWidth, wordWrap } from './word-wrap.js';\n\nconst uiLog = createUiDebugLogger('tui:inputbar');\nconst FILE_MENTION_DEBOUNCE_MS = 40;\n\n/**\n * Rows the draft takes in the composer at `width`, soft wraps included. The\n * cursor is one more cell at the end of the last line. Counting only hard\n * newlines missed a long prompt growing from one row to three, so the\n * transcript kept its old viewport and the composer covered its last rows.\n */\nexport function draftRows(value: string, width: number): number {\n const lines = value.split('\\n');\n return lines.reduce((rows, line, index) => {\n const cells = displayWidth(line) + (index === lines.length - 1 ? 1 : 0);\n const wrapped = line ? wordWrap(line, width).split('\\n').length : 1;\n return rows + Math.max(1, wrapped, Math.ceil(cells / Math.max(1, width)));\n }, 0);\n}\n\ninterface InputBarProps {\n onSubmit: (value: string, attachments?: ImageAttachment[]) => void;\n /**\n * Called when the composer's height may have changed (a menu opened or\n * closed, the draft gained or lost a line). The transcript above measures its\n * viewport only on its own layout changes, and a menu is state the app never\n * sees, so without this the viewport kept its old height and the menu covered\n * the transcript's last rows.\n */\n onLayoutChange?: () => void;\n /**\n * Called after a composer menu (commands, `@file`, `$skill`) opens or closes.\n * Ink hands every key to every input handler, so the app needs this to leave\n * an Esc alone that the open menu is already taking.\n */\n onMenuOpenChange?: (open: boolean) => void;\n onPasteImage?: () => Promise<ImageAttachment | null>;\n submissionMode: 'submit' | 'queue' | 'blocked';\n mode: PermissionMode;\n onCycleMode: () => void;\n terminalWidth?: number;\n maxMenuRows?: number;\n compact?: boolean;\n screenReader?: boolean;\n /**\n * True when a higher-priority modal (permission prompt) owns the keyboard.\n * Ink's `useInput` fans every keypress to ALL registered handlers regardless\n * of focus, so InputBar must silence BOTH its own `useInput` and InputBox's\n * (via `focus`) while a modal is up — otherwise Enter/Tab/Esc double-fire and\n * the user confirming a permission accidentally interrupts the stream.\n */\n inputSuppressed?: boolean;\n /**\n * Whether the thing holding the keyboard is actually asking the user something\n * — a permission prompt, a plan approval, a question, an elicitation.\n *\n * `inputSuppressed` covers that *and* the sheets that merely take the keys\n * while they are open (`/config`, `/model`, the rules list, the task\n * surface). Both silence the composer, but only the first is a prompt, and\n * telling someone to \"answer\" a settings menu describes a question that is\n * not being asked.\n */\n awaitingAnswer?: boolean;\n /** Allows immediate local commands such as /tasks while the parent is running. */\n canSubmitWhileBusy?: (value: string) => boolean;\n /** Allows conversational input to be queued while the parent is running. */\n canQueueWhileBusy?: (value: string) => boolean;\n /** Receives accepted queued input. Return false when the queue is full. */\n onQueue?: (value: string, attachments?: ImageAttachment[]) => boolean;\n /** Recalls the newest queued input when the composer is empty. */\n onRecallQueued?: () => string | { value: string; attachments?: ImageAttachment[] } | undefined;\n /** Keeps the parent aware of the live draft for interrupt restoration. */\n onDraftChange?: (value: string, attachments?: ImageAttachment[]) => void;\n /** Moves focus from an empty prompt to the first background task when available. */\n onFocusBackgroundTask?: () => boolean;\n /**\n * Cycles focus through main + spawned agents on Tab from an empty prompt.\n * Returns false when there are no agents so Tab falls back to its default.\n */\n onCycleAgentFocus?: () => boolean;\n /** Forward unrecognized global keyboard shortcuts to the parent App. */\n onGlobalShortcut?: (\n input: string,\n key: {\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n tab?: boolean;\n home?: boolean;\n end?: boolean;\n },\n ) => boolean;\n /** Commands for the autocomplete menu (from discoverCommands). */\n commands?: SlashCommand[];\n /** Discovered skills offered for explicit `$name` invocation. */\n skills?: Skill[];\n /** Keyed request used by conversation rewind to restore a prior prompt draft. */\n draftRestore?: { key: number; value: string; attachments?: ImageAttachment[] };\n}\n\n/**\n * Normalize a string to NFC (Canonical Composition) for consistent Unicode handling.\n */\nfunction normalizeInput(value: string): string {\n return value.normalize('NFC');\n}\n\nfunction getFilteredCommands(commands: SlashCommand[], filter: string): CommandItem[] {\n if (!filter) {\n return getCommandsForEmptyQuery(commands);\n }\n return getCommandsForQuery(commands, filter);\n}\n\nfunction getSelectedCommandValue(\n commands: SlashCommand[],\n filter: string,\n selectedIndex: number,\n): string | null {\n const matches = getFilteredCommands(commands, filter);\n if (matches.length === 0) return null;\n const index = Math.max(0, Math.min(selectedIndex, matches.length - 1));\n return '/' + matches[index].name;\n}\n\nfunction getSelectedFileMention(\n candidates: FileMentionCandidate[],\n selectedIndex: number,\n): FileMentionCandidate | null {\n if (candidates.length === 0) return null;\n const index = Math.max(0, Math.min(selectedIndex, candidates.length - 1));\n return candidates[index];\n}\n\nfunction getSelectedSkillMention(\n candidates: SkillMentionCandidate[],\n selectedIndex: number,\n): SkillMentionCandidate | null {\n if (candidates.length === 0) return null;\n const index = Math.max(0, Math.min(selectedIndex, candidates.length - 1));\n return candidates[index];\n}\n\n/**\n * Extract the command name from a slash command submission for usage tracking.\n */\nfunction extractCommandName(value: string): string | null {\n const match = value.match(/^\\/(\\S+)/);\n return match ? match[1] : null;\n}\n\n/**\n * Claude Code-style input bar with command autocomplete menu.\n *\n * When the user types `/` at the start of input, a command menu appears above\n * the input showing matching commands. Arrow keys navigate, Tab auto-fills,\n * and Enter on a selected item submits the command.\n *\n * Empty \"/\" shows commands categorized: recently used → builtins → user → project.\n * Typing after \"/\" uses fuzzy search with exact > prefix > fuzzy ranking.\n */\nexport function InputBar({\n onLayoutChange,\n onMenuOpenChange,\n onSubmit,\n onPasteImage,\n submissionMode,\n onCycleMode,\n canSubmitWhileBusy,\n canQueueWhileBusy,\n onQueue,\n onRecallQueued,\n onDraftChange,\n onFocusBackgroundTask,\n onCycleAgentFocus,\n onGlobalShortcut,\n inputSuppressed = false,\n awaitingAnswer = false,\n commands = [],\n skills = [],\n terminalWidth = 80,\n maxMenuRows = 8,\n compact = false,\n screenReader = false,\n draftRestore,\n}: InputBarProps) {\n const theme = useTheme();\n useDebugMount(uiLog, { compact, screenReader, commandsLen: commands.length });\n const [value, setValueState] = useState('');\n // Ink hands a key to the handler subscribed at the last effect flush, and every key in one\n // stdin read to the same handler, so a key can see the closure from before the key ahead of\n // it: Up right after the Enter that queued an input still saw the typed text and walked the\n // history instead of recalling the queued input. Each update writes these refs at once, and the\n // key handlers read them. The history is never rendered, so it lives in refs alone.\n const valueRef = useRef('');\n const historyRef = useRef<string[]>([]);\n const historyIndexRef = useRef(-1);\n const [attachments, setAttachmentsState] = useState<ImageAttachment[]>([]);\n const attachmentsRef = useRef<ImageAttachment[]>([]);\n // The draft reaches the app as each update is made, not only from the effect after the\n // render: the app decides what Ctrl+C does from it, and a press between the render and that\n // effect saw an empty composer and armed the exit instead of clearing the draft.\n const onDraftChangeRef = useRef(onDraftChange);\n onDraftChangeRef.current = onDraftChange;\n const reportDraft = useCallback(() => {\n const current = attachmentsRef.current;\n onDraftChangeRef.current?.(valueRef.current, current.length > 0 ? current : undefined);\n }, []);\n const setValue = useCallback(\n (next: string) => {\n valueRef.current = next;\n setValueState(next);\n reportDraft();\n },\n [reportDraft],\n );\n const setHistory = useCallback((update: (current: string[]) => string[]) => {\n historyRef.current = update(historyRef.current);\n }, []);\n const setHistoryIndex = useCallback((next: number) => {\n historyIndexRef.current = next;\n }, []);\n const setAttachments = useCallback(\n (update: ImageAttachment[] | ((current: ImageAttachment[]) => ImageAttachment[])) => {\n attachmentsRef.current =\n typeof update === 'function' ? update(attachmentsRef.current) : update;\n setAttachmentsState(attachmentsRef.current);\n reportDraft();\n },\n [reportDraft],\n );\n // An edit chord on an empty draft belongs to the transcript. A plain function: InputBox\n // re-reads its props each render, and nothing else here needs it.\n const forwardEmptyChord = (\n input: string,\n key: Parameters<NonNullable<typeof onGlobalShortcut>>[1],\n ) => {\n onGlobalShortcut?.(input, key);\n };\n const [attachmentError, setAttachmentError] = useState<string | undefined>();\n // Backspace on an empty composer removes the last attachment. InputBox reports it: only InputBox\n // knows whether the composer was empty before this key's own edit, whatever order Ink runs the\n // two handlers in (a modal re-subscribes InputBox after this handler).\n const removeLastAttachment = useCallback(() => {\n if (attachmentsRef.current.length === 0) return;\n setAttachments((current) => current.slice(0, -1));\n setAttachmentError(undefined);\n }, [setAttachments]);\n const suggestion = compact ? 'Ask...' : 'Ask me anything...';\n\n // Command menu state\n const [menuVisible, setMenuVisible] = useState(false);\n const [menuFilter, setMenuFilter] = useState('');\n const [menuSelected, setMenuSelected] = useState(0);\n const menuVisibleRef = useRef(false);\n const menuFilterRef = useRef('');\n const menuSelectedRef = useRef(0);\n // Written with the state, as `valueRef` is: Down then Enter in one read must run the item Down\n // moved to, and the ref assigned at render is a render behind until then.\n const selectMenuItem = useCallback((update: number | ((current: number) => number)) => {\n const next = typeof update === 'function' ? update(menuSelectedRef.current) : update;\n menuSelectedRef.current = next;\n setMenuSelected(next);\n }, []);\n\n // File mention menu state\n const [fileMenuVisible, setFileMenuVisible] = useState(false);\n const [fileMention, setFileMention] = useState<ActiveFileMention | null>(null);\n const [fileCandidates, setFileCandidates] = useState<FileMentionCandidate[]>([]);\n const [fileSelected, setFileSelected] = useState(0);\n const fileMenuVisibleRef = useRef(false);\n const fileMentionRef = useRef<ActiveFileMention | null>(null);\n const fileSelectedRef = useRef(0);\n const fileCandidatesRef = useRef<FileMentionCandidate[]>([]);\n\n // Skill mention menu state\n const [skillMenuVisible, setSkillMenuVisible] = useState(false);\n const [skillMention, setSkillMention] = useState<ActiveSkillMention | null>(null);\n const [skillSelected, setSkillSelected] = useState(0);\n const skillMenuVisibleRef = useRef(false);\n const skillMentionRef = useRef<ActiveSkillMention | null>(null);\n const skillSelectedRef = useRef(0);\n const skillCandidates = useMemo(\n () => getSkillMentionCandidates(skills, skillMention?.query ?? ''),\n [skillMention?.query, skills],\n );\n const skillCandidatesRef = useRef<SkillMentionCandidate[]>([]);\n\n useEffect(() => {\n onDraftChange?.(value, attachments.length > 0 ? attachments : undefined);\n }, [attachments, onDraftChange, value]);\n\n const filteredCmds = useMemo(\n () => getFilteredCommands(commands, menuFilter),\n [commands, menuFilter],\n );\n const resolveSubmissionAction = useCallback(\n (candidate: string): 'submit' | 'queue' | 'blocked' => {\n if (submissionMode === 'submit' || canSubmitWhileBusy?.(candidate)) return 'submit';\n if (submissionMode === 'queue' && (canQueueWhileBusy?.(candidate) ?? true)) return 'queue';\n return 'blocked';\n },\n [canQueueWhileBusy, canSubmitWhileBusy, submissionMode],\n );\n const workspace = process.env.BOOK_WORKSPACE || process.cwd();\n\n const pasteImage = useCallback(() => {\n if (!onPasteImage) return;\n void onPasteImage()\n .then((attachment) => {\n if (!attachment) return;\n setAttachmentError(undefined);\n setAttachments((current) => {\n if (current.length >= 4) {\n setAttachmentError('At most 4 images can be attached to one message.');\n return current;\n }\n return [...current, attachment];\n });\n })\n .catch((error) => {\n setAttachmentError(error instanceof Error ? error.message : String(error));\n });\n }, [onPasteImage]);\n\n useEffect(() => {\n if (!fileMention) {\n setFileCandidates([]);\n return;\n }\n\n const controller = new AbortController();\n const query = fileMention.query;\n const timer = setTimeout(() => {\n void getFileMentionCandidates(workspace, query, 50, controller.signal)\n .then((candidates) => {\n if (controller.signal.aborted) return;\n setFileCandidates(candidates);\n setFileSelected((selected) =>\n candidates.length === 0 ? 0 : Math.min(selected, candidates.length - 1),\n );\n })\n .catch((error) => {\n if (!controller.signal.aborted) {\n uiLog.event('file-menu:error', {\n error: error instanceof Error ? error.message : String(error),\n });\n setFileCandidates([]);\n }\n });\n }, FILE_MENTION_DEBOUNCE_MS);\n\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [fileMention?.query, workspace]);\n\n menuVisibleRef.current = menuVisible;\n menuFilterRef.current = menuFilter;\n menuSelectedRef.current = menuSelected;\n fileMenuVisibleRef.current = fileMenuVisible;\n fileMentionRef.current = fileMention;\n fileSelectedRef.current = fileSelected;\n fileCandidatesRef.current = fileCandidates;\n skillMenuVisibleRef.current = skillMenuVisible;\n skillMentionRef.current = skillMention;\n skillSelectedRef.current = skillSelected;\n skillCandidatesRef.current = skillCandidates;\n\n // A layout effect, not a passive one: a restore that follows a submission (the queue was\n // full, the model cannot read images) has to land before Ink writes the frame, or the composer\n // spends one painted frame empty — long enough, under load, to be the frame a test reads.\n useLayoutEffect(() => {\n if (!draftRestore) return;\n setValue(normalizeInput(draftRestore.value));\n setAttachments(draftRestore.attachments ?? []);\n setHistoryIndex(-1);\n setMenuVisible(false);\n selectMenuItem(0);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setFileSelected(0);\n setSkillMenuVisible(false);\n setSkillMention(null);\n setSkillSelected(0);\n }, [draftRestore?.key]);\n\n const acceptSelectedFileMention = useCallback(\n (currentValue: string, trigger: 'Tab' | 'Enter'): boolean => {\n // The refs hold offsets from the last render, and splicing them into a draft typed since\n // left stray characters, so the mention is read from the draft as it stands. The candidates,\n // though, are the ones loaded for the render's query: splicing a candidate for an older\n // query replaced what was typed since, so a new query waits for its own candidates.\n const mention = findActiveFileMention(currentValue);\n const selected = getSelectedFileMention(fileCandidatesRef.current, fileSelectedRef.current);\n if (!mention || !selected) return false;\n if (mention.query !== fileMentionRef.current?.query) return false;\n\n const nextValue = replaceActiveFileMention(currentValue, mention, selected.path);\n setValue(nextValue);\n const nextMention = findActiveFileMention(nextValue);\n setFileMention(nextMention);\n setFileMenuVisible(!!nextMention);\n setFileCandidates([]);\n setFileSelected(0);\n uiLog.event(`input:${trigger}`, { action: 'autofill-file-mention', path: selected.path });\n return true;\n },\n [],\n );\n\n const acceptSelectedSkillMention = useCallback(\n (currentValue: string, trigger: 'Tab' | 'Enter'): boolean => {\n const mention = findActiveSkillMention(currentValue);\n const selected = getSelectedSkillMention(\n skillCandidatesRef.current,\n skillSelectedRef.current,\n );\n if (!mention || !selected) return false;\n if (mention.query !== skillMentionRef.current?.query) return false;\n\n const nextValue = replaceActiveSkillMention(currentValue, mention, selected.name);\n setValue(nextValue);\n setSkillMention(null);\n setSkillMenuVisible(false);\n setSkillSelected(0);\n uiLog.event(`input:${trigger}`, { action: 'autofill-skill-mention', skill: selected.name });\n return true;\n },\n [],\n );\n\n useInput((_input, key) => {\n // TranscriptView owns mouse reports. Drop them before menu/history routing\n // so wheel movement, clicks, and drags cannot reach the prompt draft.\n if (_input.startsWith('[<') || _input.startsWith('\\x1b[<')) return;\n\n // While a modal (permission prompt) owns the keyboard, ignore all keys —\n // PermissionButtons handles them. Without this, Ink fires every `useInput`\n // handler on every keypress, so Enter/Tab/Esc would double-fire.\n if (inputSuppressed) return;\n if (key.meta && _input.toLowerCase() === 'v') {\n pasteImage();\n return;\n }\n // Only an open menu takes Esc here. Every other Esc belongs to the app (cancel the turn, drop a\n // recalled queued input, close a panel), whose handler runs before this one. Ink 6 reported a\n // lone Esc as `meta`, so the Alt/Meta filter below swallowed it; Ink 7 does not.\n const menuOpen = menuVisible || skillMenuVisible || fileMenuVisible;\n if (key.escape && !menuOpen) return;\n // Filter out Alt/Meta-modified keys — they're shortcuts, not text input. Alt+Backspace is\n // InputBox's word delete, and Alt+V is handled above.\n if (key.meta && !key.escape) return;\n\n if (key.shift && key.tab) {\n onCycleMode();\n uiLog.event('input:Shift+Tab', { action: 'cycle-mode' });\n return;\n }\n\n // ---- Command menu keyboard handling ----\n // The refs, not the state: Ink hands every key of one stdin read to the handler this hook\n // subscribed at the last effect flush, so a Down that opened the menu, or one that arrives in\n // the same read as an Enter, sees the menus as they were a render ago.\n if (menuVisibleRef.current) {\n const items = getFilteredCommands(commands, menuFilterRef.current);\n // Escape: dismiss menu\n if (key.escape) {\n setMenuVisible(false);\n selectMenuItem(0);\n uiLog.event('input:Escape', { action: 'dismiss-menu' });\n return;\n }\n // Tab: auto-fill selected command\n if (key.tab) {\n if (items.length > 0) {\n const sel = Math.max(0, Math.min(menuSelectedRef.current, items.length - 1));\n const cmd = items[sel];\n setValue('/' + cmd.name + ' ');\n setMenuVisible(false);\n selectMenuItem(0);\n uiLog.event('input:Tab', { action: 'autofill-command', command: cmd.name });\n }\n return;\n }\n // Down arrow: next item\n if (key.downArrow) {\n selectMenuItem((prev) => {\n const next = prev + 1;\n return next >= items.length ? 0 : next;\n });\n uiLog.event('input:Down', { action: 'menu-next-item' });\n return;\n }\n // Up arrow: previous item\n if (key.upArrow) {\n selectMenuItem((prev) => {\n const next = prev - 1;\n return next < 0 ? Math.max(0, items.length - 1) : next;\n });\n uiLog.event('input:Up', { action: 'menu-prev-item' });\n return;\n }\n // Enter is resolved in handleSubmit, where InputBox passes the current value.\n if (key.return) return;\n // Character keys update the filter via onChange — stay visible so the\n // user can continue typing the command name. The menu is dismissed by\n // onChange when a space is typed or the leading / is removed.\n }\n\n // ---- Explicit skill mention menu keyboard handling ----\n if (skillMenuVisible) {\n if (key.escape) {\n setSkillMenuVisible(false);\n setSkillMention(null);\n setSkillSelected(0);\n uiLog.event('input:Escape', { action: 'dismiss-skill-menu' });\n return;\n }\n if (key.tab) {\n acceptSelectedSkillMention(valueRef.current, 'Tab');\n return;\n }\n if (key.downArrow) {\n setSkillSelected((prev) => {\n const next = prev + 1;\n return next >= skillCandidates.length ? 0 : next;\n });\n return;\n }\n if (key.upArrow) {\n setSkillSelected((prev) => {\n const next = prev - 1;\n return next < 0 ? Math.max(0, skillCandidates.length - 1) : next;\n });\n return;\n }\n if (key.return) return;\n }\n\n // ---- File mention menu keyboard handling ----\n if (fileMenuVisible) {\n if (key.escape) {\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setFileSelected(0);\n uiLog.event('input:Escape', { action: 'dismiss-file-menu' });\n return;\n }\n if (key.tab) {\n acceptSelectedFileMention(valueRef.current, 'Tab');\n return;\n }\n if (key.downArrow) {\n setFileSelected((prev) => {\n const next = prev + 1;\n return next >= fileCandidates.length ? 0 : next;\n });\n uiLog.event('input:Down', { action: 'file-menu-next-item' });\n return;\n }\n if (key.upArrow) {\n setFileSelected((prev) => {\n const next = prev - 1;\n return next < 0 ? Math.max(0, fileCandidates.length - 1) : next;\n });\n uiLog.event('input:Up', { action: 'file-menu-prev-item' });\n return;\n }\n if (key.return) return;\n }\n\n // ---- Normal mode (no menu) ----\n // Tab from an empty prompt cycles focus through main + spawned agents\n // (Claude-Code-style flat switching). Falls back to accepting the\n // placeholder suggestion when there are no agents to cycle.\n if (key.tab && !valueRef.current) {\n if (onCycleAgentFocus?.()) {\n uiLog.event('input:Tab', { action: 'cycle-agent-focus' });\n return;\n }\n setValue(normalizeInput(suggestion));\n uiLog.event('input:Tab', { action: 'accept-suggestion' });\n return;\n }\n // Ctrl+J / Shift+Enter insert a newline without submitting. InputBox does\n // not expose cursor position to the parent, so append at the end of the prompt.\n if ((key.ctrl && (_input === 'j' || _input === '\\n')) || (key.shift && key.return)) {\n setValue(valueRef.current + '\\n');\n setMenuVisible(false);\n selectMenuItem(0);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setFileSelected(0);\n uiLog.event(key.ctrl ? 'input:Ctrl+J' : 'input:Shift+Enter', { action: 'insert-newline' });\n return;\n }\n // The readline chords are the editor's: it edits a draft with them, and hands them to\n // `forwardEmptyChord` below when there is no draft to edit. The pager chords join them here\n // for the same reason — a draft in hand means Ctrl+U and Ctrl+D are not the transcript's,\n // and forwarding them to the App would scroll the transcript out from under the composer\n // (Ctrl+D is not an edit, so the editor itself cannot end the key).\n if (\n key.ctrl &&\n (COMPOSER_EDIT_KEYS.has(_input.toLowerCase()) ||\n COMPOSER_PAGER_KEYS.has(_input.toLowerCase()))\n ) {\n return;\n }\n // Forward Ctrl-based shortcuts to the parent App. Ctrl+/ arrives as a bare US\n // byte with no `ctrl` flag (see `isShortcutsToggleKey`), so gating on\n // `key.ctrl` alone would swallow it here.\n if ((key.ctrl || isShortcutsToggleKey(_input, key)) && onGlobalShortcut) {\n if (onGlobalShortcut(_input, key)) return;\n }\n // Claude Code-style task access: Down from a fresh, empty prompt moves\n // focus into the task list. Enter is then handled by SubagentPanel.\n if (\n key.downArrow &&\n !valueRef.current &&\n historyIndexRef.current < 0 &&\n onFocusBackgroundTask?.()\n ) {\n uiLog.event('input:Down', { action: 'focus-background-task' });\n return;\n }\n if (key.upArrow && !valueRef.current) {\n const recalled = onRecallQueued?.();\n if (recalled !== undefined) {\n setHistoryIndex(-1);\n if (typeof recalled === 'string') {\n setValue(recalled);\n } else {\n setValue(recalled.value);\n setAttachments(recalled.attachments ?? []);\n }\n uiLog.event('input:Up', { action: 'recall-queued-input' });\n return;\n }\n }\n // Up arrow — navigate history backward\n const currentHistory = historyRef.current;\n const currentIndex = historyIndexRef.current;\n if (key.upArrow && currentHistory.length > 0 && currentIndex < currentHistory.length - 1) {\n const newIdx = currentIndex + 1;\n setHistoryIndex(newIdx);\n setValue(currentHistory[newIdx]);\n uiLog.event('input:Up', { action: 'history-back', newIdx });\n return;\n }\n // Down arrow — navigate history forward\n if (key.downArrow && currentIndex >= 0) {\n const newIdx = currentIndex - 1;\n setHistoryIndex(newIdx);\n setValue(newIdx >= 0 ? currentHistory[newIdx] : '');\n uiLog.event('input:Down', { action: 'history-forward', newIdx });\n return;\n }\n });\n\n const safeOnChange = useCallback((val: string) => {\n const clean = normalizeInput(stripSgrMouseSequences(val));\n setValue(clean);\n\n // Detect / at start for command menu.\n // Show menu when: starts with /, no space (still typing command name).\n if (clean.startsWith('/') && !clean.includes(' ')) {\n if (!menuVisibleRef.current) {\n uiLog.event('menu:visible', { filter: clean.slice(1) });\n }\n setMenuVisible(true);\n menuFilterRef.current = clean.slice(1);\n setMenuFilter(clean.slice(1));\n selectMenuItem(0);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setSkillMenuVisible(false);\n setSkillMention(null);\n setSkillSelected(0);\n return;\n } else if (clean.startsWith('/') && clean.includes(' ')) {\n // User typed a space after command name — dismiss menu, they're typing args.\n if (menuVisibleRef.current) {\n uiLog.event('menu:hidden', { reason: 'space-after-command' });\n }\n setMenuVisible(false);\n } else {\n if (menuVisibleRef.current) {\n uiLog.event('menu:hidden', { reason: 'leading-slash-removed' });\n }\n setMenuVisible(false);\n }\n\n const activeSkillMention = findActiveSkillMention(clean);\n if (activeSkillMention) {\n if (!skillMenuVisibleRef.current) {\n uiLog.event('skill-menu:visible', { filter: activeSkillMention.query });\n }\n setSkillMention(activeSkillMention);\n setSkillSelected(0);\n setSkillMenuVisible(true);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setFileSelected(0);\n return;\n }\n if (skillMenuVisibleRef.current) {\n uiLog.event('skill-menu:hidden', { reason: 'no-active-mention' });\n }\n setSkillMenuVisible(false);\n setSkillMention(null);\n setSkillSelected(0);\n\n const activeMention = findActiveFileMention(clean);\n setFileMention(activeMention);\n setFileCandidates([]);\n setFileSelected(0);\n const showFileMenu = !!activeMention;\n if (showFileMenu && !fileMenuVisibleRef.current) {\n uiLog.event('file-menu:visible', { filter: activeMention.query });\n }\n if (!showFileMenu && fileMenuVisibleRef.current) {\n uiLog.event('file-menu:hidden', { reason: 'no-active-mention' });\n }\n setFileMenuVisible(showFileMenu);\n }, []);\n\n const handleSubmit = useCallback(\n (val: string) => {\n if (menuVisibleRef.current) {\n const commandValue = getSelectedCommandValue(\n commands,\n menuFilterRef.current,\n menuSelectedRef.current,\n );\n setMenuVisible(false);\n selectMenuItem(0);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n if (!commandValue) {\n // Nothing in the menu matches: keep the text for fixing rather than clear it. It is not\n // sent on this Enter either, since an unknown command would reach the model as a prompt;\n // a second Enter, with the menu closed, sends it as typed text.\n uiLog.event('submit:menu', { result: 'no-command-value' });\n return;\n }\n const action = resolveSubmissionAction(commandValue);\n if (action === 'blocked') {\n uiLog.event('submit:menu', {\n result: 'blocked',\n command: commandValue.slice(1),\n submissionMode,\n });\n setValue(commandValue);\n } else if (action === 'queue') {\n const accepted = onQueue?.(commandValue) ?? false;\n uiLog.event('submit:menu', {\n result: accepted ? 'queued' : 'queue-full',\n command: commandValue.slice(1),\n });\n setValue(accepted ? '' : commandValue);\n } else {\n uiLog.event('submit:menu', {\n result: 'command',\n command: commandValue.slice(1),\n });\n setHistory((h) => [commandValue, ...h].slice(0, 100));\n setHistoryIndex(-1);\n recordCommandUse(commandValue.slice(1));\n onSubmit(commandValue);\n setValue('');\n }\n return;\n }\n\n if (skillMenuVisibleRef.current && acceptSelectedSkillMention(val, 'Enter')) {\n return;\n }\n\n if (fileMenuVisibleRef.current && acceptSelectedFileMention(val, 'Enter')) {\n return;\n }\n\n // Dismiss menus on submit.\n setMenuVisible(false);\n selectMenuItem(0);\n setFileMenuVisible(false);\n setFileMention(null);\n setFileCandidates([]);\n setFileSelected(0);\n setSkillMenuVisible(false);\n setSkillMention(null);\n setSkillSelected(0);\n\n const normalized = normalizeInput(val);\n if (!normalized.trim() && attachmentsRef.current.length === 0) {\n uiLog.event('submit:text', { result: 'empty' });\n return;\n }\n if (normalized.trimStart().startsWith('/') && attachmentsRef.current.length > 0) {\n setAttachmentError('Image attachments cannot be combined with slash commands.');\n return;\n }\n const action = resolveSubmissionAction(normalized);\n if (action === 'blocked') {\n uiLog.event('submit:text', { result: 'blocked', len: normalized.length, submissionMode });\n return;\n }\n if (action === 'queue') {\n const accepted =\n attachmentsRef.current.length > 0\n ? (onQueue?.(normalized, attachmentsRef.current) ?? false)\n : (onQueue?.(normalized) ?? false);\n uiLog.event('submit:text', {\n result: accepted ? 'queued' : 'queue-full',\n len: normalized.length,\n });\n if (!accepted) return;\n } else {\n uiLog.event('submit:text', { result: 'submitted', len: normalized.length });\n }\n setHistory((h) => [normalized, ...h].slice(0, 100));\n setHistoryIndex(-1);\n\n // Track command usage for autocomplete ranking.\n const cmdName = extractCommandName(normalized);\n if (cmdName) recordCommandUse(cmdName);\n\n if (action === 'submit') {\n if (attachmentsRef.current.length > 0) onSubmit(normalized, attachmentsRef.current);\n else onSubmit(normalized);\n }\n setValue('');\n setAttachments([]);\n setAttachmentError(undefined);\n },\n [\n acceptSelectedFileMention,\n acceptSelectedSkillMention,\n commands,\n onQueue,\n onSubmit,\n resolveSubmissionAction,\n submissionMode,\n pasteImage,\n ],\n );\n\n // Keep the composer calm and stable while the status line carries the\n // permission mode. The focused input is the primary action in this surface;\n // changing its border colour with every mode made the whole frame feel like\n // a warning badge even when nothing needed attention.\n const baseBorderColor = inputSuppressed ? theme.border : theme.promptBorder;\n\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\n // The composer spans the transcript rather than floating over it, so it takes\n // the full terminal like the rows above it -- not the bounded panel measure.\n const frame = frameGrid(outerWidth);\n // The prompt glyph sits in the gutter, so what you type starts on the same\n // column as every transcript row above it.\n const inputWidth = Math.max(1, frame.width - CONTENT_COLUMN);\n const promptColor = inputSuppressed ? theme.subtle : theme.userAccent;\n // A modal owns the keyboard, so the composer accepts nothing — saying\n // \"Type a follow-up\" here invited the user to type into a locked field while\n // the prompt above was reading their keystrokes as answers. Which of the two\n // things is holding the keys decides what to say instead: a prompt wants an\n // answer, a sheet just wants closing, and every sheet that suppresses input\n // closes on Esc.\n const placeholder = inputSuppressed\n ? awaitingAnswer\n ? compact\n ? 'Answer above'\n : 'Answer the prompt above'\n : compact\n ? 'Esc closes'\n : 'Esc closes this'\n : submissionMode === 'queue'\n ? compact\n ? 'Enter queues'\n : 'Type a follow-up; Enter queues it'\n : submissionMode === 'blocked'\n ? compact\n ? 'Please wait...'\n : 'Input is temporarily unavailable'\n : suggestion;\n\n // Everything that changes how many rows the composer takes.\n const layoutShape = [\n menuVisible ? Math.min(filteredCmds.length, maxMenuRows) : -1,\n skillMenuVisible && !menuVisible ? Math.min(skillCandidates.length, maxMenuRows) : -1,\n fileMenuVisible && !menuVisible && !skillMenuVisible\n ? Math.min(fileCandidates.length, maxMenuRows)\n : -1,\n draftRows(value, inputWidth),\n attachments.length,\n Boolean(attachmentError),\n ].join(':');\n useLayoutEffect(() => {\n onLayoutChange?.();\n }, [layoutShape, onLayoutChange]);\n // Reported after commit, so an Esc that is closing the menu right now still\n // finds it open in the app's handler for that same key.\n const anyMenuOpen = menuVisible || skillMenuVisible || fileMenuVisible;\n useLayoutEffect(() => {\n onMenuOpenChange?.(anyMenuOpen);\n // A remounted composer (a new session) must not leave the app thinking a\n // menu is still open.\n return () => onMenuOpenChange?.(false);\n }, [anyMenuOpen, onMenuOpenChange]);\n\n const selIdx = Math.max(0, Math.min(menuSelected, filteredCmds.length - 1));\n const fileSelIdx = Math.max(0, Math.min(fileSelected, fileCandidates.length - 1));\n const skillSelIdx = Math.max(0, Math.min(skillSelected, skillCandidates.length - 1));\n\n return (\n <Box flexDirection=\"column\" width={outerWidth}>\n <CommandMenu\n items={filteredCmds}\n filterText={menuFilter}\n selectedIndex={selIdx}\n visible={menuVisible}\n terminalWidth={outerWidth}\n maxRows={maxMenuRows}\n compact={compact}\n screenReader={screenReader}\n />\n <SkillMentionMenu\n items={skillCandidates}\n filterText={skillMention?.query ?? ''}\n selectedIndex={skillSelIdx}\n visible={skillMenuVisible && !menuVisible}\n terminalWidth={outerWidth}\n maxRows={maxMenuRows}\n compact={compact}\n screenReader={screenReader}\n />\n <FileMentionMenu\n items={fileCandidates}\n filterText={fileMention?.query ?? ''}\n selectedIndex={fileSelIdx}\n visible={fileMenuVisible && !menuVisible && !skillMenuVisible}\n terminalWidth={outerWidth}\n maxRows={maxMenuRows}\n compact={compact}\n screenReader={screenReader}\n />\n\n {attachments.length > 0 ? (\n <Box marginX={frame.marginX} paddingX={1}>\n <Text color={theme.brand}>\n {attachments.map(\n (attachment, index) =>\n `${index > 0 ? ' ' : ''}[image ${index + 1} ${(attachment.byteSize / 1024).toFixed(0)} KB]`,\n )}\n </Text>\n </Box>\n ) : null}\n {attachmentError ? (\n <Text color={theme.warning} wrap=\"wrap\">\n Image paste failed: {attachmentError}\n </Text>\n ) : null}\n\n {/* Hairlines above and below, no side walls: the composer reads as the\n foot of the page rather than a box pinned to it. */}\n <Box\n borderStyle=\"single\"\n borderLeft={false}\n borderRight={false}\n borderColor={baseBorderColor}\n width={frame.width}\n marginX={frame.marginX}\n >\n {/* The pilcrow that will open this turn in the transcript. */}\n <Text color={promptColor}>{screenReader ? '> ' : `${PILCROW} `}</Text>\n <Box width={inputWidth} flexShrink={1}>\n <InputBox\n value={value}\n liveValueRef={valueRef}\n onEmptyChord={forwardEmptyChord}\n onChange={safeOnChange}\n onSubmit={handleSubmit}\n onBackspaceWhenEmpty={removeLastAttachment}\n placeholder={placeholder}\n // Stay focused while busy so Enter can queue a follow-up; only yield\n // to a modal (permission prompt). `focus` here maps\n // to InputBox's internal `useInput` isActive — see inputSuppressed.\n focus={!inputSuppressed}\n />\n </Box>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport { useMemo } from 'react';\nimport { useTheme } from '../theme.js';\nimport type { CommandItem } from '../../commands/filter.js';\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\nimport { createRenderDebugLogger } from '../../debug-log.js';\nimport { floatingFrameMetrics, SoftPanel } from './chrome.js';\nimport { frameGrid } from '../layout.js';\nimport { useDebugRender } from '../debug.js';\n\nconst renderLog = createRenderDebugLogger('tui:cmdmenu');\n\ninterface CommandMenuProps {\n /** Pre-filtered and categorized command items to display. */\n items: CommandItem[];\n /** Current filter text (empty = show categorized sections). */\n filterText: string;\n /** Index of the currently selected item in the flattened list. */\n selectedIndex: number;\n /** Whether the menu is visible. */\n visible: boolean;\n /** Available width, excluding any parent padding. */\n terminalWidth?: number;\n /** Maximum command rows to render. */\n maxRows?: number;\n /** Compact rendering for narrow or short terminals. */\n compact?: boolean;\n /** Render plain, non-decorative output for screen readers. */\n screenReader?: boolean;\n}\n\n/** Narrower than this and a description is a stub, not a description. */\nconst MIN_DESC_WIDTH = 12;\n\n/** Columns between the name column and the description. */\nconst DESC_SEPARATOR = ' ';\n\nconst CATEGORY_LABELS: Record<CommandItem['category'], string> = {\n recent: 'Recent',\n builtin: 'Built-in',\n user: 'User',\n project: 'Project',\n};\n\nconst COMPACT_CATEGORY_LABELS: Record<CommandItem['category'], string> = {\n recent: 'R',\n builtin: 'B',\n user: 'U',\n project: 'P',\n};\n\nexport function getCommandMenuWindow(\n itemCount: number,\n selectedIndex: number,\n maxRows: number,\n): { start: number; end: number } {\n const safeCount = Math.max(0, itemCount);\n const safeRows = Math.max(1, Math.floor(maxRows));\n if (safeCount <= safeRows) return { start: 0, end: safeCount };\n\n const selected = Math.max(0, Math.min(selectedIndex, safeCount - 1));\n const half = Math.floor(safeRows / 2);\n let start = Math.max(0, selected - half);\n start = Math.min(start, safeCount - safeRows);\n return { start, end: start + safeRows };\n}\n\n/** The runs of one command row, each free to carry its own colour. */\nexport interface CommandRow {\n marker: string;\n name: string;\n /** Spaces after the name (and hint, and badge) that bring the description to its column. */\n pad: string;\n /** Argument syntax. Empty except on the selected row. */\n hint: string;\n /** Category badge. Empty when every visible row shares one category. */\n badge: string;\n desc: string;\n}\n\nexport interface CommandRowOptions {\n selected: boolean;\n width: number;\n compact: boolean;\n screenReader: boolean;\n /** False when the visible rows are all one category, making a badge noise. */\n showBadge: boolean;\n /**\n * Width of the name column: the widest name and badge in the whole list\n * (see {@link commandNameColumn}). Every description then starts on the same\n * column, so the list reads as two columns instead of a ragged run of\n * `name — description` rows. The selected row's syntax pushes only its own\n * description along.\n */\n nameWidth?: number;\n}\n\n/**\n * Lay out one command row.\n *\n * Three things used to compete for the same line. The argument syntax sat\n * between the name and the description, so `/agent` read\n * `<id>|send <id> <message>|stop <id> [Built-in] — Inspec…` — the grammar of the\n * command before any hint of what it does, and then the meaning truncated away.\n * The badge repeated `[Built-in]` down every row of a list that was entirely\n * built-ins. And the whole row was one colour, so the name did not stand out\n * from its own description.\n *\n * So: the description always follows the name, the syntax appears only on the\n * selected row — the list is for finding a command, the syntax matters once you\n * have found it — and the badge appears only when the rows actually differ.\n * The description absorbs whatever width is left, which is the part a reader\n * can lose a tail of and still recognize.\n */\nexport function composeCommandRow(item: CommandItem, options: CommandRowOptions): CommandRow {\n const { selected, width, compact, screenReader, showBadge, nameWidth = 0 } = options;\n // One steady mark. It used to pulse between `›` and `▸`, a blink that drew\n // the eye to the list's chrome instead of to the command.\n const marker = screenReader ? (selected ? 'selected ' : '') : selected ? '› ' : ' ';\n const name = `/${item.name}`;\n const badge = showBadge && !screenReader ? commandBadge(item, compact) : '';\n const hint = selected && item.hint ? ` ${item.hint}` : '';\n\n const fixed = displayWidth(marker) + displayWidth(name) + displayWidth(badge);\n // The syntax is only worth its columns if enough of the row survives to still\n // read as a row; below that the name and what it does win.\n const hintFits = hint && fixed + displayWidth(hint) + MIN_DESC_WIDTH <= width;\n const keptHint = hintFits ? hint : '';\n const lead = displayWidth(name) + displayWidth(keptHint) + displayWidth(badge);\n const padWidth = compact || screenReader ? 0 : Math.max(0, nameWidth - lead);\n const descBudget = width - fixed - displayWidth(keptHint) - padWidth - DESC_SEPARATOR.length;\n const desc =\n item.desc && !compact && descBudget >= MIN_DESC_WIDTH\n ? `${DESC_SEPARATOR}${truncateDisplay(item.desc, descBudget)}`\n : '';\n\n return { marker, name, pad: desc ? ' '.repeat(padWidth) : '', hint: keptHint, badge, desc };\n}\n\n/** The badge a row prints when the list mixes categories. */\nfunction commandBadge(item: CommandItem, compact: boolean): string {\n return ` [${compact ? COMPACT_CATEGORY_LABELS[item.category] : CATEGORY_LABELS[item.category]}]`;\n}\n\n/**\n * The name column: the widest name, with its badge when badges show, across the\n * whole filtered list, capped so a long custom command cannot squeeze every\n * description away. Measured on the whole list, not the visible window, so the\n * column holds still while the selection scrolls; and with the badge, so a\n * mixed list of built-in and custom commands still lines up.\n */\nexport function commandNameColumn(\n items: readonly CommandItem[],\n showBadge: boolean,\n compact: boolean,\n contentWidth: number,\n): number {\n const widest = Math.max(\n 0,\n ...items.map(\n (item) =>\n displayWidth(`/${item.name}`) + (showBadge ? displayWidth(commandBadge(item, compact)) : 0),\n ),\n );\n return Math.min(widest, Math.floor(contentWidth * 0.4));\n}\n\n/** Slash-command palette. Filtering/ranking lives in commands/filter.ts. */\nexport function CommandMenu({\n items,\n filterText,\n selectedIndex,\n visible,\n terminalWidth = 80,\n maxRows = 8,\n compact = false,\n screenReader = false,\n}: CommandMenuProps) {\n const theme = useTheme();\n\n const width = Math.max(20, Math.floor(terminalWidth));\n const frame = floatingFrameMetrics(width);\n const contentWidth = Math.max(8, frame.width - 4);\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\n const window = useMemo(\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\n [items.length, selIdx, safeMaxRows],\n );\n const visibleItems = items.slice(window.start, window.end);\n // A badge every row shares carries no information: `[Built-in]` down a list of\n // nothing but built-ins is a column of noise between the name and its meaning.\n // Derived from the whole filtered list rather than the visible window, so the\n // column does not appear and vanish as the selection scrolls a differing row\n // in and out of view.\n const showBadge = useMemo(() => new Set(items.map((item) => item.category)).size > 1, [items]);\n const hiddenBefore = window.start;\n const hiddenAfter = Math.max(0, items.length - window.end);\n const hiddenTotal = hiddenBefore + hiddenAfter;\n\n useDebugRender(renderLog, {\n items: items.length,\n visible: visibleItems.length,\n selected: selIdx,\n window: `[${window.start}..${window.end})`,\n hidden: hiddenTotal,\n filter: filterText || '(empty)',\n });\n\n if (!visible) return null;\n\n const title = filterText ? `Commands matching “${filterText}”` : 'Commands';\n const count = `${items.length} ${items.length === 1 ? 'command' : 'commands'}`;\n const nameWidth = commandNameColumn(items, showBadge, compact, contentWidth);\n\n // The hairline spans the terminal like the composer's; rows keep the panel measure.\n return (\n <SoftPanel\n width={frameGrid(width).width}\n marginX={frame.marginX}\n attached\n title={title}\n meta={hiddenTotal > 0 ? `${count} · type to filter` : count}\n >\n {items.length === 0 ? (\n <Text color={theme.subtle} dimColor>\n No matching commands\n </Text>\n ) : (\n visibleItems.map((item, index) => {\n const globalIndex = window.start + index;\n const isSelected = globalIndex === selIdx;\n const row = composeCommandRow(item, {\n selected: isSelected,\n width: contentWidth,\n compact,\n screenReader,\n showBadge,\n nameWidth,\n });\n // The name in ink, the syntax and badge quiet, the description a step\n // quieter still; the selected row is marked and bold, never barred.\n return (\n <Box key={`${item.category}-${item.name}-${globalIndex}`} width={contentWidth}>\n <Text color={theme.brand}>{row.marker}</Text>\n <Text bold={isSelected} color={isSelected ? theme.selectionText : theme.text}>\n {row.name}\n </Text>\n <Text color={theme.inactive}>{row.hint}</Text>\n <Text color={theme.inactive}>{row.badge}</Text>\n <Text>{row.pad}</Text>\n <Text color={isSelected ? theme.text : theme.inactive}>{row.desc}</Text>\n </Box>\n );\n })\n )}\n </SoftPanel>\n );\n}\n","import { Text } from 'ink';\nimport { useMemo } from 'react';\nimport { useTheme } from '../theme.js';\nimport type { FileMentionCandidate } from '../../input/file-mentions.js';\nimport { getCommandMenuWindow } from './CommandMenu.js';\nimport { floatingFrameMetrics, MenuRow, SoftPanel } from './chrome.js';\nimport { frameGrid } from '../layout.js';\n\ninterface FileMentionMenuProps {\n items: FileMentionCandidate[];\n filterText: string;\n selectedIndex: number;\n visible: boolean;\n terminalWidth?: number;\n maxRows?: number;\n compact?: boolean;\n screenReader?: boolean;\n}\n\nfunction fileBadge(item: FileMentionCandidate, compact: boolean): string {\n if (item.kind === 'directory') return compact ? ' [D]' : ' [Directory]';\n return compact ? ' [F]' : ' [File]';\n}\n\n/** Workspace file picker for @ mentions. */\nexport function FileMentionMenu({\n items,\n filterText,\n selectedIndex,\n visible,\n terminalWidth = 80,\n maxRows = 8,\n compact = false,\n screenReader = false,\n}: FileMentionMenuProps) {\n const theme = useTheme();\n\n const width = Math.max(20, Math.floor(terminalWidth));\n const frame = floatingFrameMetrics(width);\n const contentWidth = Math.max(8, frame.width - 4);\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\n const window = useMemo(\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\n [items.length, selIdx, safeMaxRows],\n );\n const visibleItems = items.slice(window.start, window.end);\n const hiddenTotal = window.start + Math.max(0, items.length - window.end);\n\n if (!visible) return null;\n\n const title = filterText ? `Files matching “${filterText}”` : 'Files';\n\n // The hairline spans the terminal like the composer's; rows keep the panel measure.\n return (\n <SoftPanel\n width={frameGrid(width).width}\n marginX={frame.marginX}\n attached\n title={title}\n meta={`${items.length} ${items.length === 1 ? 'file' : 'files'}${hiddenTotal > 0 ? ' · type to filter' : ''}`}\n >\n {items.length === 0 ? (\n <Text color={theme.subtle} dimColor>\n No matching files\n </Text>\n ) : (\n visibleItems.map((item, index) => {\n const globalIndex = window.start + index;\n const isSelected = globalIndex === selIdx;\n return (\n <MenuRow\n key={`${item.kind}-${item.path}-${globalIndex}`}\n selected={isSelected}\n name={`@${item.path}`}\n badge={fileBadge(item, compact)}\n desc={compact ? '' : item.desc}\n width={contentWidth}\n screenReader={screenReader}\n />\n );\n })\n )}\n </SoftPanel>\n );\n}\n","import { Text } from 'ink';\nimport { useMemo } from 'react';\nimport { useTheme } from '../theme.js';\nimport type { SkillMentionCandidate } from '../../input/skill-mentions.js';\nimport { getCommandMenuWindow } from './CommandMenu.js';\nimport { floatingFrameMetrics, MenuRow, SoftPanel } from './chrome.js';\nimport { frameGrid } from '../layout.js';\n\ninterface SkillMentionMenuProps {\n items: SkillMentionCandidate[];\n filterText: string;\n selectedIndex: number;\n visible: boolean;\n terminalWidth?: number;\n maxRows?: number;\n compact?: boolean;\n screenReader?: boolean;\n}\n\n/** Skill picker for explicit `$name` mentions. */\nexport function SkillMentionMenu({\n items,\n filterText,\n selectedIndex,\n visible,\n terminalWidth = 80,\n maxRows = 8,\n compact = false,\n screenReader = false,\n}: SkillMentionMenuProps) {\n const theme = useTheme();\n const width = Math.max(20, Math.floor(terminalWidth));\n const frame = floatingFrameMetrics(width);\n const contentWidth = Math.max(8, frame.width - 4);\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\n const window = useMemo(\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\n [items.length, selIdx, safeMaxRows],\n );\n const visibleItems = items.slice(window.start, window.end);\n const hiddenTotal = window.start + Math.max(0, items.length - window.end);\n\n if (!visible) return null;\n\n // The hairline spans the terminal like the composer's; rows keep the panel measure.\n return (\n <SoftPanel\n width={frameGrid(width).width}\n marginX={frame.marginX}\n attached\n title={filterText ? `Skills matching “${filterText}”` : 'Skills'}\n meta={`${items.length} ${items.length === 1 ? 'skill' : 'skills'}${hiddenTotal > 0 ? ' · type to filter' : ''}`}\n >\n {items.length === 0 ? (\n <Text color={theme.subtle} dimColor>\n No matching skills\n </Text>\n ) : (\n visibleItems.map((item, index) => {\n const globalIndex = window.start + index;\n const selected = globalIndex === selIdx;\n return (\n <MenuRow\n key={`${item.source}:${item.rootKind}:${item.name}:${globalIndex}`}\n selected={selected}\n name={`$${item.name}`}\n desc={compact ? '' : item.description}\n width={contentWidth}\n screenReader={screenReader}\n />\n );\n })\n )}\n </SoftPanel>\n );\n}\n","import type { Skill } from '../skills.js';\n\nexport interface ActiveSkillMention {\n start: number;\n end: number;\n query: string;\n}\n\nexport interface SkillMentionCandidate {\n name: string;\n description: string;\n source: Skill['source'];\n rootKind: Skill['rootKind'];\n}\n\nfunction isMentionBoundary(input: string, index: number): boolean {\n if (index === 0) return true;\n return /[\\s([{<\"']/.test(input[index - 1]);\n}\n\n/** Find an unfinished `$skill-name` mention at the end of the prompt. */\nexport function findActiveSkillMention(input: string): ActiveSkillMention | null {\n for (let index = input.length - 1; index >= 0; index--) {\n if (input[index] !== '$' || !isMentionBoundary(input, index)) continue;\n\n const query = input.slice(index + 1);\n if (!/^[a-z0-9-]*$/i.test(query)) return null;\n return { start: index, end: input.length, query };\n }\n return null;\n}\n\n/** Rank valid, explicitly invocable skills for the active mention. */\nexport function getSkillMentionCandidates(\n skills: readonly Skill[],\n query: string,\n limit = 50,\n): SkillMentionCandidate[] {\n const normalizedQuery = query.toLowerCase();\n const candidates: Array<SkillMentionCandidate & { score: number }> = [];\n\n for (const skill of skills) {\n // This is the explicit `$name` picker, so Claude-compatible\n // `disable-model-invocation` remains intentionally invocable by the user.\n if (!skill.valid || skill.activation === 'off' || skill.execution === 'deny') continue;\n\n const name = skill.name.toLowerCase();\n const description = skill.description.toLowerCase();\n let score: number | null = null;\n if (!normalizedQuery) score = 3;\n else if (name === normalizedQuery) score = 0;\n else if (name.startsWith(normalizedQuery)) score = 1;\n else if (name.includes(normalizedQuery)) score = 2;\n else if (description.includes(normalizedQuery)) score = 4;\n if (score === null) continue;\n\n candidates.push({\n name: skill.name,\n description: skill.description,\n source: skill.source,\n rootKind: skill.rootKind,\n score,\n });\n }\n\n candidates.sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\n return candidates.slice(0, limit).map(({ score: _score, ...candidate }) => candidate);\n}\n\nexport function replaceActiveSkillMention(\n input: string,\n mention: ActiveSkillMention,\n skillName: string,\n): string {\n return input.slice(0, mention.start) + `$${skillName} ` + input.slice(mention.end);\n}\n","/**\n * Session-level recently-used command tracker.\n *\n * Tracks how many times each command has been invoked via `/` in the current\n * session. Used to surface frequently-used commands at the top of the `/`\n * autocomplete when the user types an empty query.\n */\n\nconst usage = new Map<string, number>();\n\nexport function recordCommandUse(name: string): void {\n usage.set(name, (usage.get(name) ?? 0) + 1);\n}\n\nexport function getRecentCommands(limit = 5): string[] {\n return Array.from(usage.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit)\n .map(([name]) => name);\n}\n","/**\n * Slash command filtering with categorized display and fuzzy search.\n *\n * Two modes:\n * - Empty query (\"/\"): categorized list with recently-used at top\n * - Typed query (\"/com\"): Fuse.js fuzzy search with priority ranking\n */\n\nimport Fuse from 'fuse.js';\nimport type { SlashCommand } from '../types/commands.js';\nimport { BUILTIN_COMMANDS } from './builtins.js';\nimport { getRecentCommands } from './recent.js';\n\nexport interface CommandItem {\n name: string;\n hint: string;\n desc: string;\n /** Category badge: 'recent' | 'builtin' | 'user' | 'project' */\n category: 'recent' | 'builtin' | 'user' | 'project';\n}\n\n// ── Fuse.js index (built once per commands array identity via memoization) ──\n\nlet _fuseCommands: SlashCommand[] | null = null;\nlet _fuse: Fuse<{ name: string; desc: string; hint: string }> | null = null;\n\nfunction getFuse(commands: SlashCommand[]): Fuse<{ name: string; desc: string; hint: string }> {\n // Build a unified list: builtins + custom\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\n\n const items: Array<{ name: string; desc: string; hint: string }> = [];\n\n for (const b of BUILTIN_COMMANDS) {\n if (!b.isHidden) {\n items.push({ name: b.name, desc: b.description, hint: b.argumentHint ?? '' });\n }\n }\n\n for (const cmd of commands) {\n if (builtinNames.has(cmd.name)) continue;\n if (cmd.isHidden) continue;\n items.push({ name: cmd.name, desc: cmd.description, hint: cmd.argumentHint ?? '' });\n }\n\n // Only rebuild if commands changed\n if (_fuseCommands === commands && _fuse) return _fuse;\n\n _fuseCommands = commands;\n _fuse = new Fuse(items, {\n keys: [\n { name: 'name', weight: 3 },\n { name: 'desc', weight: 0.5 },\n ],\n threshold: 0.3,\n location: 0,\n distance: 100,\n });\n\n return _fuse;\n}\n\n// ── Empty query: categorized display ──\n\nexport function getCommandsForEmptyQuery(commands: SlashCommand[]): CommandItem[] {\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\n const recentNames = new Set(getRecentCommands());\n\n const result: CommandItem[] = [];\n\n // 1. Recently used (sorted by frequency)\n for (const name of getRecentCommands()) {\n const builtin = BUILTIN_COMMANDS.find((b) => b.name === name);\n if (builtin && !builtin.isHidden) {\n result.push({\n name: builtin.name,\n hint: builtin.argumentHint ?? '',\n desc: builtin.description,\n category: 'recent',\n });\n }\n }\n\n // 2. Built-in commands (alphabetical, excluding recently used and hidden)\n const builtins: CommandItem[] = [];\n for (const b of BUILTIN_COMMANDS) {\n if (b.isHidden || recentNames.has(b.name)) continue;\n builtins.push({\n name: b.name,\n hint: b.argumentHint ?? '',\n desc: b.description,\n category: 'builtin',\n });\n }\n builtins.sort((a, b) => {\n if (a.name === 'clear') return -1;\n if (b.name === 'clear') return 1;\n return a.name.localeCompare(b.name);\n });\n result.push(...builtins);\n\n // 3. User commands (alphabetical, excluding recently used)\n const userCmds: CommandItem[] = [];\n for (const cmd of commands) {\n if (builtinNames.has(cmd.name) || recentNames.has(cmd.name) || cmd.isHidden) continue;\n if (cmd.source === 'user') {\n userCmds.push({\n name: cmd.name,\n hint: cmd.argumentHint ?? '',\n desc: cmd.description,\n category: 'user',\n });\n }\n }\n userCmds.sort((a, b) => a.name.localeCompare(b.name));\n result.push(...userCmds);\n\n // 4. Project commands (alphabetical)\n const projectCmds: CommandItem[] = [];\n for (const cmd of commands) {\n if (builtinNames.has(cmd.name) || recentNames.has(cmd.name) || cmd.isHidden) continue;\n if (cmd.source === 'project') {\n projectCmds.push({\n name: cmd.name,\n hint: cmd.argumentHint ?? '',\n desc: cmd.description,\n category: 'project',\n });\n }\n }\n projectCmds.sort((a, b) => a.name.localeCompare(b.name));\n result.push(...projectCmds);\n\n return result;\n}\n\n// ── Typed query: Fuse.js fuzzy search with priority ranking ──\n\nexport function getCommandsForQuery(commands: SlashCommand[], query: string): CommandItem[] {\n const fuse = getFuse(commands);\n const q = query.toLowerCase().trim();\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\n\n const searchResults = fuse.search(q);\n\n // Build a lookup for custom command → source\n const customSource = new Map<string, 'user' | 'project'>();\n for (const cmd of commands) {\n if (!builtinNames.has(cmd.name)) {\n customSource.set(cmd.name, cmd.source);\n }\n }\n\n // Score each result: 0 = exact name, 1 = prefix name, 2 = fuzzy\n const scored = searchResults.map((r) => {\n const name = r.item.name.toLowerCase();\n let priority: number;\n if (name === q) {\n priority = 0;\n } else if (name.startsWith(q)) {\n priority = 1;\n } else {\n priority = 2;\n }\n\n const isBuiltin = builtinNames.has(r.item.name);\n const category: CommandItem['category'] = isBuiltin\n ? 'builtin'\n : customSource.get(r.item.name) === 'project'\n ? 'project'\n : 'user';\n\n return {\n name: r.item.name,\n hint: r.item.hint,\n desc: r.item.desc,\n category,\n priority,\n };\n });\n\n // Sort: priority first, then alphabetically\n scored.sort((a, b) => {\n if (a.priority !== b.priority) return a.priority - b.priority;\n return a.name.localeCompare(b.name);\n });\n\n return scored.map(({ priority: _priority, ...item }) => item);\n}\n","export type SgrMouseEventType = 'press' | 'release' | 'move' | 'wheel';\nexport type SgrMouseButton = 'left' | 'middle' | 'right' | 'none' | 'wheel-up' | 'wheel-down';\n\nexport interface SgrMouseEvent {\n type: SgrMouseEventType;\n button: SgrMouseButton;\n x: number;\n y: number;\n shift: boolean;\n alt: boolean;\n ctrl: boolean;\n}\n\nconst SGR_MOUSE_PATTERN = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)(M|m)$/;\nconst COMPLETE_SGR_MOUSE_SEQUENCE_PATTERN = /\\x1b\\[<\\d+;\\d+;\\d+[Mm]/g;\nconst INPUT_SGR_MOUSE_SEQUENCE_PATTERN = /(?:\\x1b)?\\[<\\d+;\\d+;\\d+[Mm]/g;\n\n/** Remove complete SGR mouse reports, with or without the escape byte Ink may consume. */\nexport function stripSgrMouseSequences(input: string): string {\n return input.replace(INPUT_SGR_MOUSE_SEQUENCE_PATTERN, '');\n}\n\n/** Parse one complete SGR mouse report into a typed, 1-based terminal event. */\nexport function parseSgrMouseEvent(input: string): SgrMouseEvent | null {\n const match = SGR_MOUSE_PATTERN.exec(input);\n if (!match) return null;\n\n const code = Number(match[1]);\n const x = Number(match[2]);\n const y = Number(match[3]);\n if (![code, x, y].every(Number.isSafeInteger) || x < 1 || y < 1) return null;\n\n const shift = (code & 4) !== 0;\n const alt = (code & 8) !== 0;\n const ctrl = (code & 16) !== 0;\n const isWheel = (code & 64) !== 0;\n const isMove = (code & 32) !== 0;\n const buttonCode = code & 3;\n\n if (isWheel) {\n if (buttonCode > 1 || match[4] === 'm') return null;\n return {\n type: 'wheel',\n button: buttonCode === 0 ? 'wheel-up' : 'wheel-down',\n x,\n y,\n shift,\n alt,\n ctrl,\n };\n }\n\n const button: SgrMouseButton =\n buttonCode === 0 ? 'left' : buttonCode === 1 ? 'middle' : buttonCode === 2 ? 'right' : 'none';\n const type: SgrMouseEventType =\n match[4] === 'm' ? 'release' : isMove ? 'move' : buttonCode === 3 ? 'release' : 'press';\n return { type, button, x, y, shift, alt, ctrl };\n}\n\n/** Parse every complete SGR mouse report from a coalesced terminal input chunk. */\nexport function parseSgrMouseEvents(input: string): SgrMouseEvent[] {\n const events: SgrMouseEvent[] = [];\n for (const match of input.matchAll(COMPLETE_SGR_MOUSE_SEQUENCE_PATTERN)) {\n const event = parseSgrMouseEvent(match[0]);\n if (event) events.push(event);\n }\n return events;\n}\n","import { Text, useInput, type Key } from 'ink';\nimport { useEffect, useReducer, useRef } from 'react';\nimport {\n applyInputSequence,\n cut,\n deleteNextGrapheme,\n deletePreviousGrapheme,\n nextGraphemeBoundary,\n nextWordBoundary,\n previousGraphemeBoundary,\n previousWordBoundary,\n type EditState,\n} from '../line-edit.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\n\ninterface InputBoxProps {\n value: string;\n /**\n * The parent's copy of the draft, written the moment the parent changes it (history,\n * autocomplete, a restored draft). Ink hands every key of one stdin read to the handlers in\n * turn before React renders, so the key after Up reached this editor while `value` still\n * held the text Up had replaced: Up then a character gave the old text plus the character,\n * and Up then Enter submitted nothing. Each key starts from this copy when it differs.\n */\n liveValueRef?: { readonly current: string };\n /**\n * An edit chord arrived with an empty draft. The editor knows the draft was empty before the key\n * and has already declined to apply it, so the key belongs to the transcript.\n */\n onEmptyChord?: (input: string, key: Key) => void;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n /** Backspace pressed while the composer is empty; the key edits nothing here. */\n onBackspaceWhenEmpty?: () => void;\n placeholder?: string;\n focus?: boolean;\n}\n\n/**\n * Ctrl chords the editor handles as text edits. With an empty draft there is nothing for them to\n * edit, so they belong to the transcript (Ctrl+E expands a tool, Ctrl+U scrolls) and are handed to\n * `onEmptyChord`; Ctrl+Y still yanks into an empty draft when the kill ring holds text.\n */\nexport const COMPOSER_EDIT_KEYS = new Set(['a', 'e', 'w', 'u', 'k', 'y']);\n\n/**\n * Chords that scroll the transcript half a page, and only ever reach it when\n * the composer has no draft to edit.\n *\n * Ctrl+U is in {@link COMPOSER_EDIT_KEYS} as well, because it is also an edit\n * (kill to the start of the line). Ctrl+D is not an edit at all: readline uses\n * it for end-of-file, which a non-empty line ignores. Both are listed here\n * because that is the question both are asked — is there a draft? — and because\n * the transcript cannot answer it once the editor has run.\n */\nexport const COMPOSER_PAGER_KEYS = new Set(['u', 'd']);\n\n/**\n * A Backspace this soon after the previous one is key repeat, not a new press. Repeats come every\n * 30-90 ms once a held key starts repeating (Windows ~33 ms, GNOME/X11 ~30-40 ms, macOS ~90 ms);\n * deliberate taps are slower. The first repeat comes later, after the 250-660 ms repeat delay, and\n * only the second one tells a hold from a tap, so a Backspace on an empty composer removes an\n * attachment this long after the press unless a repeat cancels it. Ink 7 hands each repeated byte\n * over as its own key; without this, holding Backspace to clear a draft went on to delete every\n * attached image.\n */\nconst HELD_REPEAT_MS = 120;\n\n/**\n * Unicode input editor that keeps its draft in refs so rapid IME replacement\n * events never operate on stale React render state.\n */\nexport function InputBox({\n value,\n liveValueRef,\n onEmptyChord,\n onChange,\n onSubmit,\n onBackspaceWhenEmpty,\n placeholder = '',\n focus = true,\n}: InputBoxProps) {\n const valueRef = useRef(value);\n const cursorOffsetRef = useRef(value.length);\n // Kill ring. The three kill keys are the only edits here that can destroy a\n // long prompt in one keystroke, and Ctrl+U in particular used to scroll the\n // transcript instead — so the recovery key ships with them, not after them.\n const killRingRef = useRef('');\n const lastBackspaceAtRef = useRef(Number.NEGATIVE_INFINITY);\n const pendingRemovalRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const onBackspaceWhenEmptyRef = useRef(onBackspaceWhenEmpty);\n onBackspaceWhenEmptyRef.current = onBackspaceWhenEmpty;\n const cancelPendingRemoval = () => {\n clearTimeout(pendingRemovalRef.current);\n pendingRemovalRef.current = undefined;\n };\n useEffect(() => () => clearTimeout(pendingRemovalRef.current), []);\n const [, rerender] = useReducer((version: number) => version + 1, 0);\n\n // Parent-driven changes such as history navigation and autocomplete own the cursor.\n if (value !== valueRef.current) {\n valueRef.current = value;\n cursorOffsetRef.current = value.length;\n }\n\n const commit = (edit: EditState) => {\n const changed = edit.value !== valueRef.current;\n valueRef.current = edit.value;\n cursorOffsetRef.current = edit.cursorOffset;\n rerender();\n if (changed) onChange(edit.value);\n };\n\n const killTo = (start: number, end: number) => {\n const { edit, killed } = cut(valueRef.current, start, end);\n if (!killed) return;\n killRingRef.current = killed;\n commit(edit);\n };\n\n useInput(\n (rawInput, key) => {\n // TranscriptView owns mouse reports. Ink hands them to every handler, and typed into the\n // draft here they cost a whole extra render per wheel tick — the frame slot the scroll\n // itself needed — and moved the cursor to the end of the draft once InputBar stripped\n // them again. Text typed in the same read as a report is kept.\n const input = stripSgrMouseSequences(rawInput);\n if (rawInput && !input) return;\n const parentValue = liveValueRef?.current;\n if (parentValue !== undefined && parentValue !== valueRef.current) {\n valueRef.current = parentValue;\n cursorOffsetRef.current = parentValue.length;\n }\n // Any other key ends a Backspace run, so the next Backspace is a fresh press.\n if (!key.backspace || key.meta) lastBackspaceAtRef.current = Number.NEGATIVE_INFINITY;\n\n // Alt+Backspace deletes the previous word and Alt+Delete the next one, as\n // they do in every other terminal composer.\n if (key.meta && key.backspace) {\n const cursor = cursorOffsetRef.current;\n killTo(previousWordBoundary(valueRef.current, cursor), cursor);\n return;\n }\n if (key.meta && key.delete) {\n const cursor = cursorOffsetRef.current;\n killTo(cursor, nextWordBoundary(valueRef.current, cursor));\n return;\n }\n if (key.meta && key.delete) {\n const cursor = cursorOffsetRef.current;\n killTo(cursor, nextWordBoundary(valueRef.current, cursor));\n return;\n }\n\n // Readline motions. The composer dropped every Ctrl chord, so fixing a\n // typo halfway through a long prompt meant holding Backspace — slower\n // still in a language where one character can take several keystrokes to\n // compose.\n if (key.ctrl && !key.meta) {\n const cursor = cursorOffsetRef.current;\n const current = valueRef.current;\n const chord = input.toLowerCase();\n if (COMPOSER_EDIT_KEYS.has(chord) && !current && !(chord === 'y' && killRingRef.current)) {\n onEmptyChord?.(input, key);\n return;\n }\n switch (chord) {\n case 'd':\n // Not an edit: readline's end-of-file, which a non-empty line\n // ignores. With nothing to edit it is the transcript's.\n if (!current) onEmptyChord?.(input, key);\n return;\n case 'a':\n commit({ value: current, cursorOffset: 0 });\n return;\n case 'e':\n commit({ value: current, cursorOffset: current.length });\n return;\n case 'w':\n killTo(previousWordBoundary(current, cursor), cursor);\n return;\n case 'u':\n killTo(0, cursor);\n return;\n case 'k':\n killTo(cursor, current.length);\n return;\n case 'y': {\n const yanked = killRingRef.current;\n if (!yanked) return;\n commit({\n value: current.slice(0, cursor) + yanked + current.slice(cursor),\n cursorOffset: cursor + yanked.length,\n });\n return;\n }\n default:\n return;\n }\n }\n\n if (key.upArrow || key.downArrow || key.tab || key.ctrl || key.meta || key.escape) {\n return;\n }\n\n if (key.return) {\n if (!key.shift) onSubmit?.(valueRef.current);\n return;\n }\n\n if (key.leftArrow) {\n commit({\n value: valueRef.current,\n cursorOffset: previousGraphemeBoundary(valueRef.current, cursorOffsetRef.current),\n });\n return;\n }\n\n if (key.rightArrow) {\n commit({\n value: valueRef.current,\n cursorOffset: nextGraphemeBoundary(valueRef.current, cursorOffsetRef.current),\n });\n return;\n }\n\n if (key.home) {\n commit({ value: valueRef.current, cursorOffset: 0 });\n return;\n }\n\n if (key.end) {\n commit({ value: valueRef.current, cursorOffset: valueRef.current.length });\n return;\n }\n\n if (key.backspace) {\n const now = performance.now();\n const repeat = now - lastBackspaceAtRef.current < HELD_REPEAT_MS;\n lastBackspaceAtRef.current = now;\n // The key is held, so the press that scheduled a removal only started the hold.\n if (repeat) cancelPendingRemoval();\n if (valueRef.current !== '') {\n commit(deletePreviousGrapheme(valueRef.current, cursorOffsetRef.current));\n return;\n }\n if (!repeat) {\n cancelPendingRemoval();\n pendingRemovalRef.current = setTimeout(() => {\n pendingRemovalRef.current = undefined;\n onBackspaceWhenEmptyRef.current?.();\n }, HELD_REPEAT_MS);\n }\n return;\n }\n\n // Ink 7 reports the Delete key (ESC [3~) apart from Backspace; Ink 6 could not tell them apart.\n if (key.delete) {\n commit(deleteNextGrapheme(valueRef.current, cursorOffsetRef.current));\n return;\n }\n\n if (input) {\n commit(applyInputSequence(valueRef.current, cursorOffsetRef.current, input));\n }\n },\n { isActive: focus },\n );\n\n const currentValue = valueRef.current;\n if (!focus) {\n // A placeholder is a hint, focused or not: in full-strength text it read as\n // something the user had typed.\n return currentValue ? <Text>{currentValue}</Text> : <Text color=\"gray\">{placeholder}</Text>;\n }\n\n if (!currentValue) {\n const [first = ' ', ...rest] = [...placeholder];\n return (\n <Text color=\"gray\">\n <Text inverse>{first}</Text>\n {rest.join('')}\n </Text>\n );\n }\n\n const cursorOffset = cursorOffsetRef.current;\n const nextOffset = nextGraphemeBoundary(currentValue, cursorOffset);\n const before = currentValue.slice(0, cursorOffset);\n const cursor = currentValue.slice(cursorOffset, nextOffset) || ' ';\n const after = currentValue.slice(nextOffset);\n\n return (\n <Text>\n {before}\n <Text inverse>{cursor}</Text>\n {after}\n </Text>\n );\n}\n","/**\n * Single-line text edits, shared by every editor in the TUI.\n *\n * The composer and the sheet fields are the same problem at two sizes, so the\n * offsets a cursor moves by and the text a chord kills live here once rather\n * than being re-derived per component. Everything is a pure function over\n * `(value, cursorOffset)`: no component state, no refs, nothing a keystroke can\n * read stale.\n */\n\nexport interface EditState {\n value: string;\n cursorOffset: number;\n}\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n\nexport function previousGraphemeBoundary(value: string, offset: number): number {\n let previous = 0;\n for (const segment of graphemeSegmenter.segment(value)) {\n if (segment.index >= offset) break;\n previous = segment.index;\n }\n return previous;\n}\n\nexport function nextGraphemeBoundary(value: string, offset: number): number {\n for (const segment of graphemeSegmenter.segment(value)) {\n if (segment.index > offset) return segment.index;\n }\n return value.length;\n}\n\n/**\n * Offset of the start of the word before `offset`.\n *\n * Skips the whitespace immediately behind the cursor, then the run of\n * non-whitespace before that — readline's `unix-word-rubout`, which is what\n * Ctrl+W and Alt+Backspace both mean to a terminal user.\n */\nexport function previousWordBoundary(value: string, offset: number): number {\n let index = offset;\n while (index > 0 && /\\s/.test(value[index - 1]!)) index -= 1;\n while (index > 0 && !/\\s/.test(value[index - 1]!)) index -= 1;\n return index;\n}\n\n/** Offset of the end of the word after `offset`: readline's `kill-word`, what Alt+Delete means. */\nexport function nextWordBoundary(value: string, offset: number): number {\n let index = offset;\n while (index < value.length && /\\s/.test(value[index]!)) index += 1;\n while (index < value.length && !/\\s/.test(value[index]!)) index += 1;\n return index;\n}\n\n/** Remove `[start, end)` and leave the cursor where the text was. */\nexport function cut(\n value: string,\n start: number,\n end: number,\n): { edit: EditState; killed: string } {\n return {\n edit: { value: value.slice(0, start) + value.slice(end), cursorOffset: start },\n killed: value.slice(start, end),\n };\n}\n\nexport function normalizeEdit(value: string, cursorOffset: number): EditState {\n return {\n value: value.normalize('NFC'),\n cursorOffset: value.slice(0, cursorOffset).normalize('NFC').length,\n };\n}\n\nexport function deletePreviousGrapheme(value: string, cursorOffset: number): EditState {\n if (cursorOffset <= 0) return { value, cursorOffset };\n const previousOffset = previousGraphemeBoundary(value, cursorOffset);\n return {\n value: value.slice(0, previousOffset) + value.slice(cursorOffset),\n cursorOffset: previousOffset,\n };\n}\n\nexport function deleteNextGrapheme(value: string, cursorOffset: number): EditState {\n if (cursorOffset >= value.length) return { value, cursorOffset };\n const nextOffset = nextGraphemeBoundary(value, cursorOffset);\n return { value: value.slice(0, cursorOffset) + value.slice(nextOffset), cursorOffset };\n}\n\n/** Apply a raw terminal input chunk, including IME backspace/replacement sequences. */\nexport function applyInputSequence(value: string, cursorOffset: number, input: string): EditState {\n let edit = { value, cursorOffset };\n\n for (const character of input) {\n if (character === '\\b' || character === '\\x7f') {\n edit = deletePreviousGrapheme(edit.value, edit.cursorOffset);\n continue;\n }\n\n // Ignore control bytes that should never become visible prompt text.\n if (character < ' ' && character !== '\\n' && character !== '\\t') continue;\n\n edit = {\n value:\n edit.value.slice(0, edit.cursorOffset) + character + edit.value.slice(edit.cursorOffset),\n cursorOffset: edit.cursorOffset + character.length,\n };\n }\n\n return normalizeEdit(edit.value, edit.cursorOffset);\n}\n\n/**\n * The readline chords a single-line field honours, or `null` when the key is\n * not one of them.\n *\n * A field's editor is the only thing that can act on these: it is the thing\n * holding the cursor. The composer layers a kill ring and its own chord set on\n * top (see `InputBox`); a field has nothing to recover a kill from, so this is\n * the whole contract.\n *\n * Ctrl+A / Ctrl+E the start and the end of the line\n * Ctrl+U kill to the cursor (`unix-line-discard`)\n * Ctrl+K kill to the end of the line (`kill-line`)\n * Ctrl+W kill the word to the left (`unix-word-rubout`)\n * Ctrl+D delete the character under the cursor (`delete-char`)\n *\n * Every other Ctrl chord returns `null`: ignored, never inserted as text. The\n * chords arrive from Ink as the bare letter with `key.ctrl`, so an editor that\n * fell through to insert would type `u`, `w` or `d` into the value.\n */\nexport function applyReadlineChord(edit: EditState, chord: string): EditState | null {\n const { value, cursorOffset } = edit;\n switch (chord) {\n case 'a':\n return { value, cursorOffset: 0 };\n case 'e':\n return { value, cursorOffset: value.length };\n case 'u':\n return cut(value, 0, cursorOffset).edit;\n case 'k':\n return cut(value, cursorOffset, value.length).edit;\n case 'w':\n return cut(value, previousWordBoundary(value, cursorOffset), cursorOffset).edit;\n case 'd':\n return deleteNextGrapheme(value, cursorOffset);\n default:\n return null;\n }\n}\n\n/** The readline chords {@link applyReadlineChord} acts on. */\nexport const LINE_EDIT_CHORDS = new Set(['a', 'e', 'u', 'k', 'w', 'd']);\n","import { Box, Text } from 'ink';\nimport type { QueuedInput } from '../queued-inputs.js';\nimport { CONTENT_COLUMN } from '../layout.js';\nimport { useTheme } from '../theme.js';\nimport { truncateDisplay } from './word-wrap.js';\n\n/**\n * How a note above the composer reads. `warning` is for a state that needs\n * you (the exit window, a paused queue); `done` confirms something that just\n * happened, with a green check; `info` is a plain remark.\n */\nexport type NoticeTone = 'warning' | 'done' | 'info';\n\n/** A note that fades on its own after a few seconds. */\nexport interface FlashNotice {\n text: string;\n tone: NoticeTone;\n}\n\ninterface QueuedInputPreviewProps {\n items: readonly QueuedInput[];\n terminalWidth: number;\n notice?: string;\n noticeTone?: NoticeTone;\n}\n\n/**\n * What sits between the transcript and the composer: follow-ups waiting for\n * the turn to end, and a one-line note. Quiet grey on the content column, so\n * it reads as margin matter; the rubric red belongs to marks.\n */\nexport function QueuedInputPreview({\n items,\n terminalWidth,\n notice,\n noticeTone = 'warning',\n}: QueuedInputPreviewProps) {\n const theme = useTheme();\n if (items.length === 0 && !notice) return null;\n\n const width = Math.max(8, Math.floor(terminalWidth) - CONTENT_COLUMN - 4);\n const visible = items.slice(0, 3);\n const hidden = items.length - visible.length;\n\n return (\n <Box flexDirection=\"column\" paddingLeft={CONTENT_COLUMN} marginBottom={1}>\n {items.length > 0 ? (\n <Text color={theme.subtle}>Queued follow-up inputs ({items.length})</Text>\n ) : null}\n {visible.map((item) => (\n <Text key={item.id} color={theme.inactive}>\n {' ↳ '}\n {item.attachments?.length\n ? `[${item.attachments.length} image${item.attachments.length === 1 ? '' : 's'}] `\n : ''}\n {truncateDisplay(item.value.replace(/\\s+/g, ' ').trim(), width)}\n </Text>\n ))}\n {hidden > 0 ? <Text color={theme.inactive}> ... {hidden} more</Text> : null}\n {notice ? (\n noticeTone === 'done' ? (\n <Text>\n <Text color={theme.success}>✓ </Text>\n <Text color={theme.subtle}>{truncateDisplay(notice, width + 2)}</Text>\n </Text>\n ) : (\n <Text color={noticeTone === 'info' ? theme.subtle : theme.warning}>\n {truncateDisplay(notice, width + 4)}\n </Text>\n )\n ) : null}\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport { useMemo } from 'react';\nimport { useTimedFlash } from '../hooks/useAnimation.js';\nimport { useTheme } from '../theme.js';\nimport type { PermissionMode } from '../../types/runtime.js';\nimport type { ContextWindowSource } from '../../types/messages.js';\nimport { stripProvider } from '../../models.js';\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\nimport { createRenderDebugLogger } from '../../debug-log.js';\nimport { modeColorToken, modeLabel } from '../mode-style.js';\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\nimport { useDebugRender } from '../debug.js';\nimport { romanNumeral } from '../roman.js';\n\nconst renderLog = createRenderDebugLogger('tui:statusline');\n\n/** Marks the permission mode, the one safety-relevant fact in the footer. */\nconst MODE_CHIP = '◆';\n\n/** `useGitStatus` reports a clean tree as a check mark. */\nconst CLEAN_TREE = '✓';\n\n/**\n * Segments are separated by a faint middle dot.\n *\n * The dot is drawn a step dimmer than the segments, so it separates them\n * without adding a colour of its own. Colour is kept for a state that needs a\n * decision, not for telling one grey fact from the next.\n */\nconst SEGMENT_SEPARATOR = ' · ';\n\ninterface StatusLineProps {\n model: string;\n /**\n * Reasoning effort, when the model takes one. Shown beside the model, so a\n * change of either is visible where it lives instead of announced in the\n * transcript.\n */\n effort?: string;\n tokenCount?: number;\n maxTokens?: number;\n maxTokensSource?: ContextWindowSource;\n mode: PermissionMode;\n taskCount: number;\n activeTaskCount: number;\n /** Current branch, when the workspace is a git repository. */\n gitBranch?: string;\n /** Short working-tree summary: `✓` clean, or `+2 ~1`. */\n gitStatus?: string;\n agentCount?: number;\n activeAgentCount?: number;\n needsInputAgentCount?: number;\n /** Turns written so far; drawn at the right edge as the page's folio. */\n turnCount?: number;\n /** The plan's place, `step 3/7`; drawn at the right edge before the folio. */\n stepLabel?: string;\n terminalWidth?: number;\n compact?: boolean;\n reducedMotion?: boolean;\n screenReader?: boolean;\n}\n\n/**\n * Pack colored status segments from left to right, skipping an oversized\n * segment so that later short, higher-value segments can still be shown.\n */\nexport function buildColoredSegments(\n segments: Array<{ text: string; color?: string }>,\n maxWidth: number,\n separatorText = ' · ',\n separatorColor?: string,\n): Array<{ text: string; color: string }> {\n const result: Array<{ text: string; color: string }> = [];\n let totalWidth = 0;\n\n for (const segment of segments) {\n const separator = result.length === 0 ? '' : separatorText;\n const candidateWidth = totalWidth + displayWidth(separator) + displayWidth(segment.text);\n if (candidateWidth > maxWidth) continue;\n\n const color = segment.color ?? 'text';\n if (separator) result.push({ text: separator, color: separatorColor ?? color });\n result.push({ text: segment.text, color });\n totalWidth = candidateWidth;\n }\n\n return result;\n}\n\n/** The status line's folio: the turn count as a front-matter page number. */\nexport function romanFolio(count: number): string {\n return romanNumeral(count);\n}\n\n/** Columns kept clear between the last segment and the folio. */\nconst FOLIO_GAP = 3;\n\n/** Narrowest row that still carries the plan's step. */\nconst STEP_MIN_ROW_WIDTH = 32;\n\n/** Narrowest row that carries both the step and the folio; the folio goes first. */\nconst STEP_AND_FOLIO_MIN_ROW_WIDTH = 56;\n\n/**\n * Single-row responsive status line.\n *\n * The row aggressively shortens low-priority details before Ink can wrap them,\n * keeping the input area stable while the terminal is resized.\n */\nexport function StatusLine({\n model,\n effort,\n tokenCount: _tokenCount,\n maxTokens: _maxTokens,\n maxTokensSource: _maxTokensSource,\n mode,\n taskCount,\n activeTaskCount,\n gitBranch,\n gitStatus,\n agentCount = 0,\n activeAgentCount = 0,\n needsInputAgentCount = 0,\n turnCount = 0,\n stepLabel,\n terminalWidth = 80,\n compact = false,\n reducedMotion = false,\n screenReader = false,\n}: StatusLineProps) {\n const theme = useTheme();\n const width = transcriptGrid(terminalWidth).width;\n // Footer rows share the transcript's content column so the status text, the\n // activity label and every tool row start on the same column.\n const horizontalInset = CONTENT_COLUMN;\n // The folio takes the right edge, like a page number in the outer margin. It\n // is the first thing a narrow row gives up.\n const rowWidth = Math.max(8, width - horizontalInset - 1);\n // The plan's step sits beside the folio. It says more than the page number,\n // so a narrowing row gives up the folio first.\n const step = stepLabel && rowWidth >= STEP_MIN_ROW_WIDTH ? stepLabel : '';\n const rawFolio = romanFolio(turnCount);\n const folio = rawFolio && rowWidth >= (step ? STEP_AND_FOLIO_MIN_ROW_WIDTH : 40) ? rawFolio : '';\n const tailWidth = displayWidth(step) + (step && folio ? FOLIO_GAP : 0) + displayWidth(folio);\n const contentWidth = tailWidth > 0 ? rowWidth - tailWidth - FOLIO_GAP : rowWidth;\n\n const motionDisabled = reducedMotion || screenReader;\n const modeFlash = useTimedFlash(mode, 260, motionDisabled);\n\n useDebugRender(renderLog, {\n width,\n contentWidth,\n compact,\n mode,\n taskCount,\n activeTaskCount,\n });\n\n // Most of the footer is metadata. Reserve saturated colour for a state that\n // needs a decision, so the transcript and composer keep visual priority.\n // `default` is not a decision — it is the absence of one — so it stays as\n // grey as the model name beside it, whatever the palette's `modeDefault` is.\n const modeColor = mode === 'default' ? theme.subtle : (theme[modeColorToken(mode)] as string);\n const activeModeColor = modeFlash ? theme.brandShimmer : modeColor;\n\n const coloredRuns = useMemo(() => {\n // The branch outranks the model when the row gets tight. Both are identity,\n // but the branch is the one that changes under you — you chose the model and\n // it stays chosen, while a rebase or a checkout in another worktree moves\n // the branch without asking.\n //\n // Both shrink together rather than one taking the row: packing is first-fit\n // and skips what will not fit, so a branch budget generous enough to crowd\n // the model drops the model entirely instead of shortening it.\n const modelBudget = width < 44 ? 8 : width < 72 ? 14 : 32;\n const branchBudget = width < 44 ? 10 : width < 72 ? 16 : 24;\n const displayModel = stripProvider(model);\n\n // Ordered by what the reader needs first. Packing is first-fit, not\n // truncating: a segment too wide for the remaining space is skipped and\n // later, shorter ones still get their turn.\n const segments: Array<{ text: string; color?: string }> = [\n { text: `${MODE_CHIP} ${modeLabel(mode)}`, color: activeModeColor },\n ];\n\n if (gitBranch && gitBranch !== '?') {\n const dirty = Boolean(gitStatus && gitStatus !== CLEAN_TREE);\n // A dirty tree is not a warning. It is how a working tree normally looks,\n // so the `*` says it and the colour stays quiet.\n segments.push({\n text: `${truncateDisplay(gitBranch, branchBudget)}${dirty ? '*' : ''}`,\n color: theme.subtle,\n });\n }\n\n segments.push({ text: truncateDisplay(displayModel, modelBudget), color: theme.subtle });\n if (effort) segments.push({ text: `${effort} effort`, color: theme.inactive });\n\n if (taskCount > 0) {\n segments.push({\n text: `tasks ${activeTaskCount > 0 ? `${activeTaskCount}/` : ''}${taskCount}`,\n color: theme.subtle,\n });\n }\n\n if (agentCount > 0) {\n segments.push({\n text:\n needsInputAgentCount > 0\n ? `agents ${activeAgentCount} | ${needsInputAgentCount} needs input`\n : `agents ${activeAgentCount}/${agentCount}`,\n color: needsInputAgentCount > 0 ? theme.warning : theme.subtle,\n });\n }\n\n return buildColoredSegments(segments, contentWidth, SEGMENT_SEPARATOR, theme.inactive);\n }, [\n gitBranch,\n gitStatus,\n activeTaskCount,\n activeAgentCount,\n agentCount,\n contentWidth,\n mode,\n activeModeColor,\n model,\n effort,\n taskCount,\n needsInputAgentCount,\n theme.inactive,\n theme.subtle,\n theme.warning,\n width,\n ]);\n\n const used = coloredRuns.reduce((total, run) => total + displayWidth(run.text), 0);\n return (\n <Box paddingLeft={horizontalInset} width={width} flexDirection=\"row\" flexWrap=\"nowrap\">\n {coloredRuns.map((run, i) => (\n <Text key={i} color={run.color}>\n {run.text}\n </Text>\n ))}\n {tailWidth > 0 ? (\n <>\n <Text>{' '.repeat(Math.max(FOLIO_GAP, rowWidth - used - tailWidth))}</Text>\n {step ? <Text color={theme.subtle}>{step}</Text> : null}\n {step && folio ? <Text>{' '.repeat(FOLIO_GAP)}</Text> : null}\n {folio ? (\n <Text color={theme.inactive} italic>\n {folio}\n </Text>\n ) : null}\n </>\n ) : null}\n </Box>\n );\n}\n","import type { PermissionMode } from '../types/runtime.js';\n\nexport type ModeColorToken =\n 'modeDefault' | 'modeAuto' | 'modePlan' | 'modeAcceptEdits' | 'modeDontAsk' | 'modeBypass';\n\nexport const MODE_COLOR_TOKENS: Record<PermissionMode, ModeColorToken> = {\n default: 'modeDefault',\n auto: 'modeAuto',\n plan: 'modePlan',\n 'accept-edits': 'modeAcceptEdits',\n dontAsk: 'modeDontAsk',\n bypassPermissions: 'modeBypass',\n};\n\nexport function modeColorToken(mode: PermissionMode): ModeColorToken {\n return MODE_COLOR_TOKENS[mode];\n}\n\nexport function modeLabel(mode: PermissionMode): string {\n switch (mode) {\n case 'accept-edits':\n return 'accept edits';\n case 'dontAsk':\n return \"don't ask\";\n case 'bypassPermissions':\n return 'bypass';\n default:\n return mode;\n }\n}\n","import { Box, Text } from 'ink';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport type { Message } from '../../types/messages.js';\nimport type { RetryPhase } from '../../types/runtime.js';\nimport type {\n PendingElicitationRequest,\n PendingPermissionRequest,\n PendingPlanApprovalRequest,\n PendingUserQuestionRequest,\n} from '../../session/agent-interactions.js';\nimport { useAnimatedProgress, useGradientSpinner } from '../hooks/useAnimation.js';\nimport { SpinnerGlyphs } from './Spinner.js';\nimport { useUiClock } from '../ui-clock.js';\nimport { useTheme } from '../theme.js';\nimport type { ThemeTokens } from '../../types/theme.js';\nimport { deriveWorkingActivity } from '../working-activity.js';\nimport type { ActivityTone } from '../working-activity.js';\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\nimport { formatElapsedDuration } from './SubagentRow.js';\nimport { displayWidth, padDisplay, truncateDisplay } from './word-wrap.js';\n\ninterface WorkingIndicatorProps {\n isThinking: boolean;\n /** True while /compact or auto-compact summarization is running. */\n isCompacting?: boolean;\n /** Auto vs manual compact busy label. */\n compactTrigger?: 'manual' | 'auto';\n /** True only after compaction has completed successfully. */\n compactComplete?: boolean;\n messages: Message[];\n streamingMessageId?: string | null;\n pendingPermission?: PendingPermissionRequest | null;\n pendingPlanApproval?: PendingPlanApprovalRequest | null;\n pendingUserQuestion?: PendingUserQuestionRequest | null;\n pendingElicitation?: PendingElicitationRequest | null;\n retryPhase?: RetryPhase;\n retryAttempt?: number;\n retryMax?: number;\n retryCountdownMs?: number;\n terminalWidth?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n /** The plan step in flight, for the activity wording. */\n activeStep?: string;\n}\n\nfunction useElapsedSeconds(active: boolean, disabled: boolean): number {\n const running = active && !disabled;\n const startedAtRef = useRef(Date.now());\n const resetPendingRef = useRef(true);\n const wasRunningRef = useRef(false);\n const [, refresh] = useState(0);\n const tick = useUiClock('slow', running);\n\n useLayoutEffect(() => {\n if (running && !wasRunningRef.current) {\n startedAtRef.current = Date.now();\n resetPendingRef.current = false;\n wasRunningRef.current = true;\n refresh((value) => value + 1);\n } else if (!running && wasRunningRef.current) {\n resetPendingRef.current = true;\n wasRunningRef.current = false;\n }\n }, [running]);\n\n if (!running || resetPendingRef.current) return 0;\n void tick;\n return Math.floor(Math.max(0, Date.now() - startedAtRef.current) / 1000);\n}\n\n/**\n * Fit `[label][elapsed][hint]` into one row.\n *\n * The three runs come back separately so each can carry its own colour: the\n * label is the live agent voice, the elapsed time is quiet metadata, the hint\n * is quieter still. Elapsed is dropped first when the row is tight — a duration\n * is the piece a reader can most afford to lose — then the hint, and only then\n * does the label truncate.\n */\nfunction fitActivityLine(\n label: string,\n elapsed: string,\n hint: string,\n maxWidth: number,\n): { label: string; elapsed: string; hint: string } {\n const minimumLabelWidth = Math.min(8, maxWidth);\n let suffix = { elapsed, hint };\n const suffixWidth = () => displayWidth(suffix.elapsed) + displayWidth(suffix.hint);\n\n if (suffixWidth() > maxWidth - minimumLabelWidth) suffix = { elapsed: '', hint };\n if (suffixWidth() > maxWidth - minimumLabelWidth) suffix = { elapsed: '', hint: '' };\n\n const labelWidth = Math.max(1, maxWidth - suffixWidth());\n return { label: truncateDisplay(label, labelWidth), ...suffix };\n}\n\nexport interface ActivityPalette {\n /** The spinner glyph, or `◇` when the turn is blocked on the user. */\n indicator: string;\n /** The activity wording. */\n label: string;\n /** Elapsed time and the keyboard hint behind it. */\n meta: string;\n}\n\n/**\n * Colours for the activity row.\n *\n * The wording rides the spinner's own colour instead of sitting in `text`. Body\n * prose, plan steps and tool targets are all `text`, so leaving the activity\n * there made the one row that is actually *changing* the hardest row to pick\n * out — a moving glyph welded to a sentence that looked like every other\n * sentence. Sage is the agent's own voice, the same hue as the glyph in front\n * of it, so glyph and wording read as one live element, distinct from the\n * transcript around it.\n *\n * A blocked or retrying row is not the agent talking, so it keeps its status\n * colour and the row stops looking live.\n */\nexport function activityPalette(\n tone: ActivityTone,\n theme: ThemeTokens,\n spinnerColor: string,\n markColor: string = spinnerColor,\n): ActivityPalette {\n if (tone === 'warning') {\n return { indicator: theme.warning, label: theme.warning, meta: theme.warning };\n }\n if (tone === 'waiting') {\n return { indicator: theme.permission, label: theme.permission, meta: theme.subtle };\n }\n // The quill's ink is a mark and takes the rubric; the wording stays in the\n // agent's breathing ink beside it.\n return { indicator: markColor, label: spinnerColor, meta: theme.subtle };\n}\n\nexport function WorkingIndicator({\n isThinking,\n isCompacting = false,\n compactTrigger,\n compactComplete = false,\n messages,\n streamingMessageId,\n pendingPermission,\n pendingPlanApproval,\n pendingUserQuestion,\n pendingElicitation,\n retryPhase = 'none',\n retryAttempt = 0,\n retryMax = 0,\n retryCountdownMs = 0,\n terminalWidth = 80,\n reducedMotion = false,\n screenReader = false,\n activeStep,\n}: WorkingIndicatorProps) {\n const theme = useTheme();\n const motionDisabled = reducedMotion || screenReader;\n const shouldTrackElapsed =\n isThinking &&\n !isCompacting &&\n retryPhase === 'none' &&\n !pendingPermission &&\n !pendingPlanApproval &&\n !pendingUserQuestion &&\n !pendingElicitation;\n const elapsedSeconds = useElapsedSeconds(shouldTrackElapsed, motionDisabled);\n const activity = deriveWorkingActivity({\n isThinking,\n isCompacting,\n compactTrigger,\n messages,\n streamingMessageId,\n pendingPermission: Boolean(pendingPermission),\n pendingPlanApproval: Boolean(pendingPlanApproval),\n // An MCP form asks the user for input just like a question does.\n pendingUserQuestion: Boolean(pendingUserQuestion || pendingElicitation),\n retryPhase,\n retryAttempt,\n retryMax,\n retryCountdownMs,\n elapsedSeconds,\n activeStep,\n });\n\n const width = transcriptGrid(terminalWidth).width;\n // Footer rows share the transcript's content column so the status text, the\n // activity label and every tool row start on the same column.\n const horizontalInset = CONTENT_COLUMN;\n const contentWidth = Math.max(8, width - horizontalInset - 1);\n const showCompactProgress =\n (isCompacting || compactComplete) && retryPhase === 'none' && !motionDisabled;\n const compactProgress = useAnimatedProgress(isCompacting, 2_400, motionDisabled);\n const spinner = useGradientSpinner(\n Boolean(activity) && !showCompactProgress && !motionDisabled && !activity?.blocked,\n 'quill',\n motionDisabled,\n );\n\n if (!activity && !showCompactProgress) return null;\n if (showCompactProgress) {\n const displayProgress = compactComplete ? 100 : compactProgress;\n const compactLabel = compactComplete\n ? width < 30\n ? 'Done'\n : 'Compacted'\n : compactTrigger === 'auto'\n ? width < 36\n ? 'Auto'\n : 'Auto-compacting'\n : width < 30\n ? 'Compact'\n : 'Compacting';\n const percent = `${String(displayProgress).padStart(3, ' ')}%`;\n const hint = isCompacting && !compactComplete && width >= 52 ? ' · Esc to cancel' : '';\n const barWidth = Math.max(\n 1,\n Math.min(\n 24,\n contentWidth - displayWidth(compactLabel) - displayWidth(percent) - displayWidth(hint) - 2,\n ),\n );\n const filled = Math.min(barWidth, Math.round((displayProgress / 100) * barWidth));\n const progressColor = compactComplete ? theme.success : theme.brand;\n\n return (\n <Box paddingLeft={horizontalInset} width={width} flexDirection=\"row\" flexWrap=\"nowrap\">\n <Text color={theme.subtle} dimColor>\n {compactLabel}{' '}\n </Text>\n <Text color={progressColor}>{'█'.repeat(filled)}</Text>\n <Text color={theme.subtle} dimColor>\n {'░'.repeat(barWidth - filled)}\n </Text>\n <Text color={compactComplete ? theme.success : theme.brandShimmer}> {percent}</Text>\n {hint ? (\n <Text color={theme.subtle} dimColor>\n {hint}\n </Text>\n ) : null}\n </Box>\n );\n }\n\n const hint = pendingPlanApproval\n ? ' · choose approve, adjust, or reject above'\n : pendingUserQuestion || pendingElicitation\n ? ' · answer the question above'\n : pendingPermission\n ? ' · Esc to deny'\n : isThinking || isCompacting\n ? ' · Esc to cancel'\n : '';\n // Rolls up to `4m 8s` / `1h 2m 3s` past a minute, matching subagent rows,\n // background shells and tool rows. A bare second count stops being readable\n // as a duration somewhere around three digits.\n const elapsed =\n shouldTrackElapsed && !motionDisabled ? ` · ${formatElapsedDuration(elapsedSeconds)}` : '';\n // The quill spans four cells. The waiting mark takes the same column, so the\n // wording does not shift when the turn stops to ask you something.\n const indicatorWidth = displayWidth(spinner.frame);\n const line = fitActivityLine(\n activity?.label ?? '',\n elapsed,\n hint,\n Math.max(1, contentWidth - indicatorWidth - 1),\n );\n const indicator = activity?.blocked ? padDisplay('◇', indicatorWidth) : spinner.frame;\n const tone = activity?.tone ?? 'normal';\n const palette = activityPalette(tone, theme, spinner.color, spinner.markColor);\n\n return (\n <Box width={width} flexWrap=\"nowrap\">\n {tone === 'normal' && !activity?.blocked ? (\n // Fresh ink in the rubric drying to grey, a colour per cell.\n <SpinnerGlyphs frame={spinner.frame} colors={spinner.colors} />\n ) : (\n <Text color={palette.indicator}>{indicator}</Text>\n )}\n <Text> </Text>\n <Text color={palette.label} bold={tone === 'normal'} dimColor={tone !== 'normal'}>\n {line.label}\n </Text>\n {line.elapsed ? <Text color={palette.meta}>{line.elapsed}</Text> : null}\n {line.hint ? (\n <Text color={palette.meta} dimColor>\n {line.hint}\n </Text>\n ) : null}\n </Box>\n );\n}\n","import type { Message } from '../types/messages.js';\nimport type { RetryPhase } from '../types/runtime.js';\nimport type { ToolCall } from '../types/tools.js';\nimport { canonicalToolName } from '../tools/aliases.js';\nimport { getPrimaryArg } from '../tools/primary-arg.js';\nimport { parseMcpToolName } from './tool-presentation.js';\n\nexport type ActivityTone = 'normal' | 'waiting' | 'warning';\n\nexport interface WorkingActivity {\n label: string;\n tone: ActivityTone;\n blocked?: boolean;\n}\n\ninterface WorkingActivityInput {\n isThinking: boolean;\n isCompacting: boolean;\n compactTrigger?: 'manual' | 'auto';\n messages: Message[];\n streamingMessageId?: string | null;\n pendingPermission: boolean;\n pendingPlanApproval: boolean;\n pendingUserQuestion: boolean;\n retryPhase: RetryPhase;\n retryAttempt: number;\n retryMax: number;\n retryCountdownMs: number;\n elapsedSeconds: number;\n /**\n * The plan step in flight: its `activeForm`, or its wording when the model\n * gave none. Absent when no step is in progress.\n */\n activeStep?: string;\n}\n\n/**\n * Widest a phrase may be, in columns.\n *\n * The activity row is one line and the label shares it with an elapsed time and\n * a keyboard hint — about 50 columns on an 80-column terminal. A phrase is only\n * the frame; the target inside it (a path, a pattern, a shell command) is the\n * part the reader is actually waiting to see. `Peeking between the covers of`\n * spent 29 of those columns on a joke and then truncated the filename it was\n * introducing. Short phrases are funnier anyway: the gag lands before the eye\n * has finished the line, and what the run is *doing* survives.\n */\nexport const MAX_PHRASE_WIDTH = 28;\n\n/**\n * The reasoning phases.\n *\n * Shown while the model is thinking and nothing more specific is known, one\n * every three seconds, in this order — so the openers are the ones a short turn\n * will actually show. Each line is a small joke about *thinking*, never a claim\n * about progress the run has not made: `Almost there` would be a lie the\n * indicator has no way to check.\n */\nexport const REASONING_PHASES = [\n 'Pondering the plot twist',\n 'Consulting the footnotes',\n 'Untangling a subplot',\n 'Sharpening a tiny pencil',\n 'Rearranging the bookshelves',\n 'Following the semicolons',\n 'Asking the rubber duck',\n 'Turning it sideways',\n 'Reading between the lines',\n 'Negotiating with edge cases',\n 'Chasing a runaway thought',\n 'Auditioning better verbs',\n 'Squinting at the margins',\n 'Arguing with a footnote',\n 'Letting the ink dry',\n 'Rereading that paragraph',\n 'Hunting a missing comma',\n 'Blaming the typesetter',\n 'Checking the index twice',\n 'Dog-earing the good bit',\n 'Filing off a rough edge',\n 'Weighing two adjectives',\n 'Drafting in the margins',\n 'Counting the loose ends',\n 'Consulting the errata',\n 'Retracing the outline',\n 'Second-guessing chapter two',\n 'Plotting the next twist',\n] as const;\n\n/**\n * One phrase list per tool.\n *\n * Kept in a single catalog rather than inline in the switch so the set can be\n * read — and width-checked — in one place. Phrases that take a target end where\n * the target begins, so they read as one clause: `Redlining src/tui/app.tsx`,\n * `Chewing on npm test`.\n */\nconst TOOL_PHRASES = {\n read: ['Cracking open', 'Leafing through', 'Skimming', 'Peeking inside'],\n write: ['Putting ink to', 'Drafting', 'Inking'],\n applyPatch: ['Patching', 'Stitching an edit into', 'Reworking'],\n edit: ['Redlining', 'Polishing', 'Rewording', 'Marking up'],\n notebookEdit: ['Scribbling in', 'Annotating', 'Adding marginalia to'],\n glob: ['Scanning shelves for', 'Checking spines for', 'Combing the stacks for'],\n grep: ['Hunting for', 'Combing the lines for', 'Tracking down', 'Grilling the code for'],\n bash: ['Running', 'Poking the shell with', 'Chewing on'],\n bashOutput: ['Listening to shell', 'Eavesdropping on shell', 'Checking in on shell'],\n killShell: ['Quieting shell', 'Hushing shell', 'Pulling the plug on shell'],\n dismissShell: ['Clearing shell', 'Filing away shell', 'Tidying up shell'],\n webFetch: ['Fetching', 'Pulling a page from', 'Borrowing ink from'],\n webSearch: ['Roaming the web for', 'Chasing links for', 'Asking the internet about'],\n gitStatus: [\n \"Taking the repo's pulse\",\n 'Asking Git what changed',\n 'Seeing if Git looks nervous',\n \"Reading the repo's mood\",\n ],\n gitDiff: ['Reading the red ink', 'Studying the markup', 'Comparing drafts'],\n gitLog: ['Flipping through history', \"Reading the repo's diary\", 'Checking old plot twists'],\n gitCommit: ['Binding the chapter', 'Stamping a bookmark', 'Filing this chapter away'],\n gitBranch: [\"Following Git's branches\", 'Climbing the branches', 'Checking other timelines'],\n todoWrite: ['Redrawing the plan', 'Shuffling the plot points', 'Updating the quest log'],\n task: ['Handing off a subplot:', 'Sending a side quest:', 'Recruiting help for:'],\n taskCreate: ['Adding a plot point:', 'Pinning a new quest:', 'Writing a task card:'],\n taskList: ['Checking the plot points', 'Reviewing the quest log', 'Counting loose ends'],\n taskGet: ['Opening plot point', 'Checking quest', 'Reading the card for'],\n taskUpdate: ['Revising plot point', 'Moving quest along', 'Updating the card for'],\n taskStop: ['Dropping plot point', 'Calling off quest', 'Closing the card for'],\n invokeSkill: ['Opening the playbook:', 'Equipping', 'Dusting off'],\n readSkillResource: ['Turning to', 'Opening', 'Consulting'],\n toolSearch: ['Rummaging the toolbox for', 'Sizing up tools for', 'Hunting a tool for'],\n askUserQuestion: ['Composing a question', 'Preparing a tiny pop quiz', 'Wording it carefully'],\n enterPlanMode: [\n 'Outlining the next chapter',\n 'Unrolling the parchment',\n 'Sketching the treasure map',\n ],\n exitPlanMode: ['Closing the outline', 'Folding the treasure map', 'Setting the plan in motion'],\n sessionHistorySearch: [\n 'Flipping back for',\n 'Searching old chapters for',\n 'Checking the recap for',\n ],\n sessionHistoryRead: [\n 'Rereading an old chapter',\n 'Catching up on the lore',\n 'Checking last episode',\n ],\n agentPlan: ['Planning the handoff', 'Drawing up the roster', 'Casting the chapter'],\n agentSpawn: ['Commissioning:', 'Handing off:', 'Hiring a ghostwriter:'],\n agentList: ['Counting the ghostwriters', 'Taking attendance', 'Checking the writers room'],\n agentGet: ['Checking on agent', 'Asking after agent', 'Looking in on agent'],\n agentRead: ['Reading back agent', 'Collecting notes from', 'Opening the report from'],\n agentSend: ['Passing a note:', 'Nudging the agent:', 'Sending word:'],\n agentWait: ['Waiting on agent', 'Holding for agent', 'Letting agent finish'],\n agentStop: ['Calling back agent', 'Stopping agent', 'Pulling agent off the job'],\n agentApply: ['Accepting the patch', 'Taking the draft', 'Folding in the patch'],\n evidencePublish: ['Filing evidence:', 'Pinning up:', 'Logging the receipt:'],\n evidenceList: ['Checking the evidence', 'Counting the receipts', 'Reviewing the exhibits'],\n evidenceReview: ['Weighing the evidence', 'Reading the exhibits', 'Second-opinioning'],\n} as const;\n\n/** Every static phrase list in this module, for the width budget check. */\nexport const ACTIVITY_PHRASE_LISTS: readonly (readonly string[])[] = [\n REASONING_PHASES,\n ...Object.values(TOOL_PHRASES),\n];\n\nfunction stringArg(args: Record<string, unknown>, ...names: string[]): string | undefined {\n for (const name of names) {\n const value = args[name];\n if (typeof value === 'string' && value.trim()) return value;\n }\n return undefined;\n}\n\nfunction cleanTarget(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const clean = value\n .replace(/[\\u0000-\\u001f\\u007f]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n return clean || undefined;\n}\n\nfunction withTarget(action: string, target: string | undefined): string {\n const clean = cleanTarget(target);\n if (!clean) return action.endsWith(':') ? action.slice(0, -1) : action;\n return `${action} ${clean}`;\n}\n\nfunction humanizeToolName(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim()\n .toLowerCase();\n}\n\nfunction pickPhrase(call: ToolCall, phrases: readonly string[]): string {\n const seed = `${call.name}:${call.id}:${getPrimaryArg(call.arguments)}`;\n let hash = 0;\n for (let index = 0; index < seed.length; index++) {\n hash = (Math.imul(hash, 31) + seed.charCodeAt(index)) >>> 0;\n }\n return phrases[hash % phrases.length];\n}\n\nfunction playfulTarget(call: ToolCall, phrases: readonly string[], target: string | undefined) {\n return withTarget(pickPhrase(call, phrases), target);\n}\n\nexport function toolActivityText(call: ToolCall): string {\n const canonicalName = canonicalToolName(call.name);\n const args = call.arguments;\n const primary = getPrimaryArg(args);\n const filePath = stringArg(args, 'filePath', 'file_path', 'path') ?? primary;\n const mcp = parseMcpToolName(call.name);\n\n if (mcp) {\n return withTarget(\n pickPhrase(call, [\n `Asking ${mcp.server} to`,\n `Nudging ${mcp.server} to`,\n `Calling on ${mcp.server} to`,\n ]),\n mcp.tool,\n );\n }\n\n switch (canonicalName) {\n case 'Read':\n return playfulTarget(call, TOOL_PHRASES.read, filePath);\n case 'Write':\n return playfulTarget(call, TOOL_PHRASES.write, filePath);\n case 'ApplyPatch':\n // `getPrimaryArg` digs the touched file out of the `*** Update File:`\n // envelope, so the row can name it instead of saying `workspace files`.\n return playfulTarget(call, TOOL_PHRASES.applyPatch, primary);\n case 'Edit':\n case 'MultiEdit':\n return playfulTarget(call, TOOL_PHRASES.edit, filePath);\n case 'NotebookEdit':\n return playfulTarget(\n call,\n TOOL_PHRASES.notebookEdit,\n stringArg(args, 'notebook_path', 'path') ?? primary,\n );\n case 'Glob':\n return playfulTarget(call, TOOL_PHRASES.glob, stringArg(args, 'pattern') ?? primary);\n case 'Grep':\n return playfulTarget(call, TOOL_PHRASES.grep, stringArg(args, 'pattern') ?? primary);\n case 'Bash':\n return playfulTarget(call, TOOL_PHRASES.bash, primary);\n case 'BashOutput':\n return playfulTarget(call, TOOL_PHRASES.bashOutput, primary);\n case 'KillShell':\n return playfulTarget(call, TOOL_PHRASES.killShell, primary);\n case 'DismissShell':\n return playfulTarget(call, TOOL_PHRASES.dismissShell, primary);\n case 'WebFetch':\n return playfulTarget(call, TOOL_PHRASES.webFetch, stringArg(args, 'url') ?? primary);\n case 'WebSearch':\n return playfulTarget(call, TOOL_PHRASES.webSearch, stringArg(args, 'query') ?? primary);\n case 'GitStatus':\n return pickPhrase(call, TOOL_PHRASES.gitStatus);\n case 'GitDiff':\n return pickPhrase(call, TOOL_PHRASES.gitDiff);\n case 'GitLog':\n return pickPhrase(call, TOOL_PHRASES.gitLog);\n case 'GitCommit':\n return pickPhrase(call, TOOL_PHRASES.gitCommit);\n case 'GitBranch':\n return pickPhrase(call, TOOL_PHRASES.gitBranch);\n case 'TodoWrite':\n return pickPhrase(call, TOOL_PHRASES.todoWrite);\n case 'Task':\n return playfulTarget(\n call,\n TOOL_PHRASES.task,\n stringArg(args, 'subject', 'description', 'prompt', 'agent') ?? primary,\n );\n case 'TaskCreate':\n return playfulTarget(call, TOOL_PHRASES.taskCreate, stringArg(args, 'subject') ?? primary);\n case 'TaskList':\n return pickPhrase(call, TOOL_PHRASES.taskList);\n case 'TaskGet':\n return playfulTarget(call, TOOL_PHRASES.taskGet, primary);\n case 'TaskUpdate':\n return playfulTarget(call, TOOL_PHRASES.taskUpdate, primary);\n case 'TaskStop':\n return playfulTarget(call, TOOL_PHRASES.taskStop, primary);\n case 'InvokeSkill':\n return playfulTarget(call, TOOL_PHRASES.invokeSkill, stringArg(args, 'skill') ?? primary);\n case 'ReadSkillResource':\n return playfulTarget(\n call,\n TOOL_PHRASES.readSkillResource,\n stringArg(args, 'path') ?? primary,\n );\n case 'ToolSearch':\n return playfulTarget(call, TOOL_PHRASES.toolSearch, stringArg(args, 'query') ?? primary);\n case 'AskUserQuestion':\n return pickPhrase(call, TOOL_PHRASES.askUserQuestion);\n case 'EnterPlanMode':\n return pickPhrase(call, TOOL_PHRASES.enterPlanMode);\n case 'ExitPlanMode':\n return pickPhrase(call, TOOL_PHRASES.exitPlanMode);\n case 'SessionHistorySearch':\n return playfulTarget(\n call,\n TOOL_PHRASES.sessionHistorySearch,\n stringArg(args, 'query') ?? primary,\n );\n case 'SessionHistoryRead':\n return pickPhrase(call, TOOL_PHRASES.sessionHistoryRead);\n case 'AgentPlan':\n return pickPhrase(call, TOOL_PHRASES.agentPlan);\n case 'AgentSpawn':\n return playfulTarget(\n call,\n TOOL_PHRASES.agentSpawn,\n stringArg(args, 'description', 'agent') ?? primary,\n );\n case 'AgentList':\n return pickPhrase(call, TOOL_PHRASES.agentList);\n case 'AgentGet':\n return playfulTarget(call, TOOL_PHRASES.agentGet, stringArg(args, 'agentId') ?? primary);\n case 'AgentRead':\n return playfulTarget(call, TOOL_PHRASES.agentRead, stringArg(args, 'agentId') ?? primary);\n case 'AgentSend':\n return playfulTarget(call, TOOL_PHRASES.agentSend, stringArg(args, 'message') ?? primary);\n case 'AgentWait':\n return playfulTarget(call, TOOL_PHRASES.agentWait, stringArg(args, 'agentId') ?? primary);\n case 'AgentStop':\n return playfulTarget(call, TOOL_PHRASES.agentStop, stringArg(args, 'agentId') ?? primary);\n case 'AgentApply':\n return pickPhrase(call, TOOL_PHRASES.agentApply);\n case 'EvidencePublish':\n // Deliberately no `?? primary` fallback, unlike its siblings: this call's\n // arguments carry no path or query, so `getPrimaryArg` falls through to\n // the first string key and hands back the `kind` enum. A row reading\n // `Filing evidence: blocker` names a category, not the finding; better to\n // drop the target and let the phrase stand alone.\n return playfulTarget(call, TOOL_PHRASES.evidencePublish, stringArg(args, 'summary'));\n case 'EvidenceList':\n return pickPhrase(call, TOOL_PHRASES.evidenceList);\n case 'EvidenceReview':\n return pickPhrase(call, TOOL_PHRASES.evidenceReview);\n default: {\n const toolName = humanizeToolName(canonicalName) || 'a tool';\n if (!primary) {\n return pickPhrase(call, [\n `Trying ${toolName}`,\n `Running ${toolName}`,\n `Giving ${toolName} a whirl`,\n ]);\n }\n return withTarget(\n pickPhrase(call, [\n `Trying ${toolName} on`,\n `Running ${toolName} on`,\n `Pointing ${toolName} at`,\n ]),\n primary,\n );\n }\n }\n}\n\nfunction queuedActivity(label: string, count: number): string {\n if (count <= 1) return label;\n const waiting = count - 1;\n return `${label} · ${waiting} ${waiting === 1 ? 'tool' : 'tools'} in the wings`;\n}\n\nfunction activeToolText(message: Message | undefined): string | null {\n if (!message) return null;\n\n const pendingNested = (message.nestedToolInvocations ?? []).filter(\n (invocation) => !invocation.result,\n );\n if (pendingNested.length > 0) {\n const active = pendingNested[pendingNested.length - 1];\n return queuedActivity(toolActivityText(active.call), pendingNested.length);\n }\n\n const completed = new Set((message.toolResults ?? []).map((result) => result.toolCallId));\n const pending = (message.toolCalls ?? []).filter((call) => !completed.has(call.id));\n if (pending.length === 0) return null;\n return queuedActivity(toolActivityText(pending[0]), pending.length);\n}\n\nfunction retryText(\n phase: RetryPhase,\n attempt: number,\n max: number,\n countdownMs: number,\n): string | null {\n if (phase === 'none') return null;\n\n const countdown = Math.max(0, Math.ceil(countdownMs / 1000));\n const attemptText = max > 0 ? `attempt ${attempt}/${max}` : `attempt ${attempt}`;\n\n if (phase === 'stalled') return `Waiting for API response · retrying in ${countdown}s`;\n if (phase === 'tool') return `Waiting for tool response · retrying in ${countdown}s`;\n if (phase === 'watchdog') return `Retrying watchdog · ${attemptText}`;\n if (phase === 'continue') return `Continuing past the output limit · ${attemptText}`;\n if (phase === 'reissue') return `Re-sending the turn in ${countdown}s · ${attemptText}`;\n return `Retrying in ${countdown}s · ${attemptText}`;\n}\n\nexport function deriveWorkingActivity({\n isThinking,\n isCompacting,\n compactTrigger,\n messages,\n streamingMessageId,\n pendingPermission,\n pendingPlanApproval,\n pendingUserQuestion,\n retryPhase,\n retryAttempt,\n retryMax,\n retryCountdownMs,\n elapsedSeconds,\n activeStep,\n}: WorkingActivityInput): WorkingActivity | null {\n const retry = retryText(retryPhase, retryAttempt, retryMax, retryCountdownMs);\n if (retry) return { label: retry, tone: 'warning' };\n if (isCompacting) {\n return {\n label: compactTrigger === 'auto' ? 'Auto-compacting…' : 'Compacting…',\n tone: 'normal',\n };\n }\n if (!isThinking) return null;\n // The blocked labels stay plain on purpose: the run has stopped and is asking\n // the reader for something, which is the one moment a joke is in the way.\n if (pendingPlanApproval) {\n return { label: 'Waiting for plan approval', tone: 'waiting', blocked: true };\n }\n if (pendingUserQuestion) {\n return { label: 'Waiting for your answer', tone: 'waiting', blocked: true };\n }\n if (pendingPermission) {\n return { label: 'Waiting for permission', tone: 'waiting', blocked: true };\n }\n\n // A plan step in flight names the work better than any phrase below. The\n // running tool already has its own row in the transcript, and while the Steps\n // sheet is closed the step is spelled out nowhere else. Only a retry, a\n // compaction, or a wait on the reader outranks it.\n if (activeStep) return { label: activeStep, tone: 'normal' };\n\n // The streaming message is at (or near) the end; scan backwards so this\n // per-render lookup stays O(1) on long transcripts.\n let activeMessage: Message | undefined;\n if (streamingMessageId) {\n for (let index = messages.length - 1; index >= 0; index--) {\n if (messages[index].id === streamingMessageId) {\n activeMessage = messages[index];\n break;\n }\n }\n }\n const toolText = activeToolText(activeMessage);\n if (toolText) return { label: toolText, tone: 'normal' };\n if (\n (activeMessage?.toolCalls?.length ?? 0) > 0 ||\n (activeMessage?.nestedToolInvocations?.length ?? 0) > 0\n ) {\n return { label: 'Reading what came back', tone: 'normal' };\n }\n if (activeMessage?.content) return { label: 'Writing the final page', tone: 'normal' };\n\n const phase = Math.floor(elapsedSeconds / 3) % REASONING_PHASES.length;\n return { label: REASONING_PHASES[phase], tone: 'normal' };\n}\n","import { Box, Text } from 'ink';\nimport { useEffect, useRef, useState } from 'react';\nimport { createRenderDebugLogger } from '../../debug-log.js';\nimport {\n createBookRuneMask,\n STARTUP_FIRE_TOTAL_TICKS,\n StartupFireSimulation,\n startupFireStepOptions,\n} from '../startup-fire.js';\nimport { composeStartupFireFrame } from '../startup-fire-frame.js';\nimport { useTheme } from '../theme.js';\nimport { useUiClock } from '../ui-clock.js';\n\nconst fireLog = createRenderDebugLogger('tui:startup-fire');\n\ninterface StartupFireProps {\n width: number;\n height: number;\n onComplete: () => void;\n}\n\nexport function StartupFire({ width, height, onComplete }: StartupFireProps) {\n const theme = useTheme();\n const safeWidth = Math.max(1, Math.floor(width));\n const safeHeight = Math.max(1, Math.floor(height));\n const simulationRef = useRef(new StartupFireSimulation(safeWidth, safeHeight * 2));\n const [tick, setTick] = useState(0);\n const tickRef = useRef(0);\n const completedRef = useRef(false);\n const clock = useUiClock('cinematic', tick < STARTUP_FIRE_TOTAL_TICKS);\n\n useEffect(() => {\n fireLog.event('start', { width: safeWidth, height: safeHeight });\n return () => fireLog.event('stop', { tick: tickRef.current });\n // Only log the lifecycle, not every animation tick.\n }, []);\n\n useEffect(() => {\n const simulation = simulationRef.current;\n simulation.resize(safeWidth, safeHeight * 2);\n const currentTick = tickRef.current;\n if (currentTick >= STARTUP_FIRE_TOTAL_TICKS) return;\n const rune =\n currentTick >= 24 && currentTick < 44\n ? createBookRuneMask(safeWidth, safeHeight * 2).mask\n : undefined;\n const step = startupFireStepOptions(currentTick);\n simulation.step({ ...step, protectedMask: rune });\n simulation.step({ ...step, protectedMask: rune });\n tickRef.current = Math.min(STARTUP_FIRE_TOTAL_TICKS, currentTick + 1);\n setTick(tickRef.current);\n }, [clock, safeHeight, safeWidth]);\n\n useEffect(() => {\n if (tick < STARTUP_FIRE_TOTAL_TICKS || completedRef.current) return;\n completedRef.current = true;\n fireLog.event('complete', { width: safeWidth, height: safeHeight });\n onComplete();\n }, [onComplete, safeHeight, safeWidth, tick]);\n\n const frame = composeStartupFireFrame(simulationRef.current, tick, safeHeight, theme);\n return (\n <Box flexDirection=\"column\" width={safeWidth} height={safeHeight} overflow=\"hidden\">\n {frame.rows.map((runs, rowIndex) => (\n <Box key={rowIndex} width={safeWidth} height={1} flexShrink={0}>\n {runs.map((run, runIndex) => (\n <Text\n key={runIndex}\n color={run.color}\n backgroundColor={run.backgroundColor}\n bold={run.bold}\n dimColor={run.dimColor}\n >\n {run.text}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n );\n}\n","/**\n * Deterministic terminal fire inspired by the PSX DOOM heat-buffer effect documented at\n * https://fabiensanglard.net/doom_fire_psx/. This is an independent implementation adapted for\n * Book's bounded, testable TUI renderer.\n */\n\nexport interface FireStepOptions {\n sourceStrength: number;\n sourceWidth: number;\n wind: number;\n protectedMask?: Uint8Array;\n}\n\nexport interface BookRuneLayout {\n mask: Uint8Array;\n terminalTop: number;\n terminalHeight: number;\n}\n\nconst GLYPHS: Record<string, readonly string[]> = {\n B: ['####.', '#...#', '####.', '#...#', '####.'],\n O: ['.###.', '#...#', '#...#', '#...#', '.###.'],\n K: ['#..#.', '#.#..', '##...', '#.#..', '#..#.'],\n};\n\nfunction clampByte(value: number): number {\n return Math.max(0, Math.min(255, Math.round(value)));\n}\n\nfunction mixSeed(seed: number): number {\n let value = seed >>> 0;\n value ^= value << 13;\n value ^= value >>> 17;\n value ^= value << 5;\n return value >>> 0;\n}\n\nexport function hashNoise(...values: number[]): number {\n let hash = 0x9e3779b9;\n for (const value of values) hash = mixSeed(hash ^ Math.imul(value | 0, 0x85ebca6b));\n return hash >>> 0;\n}\n\nexport function createBookRuneMask(width: number, pixelHeight: number): BookRuneLayout {\n const safeWidth = Math.max(1, Math.floor(width));\n const safeHeight = Math.max(2, Math.floor(pixelHeight));\n const terminalHeight = Math.floor(safeHeight / 2);\n const scaleX = safeWidth >= 72 ? 2 : 1;\n const letters = 'BOOK';\n const glyphWidth = 5 * scaleX;\n const gap = scaleX;\n const runeWidth = letters.length * glyphWidth + (letters.length - 1) * gap;\n const left = Math.max(0, Math.floor((safeWidth - runeWidth) / 2));\n const terminalTop = Math.max(1, Math.floor(terminalHeight * 0.42) - 2);\n const mask = new Uint8Array(safeWidth * safeHeight);\n\n for (let letterIndex = 0; letterIndex < letters.length; letterIndex++) {\n const glyph = GLYPHS[letters[letterIndex]];\n const glyphLeft = left + letterIndex * (glyphWidth + gap);\n for (let row = 0; row < glyph.length; row++) {\n for (let column = 0; column < glyph[row].length; column++) {\n if (glyph[row][column] !== '#') continue;\n for (let scale = 0; scale < scaleX; scale++) {\n const x = glyphLeft + column * scaleX + scale;\n const terminalY = terminalTop + row;\n if (x < 0 || x >= safeWidth || terminalY < 0 || terminalY >= terminalHeight) continue;\n mask[terminalY * 2 * safeWidth + x] = 1;\n mask[(terminalY * 2 + 1) * safeWidth + x] = 1;\n }\n }\n }\n }\n\n return { mask, terminalTop, terminalHeight: 5 };\n}\n\nexport class StartupFireSimulation {\n private current: Uint8Array;\n private next: Uint8Array;\n private randomState: number;\n\n width: number;\n pixelHeight: number;\n\n constructor(width: number, pixelHeight: number, seed = 0x00b00c) {\n this.width = Math.max(1, Math.floor(width));\n this.pixelHeight = Math.max(2, Math.floor(pixelHeight));\n this.current = new Uint8Array(this.width * this.pixelHeight);\n this.next = new Uint8Array(this.current.length);\n this.randomState = seed >>> 0;\n }\n\n private random(maxExclusive: number): number {\n this.randomState = mixSeed(this.randomState || 1);\n return this.randomState % Math.max(1, maxExclusive);\n }\n\n get heat(): Uint8Array {\n return this.current;\n }\n\n step({ sourceStrength, sourceWidth, wind, protectedMask }: FireStepOptions): void {\n const width = this.width;\n const height = this.pixelHeight;\n const bottom = (height - 1) * width;\n const halfSource = Math.max(0, Math.min(width / 2, (width * sourceWidth) / 2));\n const center = (width - 1) / 2;\n\n for (let x = 0; x < width; x++) {\n const insideSource = Math.abs(x - center) <= halfSource;\n this.current[bottom + x] = insideSource\n ? clampByte(sourceStrength - this.random(28))\n : Math.max(0, this.current[bottom + x] - 28);\n }\n\n this.next.fill(0);\n for (let y = 0; y < height - 1; y++) {\n const belowY = y + 1;\n const lowerY = Math.min(height - 1, y + 2);\n for (let x = 0; x < width; x++) {\n const gust = Math.round(wind) + this.random(3) - 1;\n const sampleX = Math.max(0, Math.min(width - 1, x - gust));\n const left = Math.max(0, sampleX - 1);\n const right = Math.min(width - 1, sampleX + 1);\n const below = belowY * width;\n const lower = lowerY * width;\n const average =\n (this.current[below + sampleX] * 3 +\n this.current[below + left] +\n this.current[below + right] +\n this.current[lower + sampleX] * 2) /\n 7;\n this.next[y * width + x] = clampByte(average - 2 - this.random(11));\n }\n }\n this.next.set(this.current.subarray(bottom, bottom + width), bottom);\n\n if (protectedMask?.length === this.next.length) {\n for (let index = 0; index < protectedMask.length; index++) {\n if (!protectedMask[index]) continue;\n this.next[index] = 0;\n }\n for (let index = 0; index < protectedMask.length; index++) {\n if (!protectedMask[index]) continue;\n const x = index % width;\n if (x > 0 && !protectedMask[index - 1]) {\n this.next[index - 1] = Math.max(this.next[index - 1], 190);\n }\n if (x + 1 < width && !protectedMask[index + 1]) {\n this.next[index + 1] = Math.max(this.next[index + 1], 190);\n }\n }\n }\n\n [this.current, this.next] = [this.next, this.current];\n }\n\n resize(width: number, pixelHeight: number): void {\n const nextWidth = Math.max(1, Math.floor(width));\n const nextHeight = Math.max(2, Math.floor(pixelHeight));\n if (nextWidth === this.width && nextHeight === this.pixelHeight) return;\n\n const resized = new Uint8Array(nextWidth * nextHeight);\n for (let y = 0; y < nextHeight; y++) {\n const sourceY = Math.min(\n this.pixelHeight - 1,\n Math.floor((y / nextHeight) * this.pixelHeight),\n );\n for (let x = 0; x < nextWidth; x++) {\n const sourceX = Math.min(this.width - 1, Math.floor((x / nextWidth) * this.width));\n resized[y * nextWidth + x] = this.current[sourceY * this.width + sourceX];\n }\n }\n this.width = nextWidth;\n this.pixelHeight = nextHeight;\n this.current = resized;\n this.next = new Uint8Array(resized.length);\n }\n}\n\nexport const STARTUP_FIRE_TOTAL_TICKS = 56;\n\nexport function startupFireStepOptions(tick: number): Omit<FireStepOptions, 'protectedMask'> {\n if (tick < 7) {\n return {\n sourceStrength: 255,\n sourceWidth: 0.04 + tick * 0.035,\n wind: Math.sin(tick * 0.6) * 0.7,\n };\n }\n if (tick < 34) {\n return {\n sourceStrength: 255,\n sourceWidth: Math.min(1.1, 0.28 + (tick - 7) * 0.08),\n wind: Math.sin(tick * 0.35) * 1.2,\n };\n }\n if (tick < 47) {\n const remaining = 1 - (tick - 34) / 13;\n return {\n sourceStrength: 255 * remaining,\n sourceWidth: 1,\n wind: Math.sin(tick * 0.42) * 1.5,\n };\n }\n return { sourceStrength: 0, sourceWidth: 0, wind: 0 };\n}\n","import type { ThemeTokens } from '../types/theme.js';\nimport { createBookRuneMask, hashNoise, type StartupFireSimulation } from './startup-fire.js';\n\nexport interface StartupFireRun {\n text: string;\n color?: string;\n backgroundColor?: string;\n bold?: boolean;\n dimColor?: boolean;\n}\n\nexport interface StartupFireFrame {\n rows: StartupFireRun[][];\n phase: 'spark' | 'inferno' | 'reveal' | 'ashes' | 'awakened';\n}\n\ninterface CellStyle {\n text: string;\n color?: string;\n backgroundColor?: string;\n bold?: boolean;\n dimColor?: boolean;\n}\n\nconst HEAT_PALETTE = [\n '#070707',\n '#1d0707',\n '#3a0907',\n '#5b0d06',\n '#7f1405',\n '#a52205',\n '#c93405',\n '#e84a07',\n '#f5660b',\n '#ff8612',\n '#ffaa22',\n '#ffcb43',\n '#ffe477',\n '#fff1b3',\n '#ffffff',\n] as const;\n\nconst CODE_FRAGMENTS = ['{}', '=>', 'git', '@file', 'async', '<T>', '/help'];\nconst ASH_GLYPHS = ['·', '.', \"'\", '`'];\n\nfunction phaseFor(tick: number): StartupFireFrame['phase'] {\n if (tick < 7) return 'spark';\n if (tick < 24) return 'inferno';\n if (tick < 44) return 'reveal';\n if (tick < 52) return 'ashes';\n return 'awakened';\n}\n\nexport function heatColor(intensity: number): string | undefined {\n if (intensity < 5) return undefined;\n const index = Math.min(\n HEAT_PALETTE.length - 1,\n Math.floor((intensity / 255) * HEAT_PALETTE.length),\n );\n return HEAT_PALETTE[index];\n}\n\nfunction sameStyle(left: CellStyle, right: CellStyle): boolean {\n return (\n left.color === right.color &&\n left.backgroundColor === right.backgroundColor &&\n left.bold === right.bold &&\n left.dimColor === right.dimColor\n );\n}\n\nfunction toRuns(cells: CellStyle[]): StartupFireRun[] {\n const runs: StartupFireRun[] = [];\n for (const cell of cells) {\n const previous = runs.at(-1);\n if (previous && sameStyle(previous, cell)) {\n previous.text += cell.text;\n } else {\n runs.push({ ...cell });\n }\n }\n return runs;\n}\n\nfunction writeText(\n cells: CellStyle[][],\n row: number,\n text: string,\n style: Omit<CellStyle, 'text'>,\n centered = true,\n): void {\n if (row < 0 || row >= cells.length) return;\n const left = centered ? Math.max(0, Math.floor((cells[row].length - text.length) / 2)) : 0;\n for (let index = 0; index < text.length && left + index < cells[row].length; index++) {\n cells[row][left + index] = { text: text[index], ...style };\n }\n}\n\nfunction addAtmosphere(\n cells: CellStyle[][],\n tick: number,\n theme: ThemeTokens,\n phase: StartupFireFrame['phase'],\n): void {\n const height = cells.length;\n const width = cells[0]?.length ?? 0;\n if (phase === 'spark') {\n for (let index = 0; index < CODE_FRAGMENTS.length; index++) {\n const text = CODE_FRAGMENTS[index];\n const x = hashNoise(index, width) % Math.max(1, width - text.length);\n const y = Math.min(height - 1, 1 + (hashNoise(index, height) % Math.max(1, height - 5)));\n for (let offset = 0; offset < text.length && x + offset < width; offset++) {\n cells[y][x + offset] = { text: text[offset], color: theme.subtle, dimColor: true };\n }\n }\n const sparkRow = Math.max(0, height - 3 - Math.floor(tick / 2));\n writeText(cells, sparkRow, tick < 3 ? '·' : tick < 5 ? '✦' : '⟡', {\n color: tick < 4 ? '#ffffff' : theme.brandShimmer,\n bold: true,\n });\n if (tick >= 3) {\n writeText(cells, Math.max(0, height - 5), 'KNOWLEDGE HAS A SPARK', {\n color: theme.brand,\n dimColor: tick < 5,\n });\n }\n }\n\n if (phase === 'inferno' || phase === 'reveal') {\n const emberCount = Math.min(32, Math.max(6, Math.floor(width / 5)));\n for (let index = 0; index < emberCount; index++) {\n const x = hashNoise(tick, index, width) % width;\n const y = hashNoise(tick - index, height, index) % Math.max(1, height - 2);\n if (cells[y][x].text !== ' ') continue;\n const glyph = ['·', '•', '*', '✦'][hashNoise(index, tick) % 4];\n cells[y][x] = {\n text: glyph,\n color: hashNoise(tick, x, y) % 4 === 0 ? '#fff1b3' : '#f5660b',\n bold: glyph === '✦',\n };\n }\n }\n\n if (phase === 'ashes' || phase === 'awakened') {\n const count = phase === 'ashes' ? Math.min(48, Math.floor(width / 2)) : 6;\n for (let index = 0; index < count; index++) {\n const x = hashNoise(index, tick, width) % width;\n const y = hashNoise(index * 7, tick, height) % Math.max(1, height - 1);\n if (cells[y][x].text !== ' ') continue;\n cells[y][x] = {\n text: ASH_GLYPHS[hashNoise(tick, index) % ASH_GLYPHS.length],\n color: theme.subtle,\n dimColor: true,\n };\n }\n }\n}\n\nexport function composeStartupFireFrame(\n simulation: StartupFireSimulation,\n tick: number,\n terminalHeight: number,\n theme: ThemeTokens,\n): StartupFireFrame {\n const width = simulation.width;\n const height = Math.max(1, Math.floor(terminalHeight));\n const heat = simulation.heat;\n const phase = phaseFor(tick);\n const rune = createBookRuneMask(width, simulation.pixelHeight);\n const cells: CellStyle[][] = Array.from({ length: height }, (_, y) =>\n Array.from({ length: width }, (_, x): CellStyle => {\n const topIndex = y * 2 * width + x;\n const bottomIndex = Math.min(simulation.pixelHeight - 1, y * 2 + 1) * width + x;\n const top = heat[topIndex] ?? 0;\n const bottom = heat[bottomIndex] ?? 0;\n const topColor = heatColor(top);\n const bottomColor = heatColor(bottom);\n if (!topColor && !bottomColor) return { text: ' ' };\n return {\n text: '▀',\n color: topColor ?? '#070707',\n backgroundColor: bottomColor ?? '#070707',\n };\n }),\n );\n\n if (phase === 'reveal') {\n const revealThreshold = Math.min(width, Math.max(0, (tick - 24) * Math.ceil(width / 14)));\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const topIndex = y * 2 * width + x;\n if (!rune.mask[topIndex]) continue;\n const distanceFromCenter = Math.abs(x - width / 2) * 2;\n if (distanceFromCenter > revealThreshold) continue;\n cells[y][x] = {\n text: '█',\n color: tick < 29 ? '#ffffff' : tick < 34 ? '#fff1b3' : theme.brandShimmer,\n bold: true,\n };\n }\n }\n if (tick >= 35) {\n writeText(\n cells,\n Math.min(height - 2, rune.terminalTop + rune.terminalHeight + 2),\n 'WHAT SURVIVES BECOMES KNOWLEDGE',\n {\n color: theme.brand,\n bold: true,\n },\n );\n }\n }\n\n addAtmosphere(cells, tick, theme, phase);\n\n if (phase === 'ashes' || phase === 'awakened') {\n const center = Math.floor(height / 2);\n writeText(cells, center - 1, '╭ BOOK', { color: theme.assistantAccent, bold: true });\n writeText(cells, center, '╰ Your coding workspace, indexed.', { color: theme.text });\n if (phase === 'awakened') {\n writeText(cells, center + 2, 'AGENT AWAKENED ✦', {\n color: theme.brandShimmer,\n bold: true,\n });\n }\n }\n\n if (phase !== 'awakened' && width >= 18) {\n const hint = 'Esc skip';\n const row = cells[height - 1];\n const start = Math.max(0, width - hint.length - 1);\n for (let index = 0; index < hint.length; index++) {\n row[start + index] = { text: hint[index], color: theme.subtle, dimColor: true };\n }\n }\n\n return { phase, rows: cells.map(toRuns) };\n}\n","import { Box, Text } from 'ink';\nimport { useEffect } from 'react';\nimport type { CompactUiState } from '../hooks/useAgent.js';\nimport { useTheme } from '../theme.js';\nimport { truncateDisplay } from './word-wrap.js';\n\nexport interface CompactDiffCardProps {\n state: CompactUiState;\n terminalWidth?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n onSettled?: () => void;\n}\n\nfunction compactSummary(state: CompactUiState): string {\n const details: string[] = [];\n if (state.trigger === 'auto') details.push('automatic');\n if (state.judge) {\n // An inconclusive verdict names its reason: it is the difference between a\n // judge that had nothing to read and one whose reply never parsed.\n const why =\n state.judge.verdict === 'inconclusive' && state.judge.note ? ` (${state.judge.note})` : '';\n details.push(`deferred · judge ${state.judge.verdict}${why}`);\n }\n if (state.preMessages !== undefined) {\n details.push(`${state.preMessages} ${state.preMessages === 1 ? 'message' : 'messages'}`);\n }\n if (state.preContextTokens !== undefined && state.preContextTokens > 0) {\n details.push(`~${Math.round(state.preContextTokens / 100) / 10}k context`);\n }\n if (state.degraded) details.unshift('reduced fidelity');\n else if (state.warning) details.unshift('with a warning');\n return ['Compact conversation', ...details].join(' · ');\n}\n\n/** Post-compact status rendered like a tool result without creating a tool invocation. */\nexport function CompactDiffCard({\n state,\n terminalWidth = 80,\n reducedMotion = false,\n screenReader = false,\n onSettled,\n}: CompactDiffCardProps) {\n const theme = useTheme();\n const width = Math.max(12, Math.floor(terminalWidth) - 2);\n const summaryWidth = Math.max(4, width - 4);\n\n useEffect(() => {\n if (state.phase !== 'diff' || !onSettled) return;\n if (reducedMotion || screenReader) {\n onSettled();\n return;\n }\n const timer = setTimeout(onSettled, 760);\n return () => clearTimeout(timer);\n }, [onSettled, reducedMotion, screenReader, state.phase]);\n\n if (state.phase === 'working') return null;\n\n const failed = state.phase === 'error';\n const skipped = state.phase === 'skipped';\n const symbol = failed ? '×' : skipped ? '–' : '✓';\n const color = failed ? theme.error : skipped ? theme.warning : theme.inactive;\n const summary =\n failed || skipped ? (state.message ?? compactSummary(state)) : compactSummary(state);\n\n return (\n <Box flexDirection=\"column\" marginLeft={2} width={width}>\n <Box>\n <Text color={color}>{symbol} </Text>\n <Text color={failed ? theme.error : theme.text}>\n {truncateDisplay(summary, summaryWidth)}\n </Text>\n </Box>\n {state.warning ? (\n <Box\n marginLeft={2}\n borderStyle=\"single\"\n borderLeft\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeftColor={theme.toolRail}\n paddingLeft={1}\n >\n <Text color={theme.warning}>\n {truncateDisplay(state.warning, Math.max(8, width - 6))}\n </Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n","import { Component } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { createUiDebugLogger } from '../../debug-log.js';\nimport { useTheme } from '../theme.js';\n\nconst uiLog = createUiDebugLogger('tui:errorboundary');\n\ninterface ErrorBoundaryProps {\n children: React.ReactNode;\n /**\n * The command that reopens this conversation, shown so a render crash does not\n * read as lost work. The session file is durable by the time anything can\n * crash — `SessionStore.create` appends the `session_meta` header\n * synchronously at startup and every record after it lands the same way — so\n * for a persisted session this is a promise the store can keep.\n *\n * Left undefined when persistence is off, and when the session holds nothing\n * worth reopening. A resume line that fails, or that reopens an empty\n * conversation, is worse than no resume line at all.\n */\n resumeCommand?: string;\n /**\n * How the host leaves. The fallback has to own this itself: the app's global\n * key handler is still mounted and still holds whatever state it had when the\n * render blew up, so it swallows Ctrl+C whenever a picker was open and turns\n * it into a stream interrupt whenever a turn was in flight. Neither reaches\n * an exit, and Ink runs with `exitOnCtrlC: false` with no SIGINT handler\n * behind it, so nothing else would either.\n */\n onExit?: () => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n /** First frames of the stack, kept for the box — see `componentDidCatch`. */\n origin: string | null;\n}\n\nconst CLEAR_STATE: ErrorBoundaryState = { hasError: false, error: null, origin: null };\n\n/** Longest stack frame the box will print before it starts costing more than it tells. */\nconst ORIGIN_WIDTH = 72;\n\n/**\n * The single most useful line of a stack: where the throw came from, and which\n * component was rendering. Node stacks carry absolute paths, which on Windows\n * are long enough to wrap the box on their own, so only the tail of the path\n * survives.\n */\nfunction describeOrigin(error: Error, componentStack?: string | null): string | null {\n const shorten = (line: string) =>\n line.replace(/(?:file:\\/\\/)?(?:[A-Za-z]:)?[\\\\/][^\\s)]*[\\\\/]/g, '').trim();\n const component = componentStack\n ?.split('\\n')\n .map((line) => line.trim())\n .find(Boolean);\n const frame = error.stack\n ?.split('\\n')\n .slice(1)\n .map((line) => line.trim())\n .find((line) => line.startsWith('at '));\n // The component stack usually carries the location too, and for a throw in\n // the component's own body both name the same symbol — so the raw frame is\n // only worth the width when it points somewhere else.\n const symbol = (line?: string) => line?.replace(/^at\\s+/, '').split(/[\\s(]/)[0] ?? '';\n const best = component ? shorten(component) : frame ? shorten(frame) : '';\n const extra = frame && component && symbol(frame) !== symbol(component) ? shorten(frame) : '';\n const line = [best, extra].filter(Boolean).join(' — ');\n if (!line) return null;\n return line.length > ORIGIN_WIDTH ? `${line.slice(0, ORIGIN_WIDTH - 1)}…` : line;\n}\n\nfunction ErrorReport({\n error,\n origin,\n resumeCommand,\n onExit,\n onRetry,\n}: {\n error: Error | null;\n origin: string | null;\n resumeCommand?: string;\n onExit?: () => void;\n onRetry: () => void;\n}) {\n const theme = useTheme();\n const { exit } = useApp();\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') {\n (onExit ?? exit)();\n return;\n }\n if (input.toLowerCase() === 'r') onRetry();\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.error} padding={1}>\n <Text bold color={theme.error}>\n Something went wrong\n </Text>\n <Text color={theme.subtle}>{error?.message ?? 'Unknown error'}</Text>\n {origin ? <Text color={theme.subtle}>{origin}</Text> : null}\n {resumeCommand ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.text}>This conversation is saved. Reopen it with:</Text>\n <Text color={theme.brand}>{resumeCommand}</Text>\n </Box>\n ) : (\n <Box marginTop={1}>\n <Text color={theme.subtle}>Restart Book to recover.</Text>\n </Box>\n )}\n <Text color={theme.subtle}>Press R to try again, or Ctrl+C to exit.</Text>\n </Box>\n );\n}\n\n/**\n * React error boundary for the Ink TUI. Catches render errors in child\n * components and displays a friendly error message instead of crashing\n * the entire terminal UI.\n *\n * The fallback is a component rather than inline JSX so that it can hold the\n * keyboard: once the boundary is showing, it is the only thing on screen, and\n * it has to be able to both leave and retry. Retrying is worth offering because\n * plenty of render throws are transient — one bad message, a momentarily zero\n * width — and the surrounding app has kept running the whole time.\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = CLEAR_STATE;\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n // No `console.warn` here: it printed `error.message` — already the second\n // line of the box — as raw text over the alternate screen, so a crashing\n // user's first sight was a smeared frame with a duplicated message. Its\n // diagnostic value is replaced rather than dropped. `uiLog` is a no-op\n // unless BOOK_DEBUG is set, so it cannot be the only record; the box itself\n // carries the throw site, which is what a bug report actually needs.\n this.setState({ origin: describeOrigin(error, errorInfo.componentStack) });\n uiLog.warn('caught', {\n name: error.name,\n message: error.message,\n stack: error.stack?.split('\\n').slice(0, 3).join(' | '),\n componentStack: errorInfo.componentStack\n ?.split('\\n')\n .map((s) => s.trim())\n .filter(Boolean)\n .slice(0, 6)\n .join(' > '),\n });\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <ErrorReport\n error={this.state.error}\n origin={this.state.origin}\n resumeCommand={this.props.resumeCommand}\n onExit={this.props.onExit}\n onRetry={() => this.setState(CLEAR_STATE)}\n />\n );\n }\n\n return this.props.children;\n }\n}\n","import { Box, Text } from 'ink';\nimport { useTheme } from '../theme.js';\nimport { STATUS_INDICATORS } from '../status-indicators.js';\nimport type { Task } from '../hooks/useTasks.js';\nimport { SoftPanel } from './chrome.js';\n\ninterface TaskListProps {\n tasks: Task[];\n onUpdateStatus: (id: string, status: Task['status']) => void;\n onRemove: (id: string) => void;\n /** Sheet width; with it the title becomes a ruled head like the other reference panels. */\n width?: number;\n}\n\nexport function TaskList({ tasks, width }: TaskListProps) {\n const theme = useTheme();\n const visible = tasks.slice(0, 5);\n\n return (\n <SoftPanel title=\"Tasks\" meta={String(tasks.length)} width={width}>\n {visible.length === 0 && (\n <Text color={theme.subtle}>No tasks yet. Use /task &lt;description&gt; to create one.</Text>\n )}\n {visible.map((task) => {\n const indicator = STATUS_INDICATORS[task.status];\n return (\n <Box key={task.id}>\n <Text color={theme[indicator.colorToken]}>{indicator.icon} </Text>\n <Text\n color={task.status === 'completed' ? theme.subtle : theme.text}\n strikethrough={task.status === 'completed'}\n >\n {task.subject}\n </Text>\n </Box>\n );\n })}\n {tasks.length > 5 && <Text color={theme.inactive}>…and {tasks.length - 5} more</Text>}\n </SoftPanel>\n );\n}\n","/**\n * Shared status glyphs and colour tokens for the agent's steps and the task list.\n *\n * Every glyph here is East Asian **Neutral**, so every terminal draws it one cell\n * wide. An Ambiguous glyph (`○`, and also `·` and `•`) is drawn two cells wide by\n * some terminals, which swallows the space behind it and lands the row's text a\n * column off the grid. Each is also in the common coding fonts (JetBrains Mono,\n * Cascadia): a glyph the font lacks comes from a fallback font, often as a colour\n * emoji wider than its cell, which is how `✎` failed.\n *\n * The set reads as a circle being filled: `◌` a step not yet begun, `◔` the one\n * in hand, `✓` the ones finished. Only the step in hand takes the rubric. A\n * finished step takes the same grey `✓` as a finished tool row, because success\n * is the default: colour is what a failure or a pending prompt spends, and a\n * check that is merely done has nothing to report.\n */\nexport const STATUS_INDICATORS = {\n pending: { icon: '◌' as const, colorToken: 'inactive' as const },\n in_progress: { icon: '◔' as const, colorToken: 'brand' as const },\n completed: { icon: '✓' as const, colorToken: 'inactive' as const },\n};\n","import { Box, Text } from 'ink';\nimport { useTheme } from '../theme.js';\nimport { STATUS_INDICATORS } from '../status-indicators.js';\nimport { SHEET_GUTTER_INDENT, sheetRowTextWidth } from '../layout.js';\nimport { stepProgress, stepWindow } from '../steps.js';\nimport type { Todo } from '../../tools/todo.js';\nimport { SoftPanel } from './chrome.js';\nimport { foldControlCharacters } from '../../control-characters.js';\nimport { truncateDisplay } from './word-wrap.js';\n\n/**\n * The agent's steps, opened with Ctrl+T.\n *\n * The plan is not a standing block. While a step is in flight the working line\n * and the status line carry it, so the full list is a reference sheet like\n * /help: set under `─ § Steps ──── 2 of 7 done · Ctrl+T to close ─`. Esc closes\n * it too once the agent is idle; while it works, Esc still cancels the turn, as\n * it always has. Its markers sit where a tool row's `✓` sits, its text on the\n * content column. A step shows its plain wording here; the working line has the\n * `activeForm`.\n */\nexport function StepsSheet({ todos, width }: { todos: readonly Todo[]; width: number }) {\n const theme = useTheme();\n const textWidth = sheetRowTextWidth(width);\n const { before, rows, after } = stepWindow(todos);\n const beforeFinished = before.every((todo) => todo.status === 'completed');\n return (\n <SoftPanel\n title=\"Steps\"\n meta={todos.length > 0 ? `${stepProgress(todos)} · Ctrl+T to close` : 'Ctrl+T to close'}\n width={width}\n >\n {todos.length === 0 ? (\n <Text color={theme.subtle}>No steps yet. The agent sets them out on multi-step work.</Text>\n ) : null}\n {before.length > 0 ? (\n <Box>\n <Text color={theme[STATUS_INDICATORS.completed.colorToken]}>\n {beforeFinished ? `${STATUS_INDICATORS.completed.icon} ` : SHEET_GUTTER_INDENT}\n </Text>\n <Text color={theme.inactive}>\n {beforeFinished ? `${before.length} done` : `${before.length} earlier`}\n </Text>\n </Box>\n ) : null}\n {rows.map((todo, index) => {\n const indicator = STATUS_INDICATORS[todo.status];\n const active = todo.status === 'in_progress';\n const color =\n todo.status === 'completed' ? theme.inactive : active ? theme.text : theme.subtle;\n return (\n <Box key={`${index}-${todo.content}`} flexWrap=\"nowrap\">\n <Text color={theme[indicator.colorToken]}>{`${indicator.icon} `}</Text>\n <Text color={color} bold={active}>\n {truncateDisplay(foldControlCharacters(todo.content), textWidth)}\n </Text>\n </Box>\n );\n })}\n {after > 0 ? (\n <Text color={theme.inactive}>{`${SHEET_GUTTER_INDENT}+${after} more`}</Text>\n ) : null}\n </SoftPanel>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport TextInput from './TextInputField.js';\nimport { useState, useCallback, useRef, useEffect, useMemo } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useTheme } from '../theme.js';\nimport { PILCROW } from '../marks.js';\nimport type { AgentConfig } from '../../types/runtime.js';\nimport type { ProviderConfig } from '../../settings.js';\nimport { resolveSecret } from '../../config.js';\nimport { discoverModels, type ModelDiscoveryOptions } from '../../provider/model-discovery.js';\nimport {\n parseModelIds,\n type ModelPickerOption,\n type ProviderSaveRequest,\n} from '../model-options.js';\nimport { EFFORT_LEVELS, type EffortLevel, type EffortResult } from '../../commands/effort.js';\nimport { ByokWizard } from './ByokWizard.js';\nimport { modelPickerHints } from './model-picker-hints.js';\nimport { useDensityMetrics } from '../density.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\nimport { SoftPanel } from './chrome.js';\nimport { panelGrid, sheetContentWidth } from '../layout.js';\n\nexport type ProviderRemovalResult =\n | {\n ok: true;\n providerId: string;\n removedModelCount: number;\n activeModel: string;\n switched: boolean;\n inheritedProviderRevealed: boolean;\n }\n | {\n ok: false;\n error: string;\n };\n\ninterface ModelPickerProps {\n title?: string;\n /** Terminal columns; the sheet's rule spans them. */\n terminalWidth?: number;\n options: ModelPickerOption[];\n currentModel: string;\n currentEffort?: AgentConfig['effort'];\n effortLevels?: readonly EffortLevel[];\n hasPriorOutput: boolean;\n warnings?: string[];\n providers: Record<string, ProviderConfig>;\n workspace: string;\n retry: AgentConfig['retry'];\n compact?: boolean;\n maxVisibleModels?: number;\n discover?: (options: ModelDiscoveryOptions) => Promise<Array<{ id: string; label?: string }>>;\n onPick: (model: string, saveDefault: boolean) => { ok: boolean; error?: string } | void;\n onPickEffort: (level: EffortLevel) => EffortResult;\n onSaveProvider: (request: ProviderSaveRequest) => { ok: boolean; error?: string };\n removableProviderIds: ReadonlySet<string>;\n removableProviderModelCounts?: ReadonlyMap<string, number>;\n onRemoveProvider: (providerId: string) => ProviderRemovalResult;\n onProviderSaved?: (request: ProviderSaveRequest) => void;\n allowProviderManagement?: boolean;\n onCancel: () => void;\n}\n\nconst EMPTY_PROVIDER_IDS: ReadonlySet<string> = new Set();\n\nfunction plural(count: number): string {\n return count === 1 ? '' : 's';\n}\n\nexport function ModelPicker({\n title,\n terminalWidth = 80,\n options,\n currentModel,\n currentEffort,\n effortLevels = EFFORT_LEVELS,\n hasPriorOutput,\n warnings = [],\n providers,\n workspace,\n retry,\n compact = false,\n maxVisibleModels = 10,\n discover = discoverModels,\n onPick,\n onPickEffort,\n onSaveProvider,\n removableProviderIds = EMPTY_PROVIDER_IDS,\n removableProviderModelCounts,\n onRemoveProvider,\n onProviderSaved,\n allowProviderManagement = true,\n onCancel,\n}: ModelPickerProps) {\n const theme = useTheme();\n const sheetWidth = panelGrid(Math.max(20, Math.floor(terminalWidth))).width;\n const density = useDensityMetrics();\n const [selected, setSelected, currentSelected] = useKeyState(0);\n const [filter, setFilter] = useState('');\n const [onEffort, setOnEffort] = useState(false);\n const [showWizard, setShowWizard] = useState(false);\n const [refreshing, setRefreshing] = useState<string>();\n const [manualEntry, setManualEntry] = useState<{ providerId: string; value: string }>();\n const [removal, setRemoval, currentRemoval] = useKeyState<\n { providerId: string; modelCount: number; active: boolean } | undefined\n >(undefined);\n const [error, setError] = useState<string>();\n const [notice, setNotice] = useState<string>();\n const pickedRef = useRef(false);\n const removalInFlightRef = useRef(false);\n const reanchorRef = useRef<string | undefined>(undefined);\n const filteredOptions = useMemo(() => {\n const query = filter.trim().toLowerCase();\n if (!query) return options;\n return options.filter(\n (option) =>\n option.id.toLowerCase().includes(query) ||\n option.label.toLowerCase().includes(query) ||\n option.providerId?.toLowerCase().includes(query),\n );\n }, [filter, options]);\n const itemCount = filteredOptions.length + (allowProviderManagement ? 1 : 0);\n const addIndex = filteredOptions.length;\n\n useEffect(() => {\n setSelected(Math.min(currentSelected(), Math.max(0, itemCount - 1)));\n }, [filteredOptions.length, itemCount]);\n\n // Refreshing or extending a catalog re-sorts the list under the cursor, so a\n // row can slide out from under the highlight and Enter would then save a\n // model the user never looked at. Re-anchor on the id that was selected.\n useEffect(() => {\n const anchor = reanchorRef.current;\n if (!anchor) return;\n reanchorRef.current = undefined;\n const index = filteredOptions.findIndex((option) => option.id === anchor);\n if (index >= 0) setSelected(index);\n }, [filteredOptions]);\n\n // Catalog edits are written to the user-global settings layer. Doing that for\n // a provider inherited from a project layer would copy its credential into a\n // second file and make the inherited copy look removable, so the same\n // ownership rule that guards removal guards refresh and manual entry.\n const ownsProvider = useCallback(\n (providerId: string) => {\n if (removableProviderIds.has(providerId)) return true;\n setError('Only BYOK providers you added can be changed.');\n return false;\n },\n [removableProviderIds],\n );\n\n const handlePick = useCallback(\n (model: string, saveDefault: boolean) => {\n if (pickedRef.current) return;\n const result = onPick(model, saveDefault);\n if (result && !result.ok) {\n setError(result.error ?? 'Could not save the selected model.');\n return;\n }\n pickedRef.current = true;\n },\n [onPick],\n );\n\n const refreshProvider = useCallback(\n async (providerId: string) => {\n const provider = providers[providerId];\n if (!provider) return;\n const apiKey = resolveSecret(provider.apiKey, workspace);\n if (!apiKey) {\n setError(`No usable API key is configured for ${providerId}.`);\n return;\n }\n setError(undefined);\n setNotice(undefined);\n setRefreshing(providerId);\n try {\n const models = await discover({\n type: provider.type,\n baseUrl: provider.baseURL ?? provider.baseUrl ?? '',\n apiKey,\n retry,\n });\n if (models.length === 0) {\n setError(`${providerId} did not return any models.`);\n return;\n }\n const currentForProvider = options.find(\n (option) => option.providerId === providerId && option.id === currentModel,\n );\n const activeModelId = currentForProvider\n ? currentForProvider.id.slice(providerId.length + 1)\n : models[0].id;\n const request: ProviderSaveRequest = {\n providerId,\n type: provider.type,\n baseURL: provider.baseURL ?? provider.baseUrl ?? '',\n apiKey: provider.apiKey ?? apiKey,\n models,\n activeModelId,\n replaceModels: true,\n activate: false,\n };\n const result = onSaveProvider(request);\n if (!result.ok) setError(result.error ?? 'Could not save refreshed models.');\n else setNotice(`${providerId}: ${models.length} model${plural(models.length)} listed.`);\n } catch (caught) {\n setError(caught instanceof Error ? caught.message : 'Could not refresh models.');\n } finally {\n setRefreshing(undefined);\n }\n },\n [currentModel, discover, onSaveProvider, options, providers, retry, workspace],\n );\n\n // Add hand-typed model IDs to a provider without touching its credentials or\n // the active selection — the catalog grows, nothing else moves.\n const addManualModels = useCallback(\n (providerId: string, raw: string) => {\n const provider = providers[providerId];\n if (!provider) {\n setError(`${providerId} is no longer configured.`);\n return;\n }\n let ids: string[];\n try {\n ids = parseModelIds(raw);\n } catch (caught) {\n setError(caught instanceof Error ? caught.message : 'Enter at least one model ID.');\n return;\n }\n const result = onSaveProvider({\n providerId,\n type: provider.type,\n baseURL: provider.baseURL ?? provider.baseUrl ?? '',\n apiKey: provider.apiKey ?? '',\n models: ids.map((id) => ({ id })),\n activeModelId: ids[0],\n manual: true,\n activate: false,\n });\n if (!result.ok) {\n setError(result.error ?? 'Could not save the model.');\n return;\n }\n setManualEntry(undefined);\n setError(undefined);\n setNotice(`Added ${ids.length} model${plural(ids.length)} to ${providerId}.`);\n },\n [onSaveProvider, providers],\n );\n\n useInput(\n (input, key) => {\n if (showWizard) return;\n // The text field owns every other key while it is open.\n if (manualEntry) {\n if (key.escape) {\n reanchorRef.current = undefined;\n setManualEntry(undefined);\n setError(undefined);\n }\n return;\n }\n // Read back rather than closing over `removal`: Alt+D and the `y` that\n // confirms it can arrive in one chunk, and the second key would then be\n // dispatched by the branch that was live before the prompt opened.\n const pendingRemoval = currentRemoval();\n if (pendingRemoval) {\n if (key.escape || input.toLowerCase() === 'n') {\n removalInFlightRef.current = false;\n setRemoval(undefined);\n setError(undefined);\n return;\n }\n if (key.return || input.toLowerCase() === 'y') {\n if (removalInFlightRef.current) return;\n removalInFlightRef.current = true;\n let result: ProviderRemovalResult;\n try {\n result = onRemoveProvider(pendingRemoval.providerId);\n } catch (caught) {\n result = {\n ok: false,\n error: caught instanceof Error ? caught.message : 'Could not remove the provider.',\n };\n }\n if (!result.ok) {\n removalInFlightRef.current = false;\n setError(result.error);\n }\n return;\n }\n return;\n }\n if (key.escape) {\n if (filter) {\n setFilter('');\n setSelected(0);\n return;\n }\n onCancel();\n return;\n }\n if (onEffort) {\n if (input === 'e') {\n setOnEffort(false);\n return;\n }\n const currentIndex = currentEffort ? effortLevels.indexOf(currentEffort) : -1;\n const idx = currentIndex >= 0 ? currentIndex : 0;\n const nextLevel = key.leftArrow\n ? effortLevels[Math.max(0, idx - 1)]\n : key.rightArrow\n ? effortLevels[Math.min(effortLevels.length - 1, idx + 1)]\n : undefined;\n if (nextLevel) {\n const result = onPickEffort(nextLevel);\n setError(result.ok ? undefined : (result.error ?? 'Could not save effort level.'));\n }\n return;\n }\n if (key.return) {\n if (allowProviderManagement && currentSelected() === addIndex) setShowWizard(true);\n else {\n const option = filteredOptions[currentSelected()];\n if (option) handlePick(option.id, true);\n }\n return;\n }\n if (key.backspace || key.delete) {\n if (filter) {\n setFilter((value) => value.slice(0, -1));\n setSelected(0);\n }\n return;\n }\n if (key.upArrow) {\n setSelected((currentSelected() - 1 + itemCount) % itemCount);\n setNotice(undefined);\n return;\n }\n if (key.downArrow) {\n setSelected((currentSelected() + 1) % itemCount);\n setNotice(undefined);\n return;\n }\n if (allowProviderManagement && key.meta && input === 'a') {\n setShowWizard(true);\n setError(undefined);\n return;\n }\n if (\n key.meta &&\n input === 'e' &&\n effortLevels.length > 0 &&\n currentSelected() !== addIndex &&\n filteredOptions[currentSelected()]?.effort\n ) {\n setOnEffort(true);\n return;\n }\n if (key.meta && input === 's' && currentSelected() !== addIndex) {\n const option = filteredOptions[currentSelected()];\n if (option) handlePick(option.id, false);\n return;\n }\n if (allowProviderManagement && key.meta && input === 'r' && currentSelected() !== addIndex) {\n const providerId = filteredOptions[currentSelected()]?.providerId;\n if (!providerId || refreshing) return;\n if (!ownsProvider(providerId)) return;\n reanchorRef.current = filteredOptions[currentSelected()]?.id;\n void refreshProvider(providerId);\n return;\n }\n if (allowProviderManagement && key.meta && input === 'm' && currentSelected() !== addIndex) {\n const providerId = filteredOptions[currentSelected()]?.providerId;\n if (!providerId) {\n setError('Only custom providers can take extra models.');\n return;\n }\n if (refreshing || !ownsProvider(providerId)) return;\n // The form swallows every key, so this row stays selected until it closes.\n reanchorRef.current = filteredOptions[currentSelected()]?.id;\n setManualEntry({ providerId, value: '' });\n setError(undefined);\n setNotice(undefined);\n return;\n }\n if (allowProviderManagement && key.meta && input === 'd' && currentSelected() !== addIndex) {\n const option = filteredOptions[currentSelected()];\n const providerId = option?.providerId;\n if (!providerId) return;\n if (!removableProviderIds.has(providerId)) {\n setError('Only BYOK providers you added can be removed.');\n return;\n }\n const provider = providers[providerId];\n setRemoval({\n providerId,\n modelCount:\n removableProviderModelCounts?.get(providerId) ??\n (provider ? Object.keys(provider.models).length : 0),\n active: currentModel.startsWith(`${providerId}/`),\n });\n setError(undefined);\n return;\n }\n const typed = stripSgrMouseSequences(input);\n if (typed && !key.ctrl && !key.meta) {\n setFilter((value) => value + typed);\n setSelected(0);\n }\n },\n { isActive: true },\n );\n\n if (showWizard) {\n return (\n <ByokWizard\n retry={retry}\n compact={compact}\n terminalWidth={terminalWidth}\n maxVisibleModels={maxVisibleModels}\n discover={discover}\n onCancel={() => setShowWizard(false)}\n onSave={(request) => {\n const result = onSaveProvider(request);\n if (result.ok) onProviderSaved?.(request);\n return result;\n }}\n />\n );\n }\n\n if (manualEntry) {\n return (\n <SoftPanel title={`Add models to ${manualEntry.providerId}`} width={sheetWidth}>\n <Text bold color={theme.text}>\n Model IDs\n </Text>\n <Box>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <TextInput\n value={manualEntry.value}\n onChange={(value) => setManualEntry({ providerId: manualEntry.providerId, value })}\n onSubmit={(value) => addManualModels(manualEntry.providerId, value)}\n />\n </Box>\n <Text color={theme.subtle} dimColor>\n Comma-separate to add several. Kept when the list is refreshed.\n </Text>\n <Text color={theme.inactive}>Enter add · Esc cancel</Text>\n {error && <Text color={theme.error}>✕ {error}</Text>}\n </SoftPanel>\n );\n }\n\n if (removal) {\n return (\n <SoftPanel tone=\"error\" title=\"Remove BYOK provider?\" width={sheetWidth}>\n <Text>\n Provider: <Text bold>{removal.providerId}</Text>\n </Text>\n <Text>Models: {removal.modelCount}</Text>\n <Text>Settings: .book/settings.local.json</Text>\n <Text color={theme.warning ?? theme.subtle}>Removes credentials and all saved models.</Text>\n <Text color={theme.subtle}>\n {removal.active\n ? 'Active provider: switches to next configured default.'\n : 'Active model: remains unchanged.'}\n </Text>\n <Text color={theme.inactive}>Enter or Y remove · N or Esc cancel</Text>\n {error && <Text color={theme.error}>✕ {error}</Text>}\n </SoftPanel>\n );\n }\n\n const effortIndex = currentEffort ? effortLevels.indexOf(currentEffort) : -1;\n const displayedEffort = effortIndex >= 0 ? effortLevels[effortIndex] : effortLevels[0];\n const windowStart = Math.max(\n 0,\n Math.min(selected - Math.floor(maxVisibleModels / 2), itemCount - maxVisibleModels),\n );\n const rows = [\n ...filteredOptions.map((option) => ({ type: 'model' as const, option })),\n ...(allowProviderManagement ? [{ type: 'add' as const }] : []),\n ].slice(windowStart, windowStart + maxVisibleModels);\n const hasRemovableProviders = removableProviderIds.size > 0;\n // Catalog actions only mean something on a row that belongs to a provider, so\n // they are announced there instead of crowding the always-on footer.\n const selectedProviderId =\n allowProviderManagement && selected !== addIndex\n ? filteredOptions[selected]?.providerId\n : undefined;\n const editableProviderId =\n selectedProviderId && removableProviderIds.has(selectedProviderId)\n ? selectedProviderId\n : undefined;\n\n return (\n <SoftPanel\n title={title ?? (allowProviderManagement ? 'Models' : 'Choose subagent model')}\n meta={`${filteredOptions.length} ${filteredOptions.length === 1 ? 'model' : 'models'}`}\n width={sheetWidth}\n >\n {/* Typing filters, the way the composer takes a prompt: after a pilcrow. */}\n <Text>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <Text color={filter ? theme.text : theme.inactive}>{filter || 'type to filter'}</Text>\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n {rows.map((row, visibleIndex) => {\n const index = windowStart + visibleIndex;\n const isSelected = index === selected && !onEffort;\n if (row.type === 'add') {\n return (\n <Text key=\"add-byok\">\n <Text color={theme.brand}>{isSelected ? '› ' : ' '}</Text>\n <Text color={isSelected ? theme.selectionText : theme.subtle} bold={isSelected}>\n + Add BYOK provider…\n </Text>\n </Text>\n );\n }\n const option = row.option;\n const isCurrent = option.id === currentModel;\n return (\n <Text key={option.id}>\n <Text color={theme.brand}>{isSelected ? '› ' : ' '}</Text>\n <Text color={isSelected ? theme.selectionText : theme.text} bold={isSelected}>\n {option.label}\n </Text>\n <Text color={theme.inactive}>\n {option.providerId ? ` ${option.providerId}` : ''}\n {option.providerId && removableProviderIds.has(option.providerId) ? ' BYOK' : ''}\n </Text>\n {isCurrent ? <Text color={theme.brand}>{' ✓ current'}</Text> : null}\n </Text>\n );\n })}\n </Box>\n <Box flexDirection=\"column\">\n {modelPickerHints({\n allowProviderManagement,\n hasRemovableProviders,\n canSetEffort:\n effortLevels.length > 0 &&\n selected !== addIndex &&\n Boolean(filteredOptions[selected]?.effort),\n // Refresh and add-model are announced only on a row they would act\n // on, which is also the only state in which they fire.\n editableProviderId: refreshing ? undefined : editableProviderId,\n compact: compact || !density.showOptionalHelp,\n filterable: true,\n width: sheetContentWidth(sheetWidth),\n }).map((line) => (\n <Text key={line} color={theme.inactive}>\n {line}\n </Text>\n ))}\n {refreshing && <Text color={theme.subtle}>Refreshing {refreshing} models…</Text>}\n {notice && !refreshing && <Text color={theme.success}>✓ {notice}</Text>}\n {onEffort && (\n <Text color={theme.text} bold>\n Effort [{displayedEffort}] <Text color={theme.inactive}>← → adjust</Text>\n </Text>\n )}\n {error && <Text color={theme.error}>✕ {error}</Text>}\n {hasPriorOutput && (\n <Text color={theme.warning ?? theme.subtle} dimColor>\n ⚠ Switching now re-reads full history on the next turn (uncached).\n </Text>\n )}\n {warnings.map((warning, index) => (\n <Text key={index} color={theme.warning ?? theme.subtle} dimColor>\n ⚠ {warning}\n </Text>\n ))}\n </Box>\n </SoftPanel>\n );\n}\n","import { Text, useInput } from 'ink';\nimport { useCallback, useReducer, useRef } from 'react';\nimport {\n applyReadlineChord,\n deleteNextGrapheme,\n deletePreviousGrapheme,\n type EditState,\n} from '../line-edit.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\n\nexport interface TextInputFieldProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n placeholder?: string;\n /** Replaces every character, for a secret: one mask character per value character. */\n mask?: string;\n focus?: boolean;\n showCursor?: boolean;\n}\n\nconst REVERSE_ON = '\\u001b[7m';\nconst REVERSE_OFF = '\\u001b[27m';\n\n/** The field's own cursor: a highlighted cell, not the terminal's cursor. */\nfunction highlight(text: string): string {\n return `${REVERSE_ON}${text}${REVERSE_OFF}`;\n}\n\n/**\n * The single-line editor every Book text field uses.\n *\n * This was a wrapper around `ink-text-input`, which has no readline keys at\n * all: it dispatched on `key.backspace`, `key.leftArrow` and `key.return` and\n * spliced everything else into the value as literal text, so every chord\n * arrived as its own letter — Ctrl+U in a wizard's prefilled base URL produced\n * `u`. Filtering in front of it could not fix that either: Ink delivers one\n * stdin chunk to every handler in turn, so after a Left the inner component\n * re-subscribed and inserted its `u` *after* the wrapper had cleared the\n * field, leaving `https://abc.example/vu1`.\n *\n * Owning the cursor is the fix. The chords a single-line field honours are\n * {@link applyReadlineChord} — Ctrl+A/E, Ctrl+U, Ctrl+K, Ctrl+W, Ctrl+D — and\n * every other Ctrl chord is dropped rather than typed, because a chord reaches\n * this handler as the bare letter it stands for.\n *\n * A mouse report used by the transcript reaches every field too, so raw input\n * is stripped before it is spliced in. That is now sufficient on its own: the\n * cursor is this component's state and moves by what was inserted rather than\n * by the length of the report, so the re-seat `ink-text-input` needed cannot\n * come back.\n */\nexport function TextInputField({\n value,\n onChange,\n onSubmit,\n placeholder = '',\n mask,\n focus = true,\n showCursor = true,\n}: TextInputFieldProps) {\n // Refs rather than state, like `InputBox`: Ink runs the handler once per\n // stdin chunk, so a key that arrives in the same React batch as the value it\n // edits must see the value as it was when the key arrived.\n const valueRef = useRef(value);\n const cursorRef = useRef(value.length);\n const onChangeRef = useRef(onChange);\n const onSubmitRef = useRef(onSubmit);\n onChangeRef.current = onChange;\n onSubmitRef.current = onSubmit;\n const [, rerender] = useReducer((version: number) => version + 1, 0);\n\n // A value the parent changed — a different step's field, a reset, a\n // suggestion — puts the cursor at its end, the way a fresh field reads.\n if (value !== valueRef.current) {\n valueRef.current = value;\n cursorRef.current = value.length;\n }\n\n const commit = useCallback((edit: EditState) => {\n const changed = edit.value !== valueRef.current;\n valueRef.current = edit.value;\n cursorRef.current = Math.max(0, Math.min(edit.cursorOffset, edit.value.length));\n rerender();\n if (changed) onChangeRef.current(edit.value);\n }, []);\n\n useInput(\n (rawInput, key) => {\n if (\n key.upArrow ||\n key.downArrow ||\n (key.ctrl && rawInput === 'c') ||\n key.tab ||\n (key.shift && key.tab)\n ) {\n return;\n }\n if (key.return) {\n onSubmitRef.current?.(valueRef.current);\n return;\n }\n\n const current: EditState = { value: valueRef.current, cursorOffset: cursorRef.current };\n\n // A chord arrives as the bare letter it stands for, so one this editor\n // does not know must end the key here: falling through would type it.\n if (key.ctrl) {\n const edit = applyReadlineChord(current, rawInput.toLowerCase());\n if (edit) commit(edit);\n return;\n }\n if (key.meta) return;\n if (key.leftArrow) {\n commit({ value: current.value, cursorOffset: current.cursorOffset - 1 });\n return;\n }\n if (key.rightArrow) {\n commit({ value: current.value, cursorOffset: current.cursorOffset + 1 });\n return;\n }\n if (key.home) {\n commit({ value: current.value, cursorOffset: 0 });\n return;\n }\n if (key.end) {\n commit({ value: current.value, cursorOffset: current.value.length });\n return;\n }\n if (key.backspace) {\n commit(deletePreviousGrapheme(current.value, current.cursorOffset));\n return;\n }\n if (key.delete) {\n commit(deleteNextGrapheme(current.value, current.cursorOffset));\n return;\n }\n // A key release is its own event; the press above already acted.\n if (key.eventType === 'release') return;\n\n const input = stripSgrMouseSequences(rawInput);\n if (!input) return;\n commit({\n value:\n current.value.slice(0, current.cursorOffset) +\n input +\n current.value.slice(current.cursorOffset),\n cursorOffset: current.cursorOffset + input.length,\n });\n },\n { isActive: focus },\n );\n\n const shown = mask ? mask.repeat(value.length) : value;\n const cursorAt = cursorRef.current;\n // An empty field shows the placeholder with the cursor over its first\n // character, which is how the field reads as focused when there is nothing to\n // edit yet. Grey is the placeholder's own colour; the theme tints the rest.\n if (shown.length === 0) {\n return (\n <Text>\n {placeholder\n ? showCursor && focus\n ? `${REVERSE_ON}${placeholder[0]}${REVERSE_OFF}${placeholder.slice(1)}`\n : placeholder\n : showCursor && focus\n ? highlight(' ')\n : ''}\n </Text>\n );\n }\n\n let body: string;\n if (showCursor && focus) {\n body = '';\n let index = 0;\n for (const character of shown) {\n body += index === cursorAt ? highlight(character) : character;\n index += character.length;\n }\n if (cursorAt >= shown.length) body += highlight(' ');\n } else {\n body = shown;\n }\n\n return <Text>{body}</Text>;\n}\n\nexport default TextInputField;\n","import { useCallback, useRef, useState } from 'react';\n\n/**\n * State a key handler can read back inside the same keypress batch.\n *\n * Ink hands a whole chunk of stdin to its handlers in one go, and React batches\n * every `setState` made while that runs. So two keys delivered together — a\n * paste, a held arrow that repeats faster than a frame, buffered input over a\n * slow link — reach the handler with state still showing what it was before the\n * first key touched it. Anything the handler *reads back* is therefore stale:\n *\n * - a cursor, so Enter opens the row the user was on two keys ago\n * - a mode flag, so the key meant for a confirmation prompt is dispatched by\n * the branch that was live before the prompt opened, and does nothing\n *\n * Both were live defects. They were also why the picker suites had to sleep\n * between keypresses to let React flush, which is what made them flake on a\n * loaded CI runner (#148): the sleep was buying correctness, not just settling\n * the frame.\n *\n * `read()` returns the value as of the last `set()`, whether or not React has\n * re-rendered. `set` is the only writer, so the two cannot drift — which a\n * hand-rolled `useState` + `useRef` pair does the moment one update forgets the\n * ref.\n *\n * The hook only makes the value it holds batch-safe. Anything derived from\n * that value during render — the item a cursor points at, the question an\n * index selects, a list a filter narrows — is still one batch behind when the\n * handler runs. So a helper invoked from a key handler must resolve indices\n * against props or `read()`, never against a value computed during render,\n * and take what it acts on as an argument. Passing the index alone is not\n * enough if the helper then looks it up in a render-derived value.\n *\n * A batch-safe mode flag has one more consequence: a keypress a child text\n * input consumes through `onSubmit` is also seen by the parent handler, which\n * by then reads the flag already flipped and dispatches the same key again.\n * Give Enter a single owner — either the text input's `onSubmit` with the flag\n * left as plain state, or the parent handler with no `onSubmit` at all.\n *\n * Use it for state a `useInput` handler reads. Plain `useState` is right for\n * everything a handler only writes (an error string, a filter echoed back into\n * the render).\n */\nexport function useKeyState<T>(initial: T | (() => T)): [T, (next: T) => void, () => T] {\n const [value, setValue] = useState(initial);\n const ref = useRef(value);\n const set = useCallback((next: T) => {\n ref.current = next;\n setValue(next);\n }, []);\n const read = useCallback(() => ref.current, []);\n return [value, set, read];\n}\n","import type { RetryConfig } from '../types/runtime.js';\n\nexport type ProviderProtocol = 'openai' | 'anthropic';\n\nexport interface DiscoveredModel {\n id: string;\n label?: string;\n}\n\nimport { systemClock, type Clock } from '../clock.js';\n\nexport interface ModelDiscoveryOptions {\n type: ProviderProtocol;\n baseUrl: string;\n apiKey: string;\n retry: RetryConfig;\n signal?: AbortSignal;\n fetchImpl?: typeof fetch;\n onRetry?: (attempt: number, max: number, delayMs: number) => void;\n /** Injected by tests; the retry budget below is a duration, not a stamp. */\n clock?: Clock;\n}\n\nexport const DEFAULT_PROVIDER_BASE_URLS: Record<ProviderProtocol, string> = {\n openai: 'https://api.openai.com/v1',\n anthropic: 'https://api.anthropic.com',\n};\n\nconst RETRYABLE_STATUSES = new Set([408, 429, 529]);\nconst MAX_ANTHROPIC_PAGES = 100;\n\nexport class ModelDiscoveryError extends Error {\n constructor(\n message: string,\n readonly code: 'aborted' | 'auth' | 'unsupported' | 'invalid_response' | 'network' | 'request',\n ) {\n super(message);\n this.name = 'ModelDiscoveryError';\n }\n}\n\nexport function normalizeProviderBaseUrl(_type: ProviderProtocol, raw: string): string {\n const trimmed = raw.trim();\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n throw new ModelDiscoveryError('Enter a valid HTTP(S) base URL.', 'request');\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new ModelDiscoveryError('Base URL must use HTTP or HTTPS.', 'request');\n }\n if (url.username || url.password) {\n throw new ModelDiscoveryError('Base URL cannot contain embedded credentials.', 'request');\n }\n url.search = '';\n url.hash = '';\n url.pathname = url.pathname.replace(/\\/+$/, '') || '/';\n return url.toString().replace(/\\/$/, '');\n}\n\nfunction discoveryUrl(type: ProviderProtocol, baseUrl: string, afterId?: string): string {\n const base = normalizeProviderBaseUrl(type, baseUrl);\n if (type === 'openai') return `${base}/models`;\n const url = new URL(`${base}${/\\/v1$/i.test(new URL(base).pathname) ? '' : '/v1'}/models`);\n url.searchParams.set('limit', '100');\n if (afterId) url.searchParams.set('after_id', afterId);\n return url.toString();\n}\n\nfunction safeStatusError(status: number): ModelDiscoveryError {\n if (status === 401 || status === 403) {\n return new ModelDiscoveryError(\n 'Model discovery was not authorized. Check the API key and endpoint permissions.',\n 'auth',\n );\n }\n if (status === 404 || status === 405 || status === 501) {\n return new ModelDiscoveryError(\n 'This endpoint does not expose a supported model-list API.',\n 'unsupported',\n );\n }\n return new ModelDiscoveryError(`Model discovery request failed with HTTP ${status}.`, 'request');\n}\n\nfunction retryDelay(attempt: number, retry: RetryConfig, retryAfter: string | null): number {\n const retryAfterSeconds = retryAfter === null ? NaN : Number(retryAfter);\n if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0) {\n return Math.min(retryAfterSeconds * 1000, retry.maxDelayMs);\n }\n return Math.min(retry.baseDelayMs * 2 ** attempt, retry.maxDelayMs);\n}\n\nfunction wait(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n return Promise.reject(new ModelDiscoveryError('Model discovery was cancelled.', 'aborted'));\n }\n return new Promise((resolve, reject) => {\n const abort = () => {\n clearTimeout(timer);\n reject(new ModelDiscoveryError('Model discovery was cancelled.', 'aborted'));\n };\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', abort);\n resolve();\n }, ms);\n signal?.addEventListener('abort', abort, { once: true });\n });\n}\n\nasync function fetchWithRetry(\n url: string,\n init: RequestInit,\n options: ModelDiscoveryOptions,\n): Promise<Response> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const clock = options.clock ?? systemClock;\n const startedAt = clock.monotonicNowMs();\n let lastNetworkError: unknown;\n\n for (let attempt = 0; attempt <= options.retry.maxAttempts; attempt++) {\n if (options.signal?.aborted) {\n throw new ModelDiscoveryError('Model discovery was cancelled.', 'aborted');\n }\n\n const controller = new AbortController();\n const abortFromCaller = () => controller.abort(options.signal?.reason);\n options.signal?.addEventListener('abort', abortFromCaller, { once: true });\n const timeout = setTimeout(\n () => controller.abort(new Error('request timeout')),\n options.retry.requestTimeoutMs,\n );\n\n let response: Response | undefined;\n try {\n response = await fetchImpl(url, { ...init, signal: controller.signal });\n } catch (error) {\n if (options.signal?.aborted) {\n throw new ModelDiscoveryError('Model discovery was cancelled.', 'aborted');\n }\n lastNetworkError = error;\n } finally {\n clearTimeout(timeout);\n options.signal?.removeEventListener('abort', abortFromCaller);\n }\n\n if (response && !(RETRYABLE_STATUSES.has(response.status) || response.status >= 500)) {\n return response;\n }\n\n if (attempt >= options.retry.maxAttempts) {\n if (response) return response;\n throw new ModelDiscoveryError('Could not reach the model-list endpoint.', 'network');\n }\n if (\n options.retry.totalBudgetMs > 0 &&\n clock.monotonicNowMs() - startedAt >= options.retry.totalBudgetMs\n ) {\n if (response) return response;\n throw new ModelDiscoveryError('Could not reach the model-list endpoint.', 'network');\n }\n\n const delay = retryDelay(attempt, options.retry, response?.headers.get('retry-after') ?? null);\n options.onRetry?.(attempt + 1, options.retry.maxAttempts, delay);\n await wait(delay, options.signal);\n }\n\n throw new ModelDiscoveryError(\n lastNetworkError ? 'Could not reach the model-list endpoint.' : 'Model discovery failed.',\n 'network',\n );\n}\n\nfunction parseModels(payload: unknown, type: ProviderProtocol): DiscoveredModel[] {\n if (!payload || typeof payload !== 'object') {\n throw new ModelDiscoveryError(\n 'The model-list endpoint returned invalid JSON.',\n 'invalid_response',\n );\n }\n const data = (payload as { data?: unknown }).data;\n if (!Array.isArray(data)) {\n throw new ModelDiscoveryError(\n 'The model-list endpoint returned an unsupported response shape.',\n 'invalid_response',\n );\n }\n\n const models: DiscoveredModel[] = [];\n for (const item of data) {\n if (!item || typeof item !== 'object') continue;\n const record = item as Record<string, unknown>;\n const id = typeof record.id === 'string' ? record.id.trim() : '';\n if (!id || /[\\x00-\\x1f\\x7f]/.test(id)) continue;\n const rawLabel =\n type === 'anthropic'\n ? record.display_name\n : (record.name ?? record.display_name ?? record.label);\n const label = typeof rawLabel === 'string' && rawLabel.trim() ? rawLabel.trim() : undefined;\n models.push({ id, label });\n }\n return models;\n}\n\nexport async function discoverModels(options: ModelDiscoveryOptions): Promise<DiscoveredModel[]> {\n const headers: Record<string, string> =\n options.type === 'anthropic'\n ? {\n 'x-api-key': options.apiKey,\n 'anthropic-version': '2023-06-01',\n }\n : { Authorization: `Bearer ${options.apiKey}` };\n\n const discovered: DiscoveredModel[] = [];\n let afterId: string | undefined;\n let finished = false;\n\n for (let page = 0; page < MAX_ANTHROPIC_PAGES; page++) {\n const response = await fetchWithRetry(\n discoveryUrl(options.type, options.baseUrl, afterId),\n { method: 'GET', headers },\n options,\n );\n if (!response.ok) throw safeStatusError(response.status);\n\n let payload: unknown;\n try {\n payload = await response.json();\n } catch {\n throw new ModelDiscoveryError(\n 'The model-list endpoint returned invalid JSON.',\n 'invalid_response',\n );\n }\n discovered.push(...parseModels(payload, options.type));\n\n if (options.type !== 'anthropic') {\n finished = true;\n break;\n }\n const pageInfo = payload as { has_more?: unknown; last_id?: unknown };\n if (pageInfo.has_more !== true) {\n finished = true;\n break;\n }\n const nextId = typeof pageInfo.last_id === 'string' ? pageInfo.last_id : undefined;\n if (!nextId || nextId === afterId) {\n throw new ModelDiscoveryError(\n 'The model-list endpoint returned invalid pagination metadata.',\n 'invalid_response',\n );\n }\n afterId = nextId;\n }\n\n if (options.type === 'anthropic' && !finished) {\n throw new ModelDiscoveryError(\n 'The model-list endpoint exceeded the pagination limit.',\n 'invalid_response',\n );\n }\n\n const deduped = new Map<string, DiscoveredModel>();\n for (const model of discovered) {\n const existing = deduped.get(model.id);\n deduped.set(model.id, existing?.label ? existing : model);\n }\n const models = [...deduped.values()].sort((a, b) => a.id.localeCompare(b.id));\n if (models.length === 0) {\n throw new ModelDiscoveryError(\n 'The endpoint did not return any usable models.',\n 'invalid_response',\n );\n }\n return models;\n}\n","import { AVAILABLE_MODELS, modelSupportsEffort } from '../models.js';\nimport type { ProviderConfig, ResolvedSettings } from '../settings.js';\nimport {\n normalizeProviderBaseUrl,\n type DiscoveredModel,\n type ProviderProtocol,\n} from '../provider/model-discovery.js';\n\nexport interface ModelPickerOption {\n id: string;\n label: string;\n effort: boolean;\n custom: boolean;\n providerId?: string;\n}\n\nexport interface ByokProviderDraft {\n providerId: string;\n type: ProviderProtocol;\n baseURL: string;\n apiKey: string;\n models: DiscoveredModel[];\n activeModelId: string;\n activeLabel?: string;\n}\n\nexport interface ProviderSaveRequest extends ByokProviderDraft {\n replaceModels?: boolean;\n /** False when refreshing a catalog without changing the active model. */\n activate?: boolean;\n /** True when `models` were typed by hand instead of discovered. */\n manual?: boolean;\n}\n\nexport function buildModelOptions(settings: ResolvedSettings): ModelPickerOption[] {\n const options = new Map<string, ModelPickerOption>();\n for (const model of AVAILABLE_MODELS) {\n options.set(model.id, {\n id: model.id,\n label: model.label,\n effort: Boolean(model.effort),\n custom: false,\n });\n }\n\n for (const providerId of Object.keys(settings.provider).sort()) {\n const provider = settings.provider[providerId];\n for (const modelId of Object.keys(provider.models).sort()) {\n const id = `${providerId}/${modelId}`;\n const metadata = provider.models[modelId];\n const existing = options.get(id);\n options.set(id, {\n id,\n label: metadata.label ?? existing?.label ?? modelId,\n effort:\n metadata.effort === false\n ? false\n : typeof metadata.effort === 'object'\n ? true\n : (existing?.effort ?? modelSupportsEffort(modelId)),\n custom: true,\n providerId,\n });\n }\n }\n return [...options.values()];\n}\n\nexport function validateProviderId(raw: string): string {\n const value = raw.trim().toLowerCase();\n if (!/^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$/.test(value)) {\n throw new Error('Use 1–64 lowercase letters, numbers, hyphens, or underscores.');\n }\n return value;\n}\n\nexport function validateModelId(raw: string): string {\n const value = raw.trim();\n if (!value || value.length > 256 || /[\\x00-\\x1f\\x7f]/.test(value)) {\n throw new Error('Enter a model ID of 1–256 characters without control characters.');\n }\n return value;\n}\n\n/**\n * Split a hand-typed model list on commas or newlines so one prompt can add\n * several models at once. Order is preserved and duplicates collapse.\n */\nexport function parseModelIds(raw: string): string[] {\n const ids: string[] = [];\n for (const part of raw.split(/[,\\n]/)) {\n if (!part.trim()) continue;\n const id = validateModelId(part);\n if (!ids.includes(id)) ids.push(id);\n }\n if (ids.length === 0) throw new Error('Enter at least one model ID.');\n return ids;\n}\n\nexport function validateDisplayLabel(raw: string): string | undefined {\n const value = raw.trim();\n if (!value) return undefined;\n if (value.length > 100 || /[\\x00-\\x1f\\x7f]/.test(value)) {\n throw new Error('Use at most 100 characters without control characters.');\n }\n return value;\n}\n\nexport function validateApiKey(raw: string): string {\n if (!raw.trim()) throw new Error('API key is required.');\n if (/[\\r\\n\\x00]/.test(raw)) throw new Error('API key cannot contain line breaks.');\n return raw;\n}\n\nexport function validateBaseUrl(type: ProviderProtocol, raw: string): string {\n return normalizeProviderBaseUrl(type, raw);\n}\n\nexport function providerConfigFromDraft(\n draft: ProviderSaveRequest,\n existing?: ProviderConfig,\n replaceModels = false,\n): ProviderConfig {\n // A refresh replaces the discovered catalog with whatever the endpoint now\n // reports, but hand-entered models survive it: they were typed in because\n // the model-list API does not return them, so dropping them here would undo\n // the user's work on every refresh.\n const models: ProviderConfig['models'] = replaceModels\n ? Object.fromEntries(\n Object.entries(existing?.models ?? {}).filter(([, metadata]) => metadata.manual),\n )\n : { ...(existing?.models ?? {}) };\n for (const model of draft.models) {\n const previous = existing?.models[model.id];\n models[model.id] = {\n ...previous,\n label:\n model.id === draft.activeModelId\n ? (draft.activeLabel ?? model.label ?? previous?.label)\n : (model.label ?? previous?.label),\n manual: draft.manual ? true : undefined,\n };\n if (!models[model.id].label) delete models[model.id].label;\n // Discovery now vouches for this id, so it no longer needs the manual\n // marker to survive the next refresh.\n if (!models[model.id].manual) delete models[model.id].manual;\n }\n // Only overwrite credentials the draft actually carries; adding a model to an\n // existing provider leaves its base URL and key exactly as configured.\n const config: ProviderConfig = { ...existing, type: draft.type, models };\n if (draft.baseURL) {\n config.baseURL = draft.baseURL;\n // Readers prefer `baseURL`, so a surviving legacy `baseUrl` would sit in\n // settings.json as a stale value that looks live.\n delete config.baseUrl;\n }\n if (draft.apiKey) config.apiKey = draft.apiKey;\n return config;\n}\n","import { Box, Text, useInput } from 'ink';\nimport TextInput from './TextInputField.js';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport type { RetryConfig } from '../../types/runtime.js';\nimport {\n DEFAULT_PROVIDER_BASE_URLS,\n discoverModels,\n type DiscoveredModel,\n type ModelDiscoveryOptions,\n type ProviderProtocol,\n} from '../../provider/model-discovery.js';\nimport {\n parseModelIds,\n validateApiKey,\n validateBaseUrl,\n validateDisplayLabel,\n validateProviderId,\n type ProviderSaveRequest,\n} from '../model-options.js';\nimport { useDensityMetrics } from '../density.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\nimport { useTheme } from '../theme.js';\nimport { DecisionSheet } from './chrome.js';\nimport { truncateDisplay } from './word-wrap.js';\nimport { LABEL_COLUMN_WIDTH, panelGrid, sheetContentWidth } from '../layout.js';\n\nexport interface ByokWizardProps {\n retry: RetryConfig;\n compact?: boolean;\n terminalWidth?: number;\n maxVisibleModels?: number;\n discover?: (options: ModelDiscoveryOptions) => Promise<DiscoveredModel[]>;\n onSave: (\n request: ProviderSaveRequest,\n ) => { ok: boolean; error?: string } | Promise<{ ok: boolean; error?: string }>;\n onCancel: () => void;\n}\n\ntype Step =\n | 'provider'\n | 'protocol'\n | 'base-url'\n | 'api-key'\n | 'model-source'\n | 'discovering'\n | 'discovery-error'\n | 'choose-models'\n | 'manual-model'\n | 'label'\n | 'review';\n\n/** Where this provider's model list comes from. */\ntype ModelSource = 'discover' | 'manual';\n\nconst TOTAL_STEPS = 9;\n\nconst STEP_NUMBER: Partial<Record<Step, number>> = {\n provider: 1,\n protocol: 2,\n 'base-url': 3,\n 'api-key': 4,\n 'model-source': 5,\n discovering: 6,\n 'discovery-error': 6,\n 'choose-models': 7,\n 'manual-model': 7,\n label: 8,\n review: 9,\n};\n\nconst MODEL_SOURCES: readonly { value: ModelSource; title: string; hint: string }[] = [\n {\n value: 'discover',\n title: 'Discover models automatically',\n hint: 'Asks the endpoint for its model list.',\n },\n {\n value: 'manual',\n title: 'Enter model IDs manually',\n hint: 'Use this when the endpoint has no model-list API.',\n },\n];\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : 'Model discovery failed.';\n}\n\nfunction filterModels(models: DiscoveredModel[], filter: string): DiscoveredModel[] {\n const query = filter.trim().toLowerCase();\n return query\n ? models.filter(\n (model) =>\n model.id.toLowerCase().includes(query) || model.label?.toLowerCase().includes(query),\n )\n : models;\n}\n\nexport function ByokWizard({\n retry,\n compact = false,\n terminalWidth = 80,\n maxVisibleModels = 8,\n discover = discoverModels,\n onSave,\n onCancel,\n}: ByokWizardProps) {\n const theme = useTheme();\n const density = useDensityMetrics();\n // `step` deliberately stays plain render state. On the text-field steps Enter\n // belongs to the field's `onSubmit`, and the handler below relies on still\n // reading the old step when Ink hands it the same keypress; a batch-safe step\n // would let a double Enter submit the field and then advance a second time.\n const [step, setStep] = useState<Step>('provider');\n const [providerId, setProviderId] = useState('');\n // Everything else the key handler reads back is batch-safe. Ink runs the\n // handler once per stdin chunk, so with plain state a batched arrow+Space\n // toggled the model above the highlighted one, arrow+Enter on the source step\n // discovered models the user had just declined, Space+Enter saved a provider\n // with no models, and two arrows on the protocol step toggled it once.\n const [type, setType, currentType] = useKeyState<ProviderProtocol>('openai');\n const [baseURL, setBaseURL] = useState('');\n const [apiKey, setApiKey] = useState('');\n const [modelSource, setModelSource, currentSource] = useKeyState<ModelSource>('discover');\n const [models, setModels] = useState<DiscoveredModel[]>([]);\n const [selectedIds, setSelectedIds, currentSelected] = useKeyState<string[]>([]);\n const [modelCursor, setModelCursor, currentModel] = useKeyState(0);\n const [modelFilter, setModelFilter, currentFilter] = useKeyState('');\n const [manualModel, setManualModel] = useState('');\n const [label, setLabel] = useState('');\n const [error, setError] = useState<string>();\n const [saving, setSaving] = useState(false);\n const discoveryAbortRef = useRef<AbortController | null>(null);\n const saveRef = useRef(false);\n\n const filteredModels = useMemo(() => filterModels(models, modelFilter), [modelFilter, models]);\n\n const activeModelId = selectedIds[0] ?? '';\n\n const startDiscovery = useCallback(async () => {\n setError(undefined);\n setStep('discovering');\n const controller = new AbortController();\n discoveryAbortRef.current = controller;\n try {\n const discovered = await discover({\n type,\n baseUrl: validateBaseUrl(type, baseURL),\n apiKey: validateApiKey(apiKey),\n retry,\n signal: controller.signal,\n });\n if (controller.signal.aborted) return;\n if (discovered.length === 0) {\n // The error screen's own fallback is the way forward, so route there\n // rather than into an empty picker that refuses to continue.\n setError('The endpoint did not return any models.');\n setStep('discovery-error');\n return;\n }\n setModelSource('discover');\n setModels(discovered);\n setSelectedIds(discovered.map((model) => model.id));\n setModelCursor(0);\n setModelFilter('');\n setStep('choose-models');\n } catch (caught) {\n if (controller.signal.aborted) {\n setStep('model-source');\n return;\n }\n setError(errorMessage(caught));\n setStep('discovery-error');\n } finally {\n if (discoveryAbortRef.current === controller) discoveryAbortRef.current = null;\n }\n }, [apiKey, baseURL, discover, retry, type]);\n\n const goBack = useCallback(() => {\n setError(undefined);\n switch (step) {\n case 'provider':\n onCancel();\n break;\n case 'protocol':\n setStep('provider');\n break;\n case 'base-url':\n setStep('protocol');\n break;\n case 'api-key':\n setStep('base-url');\n break;\n case 'model-source':\n setStep('api-key');\n break;\n case 'discovering':\n discoveryAbortRef.current?.abort();\n break;\n case 'discovery-error':\n case 'choose-models':\n case 'manual-model':\n setStep('model-source');\n break;\n case 'label':\n setStep(modelSource === 'manual' ? 'manual-model' : 'choose-models');\n break;\n case 'review':\n setStep('label');\n break;\n }\n }, [modelSource, onCancel, step]);\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') {\n discoveryAbortRef.current?.abort();\n onCancel();\n return;\n }\n if (key.escape) {\n goBack();\n return;\n }\n if (step === 'protocol') {\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {\n const next: ProviderProtocol = currentType() === 'openai' ? 'anthropic' : 'openai';\n setType(next);\n setBaseURL(DEFAULT_PROVIDER_BASE_URLS[next]);\n return;\n }\n if (key.return) setStep('base-url');\n return;\n }\n if (step === 'model-source') {\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {\n setModelSource(currentSource() === 'discover' ? 'manual' : 'discover');\n return;\n }\n if (key.return) {\n if (currentSource() === 'discover') void startDiscovery();\n else {\n setError(undefined);\n setModels([]);\n setSelectedIds([]);\n setStep('manual-model');\n }\n }\n return;\n }\n if (step === 'discovery-error') {\n if (input === 'r') void startDiscovery();\n if (input === 'm') {\n setError(undefined);\n setModelSource('manual');\n setModels([]);\n setSelectedIds([]);\n setStep('manual-model');\n }\n return;\n }\n if (step === 'choose-models') {\n const typed = stripSgrMouseSequences(input);\n if (key.return) {\n if (currentSelected().length === 0) setError('Select at least one model.');\n else {\n setError(undefined);\n setStep('label');\n }\n return;\n }\n if (key.backspace || key.delete) {\n setModelFilter(currentFilter().slice(0, -1));\n setModelCursor(0);\n return;\n }\n // The list a filter character earlier in this chunk produced, not the\n // one the last render showed — otherwise Down and Space act on a model\n // the new filter hides.\n const visible = filterModels(models, currentFilter());\n if (visible.length === 0) {\n if (typed && typed !== ' ' && !key.ctrl && !key.meta) {\n setModelFilter(currentFilter() + typed);\n }\n return;\n }\n if (key.upArrow) {\n setModelCursor((currentModel() - 1 + visible.length) % visible.length);\n return;\n }\n if (key.downArrow) {\n setModelCursor((currentModel() + 1) % visible.length);\n return;\n }\n if (input === ' ') {\n const id = visible[currentModel()]?.id;\n if (!id) return;\n const current = currentSelected();\n setSelectedIds(\n current.includes(id) ? current.filter((value) => value !== id) : [...current, id],\n );\n return;\n }\n if (typed && !key.ctrl && !key.meta) {\n setModelFilter(currentFilter() + typed);\n setModelCursor(0);\n }\n return;\n }\n if (step === 'review' && key.return && !saving && !saveRef.current) {\n saveRef.current = true;\n setSaving(true);\n setError(undefined);\n const chosen = models.filter((model) => selectedIds.includes(model.id));\n void Promise.resolve(\n onSave({\n providerId,\n type,\n baseURL,\n apiKey,\n models: chosen.length > 0 ? chosen : [{ id: activeModelId }],\n activeModelId,\n activeLabel: label || undefined,\n manual: modelSource === 'manual',\n }),\n ).then((result) => {\n if (!result.ok) {\n saveRef.current = false;\n setSaving(false);\n setError(result.error ?? 'Could not save provider settings.');\n }\n });\n }\n },\n { isActive: true },\n );\n\n const submitProvider = (value: string) => {\n try {\n setProviderId(validateProviderId(value));\n setError(undefined);\n setStep('protocol');\n } catch (caught) {\n setError(errorMessage(caught));\n }\n };\n\n const submitBaseUrl = (value: string) => {\n try {\n setBaseURL(validateBaseUrl(type, value || DEFAULT_PROVIDER_BASE_URLS[type]));\n setError(undefined);\n setStep('api-key');\n } catch (caught) {\n setError(errorMessage(caught));\n }\n };\n\n const submitApiKey = (value: string) => {\n try {\n setApiKey(validateApiKey(value));\n setError(undefined);\n setStep('model-source');\n } catch (caught) {\n setError(errorMessage(caught));\n }\n };\n\n const submitManualModel = (value: string) => {\n try {\n const ids = parseModelIds(value);\n setManualModel(ids.join(', '));\n setModelSource('manual');\n setModels(ids.map((id) => ({ id })));\n setSelectedIds(ids);\n setError(undefined);\n setStep('label');\n } catch (caught) {\n setError(errorMessage(caught));\n }\n };\n\n const submitLabel = (value: string) => {\n try {\n setLabel(validateDisplayLabel(value) ?? '');\n setError(undefined);\n setStep('review');\n } catch (caught) {\n setError(errorMessage(caught));\n }\n };\n\n const stepNumber = STEP_NUMBER[step];\n const modelWindowStart = Math.max(\n 0,\n Math.min(\n modelCursor - Math.floor(maxVisibleModels / 2),\n filteredModels.length - maxVisibleModels,\n ),\n );\n const visibleModels = filteredModels.slice(modelWindowStart, modelWindowStart + maxVisibleModels);\n const showOptionalHelp = !compact && density.showOptionalHelp;\n // The rule spans the sheet and the body sits two columns in, so the wizard's\n // text lands on the transcript's content column instead of one column left of\n // it inside a box of its own.\n //\n // `panelGrid`, not `frameGrid`: the wizard opens from the model picker and\n // sits beside its other panels, so it is a floating surface and takes the same\n // `MAX_PANEL_MEASURE` cap. `frameGrid` would let it run the width of a\n // 200-column terminal, and the picker it opened from would be 80 columns\n // narrower than the surface that replaced it.\n const sheetWidth = panelGrid(terminalWidth).width;\n const contentWidth = sheetContentWidth(sheetWidth);\n\n // One model row: the cursor column, the tick, the label, then the id in a\n // quieter tone after it. The two text columns split what is left over *after*\n // those four leading columns and the two between the label and the id, so the\n // row is exactly `contentWidth` wide. Budgeting each column a share of the\n // whole width instead let a long label and a long id add up to more than the\n // row, and Ink wrapped them: the highlighted row split in two and the list\n // grew past the `maxVisibleModels` it was supposed to hold.\n const modelRowLead = 4;\n const modelRowGap = 2;\n const modelTextWidth = Math.max(8, contentWidth - modelRowLead - modelRowGap);\n const modelLabelWidth = Math.ceil(modelTextWidth * 0.6);\n const modelIdWidth = modelTextWidth - modelLabelWidth;\n\n return (\n <DecisionSheet\n label=\"Add BYOK provider\"\n tone={theme.brand}\n meta={stepNumber ? `Step ${stepNumber}/${TOTAL_STEPS}` : undefined}\n width={sheetWidth}\n >\n {step === 'provider' && (\n <Field\n label=\"Provider ID\"\n hint={showOptionalHelp ? 'Example: openrouter' : undefined}\n value={providerId}\n onChange={setProviderId}\n onSubmit={submitProvider}\n />\n )}\n {step === 'protocol' && (\n <>\n <Text bold>Protocol</Text>\n {(['openai', 'anthropic'] as const).map((value) => (\n <Text key={value} color={type === value ? theme.brand : theme.subtle}>\n {type === value ? '›' : ' '} {value === 'openai' ? 'OpenAI-compatible' : 'Anthropic'}\n </Text>\n ))}\n </>\n )}\n {step === 'base-url' && (\n <Field\n label=\"Base URL\"\n hint={\n !showOptionalHelp\n ? undefined\n : type === 'openai'\n ? 'Include /v1 when required by the endpoint.'\n : 'Book adds /v1 for Anthropic requests.'\n }\n placeholder={DEFAULT_PROVIDER_BASE_URLS[type]}\n value={baseURL}\n onChange={setBaseURL}\n onSubmit={submitBaseUrl}\n />\n )}\n {step === 'api-key' && (\n <Field\n label=\"API key\"\n hint={\n showOptionalHelp\n ? 'Stored in ~/.book/settings.json (shared across all your projects).'\n : undefined\n }\n value={apiKey}\n onChange={setApiKey}\n onSubmit={submitApiKey}\n mask=\"•\"\n />\n )}\n {step === 'model-source' && (\n <>\n <Text bold>Models</Text>\n {MODEL_SOURCES.map((source) => (\n <Text\n key={source.value}\n color={modelSource === source.value ? theme.brand : theme.subtle}\n >\n {modelSource === source.value ? '›' : ' '} {source.title}\n </Text>\n ))}\n {showOptionalHelp && (\n <Text color={theme.subtle} dimColor>\n {MODEL_SOURCES.find((source) => source.value === modelSource)?.hint}\n </Text>\n )}\n </>\n )}\n {step === 'discovering' && (\n <>\n <Text bold>Discover models</Text>\n <Text color={theme.brand}>Discovering models…</Text>\n </>\n )}\n {step === 'discovery-error' && (\n <>\n <Text bold>Discover models</Text>\n <Text color={theme.error}>✕ {error}</Text>\n <Text color={theme.subtle}>r retry · m enter model manually · Esc back</Text>\n </>\n )}\n {step === 'choose-models' && (\n <>\n <Text bold>Choose models</Text>\n <Text color={theme.subtle}>Filter: {modelFilter || '(type to filter)'}</Text>\n {visibleModels.length === 0 ? (\n <Text color={theme.subtle}>(no matching models)</Text>\n ) : (\n visibleModels.map((model, index) => {\n const absoluteIndex = modelWindowStart + index;\n return (\n <Text\n key={model.id}\n backgroundColor={absoluteIndex === modelCursor ? theme.surfaceActive : undefined}\n color={absoluteIndex === modelCursor ? theme.selectionText : theme.subtle}\n bold={absoluteIndex === modelCursor}\n >\n {absoluteIndex === modelCursor ? '›' : ' '}{' '}\n {selectedIds.includes(model.id) ? '◉' : '○'}{' '}\n {truncateDisplay(model.label ?? model.id, modelLabelWidth)}\n {model.label && model.label !== model.id\n ? `${' '.repeat(modelRowGap)}${truncateDisplay(model.id, modelIdWidth)}`\n : ''}\n </Text>\n );\n })\n )}\n <Text color={theme.subtle} dimColor>\n ↑↓ move · Space toggle · Enter continue ({selectedIds.length} selected)\n </Text>\n </>\n )}\n {step === 'manual-model' && (\n <Field\n label=\"Model IDs\"\n hint={\n showOptionalHelp\n ? 'Example: deepseek-chat, deepseek-reasoner — comma-separate to add several.'\n : undefined\n }\n value={manualModel}\n onChange={setManualModel}\n onSubmit={submitManualModel}\n />\n )}\n {step === 'label' && (\n <Field\n label=\"Display label (optional)\"\n value={label}\n onChange={setLabel}\n onSubmit={submitLabel}\n />\n )}\n {step === 'review' && (\n <>\n <Text bold>Review</Text>\n <Summary label=\"Provider\" value={providerId} />\n <Summary label=\"Protocol\" value={type === 'openai' ? 'OpenAI-compatible' : 'Anthropic'} />\n <Summary label=\"Base URL\" value={baseURL} />\n <Summary label=\"API key\" value=\"•••••••• (stored in ~/.book)\" />\n <Summary\n label=\"Models\"\n value={`${selectedIds.length} selected (${modelSource === 'manual' ? 'entered manually' : 'discovered'})`}\n />\n <Summary label=\"Active\" value={activeModelId} />\n {label && <Summary label=\"Label\" value={label} />}\n </>\n )}\n\n {error && step !== 'discovery-error' && <Text color={theme.error}>✕ {error}</Text>}\n <Text color={theme.subtle} dimColor>\n {saving\n ? 'Saving…'\n : step === 'review'\n ? 'Enter save & use · Esc back · Ctrl+C cancel'\n : step === 'discovering'\n ? 'Esc cancel request'\n : step === 'choose-models' || step === 'discovery-error'\n ? ''\n : step === 'protocol' || step === 'model-source'\n ? '↑↓ choose · Enter continue · Esc back'\n : showOptionalHelp\n ? 'Enter continue · Esc back · Ctrl+C cancel'\n : 'Enter continue · Esc back'}\n </Text>\n </DecisionSheet>\n );\n}\n\nfunction Field({\n label,\n hint,\n placeholder,\n value,\n onChange,\n onSubmit,\n mask,\n}: {\n label: string;\n hint?: string;\n placeholder?: string;\n value: string;\n onChange: (value: string) => void;\n onSubmit: (value: string) => void;\n mask?: string;\n}) {\n const theme = useTheme();\n return (\n <>\n <Text bold>{label}</Text>\n <Box>\n <Text color={theme.brand}>› </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n placeholder={placeholder}\n mask={mask}\n />\n </Box>\n {hint && (\n <Text color={theme.subtle} dimColor>\n {hint}\n </Text>\n )}\n </>\n );\n}\n\nfunction Summary({ label, value }: { label: string; value: string }) {\n const theme = useTheme();\n return (\n <Box>\n <Box width={LABEL_COLUMN_WIDTH + 2}>\n <Text color={theme.subtle}>{label}</Text>\n </Box>\n <Text>{value}</Text>\n </Box>\n );\n}\n","import { displayWidth } from './word-wrap.js';\n\n/**\n * What `/model` tells you it can do.\n *\n * The picker binds six Alt-chords. The footer used to be four hand-written\n * strings chosen by two booleans, and between them they left holes:\n *\n * - **`Alt+E` was advertised nowhere at all.** Setting a model's effort was\n * reachable only by guessing, and the row it opens (`Effort [high] ← →\n * adjust`) is only visible *after* you have already found the key.\n * - **`Alt+S` disappeared whenever a removable BYOK provider existed**, because\n * that branch spent the line on `Alt+A` and `Alt+D` instead — so the chord\n * that always works was hidden by the presence of one that sometimes does.\n *\n * Both came from writing the sentence out per case. This builds it from what is\n * actually available, so a chord cannot be advertised when it will not fire, and\n * cannot be dropped because a different one appeared.\n *\n * Two lines, split by what they act on: choosing a model, and managing the\n * catalog. That split is the reason it fits — six chords and the navigation keys\n * do not fit on one 80-column line, and a wrapped footer is what this replaces.\n */\nexport interface ModelPickerHintState {\n /** BYOK management is offered at all. */\n allowProviderManagement: boolean;\n /** Some provider in the list can be removed. */\n hasRemovableProviders: boolean;\n /** The selected row is a model that carries per-model effort. */\n canSetEffort: boolean;\n /** The selected row belongs to a provider the user owns. */\n editableProviderId?: string;\n /** Drop the descriptions, keep every chord. */\n compact: boolean;\n /** The list can be typed at. */\n filterable: boolean;\n /**\n * Columns a footer line may take. A line longer than this breaks between two\n * chords; left to the terminal it broke inside one (`Alt+M add` / `model`).\n */\n width?: number;\n}\n\n/** The footer, as one or two lines. Never empty; never missing a live chord. */\nexport function modelPickerHints(state: ModelPickerHintState): string[] {\n const { compact } = state;\n\n // Descriptions stay terse in both widths. The line this replaces was 81\n // columns and fit; spelling the chords out (\"use for this session\") pushes\n // past 100 and wraps, which is the defect. Compact drops the filter hint\n // rather than a chord — typing is discoverable by doing it, a chord is not.\n const choosing = [\n '↑↓ select',\n state.filterable && !compact ? 'type filter' : undefined,\n 'Enter save',\n 'Alt+S session',\n state.canSetEffort ? 'Alt+E effort' : undefined,\n 'Esc cancel',\n ].filter(Boolean) as string[];\n\n const managing = state.allowProviderManagement\n ? ([\n compact ? 'Alt+A add' : 'Alt+A add BYOK',\n // \"remove BYOK\" survives compact: `Alt+D` is the one chord here that\n // deletes something, and \"remove\" alone does not say what.\n state.hasRemovableProviders ? 'Alt+D remove BYOK' : undefined,\n state.editableProviderId\n ? compact\n ? 'Alt+R refresh'\n : `Alt+R refresh ${state.editableProviderId}`\n : undefined,\n state.editableProviderId ? 'Alt+M add model' : undefined,\n ].filter(Boolean) as string[])\n : [];\n\n const groups = managing.length > 0 ? [choosing, managing] : [choosing];\n return groups.flatMap((chords) => packChords(chords, state.width));\n}\n\n/** Greedy ` · ` packing into lines of at most `width` columns; a chord is never split. */\nfunction packChords(chords: readonly string[], width?: number): string[] {\n if (width === undefined) return [chords.join(' · ')];\n const lines: string[] = [];\n let line = '';\n for (const chord of chords) {\n const next = line ? `${line} · ${chord}` : chord;\n if (line && displayWidth(next) > width) {\n lines.push(line);\n line = chord;\n } else {\n line = next;\n }\n }\n if (line) lines.push(line);\n return lines;\n}\n","import { useMemo, useState } from 'react';\nimport { ListPicker } from './ListPicker.js';\nimport type { EffortLevel, EffortResult } from '../../commands/effort.js';\n\nconst DESCRIPTIONS: Record<EffortLevel, string> = {\n low: 'Fast responses with lighter reasoning',\n medium: 'Balanced reasoning for everyday tasks',\n high: 'Deeper reasoning for complex work',\n xhigh: 'Extended reasoning for difficult problems',\n max: 'Maximum reasoning depth for the hardest tasks',\n};\n\ninterface EffortPickerProps {\n /** Sheet width, from the panel grid; without it the head falls back to a plain title. */\n width?: number;\n current?: EffortLevel;\n availableLevels: readonly EffortLevel[];\n onSelect: (level: EffortLevel) => EffortResult;\n onCancel: () => void;\n}\n\nexport function EffortPicker({\n current,\n availableLevels,\n onSelect,\n onCancel,\n width,\n}: EffortPickerProps) {\n const [error, setError] = useState<string>();\n\n const items = useMemo(\n () =>\n availableLevels.map((level) => ({\n key: level,\n label: `${level.padEnd(6)} ${DESCRIPTIONS[level]}`,\n note: level === current ? '(current)' : undefined,\n accent: level === current,\n })),\n [availableLevels, current],\n );\n\n return (\n <ListPicker\n title=\"Effort\"\n width={width}\n subtitle=\"Choose how much reasoning Book uses on future requests.\"\n items={items}\n initialIndex={Math.max(0, current ? availableLevels.indexOf(current) : 0)}\n enterHint=\"save\"\n error={error}\n onSelect={(index) => {\n const level = availableLevels[index];\n if (!level) return;\n const result = onSelect(level);\n setError(\n result.ok ? undefined : (result.error ?? 'Could not save the selected effort level.'),\n );\n }}\n onCancel={onCancel}\n />\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport type { Key } from 'ink';\nimport { useEffect, useMemo } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useTheme } from '../theme.js';\nimport { useDensityMetrics } from '../density.js';\nimport { SoftPanel } from './chrome.js';\n\n/**\n * One row. The caller formats `label` — padding, columns, whatever the list\n * needs — and `ListPicker` owns the marker, the colours and the window.\n */\nexport interface ListPickerItem {\n /** React key; also the default filter text. */\n key: string;\n label: string;\n /** Shown indented under the row, only while it is selected. */\n detail?: string;\n /** Appended to the label, e.g. `(current)` or `(unavailable)`. */\n note?: string;\n /** The row that is already in effect: coloured `brand` when not selected. */\n accent?: boolean;\n /** Render unselected rows subtle rather than as body text. */\n muted?: boolean;\n /** Dimmed, and Enter refuses it. */\n disabled?: boolean;\n /** Matched against the typed filter when `filterable`. Defaults to `label`. */\n filterText?: string;\n}\n\ninterface ListPickerProps {\n title: string;\n subtitle?: string;\n items: readonly ListPickerItem[];\n /** Shown in place of the list when `items` is empty. */\n emptyText?: string;\n /** Where the cursor starts, and where it returns when this value changes. */\n initialIndex?: number;\n /** Rows drawn at once. Longer lists window around the cursor and page. */\n maxVisible?: number;\n width?: number;\n marginX?: number;\n /** The verb after Enter — \"save\", \"resume\", \"sign in\". */\n enterHint: string;\n /**\n * The verb after Esc. Dialogs used to pick their own — cancel, back, close,\n * not now — so the same key was described four ways depending on which one\n * you had open. `cancel` is the default because abandoning the choice is what\n * Esc does in a picker; override only where it genuinely returns to a\n * previous step, which is the one case a different word earns.\n */\n escHint?: string;\n /** Extra chords to advertise, already formatted: `R reset to inherit`. */\n extraHints?: string;\n /** Tab as \"next row\". Off by default: Tab means completion in the composer. */\n tabMovesNext?: boolean;\n /** Let printable keys filter the list. */\n filterable?: boolean;\n error?: string;\n /** Rendered above the hint line — \"Restoring...\". */\n status?: string;\n /** Stop taking keys without unmounting — a picker waiting on its own work. */\n isActive?: boolean;\n onSelect: (index: number) => void;\n onCancel: () => void;\n /**\n * Component-specific keys. Return `true` to claim the keypress; `ListPicker`\n * gives it first refusal on everything except Esc, so a picker can bind `R`\n * without reimplementing the cursor. Receives the batch-safe row index.\n */\n onKey?: (input: string, key: Key, index: number) => boolean;\n}\n\n/**\n * The list dialog every picker was rebuilding.\n *\n * Seven components carried their own copy of \"cursor, wrap on the arrows, Enter\n * acts, Esc leaves, and a dim hint line at the bottom\". They drifted, in the\n * ways duplicated code drifts: `SessionPicker` wrapped its cursor over every\n * session while drawing only the first twelve, so past the twelfth nothing was\n * highlighted and Enter resumed a session that was never on screen; `LoginPicker`\n * marked its selection with `❯` after the rest of the TUI had settled on `›`;\n * none of them paged, so a long list could only be walked one row at a time.\n *\n * The cursor lives in `useKeyState`, so every adopter is batch-safe against the\n * paste and key-repeat case (#165) without having to remember to be.\n */\nexport function ListPicker({\n title,\n subtitle,\n items,\n emptyText = '(nothing to choose from)',\n initialIndex = 0,\n maxVisible = 10,\n width,\n marginX,\n enterHint,\n escHint = 'cancel',\n extraHints,\n tabMovesNext = false,\n filterable = false,\n error,\n status,\n isActive = true,\n onSelect,\n onCancel,\n onKey,\n}: ListPickerProps) {\n const theme = useTheme();\n const density = useDensityMetrics();\n const [filter, setFilter, currentFilter] = useKeyState('');\n const [selected, setSelected, currentSelected] = useKeyState(initialIndex);\n\n const visibleItems = useMemo(() => {\n const needle = filter.trim().toLowerCase();\n if (!needle) return items;\n return items.filter((item) => (item.filterText ?? item.label).toLowerCase().includes(needle));\n }, [filter, items]);\n\n // Re-home the cursor when the caller's idea of \"current\" moves, and keep it\n // inside a list that just got shorter — a filter keystroke can strand it past\n // the end, which is how Enter ends up acting on nothing.\n //\n // The first effect clamps against `visibleItems` without depending on it, so\n // items must be present at mount. Every adopter builds them synchronously; an\n // adopter that loaded them asynchronously with a non-zero `initialIndex`\n // would clamp against an empty list and never re-run.\n useEffect(() => {\n setSelected(Math.max(0, Math.min(initialIndex, visibleItems.length - 1)));\n }, [initialIndex, setSelected]);\n useEffect(() => {\n if (currentSelected() > visibleItems.length - 1) {\n setSelected(Math.max(0, visibleItems.length - 1));\n }\n }, [visibleItems.length, currentSelected, setSelected]);\n\n const move = (next: number) => {\n if (visibleItems.length === 0) return;\n setSelected(((next % visibleItems.length) + visibleItems.length) % visibleItems.length);\n };\n // Paging clamps rather than wraps. Page-Down on the last screen of a long list\n // should land on the end, not spring back to the top.\n const page = (delta: number) => {\n if (visibleItems.length === 0) return;\n setSelected(Math.max(0, Math.min(visibleItems.length - 1, currentSelected() + delta)));\n };\n\n useInput(\n (input, key) => {\n if (key.escape) return onCancel();\n if (onKey?.(input, key, currentSelected())) return;\n if (key.upArrow) return move(currentSelected() - 1);\n if (key.downArrow || (tabMovesNext && key.tab && !key.shift)) {\n return move(currentSelected() + 1);\n }\n if (tabMovesNext && key.tab && key.shift) return move(currentSelected() - 1);\n if (key.pageUp) return page(-maxVisible);\n if (key.pageDown) return page(maxVisible);\n if (key.return) {\n const item = visibleItems[currentSelected()];\n if (!item || item.disabled) return;\n onSelect(items.indexOf(item));\n return;\n }\n if (!filterable || key.ctrl || key.meta) return;\n if (key.backspace || key.delete) {\n setFilter(currentFilter().slice(0, -1));\n return;\n }\n if (input && input >= ' ') setFilter(currentFilter() + input);\n },\n { isActive },\n );\n\n // Centre the cursor once the list is longer than the window, and stop the\n // window running off the end.\n const start =\n visibleItems.length <= maxVisible\n ? 0\n : Math.max(\n 0,\n Math.min(selected - Math.floor(maxVisible / 2), visibleItems.length - maxVisible),\n );\n const window = visibleItems.slice(start, start + maxVisible);\n const hidden = visibleItems.length - window.length;\n\n return (\n <SoftPanel\n title={title}\n meta={visibleItems.length > maxVisible ? `${visibleItems.length} items` : undefined}\n width={width}\n marginX={marginX}\n >\n {subtitle ? <Text color={theme.subtle}>{subtitle}</Text> : null}\n {filterable && filter ? <Text color={theme.subtle}>filter: {filter}</Text> : null}\n <Box flexDirection=\"column\" marginTop={1}>\n {visibleItems.length === 0 ? (\n <Text color={theme.subtle}>{filter ? '(no matches)' : emptyText}</Text>\n ) : (\n window.map((item, offset) => {\n const index = start + offset;\n const isSelected = index === selected;\n return (\n <Box key={item.key} flexDirection=\"column\">\n {/* A rubric cursor, the label in ink, its note quieter: no bar. */}\n <Box width={width ? width - 4 : undefined}>\n <Text color={theme.brand}>{isSelected ? '› ' : ' '}</Text>\n <Text\n color={\n item.disabled\n ? theme.inactive\n : isSelected\n ? theme.selectionText\n : item.muted\n ? theme.subtle\n : theme.text\n }\n bold={(isSelected || item.accent) && !item.disabled}\n >\n {item.label}\n </Text>\n {item.note ? <Text color={theme.inactive}>{` ${item.note}`}</Text> : null}\n </Box>\n {isSelected && item.detail ? (\n <Text color={theme.inactive}>\n {' '}\n {item.detail}\n </Text>\n ) : null}\n </Box>\n );\n })\n )}\n {hidden > 0 ? <Text color={theme.inactive}>+{hidden} more</Text> : null}\n </Box>\n {status ? <Text color={theme.subtle}>{status}</Text> : null}\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\n {density.showOptionalHelp ? (\n <Text color={theme.inactive}>\n {[\n '↑↓ select',\n visibleItems.length > maxVisible ? 'PgUp/PgDn page' : undefined,\n filterable ? 'type to filter' : undefined,\n `Enter ${enterHint}`,\n extraHints,\n `Esc ${escHint}`,\n ]\n .filter(Boolean)\n .join(' · ')}\n </Text>\n ) : null}\n </SoftPanel>\n );\n}\n","import { useMemo, useState } from 'react';\nimport { ListPicker } from './ListPicker.js';\nimport type { PermissionMode } from '../../types/runtime.js';\n\nexport interface PermissionModeSelectionResult {\n ok: boolean;\n error?: string;\n}\n\ninterface PermissionModePickerProps {\n /** Sheet width, from the panel grid; without it the head falls back to a plain title. */\n width?: number;\n current: PermissionMode;\n availableModes: readonly PermissionMode[];\n onSelect: (mode: PermissionMode) => PermissionModeSelectionResult;\n onCancel: () => void;\n}\n\nconst DESCRIPTIONS: Record<PermissionMode, string> = {\n default: 'Ask according to configured permission rules',\n auto: 'Automatically approve eligible tool calls',\n plan: 'Plan changes before applying them',\n 'accept-edits': 'Automatically approve file edits',\n dontAsk: 'Deny calls that would require prompting',\n bypassPermissions: 'Run without permission checks',\n};\n\nexport function PermissionModePicker({\n current,\n availableModes,\n onSelect,\n onCancel,\n width,\n}: PermissionModePickerProps) {\n const [error, setError] = useState<string>();\n\n const items = useMemo(\n () =>\n availableModes.map((mode) => ({\n key: mode,\n label: `${mode.padEnd(18)} ${DESCRIPTIONS[mode]}`,\n note: mode === current ? '(current)' : undefined,\n accent: mode === current,\n })),\n [availableModes, current],\n );\n\n return (\n <ListPicker\n title=\"Default permissions\"\n width={width}\n subtitle=\"Choose the mode used when a run does not specify one.\"\n items={items}\n initialIndex={Math.max(0, availableModes.indexOf(current))}\n enterHint=\"save globally\"\n error={error}\n onSelect={(index) => {\n const mode = availableModes[index];\n if (!mode) return;\n const result = onSelect(mode);\n setError(\n result.ok ? undefined : (result.error ?? 'Could not save the default permission mode.'),\n );\n }}\n onCancel={onCancel}\n />\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useTheme } from '../theme.js';\nimport { floatingFrameMetrics, SoftPanel } from './chrome.js';\nimport { displayWidth, padDisplay, truncateDisplay } from './word-wrap.js';\n\nexport type ConfigSection =\n 'model' | 'compact-model' | 'effort' | 'agents' | 'skills' | 'permission-mode';\n\ninterface ConfigMenuProps {\n model: string;\n compactModel?: string;\n effort?: string;\n memoryAutoSave: boolean;\n showThinking: boolean;\n startupAnimation?: boolean;\n agentCount: number;\n skillCount: number;\n defaultPermissionMode: string;\n terminalWidth?: number;\n /**\n * Shown under the rows when something outside the settings file decides the\n * startup animation. The row can be toggled to a value that will not apply,\n * and a menu that shows the new value with no word about that is worse than\n * one that refuses to change it.\n */\n startupAnimationWarning?: string;\n /**\n * Row the cursor starts on. The menu closes while a sub-picker is open and\n * remounts when that picker hands control back, so without this the return\n * trip always landed on Model — the user pressed `S`, cancelled, and found\n * the cursor four rows above where they had been.\n */\n initialSelection?: number;\n onOpen: (section: ConfigSection, rowIndex: number) => void;\n onToggleMemory: () => void;\n onToggleThinking: () => void;\n onToggleStartupAnimation?: () => void;\n onCancel: () => void;\n}\n\n/**\n * One table drives the cursor, the accelerator keys, and the letter each row\n * prints. The letters used to live in a separate `if` chain: five of the nine\n * were advertised nowhere, `memory` had no letter at all, and two of them (`i`,\n * `f`) flipped a setting on a row the cursor was not sitting on — so the only\n * feedback was a value changing somewhere else on the screen. Deriving the key\n * and its label from the same row is what stops a shortcut from drifting away\n * from the thing it acts on.\n *\n * `memory` keeps no accelerator rather than being given a contrived one; every\n * other free letter reads as a worse lie than a blank does. It is still\n * reachable with the arrows, and the blank column says so honestly.\n */\nconst ROWS = [\n { row: 'model', key: 'm' },\n { row: 'compact-model', key: 'c' },\n { row: 'effort', key: 'e' },\n { row: 'thinking', key: 'i' },\n { row: 'startup-animation', key: 'f' },\n { row: 'permission-mode', key: 'p' },\n { row: 'agents', key: 'a' },\n { row: 'skills', key: 's' },\n { row: 'memory' },\n] as const satisfies ReadonlyArray<{ row: string; key?: string }>;\ntype Row = (typeof ROWS)[number]['row'];\n\n/**\n * The cursor marker, the accelerator, and the gaps around them, as the string\n * the row actually prints. Measuring it beats a hand-kept column count: the\n * budget then cannot drift away from the prefix it is supposed to describe.\n */\n/** Columns of the setting names; the longest, \"Model memory writes\", fits. */\nconst LABEL_WIDTH = 22;\n\n/** Columns the value keeps before the label column starts to shrink. */\nconst MIN_VALUE_WIDTH = 6;\n\nfunction rowPrefix(selected: boolean, key?: string): string {\n return `${selected ? '›' : ' '} ${key ? key.toUpperCase() : ' '} `;\n}\n\nexport function ConfigMenu({\n model,\n compactModel,\n effort,\n memoryAutoSave,\n showThinking,\n startupAnimation = true,\n agentCount,\n skillCount,\n defaultPermissionMode,\n terminalWidth = 80,\n startupAnimationWarning,\n initialSelection = 0,\n onOpen,\n onToggleMemory,\n onToggleThinking,\n onToggleStartupAnimation = () => {},\n onCancel,\n}: ConfigMenuProps) {\n const theme = useTheme();\n // An accelerator sets the cursor and acts on it in the same keypress, so the\n // handler cannot read `selected` back from state — React has not flushed it.\n const [selected, moveSelection, currentSelected] = useKeyState(\n Math.min(Math.max(0, initialSelection), ROWS.length - 1),\n );\n const frame = floatingFrameMetrics(terminalWidth);\n const contentWidth = Math.max(16, frame.width - 4);\n\n const activate = (row: Row, index: number) => {\n if (row === 'memory') onToggleMemory();\n else if (row === 'thinking') onToggleThinking();\n else if (row === 'startup-animation') onToggleStartupAnimation();\n else onOpen(row, index);\n };\n\n useInput((input, key) => {\n if (key.escape) return onCancel();\n // Shift+Tab is back-tab everywhere else it appears; treating a bare\n // `key.tab` as \"next\" sent it forward, one row past whatever the user was\n // aiming at.\n if (key.upArrow || (key.tab && key.shift)) {\n moveSelection((currentSelected() - 1 + ROWS.length) % ROWS.length);\n return;\n }\n if (key.downArrow || key.tab) {\n moveSelection((currentSelected() + 1) % ROWS.length);\n return;\n }\n if (key.return) {\n const index = currentSelected();\n activate(ROWS[index].row, index);\n return;\n }\n if (key.ctrl || key.meta) return;\n // An accelerator moves the cursor before it acts, so the row that changes is\n // the row you are looking at. Pressing `i` used to toggle \"Show thinking\"\n // while the highlight sat on \"Model\" four rows above it.\n const shortcut = input.toLowerCase();\n const index = ROWS.findIndex((entry) => 'key' in entry && entry.key === shortcut);\n if (index < 0) return;\n moveSelection(index);\n activate(ROWS[index].row, index);\n });\n\n // Keyed rather than ordered: `ROWS` owns the order, so the two lists cannot\n // fall out of step and leave the cursor pointing at a row it does not render.\n const details: Record<Row, { label: string; value: string; description: string }> = {\n model: { label: 'Model', value: model, description: 'Default model for the main agent' },\n 'compact-model': {\n label: 'Compact model',\n value: compactModel ?? 'same as main',\n description: 'Reducer used only for conversation checkpoints',\n },\n effort: {\n label: 'Effort',\n value: effort ?? 'model default',\n description: 'Reasoning depth for supported models',\n },\n thinking: {\n label: 'Show thinking',\n value: showThinking ? 'on' : 'off',\n description: 'Display the model reasoning in the transcript',\n },\n 'startup-animation': {\n label: 'Startup fire',\n value: startupAnimation ? 'on' : 'off',\n description: 'Burn the terminal into the Book welcome screen',\n },\n 'permission-mode': {\n label: 'Default permissions',\n value: defaultPermissionMode,\n description: 'Mode for runs without an explicit override',\n },\n agents: {\n label: 'Subagent profiles',\n value: `${agentCount} available`,\n description: 'Choose a model for explorer, patcher, or validator',\n },\n skills: {\n label: 'Skills',\n value: `${skillCount} discovered`,\n description: 'Control automatic matching and explicit use',\n },\n memory: {\n label: 'Model memory writes',\n value: memoryAutoSave ? 'on' : 'off',\n description: 'Capture useful corrections for approval later',\n },\n };\n\n return (\n <SoftPanel title=\"Settings\" meta=\"Esc to close\" width={frame.width} marginX={frame.marginX}>\n <Text color={theme.subtle}>Choose a setting to change.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n {ROWS.map((entry, index) => {\n const item = details[entry.row];\n const current = index === selected;\n const prefix = rowPrefix(current, 'key' in entry ? entry.key : undefined);\n // The label column gives way before the row does: on a narrow panel it\n // shrinks and cuts, so prefix, label and value still fit one row.\n const labelWidth = Math.max(\n 4,\n Math.min(LABEL_WIDTH, contentWidth - displayWidth(prefix) - MIN_VALUE_WIDTH),\n );\n const label = padDisplay(truncateDisplay(item.label, labelWidth - 1), labelWidth);\n const valueRoom = Math.max(1, contentWidth - displayWidth(prefix) - labelWidth);\n const value = truncateDisplay(item.value, Math.min(valueRoom, 24));\n const descRoom = Math.max(0, valueRoom - displayWidth(value) - 3);\n // Cursor and letter in rubric, the setting in ink, its value, then what\n // it does in a quieter grey: columns, not one run of text.\n return (\n <Box key={entry.row} width={contentWidth}>\n <Text color={theme.brand}>{prefix}</Text>\n <Text bold={current} color={current ? theme.selectionText : theme.text}>\n {label}\n </Text>\n <Text color={theme.text}>{value}</Text>\n {descRoom >= 8 ? (\n <Text\n color={theme.inactive}\n >{` ${truncateDisplay(item.description, descRoom)}`}</Text>\n ) : null}\n </Box>\n );\n })}\n </Box>\n {startupAnimationWarning ? (\n <Box marginTop={1}>\n <Text color={theme.warning ?? theme.subtle} dimColor wrap=\"truncate-end\">\n {`⚠ ${startupAnimationWarning}`}\n </Text>\n </Box>\n ) : null}\n <Box marginTop={1}>\n <Text color={theme.inactive}>\n ↑↓ select · Enter choose · or press the letter · Esc close\n </Text>\n </Box>\n </SoftPanel>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport type { Skill } from '../../skills.js';\nimport type { SkillLifecycleEvent } from '../../skill-registry.js';\nimport type { SkillActivation, SkillExecution } from '../../settings.js';\nimport { useTheme } from '../theme.js';\nimport { PILCROW } from '../marks.js';\nimport { stripSgrMouseSequences } from '../mouse.js';\nimport { floatingFrameMetrics, SelectionRow, SoftPanel } from './chrome.js';\nimport { truncateDisplay } from './word-wrap.js';\n\nconst ACTIVATIONS: readonly SkillActivation[] = ['auto', 'name-only', 'manual', 'off'];\nconst EXECUTIONS: readonly SkillExecution[] = ['inherit', 'ask', 'deny'];\n\nconst ACTIVATION_HELP: Record<SkillActivation, string> = {\n auto: 'Name and description are visible; Book may activate it automatically.',\n 'name-only': 'Only the name is visible; explicit use remains reliable.',\n manual: 'Hidden from automatic matching; invoke it explicitly with $name.',\n off: 'Hidden and blocked from invocation.',\n};\n\nconst EXECUTION_HELP: Record<SkillExecution, string> = {\n inherit: 'Use the normal workspace and permission policy.',\n ask: 'Ask before activating this skill.',\n deny: 'Block this skill even when explicitly mentioned.',\n};\n\nexport interface SkillManagerResult {\n ok: boolean;\n error?: string;\n}\n\ninterface SkillManagerProps {\n skills: readonly Skill[];\n enabled?: boolean;\n watcherError?: string;\n lifecycleEvents?: readonly SkillLifecycleEvent[];\n activeSkillNames?: readonly string[];\n terminalWidth?: number;\n maxVisible?: number;\n onChangeActivation: (skillName: string, activation: SkillActivation) => SkillManagerResult;\n onChangeExecution: (skillName: string, execution: SkillExecution) => SkillManagerResult;\n onChangeEnabled: (enabled: boolean) => SkillManagerResult;\n onUse: (skill: Skill) => void;\n onReload: () => void;\n onCancel: () => void;\n}\n\nfunction nextValue<T>(values: readonly T[], current: T): T {\n const index = values.indexOf(current);\n return values[(index + 1) % values.length] ?? values[0];\n}\n\nexport function SkillManager({\n skills,\n enabled = true,\n watcherError,\n lifecycleEvents = [],\n activeSkillNames = [],\n terminalWidth = 80,\n maxVisible = 8,\n onChangeActivation,\n onChangeExecution,\n onChangeEnabled,\n onUse,\n onReload,\n onCancel,\n}: SkillManagerProps) {\n const theme = useTheme();\n // Both of these are read back by the key handler, so they have to survive a\n // React batch: Ink hands a whole stdin chunk over at once. With plain state a\n // batched `↓`+Space wrote an activation change to the skill above the\n // highlighted one, and a batched `/`+letter ran the letter as a command\n // instead of typing it into the search field.\n const [selected, setSelected, currentSelected] = useKeyState(0);\n const [error, setError] = useState<string>();\n const [query, setQuery] = useState('');\n const [searching, setSearching, isSearching] = useKeyState(false);\n const frame = floatingFrameMetrics(terminalWidth);\n const contentWidth = Math.max(16, frame.width - 4);\n const filteredSkills = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return skills;\n return skills.filter((skill) =>\n [skill.name, skill.description, skill.source, skill.rootKind, skill.path]\n .join(' ')\n .toLowerCase()\n .includes(normalized),\n );\n }, [query, skills]);\n\n useEffect(() => {\n setSelected(Math.max(0, Math.min(currentSelected(), filteredSkills.length - 1)));\n }, [filteredSkills.length, setSelected, currentSelected]);\n\n const window = useMemo(() => {\n if (filteredSkills.length <= maxVisible) return { start: 0, items: filteredSkills };\n const half = Math.floor(maxVisible / 2);\n const start = Math.max(0, Math.min(selected - half, filteredSkills.length - maxVisible));\n return { start, items: filteredSkills.slice(start, start + maxVisible) };\n }, [filteredSkills, maxVisible, selected]);\n\n useInput((input, key) => {\n if (isSearching()) {\n if (key.escape || key.return) {\n setSearching(false);\n return;\n }\n if (key.backspace || key.delete) {\n setQuery((current) => current.slice(0, -1));\n return;\n }\n const typed = stripSgrMouseSequences(input);\n if (!key.ctrl && !key.meta && typed && !key.upArrow && !key.downArrow) {\n setQuery((current) => current + typed);\n }\n return;\n }\n\n if (key.escape) return onCancel();\n if (input === '/') {\n setSearching(true);\n setQuery('');\n setError(undefined);\n return;\n }\n if (input.toLowerCase() === 'r') {\n setError(undefined);\n onReload();\n return;\n }\n if (input.toLowerCase() === 'g') {\n const result = onChangeEnabled(!enabled);\n setError(\n result.ok ? undefined : (result.error ?? 'Could not save the global skill setting.'),\n );\n return;\n }\n if (filteredSkills.length === 0) return;\n if (key.upArrow) {\n setSelected((currentSelected() - 1 + filteredSkills.length) % filteredSkills.length);\n setError(undefined);\n return;\n }\n if (key.downArrow || key.tab) {\n setSelected((currentSelected() + 1) % filteredSkills.length);\n setError(undefined);\n return;\n }\n\n const skill = filteredSkills[currentSelected()];\n if (!skill) return;\n if (input === ' ') {\n const activation = nextValue(ACTIVATIONS, skill.activation);\n const result = onChangeActivation(skill.name, activation);\n setError(result.ok ? undefined : (result.error ?? 'Could not save the skill setting.'));\n return;\n }\n if (input.toLowerCase() === 'e') {\n const execution = nextValue(EXECUTIONS, skill.execution);\n const result = onChangeExecution(skill.name, execution);\n setError(result.ok ? undefined : (result.error ?? 'Could not save the consent setting.'));\n return;\n }\n if (key.return) {\n if (!enabled) {\n setError('Skills are globally disabled. Press G to enable them before use.');\n return;\n }\n if (!skill.valid) {\n setError('This skill is invalid. Review its diagnostics before use.');\n return;\n }\n if (skill.activation === 'off' || skill.execution === 'deny') {\n setError('This skill is blocked. Change its activation or consent policy before use.');\n return;\n }\n onUse(skill);\n }\n });\n\n const active = filteredSkills[selected];\n const lastLifecycleEvent = active\n ? [...lifecycleEvents].reverse().find((event) => event.skill === active.name)\n : undefined;\n\n return (\n <SoftPanel\n title=\"Skills\"\n meta={`${skills.length} discovered`}\n width={frame.width}\n marginX={frame.marginX}\n >\n <Text color={enabled ? theme.success : theme.warning}>\n {enabled ? 'Enabled' : 'Globally off'} · {skills.length} discovered\n {query ? ` · ${filteredSkills.length} matching \"${query}\"` : ''}\n </Text>\n {searching ? (\n <Text>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <Text color={query ? theme.text : theme.inactive}>{query || 'search skills'}</Text>\n </Text>\n ) : null}\n {watcherError ? (\n <Text color={theme.warning}>\n Watcher: {truncateDisplay(watcherError, Math.max(8, contentWidth - 9))}\n </Text>\n ) : null}\n <Box flexDirection=\"column\" marginTop={1}>\n {filteredSkills.length === 0 ? (\n <Text color={theme.subtle} dimColor>\n {skills.length === 0\n ? 'No skills found in .book, .agents, .claude, or .opencode skill roots.'\n : 'No skills match this search.'}\n </Text>\n ) : (\n window.items.map((skill, offset) => {\n const index = window.start + offset;\n const validity = skill.valid ? 'ok' : 'invalid';\n const activeState = activeSkillNames.includes(skill.name) ? 'active' : 'idle';\n const row = `${skill.name.padEnd(20)} ${skill.activation.padEnd(9)} ${skill.execution.padEnd(7)} ${activeState.padEnd(6)} ${skill.rootKind}/${skill.source} ${validity}`;\n return (\n <SelectionRow key={`${skill.source}:${skill.path}`} selected={index === selected}>\n {index === selected ? '›' : ' '} {truncateDisplay(row, contentWidth - 2)}\n </SelectionRow>\n );\n })\n )}\n </Box>\n {active ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.text}>\n {truncateDisplay(active.description, Math.max(8, contentWidth))}\n </Text>\n <Text color={theme.text}>{ACTIVATION_HELP[active.activation]}</Text>\n <Text color={theme.subtle}>\n {active.execution === 'inherit' && active.source === 'project'\n ? 'Project instructions require consent unless an InvokeSkill rule already allows them.'\n : EXECUTION_HELP[active.execution]}\n </Text>\n <Text color={theme.subtle}>\n {active.version} · {active.entryByteSize} bytes · {active.resources.length} resources\n {active.shadowed.length ? ` · shadows ${active.shadowed.length}` : ''}\n </Text>\n {active.whenToUse ? (\n <Text color={theme.subtle}>\n Trigger: {truncateDisplay(active.whenToUse, Math.max(8, contentWidth - 9))}\n </Text>\n ) : null}\n {active.compatibility ? (\n <Text color={theme.subtle}>\n Compatibility: {truncateDisplay(active.compatibility, Math.max(8, contentWidth - 15))}\n </Text>\n ) : null}\n {active.resources.slice(0, 2).map((resource) => (\n <Text key={resource.relativePath} color={theme.subtle}>\n Resource: {truncateDisplay(resource.relativePath, Math.max(8, contentWidth - 10))}\n </Text>\n ))}\n {active.resources.length > 2 ? (\n <Text color={theme.subtle}>+{active.resources.length - 2} more resources</Text>\n ) : null}\n {active.shadowed.slice(0, 2).map((shadowed) => (\n <Text key={shadowed.path} color={theme.warning}>\n Shadows: {truncateDisplay(shadowed.path, Math.max(8, contentWidth - 9))}\n </Text>\n ))}\n {active.shadowed.length > 2 ? (\n <Text color={theme.warning}>+{active.shadowed.length - 2} more shadowed sources</Text>\n ) : null}\n {active.issues.slice(0, 3).map((issue) => (\n <Text\n key={`${issue.code}:${issue.message}`}\n color={issue.severity === 'error' ? theme.error : theme.warning}\n >\n {issue.severity}: {truncateDisplay(issue.message, Math.max(8, contentWidth - 9))}\n </Text>\n ))}\n {active.issues.length > 3 ? (\n <Text color={theme.warning}>+{active.issues.length - 3} more validation issues</Text>\n ) : null}\n {lastLifecycleEvent ? (\n <Text color={theme.subtle}>\n Last event: {lastLifecycleEvent.type}\n {typeof lastLifecycleEvent.details?.code === 'string'\n ? ` (${lastLifecycleEvent.details.code})`\n : ''}\n </Text>\n ) : null}\n <Text color={theme.subtle} dimColor>\n {truncateDisplay(active.path, contentWidth)}\n </Text>\n </Box>\n ) : null}\n {/* Two lines, split by what the keys act on. As one line this was eight\n chords that did not fit, so Ink wrapped it — and the wrap landed after\n a trailing separator, leaving \"Esc close\" stranded on a line of its\n own under a dangling \"·\". */}\n <Text color={theme.subtle} dimColor>\n ↑↓ select · / search · Enter insert · Esc close\n </Text>\n <Text color={theme.subtle} dimColor>\n Space activation · E consent · G global · R reload\n </Text>\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\n </SoftPanel>\n );\n}\n","import { useMemo } from 'react';\nimport type { ManagedAgentDef } from '../../agents/profiles.js';\nimport { floatingFrameMetrics } from './chrome.js';\nimport { ListPicker } from './ListPicker.js';\nimport { truncateDisplay } from './word-wrap.js';\n\ninterface AgentProfilePickerProps {\n profiles: readonly ManagedAgentDef[];\n parentModel: string;\n configuredModels: Readonly<Record<string, string | undefined>>;\n terminalWidth?: number;\n onSelect: (profile: string) => void;\n onReset: (profile: string) => void;\n onCancel: () => void;\n}\n\nfunction effectiveModel(\n profile: ManagedAgentDef,\n parentModel: string,\n configuredModels: Readonly<Record<string, string | undefined>>,\n): { value: string; inherited: boolean } {\n const configured = configuredModels[profile.name];\n if (configured === 'inherit') return { value: parentModel, inherited: true };\n if (configured && configured !== 'inherit') return { value: configured, inherited: false };\n return { value: profile.model ?? parentModel, inherited: true };\n}\n\nexport function AgentProfilePicker({\n profiles,\n parentModel,\n configuredModels,\n terminalWidth = 80,\n onSelect,\n onReset,\n onCancel,\n}: AgentProfilePickerProps) {\n const frame = floatingFrameMetrics(terminalWidth);\n const contentWidth = Math.max(16, frame.width - 4);\n\n const items = useMemo(\n () =>\n profiles.map((profile) => {\n const model = effectiveModel(profile, parentModel, configuredModels);\n return {\n key: profile.name,\n label: truncateDisplay(\n `${profile.name.padEnd(12)} ${model.value}${model.inherited ? ' (inherit)' : ''} · ${profile.role} · ${profile.isolation}`,\n contentWidth - 2,\n ),\n detail: profile.description,\n };\n }),\n [configuredModels, contentWidth, parentModel, profiles],\n );\n\n return (\n <ListPicker\n title=\"Subagent profiles\"\n subtitle=\"Select a profile to choose its model for future runs.\"\n items={items}\n emptyText=\"No profiles discovered.\"\n width={frame.width}\n marginX={frame.marginX}\n tabMovesNext\n enterHint=\"choose model\"\n extraHints=\"R reset to inherit\"\n escHint=\"back\"\n onKey={(input, key, index) => {\n if (key.ctrl || key.meta) return false;\n if (input.toLowerCase() !== 'r') return false;\n const profile = profiles[index];\n if (profile) onReset(profile.name);\n return true;\n }}\n onSelect={(index) => {\n const profile = profiles[index];\n if (profile) onSelect(profile.name);\n }}\n onCancel={onCancel}\n />\n );\n}\n","import { useMemo } from 'react';\nimport { ListPicker } from './ListPicker.js';\nimport type { SessionMeta } from '../../types/sessions.js';\nimport { displaySessionName } from '../../session/name.js';\nimport { formatAge } from '../relative-age.js';\n\ninterface SessionPickerProps {\n /** Sheet width, from the panel grid; without it the head falls back to a plain title. */\n width?: number;\n sessions: SessionMeta[];\n currentSessionId: string;\n onPick: (session: SessionMeta) => void;\n onCancel: () => void;\n}\n\nexport function SessionPicker({\n sessions,\n currentSessionId,\n onPick,\n onCancel,\n width,\n}: SessionPickerProps) {\n const choices = useMemo(\n () => sessions.filter((session) => session.id !== currentSessionId),\n [currentSessionId, sessions],\n );\n\n const items = useMemo(\n () =>\n choices.map((session) => ({\n key: session.id,\n label: `${displaySessionName(session.name)} · ${formatAge(session.updatedAt)} · ${session.messageCount} messages`,\n muted: true,\n })),\n [choices],\n );\n\n return (\n <ListPicker\n title=\"Resume\"\n width={width}\n items={items}\n // This list used to be cut to twelve rows while the cursor still wrapped\n // over every session, so past the twelfth nothing was highlighted and\n // Enter resumed a conversation that had never been on screen. It windows\n // now, and it is the one list long enough to be worth filtering.\n maxVisible={12}\n filterable\n emptyText=\"(no other sessions in this workspace)\"\n enterHint=\"resume\"\n onSelect={(index) => {\n const session = choices[index];\n if (session) onPick(session);\n }}\n onCancel={onCancel}\n />\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useMemo, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport type { RewindAction, RewindTarget } from '../../types/sessions.js';\nimport { useDensityMetrics } from '../density.js';\nimport { useTheme } from '../theme.js';\nimport { formatAge } from '../relative-age.js';\nimport { SoftPanel } from './chrome.js';\nimport { panelGrid } from '../layout.js';\n\ninterface RewindPickerProps {\n targets: RewindTarget[];\n isRewinding: boolean;\n onAction: (\n target: RewindTarget,\n action: RewindAction,\n ) => Promise<{ ok: true } | { ok: false; error: string }>;\n onCancel: () => void;\n /** Terminal columns; the sheet's rule spans them. */\n terminalWidth?: number;\n}\n\ntype ActionChoice = {\n action: RewindAction | 'cancel';\n label: string;\n description: string;\n};\n\nconst ACTIONS: ActionChoice[] = [\n {\n action: 'conversation',\n label: 'Conversation',\n description: 'Remove this prompt and newer conversation, then restore the prompt.',\n },\n {\n action: 'code',\n label: 'Code',\n description: 'Restore workspace files while keeping the conversation.',\n },\n {\n action: 'both',\n label: 'Both',\n description: 'Restore workspace files and conversation together.',\n },\n { action: 'cancel', label: 'Cancel', description: 'Return without changing anything.' },\n];\n\nfunction promptPreview(prompt: string): string {\n const singleLine = prompt.replace(/\\s+/g, ' ').trim();\n return singleLine.length <= 72 ? singleLine : `${singleLine.slice(0, 69)}...`;\n}\n\nexport function RewindPicker({\n targets,\n isRewinding,\n onAction,\n onCancel,\n terminalWidth = 80,\n}: RewindPickerProps) {\n const theme = useTheme();\n const sheetWidth = panelGrid(Math.max(20, Math.floor(terminalWidth))).width;\n const density = useDensityMetrics();\n // Stage and both cursors are read back by the key handler, so Enter that\n // advances the stage and Enter that acts on the new stage can arrive together.\n const [stage, setStage, currentStage] = useKeyState<'target' | 'action'>('target');\n const [selectedTarget, setSelectedTarget, currentTarget] = useKeyState(0);\n const [selectedAction, setSelectedAction, currentAction] = useKeyState(0);\n const [error, setError] = useState<string | null>(null);\n const target = targets[selectedTarget];\n const visibleTargets = useMemo(() => {\n const start = Math.max(0, Math.min(selectedTarget - 5, Math.max(0, targets.length - 12)));\n return { start, items: targets.slice(start, start + 12) };\n }, [selectedTarget, targets]);\n\n const chooseAction = async () => {\n // Called from the key handler, so the target comes from the ref as well:\n // an arrow, the Enter that picks a target and the Enter that acts on it can\n // all land in one batch, and `target` would still be the render-time row.\n const chosen = targets[currentTarget()];\n const choice = ACTIONS[currentAction()];\n if (!chosen || !choice || isRewinding) return;\n if (choice.action === 'cancel') return onCancel();\n if ((choice.action === 'code' || choice.action === 'both') && !chosen.codeAvailable) return;\n setError(null);\n const result = await onAction(chosen, choice.action);\n if (!result.ok) setError(result.error);\n };\n\n useInput(\n (_input, key) => {\n if (isRewinding) return;\n if (key.escape) {\n if (currentStage() === 'action') {\n setStage('target');\n setError(null);\n } else {\n onCancel();\n }\n return;\n }\n if (currentStage() === 'target') {\n if (targets.length === 0) return;\n if (key.upArrow) setSelectedTarget((currentTarget() - 1 + targets.length) % targets.length);\n if (key.downArrow) setSelectedTarget((currentTarget() + 1) % targets.length);\n if (key.return) {\n setSelectedAction(0);\n setError(null);\n setStage('action');\n }\n return;\n }\n if (key.upArrow) setSelectedAction((currentAction() - 1 + ACTIONS.length) % ACTIONS.length);\n if (key.downArrow) setSelectedAction((currentAction() + 1) % ACTIONS.length);\n if (key.return) void chooseAction();\n },\n { isActive: true },\n );\n\n return (\n <SoftPanel\n title=\"Rewind\"\n meta={stage === 'target' ? `${targets.length} prompts` : 'choose what to restore'}\n width={sheetWidth}\n >\n {stage === 'target' ? (\n targets.length === 0 ? (\n <Text color={theme.subtle}>(no user prompts to rewind)</Text>\n ) : (\n visibleTargets.items.map((choice, visibleIndex) => {\n const index = visibleTargets.start + visibleIndex;\n const selected = index === selectedTarget;\n return (\n <Text key={choice.id}>\n <Text color={theme.brand}>{selected ? '› ' : ' '}</Text>\n {/* Your own past prompts, set the way the transcript sets\n them: upright, in `userText`. */}\n <Text color={selected ? theme.selectionText : theme.userText} bold={selected}>\n {promptPreview(choice.prompt)}\n </Text>\n <Text color={theme.inactive}>\n {' '}\n {formatAge(choice.timestamp)} ·{' '}\n {choice.codeAvailable ? 'code ready' : 'conversation only'}\n </Text>\n </Text>\n );\n })\n )\n ) : (\n <>\n <Text color={theme.text}>{promptPreview(target?.prompt ?? '')}</Text>\n {ACTIONS.map((choice, index) => {\n const selected = index === selectedAction;\n const disabled =\n (choice.action === 'code' || choice.action === 'both') && !target?.codeAvailable;\n return (\n <Box key={choice.action} flexDirection=\"column\">\n <Text>\n <Text color={theme.brand}>{selected ? '› ' : ' '}</Text>\n <Text\n color={disabled ? theme.inactive : selected ? theme.selectionText : theme.text}\n bold={selected && !disabled}\n >\n {choice.label}\n {disabled ? ' (unavailable)' : ''}\n </Text>\n </Text>\n {selected ? (\n <Text color={disabled ? theme.error : theme.subtle} dimColor={!disabled}>\n {' '}\n {disabled ? target?.codeUnavailableReason : choice.description}\n </Text>\n ) : null}\n </Box>\n );\n })}\n </>\n )}\n {isRewinding ? <Text color={theme.subtle}>Restoring…</Text> : null}\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\n {density.showOptionalHelp ? (\n <Box marginTop={1}>\n <Text color={theme.inactive}>↑↓ select · Enter confirm · Esc back</Text>\n </Box>\n ) : null}\n </SoftPanel>\n );\n}\n","import { Box, Text, measureElement, useInput, useStdin, useStdout, type DOMElement } from 'ink';\nimport type { EventEmitter } from 'node:events';\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n memo,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n createTranscriptScrollState,\n createWheelMotion,\n getTranscriptHalfPageRows,\n getTranscriptPageRows,\n halfPageScrollDirection,\n reconcileTranscriptScroll,\n scrollTranscriptBy,\n scrollTranscriptToEnd,\n scrollTranscriptToStart,\n wheelEaseStep,\n wheelRows,\n type TranscriptMetrics,\n type TranscriptScrollState,\n type WheelMotion,\n} from '../transcript-scroll.js';\nimport { parseSgrMouseEvents, stripSgrMouseSequences } from '../mouse.js';\nimport { writeClipboard } from '../clipboard.js';\nimport { getFrameLines, getLastCursorPosition, subscribeToFrameUpdates } from '../frame-buffer.js';\nimport { paintSelection, restoreSelection } from '../selection-highlight.js';\nimport {\n extractSelectedText,\n normalizeSelectionRange,\n type SelectionCell,\n type SelectionRange,\n} from '../text-selection.js';\nimport {\n TranscriptHistoryContext,\n TranscriptLayoutContext,\n TranscriptViewportContext,\n type TranscriptHistoryLoader,\n type TranscriptHistoryRequest,\n type TranscriptViewportSnapshot,\n type TranscriptViewportStore,\n} from '../transcript-layout.js';\nimport { useTheme } from '../theme.js';\nimport { setTranscriptScrollHint } from '../ink-scroll-renderer.js';\nimport { markTranscriptScrollActivity } from '../scroll-activity.js';\nimport { resolveInkMaxFps } from '../../cli/tui-renderer-mode.js';\nimport {\n ToolRowInteractionContext,\n type ToolSummaryRowRegistration,\n} from './tool-row-interactions.js';\n\ninterface TranscriptViewProps {\n children: ReactNode;\n height?: number;\n width?: number;\n isActive?: boolean;\n followRequestKey?: number;\n /** Structural layout changes outside transcript components that self-report height updates. */\n layoutRevision?: unknown;\n /**\n * True while nothing on screen is holding a text editor's focus, and only then\n * may this transcript read Ctrl+U and Ctrl+D as its own half-page scrolls.\n * Derive it with `pagerChordsAvailable` from `../transcript-scroll.js`.\n *\n * Ctrl+U and Ctrl+D are readline's kills, and Ink hands every key to every\n * handler, so this transcript cannot decide the question on its own: by the\n * time its own handler runs, an editor has already acted, and a draft that\n * Ctrl+U itself emptied looks exactly like one that was empty all along. So\n * the editor takes the chord and, when it had nothing to edit, hands it back\n * through `scrollRequest` — and this transcript's own Ctrl+U / Ctrl+D handling\n * is for the times no editor is taking keys at all (a permission prompt, a\n * sheet of choices), which is when a scroll is the only thing the key can mean.\n *\n * A sheet with its own editor open reports through the same channel as its\n * height, so plan approval, the `Other` answer and an MCP text field take\n * these keys the way the composer does.\n */\n pagerChordsAvailable?: boolean;\n /**\n * A half-page scroll the app asked for on the composer's behalf. Keyed so a\n * repeated request scrolls again; the initial `key: 0` is treated as none.\n */\n scrollRequest?: TranscriptScrollRequest;\n onToggleTool?: (toolId: string, expanded: boolean) => void;\n onNotify?: (message: string) => void;\n onRedrawViewport?: () => void;\n}\n\n/**\n * How long growth still reads as rows mounted above the view, per request: a page lands in the\n * next commits or two, while an 'all' request mounts a whole bounded history that estimates its\n * height before it measures it, so it needs longer.\n */\nconst HISTORY_PREPEND_WINDOW_MS: Record<TranscriptHistoryRequest, number> = {\n page: 1000,\n all: 3000,\n};\n\n/** A half-page scroll asked for from outside, as the composer reports it. */\nexport interface TranscriptScrollRequest {\n key: number;\n direction: 'up' | 'down';\n}\n\nconst INITIAL_METRICS: TranscriptMetrics = { contentRows: 0, viewportRows: 1 };\n/**\n * Between wheel animation frames: a millisecond under the frame interval Ink draws at\n * (`installInkFrameThrottle`). A draw other commits scheduled for the same frame then fires after\n * the step and shows it, instead of drawing just before it and leaving the step for the frame after.\n */\nconst WHEEL_FRAME_MS = Math.ceil(1000 / resolveInkMaxFps(process.platform)) - 1;\n\ninterface DragState {\n anchor: SelectionCell;\n focus: SelectionCell;\n dragged: boolean;\n}\n\nconst selectionRangesEqual = (left: SelectionRange, right: SelectionRange): boolean =>\n left.start.x === right.start.x &&\n left.start.y === right.start.y &&\n left.end.x === right.end.x &&\n left.end.y === right.end.y;\n\nfunction getAbsolutePosition(node: DOMElement): { x: number; y: number } | undefined {\n let current: DOMElement | undefined = node;\n let x = 0;\n let y = 0;\n while (current?.parentNode) {\n if (!current.yogaNode) return undefined;\n x += current.yogaNode.getComputedLeft();\n y += current.yogaNode.getComputedTop();\n current = current.parentNode;\n }\n return { x, y };\n}\n\ninterface TranscriptContentProps {\n children: ReactNode;\n interactionRegistry: {\n register: (registration: ToolSummaryRowRegistration) => () => void;\n };\n historyRegistry: {\n register: (loader: TranscriptHistoryLoader) => () => void;\n };\n viewportStore: TranscriptViewportStore;\n onLayoutChange: () => void;\n}\n\nconst TranscriptContent = memo(function TranscriptContent({\n children,\n interactionRegistry,\n historyRegistry,\n viewportStore,\n onLayoutChange,\n}: TranscriptContentProps) {\n return (\n <TranscriptLayoutContext.Provider value={onLayoutChange}>\n <TranscriptHistoryContext.Provider value={historyRegistry}>\n <TranscriptViewportContext.Provider value={viewportStore}>\n <ToolRowInteractionContext.Provider value={interactionRegistry}>\n {children}\n </ToolRowInteractionContext.Provider>\n </TranscriptViewportContext.Provider>\n </TranscriptHistoryContext.Provider>\n </TranscriptLayoutContext.Provider>\n );\n});\n\nexport function TranscriptView({\n children,\n height,\n width,\n isActive = true,\n followRequestKey = 0,\n layoutRevision,\n // True by default: a transcript on its own has no editor to take these keys,\n // and the chords are the only thing they can mean. `app.tsx` passes the real\n // answer for the whole screen.\n pagerChordsAvailable = true,\n scrollRequest,\n onToggleTool,\n onNotify,\n onRedrawViewport,\n}: TranscriptViewProps) {\n const theme = useTheme();\n // Mouse reports need Ink's raw input events: `useInput` strips the ESC prefix and parses them as\n // keys. Ink 7 still passes the emitter in the stdin context but no longer types it.\n const { internal_eventEmitter } = useStdin() as ReturnType<typeof useStdin> & {\n internal_eventEmitter?: EventEmitter;\n };\n const { stdout } = useStdout();\n const viewportRef = useRef<DOMElement>(null);\n const contentRef = useRef<DOMElement>(null);\n const metricsRef = useRef(INITIAL_METRICS);\n const stateRef = useRef<TranscriptScrollState>(createTranscriptScrollState());\n const previousContentRowsRef = useRef(0);\n const anchoredRowsRef = useRef(0);\n const previousFollowRequestRef = useRef(followRequestKey);\n // Seeded from the request in hand, the way `previousFollowRequestRef` is seeded\n // from `followRequestKey`. A remount is not a fresh request: `app.tsx` keys\n // this component on the session, so /resume and /clear mount a new one while\n // `scrollRequest` still carries the count from the session before. Starting at\n // 0 would replay that count and open the new session scrolled half a page back\n // and no longer following output.\n const previousScrollRequestRef = useRef(scrollRequest?.key ?? 0);\n const pendingWheelRowsRef = useRef(0);\n const wheelMotionRef = useRef<WheelMotion>(createWheelMotion());\n const wheelImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\n const wheelTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const layoutMeasureImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\n const onToggleToolRef = useRef(onToggleTool);\n const onNotifyRef = useRef(onNotify);\n const onRedrawViewportRef = useRef(onRedrawViewport);\n const dragRef = useRef<DragState | null>(null);\n const selectionRef = useRef<SelectionRange | null>(null);\n const repaintImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\n const [renderedScrollTop, setRenderedScrollTop] = useState(0);\n const [followBottom, setFollowBottom] = useState(true);\n const [hasNewOutput, setHasNewOutput] = useState(false);\n const historyLoaderRef = useRef<TranscriptHistoryLoader | null>(null);\n // The deadline past which rows the loader promised are no longer treated as arriving: growth\n // measured after it is output below again. A deadline rather than a flag, because a page\n // settles over several measurements and a page that brings no net growth measures none at all,\n // so a single shot either misses the later measurements or stands for the rest of the session.\n const historyPrependUntilRef = useRef(0);\n const viewportListenersRef = useRef(new Set<() => void>());\n const viewportRevisionRef = useRef(0);\n const viewportBucketRef = useRef('');\n const toolRowsRef = useRef(new Map<string, ToolSummaryRowRegistration>());\n const interactionRegistry = useMemo(\n () => ({\n register: (registration: ToolSummaryRowRegistration) => {\n toolRowsRef.current.set(registration.id, registration);\n return () => {\n if (toolRowsRef.current.get(registration.id) === registration) {\n toolRowsRef.current.delete(registration.id);\n }\n };\n },\n }),\n [],\n );\n const historyRegistry = useMemo(\n () => ({\n register: (loader: TranscriptHistoryLoader) => {\n historyLoaderRef.current = loader;\n return () => {\n if (historyLoaderRef.current === loader) historyLoaderRef.current = null;\n };\n },\n }),\n [],\n );\n const viewportSnapshotRef = useRef<{\n revision: number;\n snapshot: TranscriptViewportSnapshot;\n } | null>(null);\n const publishViewport = useCallback((state: TranscriptScrollState) => {\n const viewportRows = metricsRef.current.viewportRows;\n const bucketRows = Math.max(1, getTranscriptHalfPageRows(viewportRows));\n const bucket = `${Math.floor(state.scrollTop / bucketRows)}:${viewportRows}:${state.followBottom}`;\n if (viewportBucketRef.current === bucket) return;\n\n viewportBucketRef.current = bucket;\n viewportRevisionRef.current++;\n for (const listener of viewportListenersRef.current) listener();\n }, []);\n const viewportStore = useMemo<TranscriptViewportStore>(\n () => ({\n subscribe: (listener) => {\n viewportListenersRef.current.add(listener);\n return () => viewportListenersRef.current.delete(listener);\n },\n getRevision: () => viewportRevisionRef.current,\n getSnapshot: () => {\n // Keep the snapshot referentially stable between revisions so consumers\n // can use it as a memo dependency without recomputing on every render.\n const revision = viewportRevisionRef.current;\n const cached = viewportSnapshotRef.current;\n if (cached?.revision === revision) return cached.snapshot;\n const snapshot = {\n scrollTop: stateRef.current.scrollTop,\n viewportRows: metricsRef.current.viewportRows,\n followBottom: stateRef.current.followBottom,\n };\n viewportSnapshotRef.current = { revision, snapshot };\n return snapshot;\n },\n anchorRowsAbove: (endRow, deltaRows) => {\n // Following the tail pins the view to the bottom anyway, and a row that reaches into the\n // view changed what the reader is looking at, so the view stays where it is.\n const state = stateRef.current;\n if (state.followBottom || deltaRows === 0 || endRow > state.scrollTop) return;\n // Not clamped: the content grows in the same commit, and the next measure reconciles.\n const next = { ...state, scrollTop: Math.max(0, state.scrollTop + deltaRows) };\n anchoredRowsRef.current += deltaRows;\n stateRef.current = next;\n setRenderedScrollTop(next.scrollTop);\n publishViewport(next);\n },\n }),\n [publishViewport],\n );\n\n /**\n * Asks the history loader for older rows, recording the window in which they count as arriving.\n * The rows it mounts go above the view, so the growth they bring is not new output below and\n * the measurements that see it must not claim otherwise. Returns whether a page was loaded.\n */\n const requestHistory = useCallback((request: TranscriptHistoryRequest) => {\n if (!historyLoaderRef.current?.(request)) return false;\n historyPrependUntilRef.current = performance.now() + HISTORY_PREPEND_WINDOW_MS[request];\n return true;\n }, []);\n\n const applyScrollState = useCallback(\n (next: TranscriptScrollState) => {\n const previous = stateRef.current;\n stateRef.current = next;\n if (previous.scrollTop !== next.scrollTop) markTranscriptScrollActivity();\n\n if (\n previous.scrollTop !== next.scrollTop &&\n previous.followBottom === next.followBottom &&\n viewportRef.current\n ) {\n const position = getAbsolutePosition(viewportRef.current);\n const viewportHeight = Math.max(1, Math.floor(measureElement(viewportRef.current).height));\n if (position) {\n setTranscriptScrollHint({\n top: position.y + 1,\n bottom: position.y + viewportHeight,\n delta: next.scrollTop - previous.scrollTop,\n });\n }\n }\n\n setRenderedScrollTop((current) => (current === next.scrollTop ? current : next.scrollTop));\n setFollowBottom((current) => (current === next.followBottom ? current : next.followBottom));\n if (next.followBottom) {\n // Following the tail: whatever was on its way above is moot, and the tail is output.\n setHasNewOutput(false);\n }\n publishViewport(next);\n },\n [publishViewport],\n );\n\n onToggleToolRef.current = onToggleTool;\n onNotifyRef.current = onNotify;\n onRedrawViewportRef.current = onRedrawViewport;\n\n const repaintSelection = useCallback(() => {\n const selection = selectionRef.current;\n if (!selection) return;\n paintSelection(\n (data) => stdout.write(data),\n getFrameLines(),\n selection,\n stdout.columns ?? width ?? 80,\n getLastCursorPosition(),\n );\n }, [stdout, width]);\n\n const cancelScheduledSelectionRepaint = useCallback(() => {\n if (repaintImmediateRef.current === null) return;\n clearImmediate(repaintImmediateRef.current);\n repaintImmediateRef.current = null;\n }, []);\n\n const scheduleSelectionRepaint = useCallback(() => {\n if (!selectionRef.current || repaintImmediateRef.current !== null) return;\n repaintImmediateRef.current = setImmediate(() => {\n repaintImmediateRef.current = null;\n repaintSelection();\n });\n }, [repaintSelection]);\n\n const clearSelection = useCallback(() => {\n cancelScheduledSelectionRepaint();\n const selection = selectionRef.current;\n if (!selection) return;\n selectionRef.current = null;\n restoreSelection(\n (data) => stdout.write(data),\n getFrameLines(),\n selection,\n getLastCursorPosition(),\n );\n }, [cancelScheduledSelectionRepaint, stdout]);\n\n const replaceSelection = useCallback(\n (selection: SelectionRange) => {\n const current = selectionRef.current;\n if (current && selectionRangesEqual(current, selection)) return;\n clearSelection();\n selectionRef.current = selection;\n repaintSelection();\n },\n [clearSelection, repaintSelection],\n );\n\n const cancelWheelScroll = useCallback(() => {\n pendingWheelRowsRef.current = 0;\n wheelMotionRef.current = createWheelMotion();\n if (wheelImmediateRef.current !== null) {\n clearImmediate(wheelImmediateRef.current);\n wheelImmediateRef.current = null;\n }\n if (wheelTimerRef.current !== null) {\n clearTimeout(wheelTimerRef.current);\n wheelTimerRef.current = null;\n }\n }, []);\n\n // One animation frame of wheel motion. Reports only move the target (`pendingWheelRowsRef`);\n // this is the one place a wheel scroll is committed, so a burst of reports costs one commit per\n // frame and the frame gets Ink's render slot.\n const stepWheelScroll = useCallback(() => {\n wheelImmediateRef.current = null;\n wheelTimerRef.current = null;\n const rows = wheelEaseStep(pendingWheelRowsRef.current);\n // Less than a row left: keep the remainder for the next report.\n if (rows === 0) return;\n\n pendingWheelRowsRef.current -= rows;\n const previous = stateRef.current;\n const next = scrollTranscriptBy(previous, metricsRef.current, rows);\n applyScrollState(next);\n\n if (next.scrollTop === previous.scrollTop) {\n pendingWheelRowsRef.current = 0;\n return;\n }\n if (\n rows < 0 &&\n next.scrollTop === 0 &&\n pendingWheelRowsRef.current < 0 &&\n requestHistory('page')\n ) {\n pendingWheelRowsRef.current = 0;\n return;\n }\n if (wheelEaseStep(pendingWheelRowsRef.current) !== 0) {\n wheelTimerRef.current = setTimeout(stepWheelScroll, WHEEL_FRAME_MS);\n }\n }, [applyScrollState, requestHistory]);\n\n const scheduleWheelScroll = useCallback(\n (direction: -1 | 1) => {\n const { rows, motion } = wheelRows(wheelMotionRef.current, direction, performance.now());\n wheelMotionRef.current = motion;\n // A report against the motion drops what is left of it instead of fighting it.\n if (Math.sign(pendingWheelRowsRef.current) === -direction) pendingWheelRowsRef.current = 0;\n pendingWheelRowsRef.current += rows;\n if (wheelImmediateRef.current !== null || wheelTimerRef.current !== null) return;\n // Idle: the first frame goes out at once, so a lone notch draws without waiting on a timer.\n wheelImmediateRef.current = setImmediate(stepWheelScroll);\n },\n [stepWheelScroll],\n );\n\n const measureTranscript = useCallback(() => {\n const viewportRows = viewportRef.current\n ? Math.max(1, Math.floor(measureElement(viewportRef.current).height))\n : Math.max(1, Math.floor(height ?? 1));\n const contentRows = contentRef.current\n ? Math.max(0, Math.floor(measureElement(contentRef.current).height))\n : 0;\n const previousMetrics = metricsRef.current;\n const nextMetrics = { contentRows, viewportRows };\n\n // Rows the view was anchored past grew above it, as history was measured on the way up; they\n // are not new output below.\n const grownRows = contentRows - previousContentRowsRef.current - anchoredRowsRef.current;\n anchoredRowsRef.current = 0;\n if (grownRows > 0 && performance.now() < historyPrependUntilRef.current) {\n // A page the loader took on request, still within its window: whatever grew here arrived\n // above the view. The window is not consumed, so the measurements that settle the page are\n // all covered; past it the growth is read as output below like any other.\n } else if (\n grownRows > 0 &&\n !stateRef.current.followBottom &&\n previousContentRowsRef.current > 0\n ) {\n setHasNewOutput(true);\n }\n previousContentRowsRef.current = contentRows;\n\n if (\n previousMetrics.contentRows !== contentRows ||\n previousMetrics.viewportRows !== viewportRows\n ) {\n metricsRef.current = nextMetrics;\n applyScrollState(reconcileTranscriptScroll(stateRef.current, nextMetrics));\n }\n }, [applyScrollState, height]);\n\n const cancelScheduledLayoutMeasure = useCallback(() => {\n if (layoutMeasureImmediateRef.current !== null) {\n clearImmediate(layoutMeasureImmediateRef.current);\n layoutMeasureImmediateRef.current = null;\n }\n }, []);\n\n const scheduleLayoutMeasure = useCallback(() => {\n if (layoutMeasureImmediateRef.current !== null) return;\n layoutMeasureImmediateRef.current = setImmediate(() => {\n layoutMeasureImmediateRef.current = null;\n measureTranscript();\n });\n }, [measureTranscript]);\n\n const scrollByHalfPage = useCallback(\n (direction: 'up' | 'down') => {\n const metrics = metricsRef.current;\n if (direction === 'up' && stateRef.current.scrollTop === 0 && requestHistory('page')) return;\n cancelWheelScroll();\n const rows = getTranscriptHalfPageRows(metrics.viewportRows);\n applyScrollState(\n scrollTranscriptBy(stateRef.current, metrics, direction === 'up' ? -rows : rows),\n );\n },\n [applyScrollState, cancelWheelScroll, requestHistory],\n );\n\n const layoutDependency = layoutRevision === undefined ? children : layoutRevision;\n useLayoutEffect(() => {\n cancelScheduledLayoutMeasure();\n measureTranscript();\n }, [cancelScheduledLayoutMeasure, height, layoutDependency, measureTranscript, width]);\n\n useEffect(\n () => () => {\n cancelScheduledLayoutMeasure();\n },\n [cancelScheduledLayoutMeasure],\n );\n\n useLayoutEffect(() => {\n if (previousFollowRequestRef.current === followRequestKey) return;\n previousFollowRequestRef.current = followRequestKey;\n cancelWheelScroll();\n clearSelection();\n dragRef.current = null;\n applyScrollState(scrollTranscriptToEnd(metricsRef.current));\n }, [applyScrollState, cancelWheelScroll, clearSelection, followRequestKey]);\n\n // A chord the composer had no draft to edit. It arrives as a request rather\n // than as a keypress, because by the time every handler has run there is no\n // telling which of the two the key was meant for.\n useLayoutEffect(() => {\n if (!isActive || !scrollRequest) return;\n if (previousScrollRequestRef.current === scrollRequest.key) return;\n previousScrollRequestRef.current = scrollRequest.key;\n scrollByHalfPage(scrollRequest.direction);\n }, [isActive, scrollByHalfPage, scrollRequest]);\n\n useEffect(() => {\n if (!isActive) return;\n\n const viewportRowSpan = (): { top: number; bottom: number } | null => {\n if (!viewportRef.current) return null;\n const position = getAbsolutePosition(viewportRef.current);\n if (!position) return null;\n const rows = Math.max(1, Math.floor(measureElement(viewportRef.current).height));\n return { top: position.y + 1, bottom: position.y + rows };\n };\n\n const cancelDrag = () => {\n clearSelection();\n dragRef.current = null;\n };\n\n const toggleToolAt = (x: number, y: number) => {\n const toggleTool = onToggleToolRef.current;\n if (!toggleTool) return;\n\n const cellX = x - 1;\n const cellY = y - 1;\n for (const registration of toolRowsRef.current.values()) {\n if (!registration.expandable || !registration.element.current) continue;\n const rect = measureElement(registration.element.current);\n const position = getAbsolutePosition(registration.element.current);\n if (\n position &&\n cellX >= position.x &&\n cellX < position.x + rect.width &&\n cellY >= position.y &&\n cellY < position.y + rect.height\n ) {\n toggleTool(registration.id, registration.expanded);\n break;\n }\n }\n };\n\n const finishDragSelection = (range: SelectionRange) => {\n const frameLines = getFrameLines();\n if (frameLines.length === 0) {\n clearSelection();\n onRedrawViewportRef.current?.();\n return;\n }\n const text = extractSelectedText(frameLines, range);\n if (!text) return;\n void writeClipboard(text).then((outcome) => {\n onNotifyRef.current?.(\n outcome === 'clipboard'\n ? 'Copied selection to clipboard.'\n : outcome === 'terminal'\n ? 'Sent selection to the terminal clipboard.'\n : 'Selection copy was unavailable.',\n );\n });\n };\n\n const handleMouseInput = (input: string) => {\n const events = parseSgrMouseEvents(input);\n if (events.length === 0) return;\n\n for (const event of events) {\n if (event.type === 'wheel') {\n if (dragRef.current || selectionRef.current) cancelDrag();\n const direction = event.button === 'wheel-up' ? -1 : 1;\n if (direction < 0 && stateRef.current.scrollTop === 0 && requestHistory('page')) {\n continue;\n }\n scheduleWheelScroll(direction);\n continue;\n }\n\n if (event.shift) {\n if (event.type === 'press') cancelDrag();\n continue;\n }\n if (event.button !== 'left') continue;\n\n if (event.type === 'press') {\n clearSelection();\n dragRef.current = null;\n const span = viewportRowSpan();\n if (!span || event.y < span.top || event.y > span.bottom) continue;\n dragRef.current = {\n anchor: { x: event.x, y: event.y },\n focus: { x: event.x, y: event.y },\n dragged: false,\n };\n continue;\n }\n\n const drag = dragRef.current;\n if (!drag) continue;\n\n if (event.type === 'move') {\n if (event.x !== drag.anchor.x || event.y !== drag.anchor.y) drag.dragged = true;\n if (!drag.dragged) continue;\n const span = viewportRowSpan();\n const focusY = span ? Math.min(Math.max(event.y, span.top), span.bottom) : event.y;\n drag.focus = { x: event.x, y: focusY };\n const range = normalizeSelectionRange(drag.anchor, drag.focus);\n replaceSelection(range);\n continue;\n }\n\n if (event.type !== 'release') continue;\n dragRef.current = null;\n const moved = drag.dragged || event.x !== drag.anchor.x || event.y !== drag.anchor.y;\n const span = viewportRowSpan();\n const focusY = span ? Math.min(Math.max(event.y, span.top), span.bottom) : event.y;\n drag.focus = { x: event.x, y: focusY };\n if (!moved) {\n toggleToolAt(event.x, event.y);\n continue;\n }\n const range = normalizeSelectionRange(drag.anchor, drag.focus);\n replaceSelection(range);\n finishDragSelection(range);\n }\n };\n\n const unsubscribeFrameUpdates = subscribeToFrameUpdates(scheduleSelectionRepaint);\n if (internal_eventEmitter) {\n internal_eventEmitter.on('input', handleMouseInput);\n }\n return () => {\n unsubscribeFrameUpdates();\n internal_eventEmitter?.removeListener('input', handleMouseInput);\n cancelWheelScroll();\n if (dragRef.current || selectionRef.current) cancelDrag();\n };\n }, [\n cancelWheelScroll,\n clearSelection,\n internal_eventEmitter,\n isActive,\n replaceSelection,\n requestHistory,\n scheduleSelectionRepaint,\n scheduleWheelScroll,\n ]);\n\n useEffect(() => {\n const handleResize = () => {\n clearSelection();\n dragRef.current = null;\n // Rows rewrap at the new width, so a glide measured in the old rows would land elsewhere.\n cancelWheelScroll();\n };\n stdout.on('resize', handleResize);\n return () => {\n stdout.off('resize', handleResize);\n };\n }, [cancelWheelScroll, clearSelection, stdout]);\n\n useInput(\n (input, key) => {\n const inputWithoutMouse = stripSgrMouseSequences(input);\n if (inputWithoutMouse !== input && inputWithoutMouse.length === 0) return;\n if (key.eventType === 'release') return;\n clearSelection();\n dragRef.current = null;\n const metrics = metricsRef.current;\n let next: TranscriptScrollState | undefined;\n\n if (key.pageUp) {\n if (stateRef.current.scrollTop === 0 && requestHistory('page')) return;\n next = scrollTranscriptBy(\n stateRef.current,\n metrics,\n -getTranscriptPageRows(metrics.viewportRows),\n );\n } else if (key.pageDown) {\n next = scrollTranscriptBy(\n stateRef.current,\n metrics,\n getTranscriptPageRows(metrics.viewportRows),\n );\n } else if (key.ctrl && key.home) {\n requestHistory('all');\n next = scrollTranscriptToStart();\n } else if (key.ctrl && key.end) {\n next = scrollTranscriptToEnd(metrics);\n } else if (pagerChordsAvailable && halfPageScrollDirection(input, key)) {\n // The pager chords reach this handler only when no editor is taking\n // keys — a permission prompt, a sheet of choices. There is then no draft\n // to edit, so a half-page scroll is the only thing the key can mean. With\n // an editor live they arrive as `scrollRequest` instead, because by the\n // time this handler runs the editor has already spent them.\n scrollByHalfPage(halfPageScrollDirection(input, key)!);\n return;\n }\n\n if (next) {\n cancelWheelScroll();\n applyScrollState(next);\n }\n },\n { isActive },\n );\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={height === undefined ? 1 : 0}\n flexShrink={1}\n minHeight={1}\n height={height}\n width={width}\n >\n <Box flexShrink={0} height={1} justifyContent=\"flex-end\">\n {!followBottom ? (\n <Text color={theme.subtle} dimColor>\n ↑ browsing history{hasNewOutput ? ' · new output below' : ''}\n </Text>\n ) : null}\n </Box>\n <Box ref={viewportRef} flexGrow={1} flexShrink={1} minHeight={1} overflowY=\"hidden\">\n <Box\n ref={contentRef}\n flexDirection=\"column\"\n flexShrink={0}\n position=\"absolute\"\n width={width}\n marginTop={-renderedScrollTop}\n >\n <TranscriptContent\n interactionRegistry={interactionRegistry}\n historyRegistry={historyRegistry}\n viewportStore={viewportStore}\n onLayoutChange={scheduleLayoutMeasure}\n >\n {children}\n </TranscriptContent>\n </Box>\n </Box>\n </Box>\n );\n}\n","export interface TranscriptMetrics {\n contentRows: number;\n viewportRows: number;\n}\n\nexport interface TranscriptScrollState {\n scrollTop: number;\n followBottom: boolean;\n}\n\nexport function createTranscriptScrollState(): TranscriptScrollState {\n return { scrollTop: 0, followBottom: true };\n}\n\nexport function getMaxScrollTop(metrics: TranscriptMetrics): number {\n const contentRows = Math.max(0, Math.floor(metrics.contentRows));\n const viewportRows = Math.max(1, Math.floor(metrics.viewportRows));\n return Math.max(0, contentRows - viewportRows);\n}\n\nexport function reconcileTranscriptScroll(\n state: TranscriptScrollState,\n metrics: TranscriptMetrics,\n): TranscriptScrollState {\n const maxScrollTop = getMaxScrollTop(metrics);\n const scrollTop = state.followBottom\n ? maxScrollTop\n : Math.max(0, Math.min(Math.floor(state.scrollTop), maxScrollTop));\n\n return scrollTop === state.scrollTop ? state : { ...state, scrollTop };\n}\n\nexport function scrollTranscriptBy(\n state: TranscriptScrollState,\n metrics: TranscriptMetrics,\n rows: number,\n): TranscriptScrollState {\n const maxScrollTop = getMaxScrollTop(metrics);\n const scrollTop = Math.max(0, Math.min(state.scrollTop + Math.trunc(rows), maxScrollTop));\n const followBottom = rows > 0 && scrollTop === maxScrollTop;\n\n if (scrollTop === state.scrollTop && followBottom === state.followBottom) return state;\n return { scrollTop, followBottom };\n}\n\nexport function scrollTranscriptToStart(): TranscriptScrollState {\n return { scrollTop: 0, followBottom: false };\n}\n\nexport function scrollTranscriptToEnd(metrics: TranscriptMetrics): TranscriptScrollState {\n return { scrollTop: getMaxScrollTop(metrics), followBottom: true };\n}\n\nexport function getTranscriptPageRows(viewportRows: number): number {\n return Math.max(1, Math.floor(viewportRows) - 2);\n}\n\nexport function getTranscriptHalfPageRows(viewportRows: number): number {\n return Math.max(1, Math.floor(viewportRows / 2));\n}\n\n/** Rows one wheel notch moves on its own: a notch after a pause, or the first of a run. */\nexport const WHEEL_NOTCH_ROWS = 3;\n/** A notch this long after the one before starts a new run at `WHEEL_NOTCH_ROWS`. */\nconst WHEEL_RUN_GAP_MS = 100;\n/** What a long, fast run of notches approaches per notch. */\nconst WHEEL_RUN_ROWS = 27;\n/** How much of the remaining climb to `WHEEL_RUN_ROWS` each further notch leaves. */\nconst WHEEL_RUN_RAMP = 0.8;\n/**\n * The fastest the wheel may move the transcript. Reports closer together than a notch can be\n * turned — a trackpad, a free-spinning wheel — each move only their share of it.\n */\nconst WHEEL_MAX_ROWS_PER_SECOND = 900;\n/** Share of the distance still to go that each animation frame covers. */\nconst WHEEL_EASE = 0.75;\n\n/** What the wheel remembers between reports: which way the run goes and how long it is. */\nexport interface WheelMotion {\n direction: -1 | 0 | 1;\n lastAt: number;\n run: number;\n}\n\nexport function createWheelMotion(): WheelMotion {\n return { direction: 0, lastAt: Number.NEGATIVE_INFINITY, run: 0 };\n}\n\n/**\n * Rows one wheel report moves the transcript, and the motion it leaves behind.\n *\n * Fitted to what Claude Code does with the same reports: a notch on its own moves three rows, and\n * notches turned in a run move further each time, so a quick spin covers a long transcript instead\n * of crawling through it three rows at a time. Measured there: a second notch within 100 ms moves\n * seven to nine rows, and a run at 60 ms climbs 3, 7, 12, 14, 16, 17, 20. Reports that arrive faster\n * than a notch can be turned share `WHEEL_MAX_ROWS_PER_SECOND` between them instead. The result can\n * be fractional; the caller keeps the remainder for the next report.\n */\nexport function wheelRows(\n motion: WheelMotion,\n direction: -1 | 1,\n now: number,\n): { rows: number; motion: WheelMotion } {\n const gap = now - motion.lastAt;\n if (direction !== motion.direction || !(gap < WHEEL_RUN_GAP_MS)) {\n return { rows: direction * WHEEL_NOTCH_ROWS, motion: { direction, lastAt: now, run: 0 } };\n }\n const run = motion.run + 1;\n const climb = (WHEEL_RUN_ROWS - WHEEL_NOTCH_ROWS) * (1 - WHEEL_RUN_RAMP ** run);\n const ceiling = (WHEEL_MAX_ROWS_PER_SECOND * Math.max(0, gap)) / 1000;\n const rows = Math.max(1, Math.min(WHEEL_NOTCH_ROWS + climb, ceiling));\n return { rows: direction * rows, motion: { direction, lastAt: now, run } };\n}\n\n/**\n * Rows the wheel animation moves this frame: three quarters of what is left, rounded up, so a lone\n * notch lands in one frame and a long run glides in over two or three, the way Claude Code draws\n * it. Always whole rows and never past the target; zero once less than a row is left.\n */\nexport function wheelEaseStep(remainingRows: number): number {\n const distance = Math.abs(remainingRows);\n if (distance < 1) return 0;\n return (\n Math.sign(remainingRows) * Math.min(Math.floor(distance), Math.ceil(distance * WHEEL_EASE))\n );\n}\n\n/**\n * Which way a readline chord scrolls the transcript, or `null` for a key that is\n * not one. Ctrl+U scrolls back half a page, Ctrl+D forward — the pager pair of\n * every terminal.\n *\n * The composer owns these keys while it accepts input and reports them here only\n * when it had no draft to edit, so the caller is the one place that knows which\n * of the two it is looking at.\n */\nexport function halfPageScrollDirection(\n input: string,\n key: { ctrl?: boolean },\n): 'up' | 'down' | null {\n if (!key.ctrl) return null;\n const chord = input.toLowerCase();\n if (chord === 'u') return 'up';\n if (chord === 'd') return 'down';\n return null;\n}\n\n/**\n * Whether the transcript's own Ctrl+U / Ctrl+D branch may scroll, or has to\n * leave the keys to whoever has them.\n *\n * The transcript may act only when *nothing* on screen is taking these keys.\n * An editor that has one spends the chord itself: the composer's Ctrl+U kills\n * the text before the cursor, and a sheet editor's kills its own field. When an\n * editor is live and has nothing to edit it reports the chord as a scroll\n * request instead, because by the time the transcript's handler runs the editor\n * has already spent the key and a draft that Ctrl+U itself emptied looks\n * exactly like one that was empty all along.\n *\n * So: true only when the composer is *not* accepting input and no sheet editor\n * holds the focus. Reading this as \"the composer is free\" instead of \"no editor\n * is taking the keys\" is the inversion that let a draft-clearing Ctrl+U scroll\n * the transcript as well, which is why the whole rule is this one function and\n * the four cases it has are tabulated in `transcript-scroll.test.ts`.\n */\nexport function pagerChordsAvailable(editors: {\n /** Whether the composer is accepting keys at all. */\n composerAcceptsInput: boolean;\n /** Whether a sheet's own text editor currently holds the focus. */\n sheetEditorFocused: boolean;\n}): boolean {\n return !editors.composerAcceptsInput && !editors.sheetEditorFocused;\n}\n","import { spawn } from 'node:child_process';\n\n/** OSC 52 clipboard-write sequence understood by modern terminals. */\nexport function buildOsc52Sequence(text: string): string {\n return `\\x1b]52;c;${Buffer.from(text, 'utf8').toString('base64')}\\x1b\\\\`;\n}\n\nexport interface ClipboardWriterDeps {\n platform?: NodeJS.Platform;\n stdout?: { write(data: string): unknown };\n spawn?: typeof spawn;\n}\n\nexport type ClipboardOutcome = 'clipboard' | 'terminal' | 'failed';\n\nconst CLIPBOARD_COMMAND_TIMEOUT_MS = 3_000;\n\nfunction pipeTextToCommand(\n spawnFn: typeof spawn,\n command: string,\n args: readonly string[],\n text: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n let child;\n try {\n child = spawnFn(command, [...args], {\n stdio: ['pipe', 'ignore', 'ignore'],\n windowsHide: true,\n });\n } catch {\n resolve(false);\n return;\n }\n\n let settled = false;\n const settle = (success: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(success);\n };\n const timer = setTimeout(() => {\n child.kill();\n settle(false);\n }, CLIPBOARD_COMMAND_TIMEOUT_MS);\n child.once('error', () => settle(false));\n child.once('close', (code) => settle(code === 0));\n child.stdin.once('error', () => {});\n child.stdin.end(text);\n });\n}\n\n/** Copy through OSC 52 and a best-effort local platform clipboard command. */\nexport async function writeClipboard(\n text: string,\n deps: ClipboardWriterDeps = {},\n): Promise<ClipboardOutcome> {\n if (!text) return 'failed';\n const platform = deps.platform ?? process.platform;\n const stdout = deps.stdout ?? process.stdout;\n const spawnFn = deps.spawn ?? spawn;\n let oscWritten = false;\n\n try {\n stdout.write(buildOsc52Sequence(text));\n oscWritten = true;\n } catch {\n // OSC 52 is optional; keep trying the local clipboard command.\n }\n\n const unconfirmed: ClipboardOutcome = oscWritten ? 'terminal' : 'failed';\n try {\n if (platform === 'win32') {\n return (await pipeTextToCommand(spawnFn, 'clip.exe', [], text)) ? 'clipboard' : unconfirmed;\n }\n if (platform === 'darwin') {\n return (await pipeTextToCommand(spawnFn, 'pbcopy', [], text)) ? 'clipboard' : unconfirmed;\n }\n if (await pipeTextToCommand(spawnFn, 'wl-copy', [], text)) return 'clipboard';\n return (await pipeTextToCommand(spawnFn, 'xclip', ['-selection', 'clipboard'], text))\n ? 'clipboard'\n : unconfirmed;\n } catch {\n return unconfirmed;\n }\n}\n","import { displayWidth, stripAnsi } from './components/word-wrap.js';\n\n/** 1-based terminal cell coordinates as reported by SGR mouse events. */\nexport interface SelectionCell {\n x: number;\n y: number;\n}\n\nexport interface SelectionRange {\n start: SelectionCell;\n end: SelectionCell;\n}\n\nexport interface SelectionRowSegment {\n row: number;\n startColumn: number;\n endColumn: number;\n}\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n\nconst normalizeCell = ({ x, y }: SelectionCell): SelectionCell => ({\n x: Math.max(1, Math.floor(x)),\n y: Math.max(1, Math.floor(y)),\n});\n\nconst compareCells = (left: SelectionCell, right: SelectionCell): number =>\n left.y === right.y ? left.x - right.x : left.y - right.y;\n\n/** Normalize anchor/focus into ordered, inclusive terminal-cell endpoints. */\nexport function normalizeSelectionRange(\n anchor: SelectionCell,\n focus: SelectionCell,\n): SelectionRange {\n const normalizedAnchor = normalizeCell(anchor);\n const normalizedFocus = normalizeCell(focus);\n return compareCells(normalizedAnchor, normalizedFocus) <= 0\n ? { start: normalizedAnchor, end: normalizedFocus }\n : { start: normalizedFocus, end: normalizedAnchor };\n}\n\n/** Return the selected inclusive columns for one rendered row. */\nexport function getSelectionRowSegment(\n range: SelectionRange,\n row: number,\n lineWidth: number,\n): SelectionRowSegment | null {\n const normalizedRow = Math.max(1, Math.floor(row));\n const normalizedWidth = Math.max(0, Math.floor(lineWidth));\n if (normalizedWidth === 0 || normalizedRow < range.start.y || normalizedRow > range.end.y) {\n return null;\n }\n\n const startColumn = normalizedRow === range.start.y ? range.start.x : 1;\n const requestedEnd = normalizedRow === range.end.y ? range.end.x : normalizedWidth;\n const endColumn = Math.min(normalizedWidth, requestedEnd);\n if (startColumn > normalizedWidth || endColumn < startColumn) return null;\n return { row: normalizedRow, startColumn, endColumn };\n}\n\n/** Slice plain text by an inclusive terminal-column range without splitting wide glyphs. */\nexport function sliceDisplayColumns(text: string, startColumn: number, endColumn: number): string {\n const plain = stripAnsi(text);\n const start = Math.max(1, Math.floor(startColumn));\n const end = Math.max(0, Math.floor(endColumn));\n if (!plain || end < start) return '';\n\n let column = 1;\n let selected = '';\n for (const { segment } of graphemeSegmenter.segment(plain)) {\n const width = displayWidth(segment);\n if (width === 0) {\n if (selected) selected += segment;\n continue;\n }\n\n const segmentEnd = column + width - 1;\n if (segmentEnd >= start && column <= end) selected += segment;\n column = segmentEnd + 1;\n if (column > end) break;\n }\n return selected;\n}\n\n/** Extract selected visible cells, removing terminal styling and layout padding. */\nexport function extractSelectedText(frameLines: readonly string[], range: SelectionRange): string {\n if (frameLines.length === 0) return '';\n const top = Math.max(1, range.start.y);\n const bottom = Math.min(frameLines.length, range.end.y);\n if (bottom < top) return '';\n\n const lines: string[] = [];\n for (let row = top; row <= bottom; row++) {\n const plain = stripAnsi(frameLines[row - 1] ?? '');\n const segment = getSelectionRowSegment(range, row, displayWidth(plain));\n lines.push(\n segment ? sliceDisplayColumns(plain, segment.startColumn, segment.endColumn).trimEnd() : '',\n );\n }\n while (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();\n return lines.join('\\n');\n}\n","import { displayWidth, stripAnsi } from './components/word-wrap.js';\nimport type { FrameCursorPosition } from './frame-buffer.js';\nimport { getSelectionRowSegment, type SelectionRange } from './text-selection.js';\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\nconst cursorTo = (row: number, column = 1): string =>\n `\\x1b[${Math.max(1, Math.floor(row))};${Math.max(1, Math.floor(column))}H`;\n\nexport interface SelectionHighlightSpan {\n startColumn: number;\n text: string;\n}\n\nfunction restoreCursorSequence(cursor: FrameCursorPosition | null, frameRows: number): string {\n if (cursor) {\n return `\\x1b[${cursor.y + 1};${cursor.x + 1}H\\x1b[?25h`;\n }\n return frameRows > 0 ? cursorTo(frameRows) + '\\x1b[?25l' : '';\n}\n\n/** Resolve the exact cells to repaint for one selected frame row. */\nexport function getSelectionHighlightSpan(\n frameLine: string,\n range: SelectionRange,\n row: number,\n columns: number,\n): SelectionHighlightSpan | null {\n const limit = Math.max(1, Math.floor(columns));\n const requested = getSelectionRowSegment(range, row, limit);\n if (!requested) return null;\n\n const plain = stripAnsi(frameLine);\n let startColumn = requested.startColumn;\n let endColumn = requested.endColumn;\n let column = 1;\n let text = '';\n\n for (const { segment: grapheme } of graphemeSegmenter.segment(plain)) {\n const width = displayWidth(grapheme);\n if (width === 0) {\n if (text) text += grapheme;\n continue;\n }\n\n const graphemeEnd = column + width - 1;\n if (graphemeEnd >= requested.startColumn && column <= requested.endColumn) {\n if (!text) startColumn = Math.min(startColumn, column);\n endColumn = Math.max(endColumn, graphemeEnd);\n text += grapheme;\n }\n column = graphemeEnd + 1;\n if (column > requested.endColumn && text) break;\n }\n\n const padding = Math.max(0, endColumn - startColumn + 1 - displayWidth(text));\n return { startColumn, text: text + ' '.repeat(padding) };\n}\n\n/** Paint a character-level selection and return the cursor to Ink's anchor. */\nexport function paintSelection(\n write: (data: string) => unknown,\n frameLines: readonly string[],\n range: SelectionRange,\n columns: number,\n cursor: FrameCursorPosition | null,\n): void {\n const top = Math.max(1, range.start.y);\n const bottom = Math.min(frameLines.length, range.end.y);\n let output = '';\n for (let row = top; row <= bottom; row++) {\n const highlighted = getSelectionHighlightSpan(frameLines[row - 1] ?? '', range, row, columns);\n if (highlighted !== null) {\n output += cursorTo(row, highlighted.startColumn) + '\\x1b[7m' + highlighted.text + '\\x1b[0m';\n }\n }\n if (output) write(output + restoreCursorSequence(cursor, frameLines.length));\n}\n\n/** Restore the frame rows under a selection and return the cursor to Ink's anchor. */\nexport function restoreSelection(\n write: (data: string) => unknown,\n frameLines: readonly string[],\n range: SelectionRange,\n cursor: FrameCursorPosition | null,\n): void {\n const top = Math.max(1, range.start.y);\n const bottom = Math.min(frameLines.length, range.end.y);\n let output = '';\n for (let row = top; row <= bottom; row++) {\n output += cursorTo(row) + (frameLines[row - 1] ?? '') + '\\x1b[K';\n }\n if (output) write(output + restoreCursorSequence(cursor, frameLines.length));\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useCallback, useMemo, useRef, useEffect, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useReportLayout } from '../hooks/useReportLayout.js';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN, PANEL_CHROME, frameGrid } from '../layout.js';\nimport { useDensityMetrics } from '../density.js';\nimport { getPrimaryArg } from '../../tools/primary-arg.js';\nimport { canonicalToolName } from '../../tools/aliases.js';\nimport { isFileMutatingTool } from '../../tools/tool-capabilities.js';\nimport {\n isPreviewableMutation,\n previewMutation,\n type MutationPreview,\n type MutationPreviewFile,\n} from '../../tools/mutation-preview.js';\nimport { permissionRuleForToolCall, permissionRuleLadder } from '../../permissions.js';\nimport type { PermissionDecision, PermissionResult, ToolCall } from '../../types/tools.js';\nimport { createUiDebugLogger } from '../../debug-log.js';\nimport { useDebugMount } from '../debug.js';\nimport { DiffBlock, expandTabs } from './Diff.js';\nimport { ChoiceList, DecisionSheet, type Choice } from './chrome.js';\nimport { displayWidth, hardWrapLine, truncateDisplay } from './word-wrap.js';\n\nconst uiLog = createUiDebugLogger('tui:permbtn');\nconst PERMISSION_PATTERN_DISPLAY_MAX_LENGTH = 40;\n/** What the \"Always allow\" row offers when the call has nothing to scope a rule to. */\nconst NO_RULE_TO_SAVE = 'this call only — no rule to save';\n\n/**\n * Rows the payload (a wrapped command, or a diff) may take before the card\n * marks a cut. The prompt sits under the transcript, so a bound is still\n * wanted — but it is a bound on rows the terminal can show, never a fixed\n * character count, and every cut is marked and can be opened with `D`.\n */\nconst COLLAPSED_COMMAND_ROWS = 6;\nconst COLLAPSED_DIFF_ROWS = 8;\n/** Rows the sheet keeps free for its rule, title, stacked choices, hints and the composer. */\nconst RESERVED_ROWS = 16;\n/** A file shown with fewer diff rows than this says nothing; hide it instead. */\nconst MIN_DIFF_ROWS_PER_FILE = 4;\n\ninterface PermissionButtonsProps {\n toolCall: ToolCall;\n /**\n * Receives the decision. `always` carries the rule the user actually chose,\n * which is not always the exact command: the scope ladder lets them widen it.\n */\n onResolve: (decision: PermissionResult | PermissionDecision) => void;\n /** When true, disables all animations/colors for screen readers. */\n screenReader?: boolean;\n /** Terminal columns; the payload wraps to the card's interior. */\n terminalWidth?: number;\n /** Terminal rows; bounds how much of the payload `D` may open. */\n terminalRows?: number;\n /**\n * Workspace the pending call would mutate. When set, file mutations show\n * the diff they would produce before anything is written; without it the\n * card can only name the path.\n */\n workspaceRoot?: string;\n /**\n * Called when the card's height may have changed: when it opens, when the\n * diff preview arrives, when `D` opens or closes a cut payload, and when it\n * closes. The transcript above measures its viewport only on its own layout\n * changes, and the preview lands after the card's first frame, so without\n * this the grown card covered the transcript's last rows: the model's reason\n * for the call and the call's own row.\n */\n onLayoutChange?: () => void;\n}\n\ninterface ButtonDef {\n label: string;\n value: PermissionResult;\n key: string;\n}\n\nconst BUTTONS: ButtonDef[] = [\n { label: 'Run once', value: 'allow', key: 'r' },\n { label: 'Skip', value: 'deny', key: 's' },\n { label: 'Always allow', value: 'always', key: 'a' },\n];\n\nexport function toolRiskLevel(toolCall: ToolCall): 'safe' | 'network' | 'write' | 'shell' {\n const name = canonicalToolName(toolCall.name);\n const lower = toolCall.name.toLowerCase();\n if (name === 'Bash' || name === 'KillShell' || lower.includes('bash') || lower === 'shell')\n return 'shell';\n if (isFileMutatingTool(name)) return 'write';\n if (name === 'WebFetch' || name === 'WebSearch') return 'network';\n return 'safe';\n}\n\nfunction riskHint(level: ReturnType<typeof toolRiskLevel>): string | null {\n if (level === 'shell') return 'This will run a shell command on your machine.';\n if (level === 'write') return 'This will modify files on disk.';\n if (level === 'network') return 'This will send a request to an external service.';\n return null;\n}\n\nexport function permissionPatternForTool(\n toolCall: ToolCall,\n primaryArg: string,\n): string | undefined {\n void primaryArg;\n return permissionRuleForToolCall(toolCall);\n}\n\n/** Caption for a scope the user has widened past the exact command. */\nexport function scopeCaption(ladder: readonly string[], index: number): string | null {\n if (index === 0) return null;\n const remaining = ladder.length - 1 - index;\n return remaining > 0\n ? `Covers every command matching this pattern. A again widens further.`\n : `Covers every command matching this pattern. A again returns to the exact one.`;\n}\n\nexport function permissionPatternForDisplay(pattern: string): string {\n if (pattern.length <= PERMISSION_PATTERN_DISPLAY_MAX_LENGTH) return pattern;\n return `${pattern.slice(0, PERMISSION_PATTERN_DISPLAY_MAX_LENGTH - 3)}...`;\n}\n\n/**\n * The text the user is consenting to. For a shell command that is the whole\n * command, every line of it: {@link getPrimaryArg} keeps only the first line\n * because it serves rule matching, and a prompt built on it showed\n * `cd x &&` for a script whose second line was the `rm`.\n */\nexport function permissionPayloadText(toolCall: ToolCall): string {\n const command = toolCall.arguments?.command;\n if (typeof command === 'string') return command;\n return getPrimaryArg(toolCall.arguments ?? {});\n}\n\nexport interface WrappedPayload {\n /** Rows to draw, already cut to the budget. */\n rows: string[];\n /** Rows the budget hid; `0` when the payload fits. */\n hiddenRows: number;\n}\n\n/**\n * Wrap a payload to `width` columns and cut it to `maxRows` rows.\n *\n * A hard wrap, not a word wrap: a command's spacing is part of the command,\n * and a display that collapses `\"a b\"` to `\"a b\"` shows something the shell\n * will not run. Tabs are expanded to the columns they will occupy, and a\n * carriage return ends a row rather than reaching the terminal, where it\n * would drag the rest of the row back over the card's border. The cut always\n * leaves room for its own marker, so a reader can tell a payload that fits\n * from one that was trimmed.\n */\nexport function wrapPayload(text: string, width: number, maxRows: number): WrappedPayload {\n const columns = Math.max(4, Math.floor(width));\n const rows = text.split(/\\r\\n|\\r|\\n/).flatMap((line) => hardWrapLine(expandTabs(line), columns));\n const budget = Math.max(1, Math.floor(maxRows));\n if (rows.length <= budget) return { rows, hiddenRows: 0 };\n // The marker takes a row of its own, so one fewer payload row survives.\n const kept = Math.max(1, budget - 1);\n return { rows: rows.slice(0, kept), hiddenRows: rows.length - kept };\n}\n\n/**\n * What `D` will do to a payload the card had to cut, as the marker words it.\n *\n * `all` is a promise the card has to be able to keep. A card is bounded by the\n * terminal it sits in, so on a short one `D` opens a bigger budget rather than\n * the whole command: the marker said `… 4 more rows · D shows all`, D cut two\n * more rows out of the same payload, and the key had not done what it said. So\n * the marker says what D will do — everything, or more of it — and a payload the\n * expanded budget cannot make any longer gets no marker and no key at all, the\n * rule the diff half already followed.\n */\nexport function payloadExpandHint(payload: {\n /** Rows the budget hid. */\n hiddenRows: number;\n expanded: boolean;\n /** Rows the payload takes with nothing cut. */\n totalRows: number;\n /** Rows the collapsed and the expanded budget each keep. */\n collapsedRows: number;\n expandedRows: number;\n}): 'none' | 'all' | 'more' {\n if (payload.expanded || payload.hiddenRows <= 0) return 'none';\n if (payload.expandedRows <= payload.collapsedRows) return 'none';\n // `all` is a promise the key has to be able to keep, so the test is the\n // inclusive one: a payload of exactly the expanded budget fits, and only a\n // payload longer than the budget is still going to be cut after `D`. One row\n // of slack here claimed `D shows all` for a command that lost a row anyway.\n return payload.expandedRows >= payload.totalRows ? 'all' : 'more';\n}\n\nfunction previewSummary(files: readonly MutationPreviewFile[]): string {\n const added = files.reduce((total, file) => total + file.stats.addedLines, 0);\n const removed = files.reduce((total, file) => total + file.stats.removedLines, 0);\n return `+${added} −${removed}`;\n}\n\nfunction diffRowCount(file: MutationPreviewFile): number {\n return file.diff.length === 0 ? 0 : file.diff.split('\\n').length;\n}\n\n/**\n * Permission prompt card.\n *\n * Navigation:\n * ↑/↓, ←/→ or Tab/Shift+Tab — move between the choices\n * Enter, or R/S — activate; A selects \"Always allow\" without activating it\n * D — open or close the rest of a cut payload (command rows, diff rows)\n * Esc — deny\n */\nexport function PermissionButtons({\n toolCall,\n onResolve,\n screenReader = false,\n terminalWidth = 80,\n terminalRows = 24,\n workspaceRoot,\n onLayoutChange,\n}: PermissionButtonsProps) {\n const theme = useTheme();\n const density = useDensityMetrics();\n // Enter reads the selection through `currentSelected()`, not from render\n // state. `A` now only arms \"Always allow\", so `A` then a quick Enter lands in\n // one React batch and an Enter handler closing over render state would still\n // see the previous index — resolving `allow` when the user asked for\n // `always`.\n const [selected, setSelected, currentSelected] = useKeyState(0);\n const resolvedToolCallIdRef = useRef<string | null>(null);\n const canonical = canonicalToolName(toolCall.name);\n const payload = permissionPayloadText(toolCall);\n const risk = toolRiskLevel(toolCall);\n const hint = riskHint(risk);\n // The rules \"Always allow\" may write, narrowest first. For a shell command\n // the exact rule matches that byte sequence and nothing else, so offering\n // only that made the button a no-op for the case it exists to serve; the user\n // steps the scope with `A` and always sees the pattern before Enter writes it.\n const ladder = useMemo(() => permissionRuleLadder(toolCall), [toolCall]);\n const ladderRef = useRef(ladder);\n ladderRef.current = ladder;\n const [scopeIndex, setScopeIndex, currentScope] = useKeyState(0);\n // No ladder means no rule to write, so the row says so rather than naming one. The\n // answer is still `always`: the loop applies it to this call and persists nothing.\n const alwaysPattern = ladder[scopeIndex] ?? ladder[0];\n const alwaysPatternDisplay = alwaysPattern\n ? permissionPatternForDisplay(alwaysPattern)\n : NO_RULE_TO_SAVE;\n const scopeHint = scopeCaption(ladder, scopeIndex);\n const [expanded, setExpanded] = useState(false);\n\n // The card is a bordered surface flush at column 0, like the composer, so\n // its border plus padding land its text on the content column.\n const frame = frameGrid(Math.max(20, Math.floor(terminalWidth)));\n const contentWidth = Math.max(8, frame.width - PANEL_CHROME);\n // Visual rows the payload may spend once `D` opens it. The card lives in\n // the fixed region under the transcript, so a payload taller than the\n // terminal pushes its own buttons off the top of the screen.\n const rowBudget = Math.max(COLLAPSED_DIFF_ROWS, Math.floor(terminalRows) - RESERVED_ROWS);\n // A change-focused diff draws a `⋮ n rows omitted` marker between every run\n // of selected rows, so in the worst case each budgeted row costs two on\n // screen; the diff budget is the row budget halved.\n const expandedDiffRows = Math.floor(rowBudget / 2);\n const collapsedDiffRows = Math.min(COLLAPSED_DIFF_ROWS, expandedDiffRows);\n\n // The header carries the payload inline only when the whole thing fits on\n // that row; otherwise the payload takes rows of its own under it, wrapped\n // to the card. A fixed 72-character slice used to hide the tail of every\n // longer command with nothing to mark the cut.\n // The rule above says \"Permission required\"; the first row is the tool.\n const header = canonical;\n const inlineRoom = contentWidth - displayWidth(header) - 1;\n const payloadInline =\n payload.length > 0 && !payload.includes('\\n') && displayWidth(payload) <= inlineRoom;\n const wrappedPayload = useMemo(\n () =>\n payloadInline || payload.length === 0\n ? { rows: [], hiddenRows: 0 }\n : // Two columns narrower: the rows sit in a code block padded one column each side.\n wrapPayload(payload, contentWidth - 2, expanded ? rowBudget : COLLAPSED_COMMAND_ROWS),\n [contentWidth, expanded, payload, payloadInline, rowBudget],\n );\n // The command with nothing cut, which is what decides whether `D` can show all\n // of it. A budget is rows *including* the marker's own, so the payload keeps\n // one fewer than the number below.\n const totalCommandRows = useMemo(\n () =>\n payloadInline || payload.length === 0\n ? 0\n : wrapPayload(payload, contentWidth - 2, Number.POSITIVE_INFINITY).rows.length,\n [contentWidth, payload, payloadInline],\n );\n const commandExpandHint = payloadExpandHint({\n hiddenRows: wrappedPayload.hiddenRows,\n expanded,\n totalRows: totalCommandRows,\n collapsedRows: Math.max(1, COLLAPSED_COMMAND_ROWS - 1),\n // The expanded budget, not one less. `wrapPayload` keeps every row when the\n // payload is no longer than the budget it is given, so a payload of exactly\n // `rowBudget` rows is one `D` already shows whole; reserving the marker's row\n // on both sides made a payload that fit claim to be cut.\n expandedRows: Math.max(1, rowBudget),\n });\n\n // File mutations show the diff they would make, computed from the pending\n // arguments against the file on disk. Nothing is written until the user\n // answers; the tool recomputes against the file it finds when it runs.\n const previewable = Boolean(workspaceRoot) && isPreviewableMutation(toolCall);\n const [preview, setPreview] = useState<MutationPreview | null>(null);\n const previewLoading = previewable && preview === null;\n // A managed agent's record is replaced wholesale on every agent event, so\n // the request object can change identity while the request does not; key\n // the preview on the call id and read the call through a ref.\n const toolCallRef = useRef(toolCall);\n toolCallRef.current = toolCall;\n useEffect(() => {\n setPreview(null);\n if (!previewable || !workspaceRoot) return;\n const controller = new AbortController();\n previewMutation(toolCallRef.current, workspaceRoot, controller.signal)\n .then((result) => {\n if (controller.signal.aborted || !result) return;\n setPreview(result);\n uiLog.event('preview', {\n tool: canonical,\n files: result.files.length,\n error: result.error ?? '',\n });\n })\n // Only the abort from the cleanup below rejects; nothing to show for it.\n .catch(() => undefined);\n return () => controller.abort();\n }, [canonical, previewable, toolCall.id, workspaceRoot]);\n\n useReportLayout([expanded ? 'expanded' : 'collapsed', preview ? 'preview' : 'none'].join(':'), {\n onLayoutChange,\n });\n\n // Row counts are constant for the life of a preview; the card re-renders on\n // every keypress and must not re-split a large diff each time.\n const diffRows = useMemo(\n () => new Map((preview?.files ?? []).map((file) => [file.filePath, diffRowCount(file)])),\n [preview],\n );\n const files = preview && !preview.error ? preview.files : [];\n const diffBudget = expanded ? expandedDiffRows : collapsedDiffRows;\n // The budget bounds the card, not each file: a patch across many files\n // shows as many as the budget can give a meaningful diff, and counts the rest.\n const filesShown =\n files.length === 0\n ? 0\n : Math.max(1, Math.min(files.length, Math.floor(diffBudget / MIN_DIFF_ROWS_PER_FILE)));\n const shownFiles = files.slice(0, filesShown);\n const hiddenFiles = files.slice(filesShown);\n const shownWithDiff = Math.max(\n 1,\n shownFiles.filter((file) => (diffRows.get(file.filePath) ?? 0) > 0).length,\n );\n const diffRowsPerFile = Math.max(MIN_DIFF_ROWS_PER_FILE, Math.floor(diffBudget / shownWithDiff));\n // `D` is offered only while it would show something more, or has. On a\n // terminal too short for a larger budget the diff already shows what it can.\n const diffHasMore =\n hiddenFiles.length > 0 ||\n shownFiles.some((file) => (diffRows.get(file.filePath) ?? 0) > diffRowsPerFile);\n const canExpand =\n expanded ||\n (files.length === 0 && commandExpandHint !== 'none') ||\n (diffHasMore && expandedDiffRows > collapsedDiffRows);\n\n // Track previous selection for old→new logging without stale closure issues.\n const prevSelectedRef = useRef(0);\n\n useDebugMount(uiLog, {\n tool: canonical,\n risk,\n primaryArg: payload ? payload.slice(0, 40) : null,\n });\n\n const moveSelection = useCallback((next: (current: number) => number) => {\n setSelected(next(currentSelected()));\n }, []);\n\n const handleResolve = useCallback(\n (value: PermissionResult) => {\n if (resolvedToolCallIdRef.current === toolCall.id) {\n uiLog.event('resolve:double-fire-prevented', {\n tool: canonical,\n attempt: value,\n });\n return;\n }\n resolvedToolCallIdRef.current = toolCall.id;\n const rule = value === 'always' ? ladderRef.current[currentScope()] : undefined;\n uiLog.event('resolve', {\n tool: canonical,\n result: value,\n selected,\n rule: rule ?? '',\n });\n onResolve(rule ? { result: value, rule } : value);\n },\n [canonical, onResolve, selected, toolCall.id],\n );\n\n useInput(\n (input, key) => {\n if (key.leftArrow || key.upArrow) {\n const prev = selected;\n moveSelection((s) => (s - 1 + BUTTONS.length) % BUTTONS.length);\n uiLog.event('input:Left', { tool: canonical, selected: `${prev}->?` });\n return;\n }\n if (key.rightArrow || key.downArrow) {\n const prev = selected;\n moveSelection((s) => (s + 1) % BUTTONS.length);\n uiLog.event('input:Right', { tool: canonical, selected: `${prev}->?` });\n return;\n }\n if (key.tab) {\n const prev = selected;\n moveSelection((s) =>\n key.shift ? (s - 1 + BUTTONS.length) % BUTTONS.length : (s + 1) % BUTTONS.length,\n );\n uiLog.event('input:Tab', { tool: canonical, shift: key.shift, selected: `${prev}->?` });\n return;\n }\n // Enter only. Space used to activate too, which put `always` two ordinary\n // keystrokes away — `a` then a space, the opening of any sentence\n // starting with \"a \" — and the card advertises Enter, never space.\n if (key.return) {\n const armed = currentSelected();\n uiLog.event('input:Enter', {\n tool: canonical,\n selected: armed,\n rule: BUTTONS[armed].value === 'always' ? ladder[currentScope()] : undefined,\n });\n handleResolve(BUTTONS[armed].value);\n return;\n }\n if (key.escape) {\n uiLog.event('input:Escape', { tool: canonical, action: 'deny' });\n handleResolve('deny');\n return;\n }\n if (input === 'r' || input === 'R') {\n uiLog.event('input:shortcut', { tool: canonical, key: 'R', action: 'allow' });\n handleResolve('allow');\n return;\n }\n if (input === 's' || input === 'S') {\n uiLog.event('input:shortcut', { tool: canonical, key: 'S', action: 'deny' });\n handleResolve('deny');\n return;\n }\n // `D` only changes what the card shows, never what it resolves, so a\n // stray press costs nothing. It does nothing at all while there is\n // nothing to open, so the card never claims to be expanded when it is not.\n if (input === 'd' || input === 'D') {\n if (!canExpand) return;\n setExpanded((current) => {\n uiLog.event('input:shortcut', {\n tool: canonical,\n key: 'D',\n action: current ? 'collapse-detail' : 'expand-detail',\n });\n return !current;\n });\n return;\n }\n // `A` deliberately has no single-key shortcut. `always` is the one choice\n // here that writes a permission rule to disk, and rules can only be\n // removed by hand, so it must not be reachable by one stray letter — a\n // lone `a` used to grant a persistent shell allow with no visible trace.\n // Select it and press Enter.\n if (input === 'a' || input === 'A') {\n const alwaysIndex = BUTTONS.findIndex((button) => button.value === 'always');\n // First `A` arms the button; each `A` after that widens the scope and\n // wraps back to the exact rule, so the key can explore every option\n // without ever committing one.\n if (currentSelected() === alwaysIndex && ladder.length > 1) {\n setScopeIndex((currentScope() + 1) % ladder.length);\n uiLog.event('input:shortcut', {\n tool: canonical,\n key: 'A',\n action: 'step-scope',\n rule: ladder[currentScope()],\n });\n return;\n }\n uiLog.event('input:shortcut', { tool: canonical, key: 'A', action: 'select-always' });\n moveSelection(() => alwaysIndex);\n return;\n }\n },\n { isActive: true },\n );\n\n // Log the resolved selection change with old→new after render.\n useEffect(() => {\n if (prevSelectedRef.current !== selected) {\n uiLog.event('selection:change', {\n tool: canonical,\n from: prevSelectedRef.current,\n to: selected,\n });\n prevSelectedRef.current = selected;\n }\n }, [selected, canonical]);\n\n if (screenReader) {\n return (\n <Box marginLeft={CONTENT_COLUMN} flexDirection=\"column\">\n <Text>Permission required for: {canonical}</Text>\n <Text>\n {risk === 'shell' ? 'Command' : 'Primary argument'}: {payload || '(none)'}\n </Text>\n {hint ? <Text>Warning: {hint}</Text> : null}\n {previewLoading ? <Text>Computing the change preview.</Text> : null}\n {preview?.error ? <Text>Cannot preview this change: {preview.error}</Text> : null}\n {files.map((file) => (\n <Text key={file.filePath}>\n Will {file.kind} {file.filePath}: {file.stats.addedLines} lines added,{' '}\n {file.stats.removedLines} lines removed.\n </Text>\n ))}\n <Text>Press: [R] Run once, [S] Skip, [Esc] Deny.</Text>\n <Text>Always allow: press [A] to select it, then Enter to confirm.</Text>\n <Text>Rule to be saved: {alwaysPattern ?? '(none — this call only)'}</Text>\n {ladder.length > 1 ? <Text>Press [A] again to widen or narrow that rule.</Text> : null}\n </Box>\n );\n }\n\n const helpKeys = [\n '↑↓ select',\n 'Enter confirm',\n ladder.length > 1 ? 'A scope' : null,\n canExpand ? (expanded ? 'D less' : 'D more') : null,\n 'R run',\n 'S skip',\n 'Esc deny',\n ].filter((entry): entry is string => entry !== null);\n\n // One tone per sheet, carried by the rule's label and nothing else: rose for a\n // shell command, amber for a write or a request that leaves the machine.\n const tone =\n risk === 'shell'\n ? theme.error\n : risk === 'write' || risk === 'network'\n ? theme.warning\n : theme.text;\n const title = permissionTitle(canonical, risk, files);\n const totals = files.reduce(\n (sum, file) => ({\n added: sum.added + file.stats.addedLines,\n removed: sum.removed + file.stats.removedLines,\n }),\n { added: 0, removed: 0 },\n );\n const counts = files.length > 0 ? ` +${totals.added} −${totals.removed}` : '';\n // A file's path is said once. It goes on the title row when it fits there;\n // a longer one takes the rows below, whole, instead of showing cut short on\n // the title row and again in full underneath.\n const singlePath = files.length === 1 ? files[0]!.filePath : undefined;\n const titleRoom = Math.max(8, contentWidth - displayWidth(title) - displayWidth(counts) - 1);\n const pathOnTitle = singlePath !== undefined && displayWidth(singlePath) <= titleRoom;\n const titleTarget =\n singlePath !== undefined\n ? pathOnTitle\n ? singlePath\n : ''\n : files.length > 1\n ? `${files.length} files`\n : payloadInline\n ? payload\n : '';\n // With a diff on the sheet the payload is the path again, or the patch the\n // diff already draws, so only a path too long for the title row keeps rows.\n const payloadRows =\n files.length === 0\n ? wrappedPayload.rows\n : singlePath !== undefined && !pathOnTitle\n ? wrapPayload(singlePath, contentWidth - 2, COLLAPSED_COMMAND_ROWS).rows\n : [];\n const choices: Choice[] = BUTTONS.map((button) =>\n button.value === 'allow'\n ? { label: risk === 'shell' ? 'Run once' : 'Allow once', detail: 'this call only' }\n : button.value === 'deny'\n ? { label: 'Skip', detail: 'the agent is told no' }\n : { label: 'Always allow', detail: alwaysPatternDisplay },\n );\n\n return (\n <DecisionSheet\n label=\"Permission required\"\n tone={tone}\n meta={riskNote(risk)}\n width={frame.width}\n marginX={frame.marginX}\n >\n <Box>\n <Text bold color={theme.text}>\n {title}\n </Text>\n {titleTarget ? (\n <Text color={theme.text}> {truncateDisplay(titleTarget, titleRoom)}</Text>\n ) : null}\n {counts ? (\n <Text>\n <Text color={theme.success}> +{totals.added}</Text>\n <Text color={theme.error}> −{totals.removed}</Text>\n </Text>\n ) : null}\n </Box>\n {payloadRows.length > 0 ? (\n // A command too long for the title row reads as code, not as prose.\n <Box flexDirection=\"column\" backgroundColor={theme.mdCodeBackground} paddingX={1}>\n {payloadRows.map((row, index) => (\n <Text key={index} color={theme.mdCodeText}>\n {row}\n </Text>\n ))}\n </Box>\n ) : null}\n {files.length === 0 && wrappedPayload.hiddenRows > 0 ? (\n <Text color={theme.inactive}>\n {truncateDisplay(\n // The cut is marked either way; the key is named only while it is\n // offered, and named for what it will do.\n `… ${wrappedPayload.hiddenRows} more ${wrappedPayload.hiddenRows === 1 ? 'row' : 'rows'}${commandExpandHint === 'none' ? '' : ` · D shows ${commandExpandHint === 'all' ? 'all' : 'more'}`}`,\n contentWidth,\n )}\n </Text>\n ) : null}\n {previewLoading ? <Text color={theme.inactive}>Computing diff…</Text> : null}\n {preview?.error ? (\n <Text color={theme.warning}>\n {truncateDisplay(`Cannot preview: ${preview.error}`, contentWidth)}\n </Text>\n ) : null}\n {files.length > 0 ? (\n <Box flexDirection=\"column\">\n {shownFiles.map((file) => {\n const noChange = file.diff.length === 0 ? ' no textual change' : '';\n const fileCounts = ` +${file.stats.addedLines} −${file.stats.removedLines}`;\n const pathRoom =\n contentWidth - displayWidth(`${file.kind} `) - displayWidth(fileCounts + noChange);\n return (\n <Box key={file.filePath} flexDirection=\"column\">\n {/* One file is already named by the title; several are named here. */}\n {files.length > 1 ? (\n <Box>\n <Text color={theme.inactive}>{file.kind} </Text>\n <Text color={theme.text}>\n {truncateDisplay(file.filePath, Math.max(8, pathRoom))}\n </Text>\n <Text color={theme.success}> +{file.stats.addedLines}</Text>\n <Text color={theme.error}> −{file.stats.removedLines}</Text>\n {noChange ? <Text color={theme.inactive}>{noChange}</Text> : null}\n </Box>\n ) : noChange ? (\n <Text color={theme.inactive}>{noChange.trim()}</Text>\n ) : null}\n {file.diff.length > 0 ? (\n <DiffBlock\n output={file.diff}\n filePath={file.filePath}\n collapsed\n maxRows={diffRowsPerFile}\n expandHint={canExpand && !expanded ? 'D shows more' : ''}\n terminalWidth={contentWidth}\n />\n ) : null}\n </Box>\n );\n })}\n {hiddenFiles.length > 0 ? (\n <Text color={theme.inactive}>\n {truncateDisplay(\n `… ${hiddenFiles.length} more ${hiddenFiles.length === 1 ? 'file' : 'files'} · ${previewSummary(hiddenFiles)}${canExpand && !expanded ? ' · D shows more' : ''}`,\n contentWidth,\n )}\n </Text>\n ) : null}\n </Box>\n ) : null}\n <Box flexDirection=\"column\" marginTop={1}>\n <ChoiceList choices={choices} selected={selected} width={contentWidth} numbered={false} />\n </Box>\n {scopeHint ? <Text color={theme.warning}>{scopeHint}</Text> : null}\n {density.showOptionalHelp ? (\n <Box marginTop={1}>\n <Text color={theme.inactive}>{helpKeys.join(' · ')}</Text>\n </Box>\n ) : null}\n </DecisionSheet>\n );\n}\n\n/** The action a permission asks for, as the verb that opens its title row. */\nfunction permissionTitle(\n canonical: string,\n risk: ReturnType<typeof toolRiskLevel>,\n files: readonly MutationPreviewFile[],\n): string {\n if (files.length === 1) {\n const kind = files[0]!.kind;\n return kind === 'create' ? 'Create' : kind === 'delete' ? 'Delete' : 'Edit';\n }\n if (files.length > 1) return 'Edit';\n if (risk === 'shell') return 'Run';\n if (canonical === 'WebFetch') return 'Fetch';\n if (canonical === 'WebSearch') return 'Search';\n return canonical;\n}\n\n/** The short note a permission's rule carries about what kind of access it is. */\nfunction riskNote(risk: ReturnType<typeof toolRiskLevel>): string {\n if (risk === 'shell') return 'shell command';\n if (risk === 'write') return 'file change';\n if (risk === 'network') return 'network request';\n return '';\n}\n","import { useEffect, useLayoutEffect, useRef } from 'react';\n\nexport interface LayoutReport {\n /** The footer's height may have changed: the app re-measures the transcript. */\n onLayoutChange?: () => void;\n /**\n * Whether this surface is holding a text editor's focus right now.\n *\n * A surface with an editor open has taken the readline chords: Ctrl+U clears\n * the editor and Ctrl+D deletes under the cursor, so the transcript must not\n * also read them as half-page scrolls. Reported on the same schedule as\n * {@link LayoutReport.onLayoutChange}, because opening and closing the editor\n * is the same event as the sheet growing and shrinking by a row.\n */\n editorFocused?: boolean;\n /** Called when {@link LayoutReport.editorFocused} changes. */\n onEditorFocusChange?: (focused: boolean) => void;\n}\n\n/**\n * Tell the app when a surface's height has changed, so the transcript above it\n * re-measures its viewport instead of being covered by the rows the surface just\n * grew into.\n *\n * `shape` identifies the surface's *rendered size*, not its content. A sheet\n * that grows by a row reports; a sheet that redraws the same number of rows does\n * not. That distinction is the whole contract: a report costs a layout\n * measurement, and a report per keystroke would make typing in a field re-measure\n * the transcript on every character. So the caller joins the facts that change\n * the row count — which question, whether an editor is open, a notice, the\n * width the body wraps to — rather than passing a value.\n *\n * Reports once on mount, once per change of shape, and once on unmount, which is\n * what lets the transcript take the rows back. Not once per render, and not\n * twice per change: a `useLayoutEffect` that reported from its own cleanup\n * fired the callback again as the next shape's effect ran, so every change cost\n * two layout measurements and the reports no longer lined up with the changes.\n */\nexport function useReportLayout(shape: string, report: LayoutReport = {}): void {\n const { onLayoutChange, editorFocused = false, onEditorFocusChange } = report;\n // Read at unmount through a ref so a caller that passes a new closure each\n // render does not turn the unmount report into one report per render.\n const onLayoutChangeRef = useRef(onLayoutChange);\n onLayoutChangeRef.current = onLayoutChange;\n const onEditorFocusChangeRef = useRef(onEditorFocusChange);\n onEditorFocusChangeRef.current = onEditorFocusChange;\n\n // `null` rather than the initial shape: the first report is a real one, and a\n // ref seeded with the shape would swallow it.\n const reportedShapeRef = useRef<string | null>(null);\n useLayoutEffect(() => {\n if (reportedShapeRef.current === shape) return;\n reportedShapeRef.current = shape;\n onLayoutChange?.();\n }, [shape, onLayoutChange]);\n\n // Empty deps on purpose: this is the unmount report, and it must not re-run\n // when the callback identity changes.\n useEffect(\n () => () => {\n onLayoutChangeRef.current?.();\n },\n [],\n );\n\n useLayoutEffect(() => {\n onEditorFocusChange?.(editorFocused);\n }, [editorFocused, onEditorFocusChange]);\n}\n","import { canonicalToolName } from './aliases.js';\nimport { renderDiffWithStatsAsync, type DiffStats } from './diff.js';\nimport { applySingleEdit } from './file.js';\nimport { readTextSnapshot, type TextSnapshot } from './mutation.js';\nimport { applyHunks, parsePatch, type PatchOperation } from './patch.js';\nimport { resolveWorkspacePath } from './path-utils.js';\nimport { toolResultErrorMessage } from './result.js';\nimport type { ToolCall, ToolResult } from '../types/tools.js';\n\n/**\n * Pre-execution preview of what a file-mutating tool call would change.\n *\n * The permission prompt is where the user consents to a mutation, so it has to\n * show the mutation, not just the path it lands on. The tools themselves only\n * produce a diff *after* writing; this module computes the same diff from the\n * pending call's arguments against the file as it is on disk right now, with\n * the same matching semantics the tool will use, and never writes anything.\n *\n * Arguments are read by their canonical names only. The agent loop runs\n * `registry.normalizeCall` on every call before hooks, permission evaluation\n * and the prompt see it (`src/agent/loop.ts`), so the pending call already\n * carries `filePath`, not `file_path`; a host that hands this module a raw\n * provider call must normalize it through the registry first.\n *\n * What is previewed is the textual change. The tools also gate on file\n * provenance (`file_not_observed`, `stale_file_observation`), which lives in\n * the tool context and is not consulted here.\n */\n\nexport interface MutationPreviewFile {\n /** Workspace-relative path the tool will write, delete, or create. */\n filePath: string;\n kind: 'create' | 'update' | 'delete';\n /** Unified diff hunks, empty when the change is textually a no-op. */\n diff: string;\n stats: DiffStats;\n}\n\nexport interface MutationPreview {\n files: MutationPreviewFile[];\n /**\n * Why no preview could be computed. This is the matching or path failure\n * the tool itself would report, surfaced at consent time so the user can\n * decline a call that is going to fail anyway.\n */\n error?: string;\n}\n\n/** Per-side line ceiling; the diff is trimmed to the changed span but still bounded here. */\nconst MAX_PREVIEW_LINES = 20_000;\nconst TOO_LARGE = 'File is too large to preview';\n\nconst PREVIEWABLE_TOOLS = new Set(['Write', 'Edit', 'MultiEdit', 'ApplyPatch']);\n\n/** Whether {@link previewMutation} can say anything about this call. */\nexport function isPreviewableMutation(toolCall: ToolCall): boolean {\n return PREVIEWABLE_TOOLS.has(canonicalToolName(toolCall.name));\n}\n\n/** A failure the tool would report; becomes {@link MutationPreview.error}. */\nclass PreviewError extends Error {}\n\nfunction fail(message: string): never {\n throw new PreviewError(message);\n}\n\nfunction failWith(result: ToolResult): never {\n return fail(toolResultErrorMessage(result) ?? result.content);\n}\n\nfunction stringArg(args: Record<string, unknown>, key: string): string | undefined {\n const value = args[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction lineCount(text: string): number {\n let count = 1;\n for (let index = text.indexOf('\\n'); index !== -1; index = text.indexOf('\\n', index + 1)) count++;\n return count;\n}\n\ninterface ResolvedTarget {\n filePath: string;\n canonicalPath: string;\n relativePath: string;\n}\n\nfunction resolveTarget(workspaceRoot: string, inputPath: string | undefined): ResolvedTarget {\n if (!inputPath) return fail('No file path given');\n return (\n resolveWorkspacePath(workspaceRoot, inputPath) ?? fail(`Path outside workspace: ${inputPath}`)\n );\n}\n\nasync function snapshotOf(target: ResolvedTarget, allowMissing: boolean): Promise<TextSnapshot> {\n let snapshot: TextSnapshot;\n try {\n snapshot = await readTextSnapshot(target.filePath, allowMissing);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n return code === 'ENOENT'\n ? fail(`File not found: ${target.relativePath}`)\n : fail(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (snapshot.binary) fail(`Binary file is unsupported: ${target.relativePath}`);\n // Bail before any matching work: every pass below is O(file).\n if (lineCount(snapshot.text) > MAX_PREVIEW_LINES) fail(TOO_LARGE);\n return snapshot;\n}\n\nasync function diffFile(\n target: ResolvedTarget,\n kind: MutationPreviewFile['kind'],\n before: string,\n after: string,\n signal?: AbortSignal,\n): Promise<MutationPreviewFile> {\n if (lineCount(after) > MAX_PREVIEW_LINES) fail(TOO_LARGE);\n const { diff, stats } = await renderDiffWithStatsAsync(before, after, 3, signal);\n return { filePath: target.relativePath, kind, diff, stats };\n}\n\nasync function previewWrite(\n args: Record<string, unknown>,\n workspaceRoot: string,\n signal?: AbortSignal,\n): Promise<MutationPreview> {\n const target = resolveTarget(workspaceRoot, stringArg(args, 'filePath'));\n const content = stringArg(args, 'content') ?? fail('No content given');\n const before = await snapshotOf(target, true);\n const after = before.exists ? content.replace(/\\r\\n/g, '\\n') : content;\n const kind = before.exists ? 'update' : 'create';\n return { files: [await diffFile(target, kind, before.text, after, signal)] };\n}\n\ninterface EditSpec {\n oldString: string;\n newString: string;\n replaceAll: boolean;\n}\n\nfunction editSpec(source: Record<string, unknown>): EditSpec {\n const oldString = stringArg(source, 'oldString');\n const newString = stringArg(source, 'newString');\n if (oldString === undefined || newString === undefined) fail('No edit given');\n return {\n oldString: oldString.replace(/\\r\\n/g, '\\n'),\n newString: newString.replace(/\\r\\n/g, '\\n'),\n replaceAll: source.replaceAll === true,\n };\n}\n\nfunction multiEditSpecs(args: Record<string, unknown>): EditSpec[] {\n const edits = args.edits;\n if (!Array.isArray(edits) || edits.length === 0) fail('No edits provided');\n return edits.map((item) =>\n item && typeof item === 'object' && !Array.isArray(item)\n ? editSpec(item as Record<string, unknown>)\n : fail('Malformed edit entry'),\n );\n}\n\nasync function previewEdits(\n args: Record<string, unknown>,\n edits: EditSpec[],\n atomic: boolean,\n workspaceRoot: string,\n signal?: AbortSignal,\n): Promise<MutationPreview> {\n const target = resolveTarget(workspaceRoot, stringArg(args, 'filePath'));\n const snapshot = await snapshotOf(target, false);\n if (snapshot.mixedLineEndings)\n fail(\n `Mixed line endings are unsupported for ${atomic ? 'MultiEdit' : 'Edit'}: ${target.relativePath}`,\n );\n let content = snapshot.text;\n for (let index = 0; index < edits.length; index++) {\n const edit = edits[index];\n const application = await applySingleEdit(\n content,\n edit.oldString,\n edit.newString,\n edit.replaceAll,\n signal,\n atomic ? `Edit ${index + 1}: ` : '',\n atomic ? ' (no changes applied — MultiEdit is atomic)' : '',\n );\n if (!application.ok) failWith(application.failure);\n content = application.content;\n }\n return { files: [await diffFile(target, 'update', snapshot.text, content, signal)] };\n}\n\nasync function previewPatchOperation(\n operation: PatchOperation,\n target: ResolvedTarget,\n signal?: AbortSignal,\n): Promise<MutationPreviewFile> {\n const before = await snapshotOf(target, operation.kind === 'add');\n if (operation.kind === 'add') {\n if (before.exists) fail(`File already exists: ${target.relativePath}`);\n const after = operation.lines.join('\\n') + (operation.lines.length > 0 ? '\\n' : '');\n return diffFile(target, 'create', '', after, signal);\n }\n if (!before.exists) fail(`File not found: ${target.relativePath}`);\n if (operation.kind === 'delete') return diffFile(target, 'delete', before.text, '', signal);\n if (before.mixedLineEndings)\n fail(`Mixed line endings are unsupported for patch updates: ${target.relativePath}`);\n const applied = applyHunks(before.text, operation.hunks);\n if (applied.mismatch)\n fail(\n `${target.relativePath}: ${toolResultErrorMessage(applied.mismatch) ?? applied.mismatch.content}`,\n );\n return diffFile(target, 'update', before.text, applied.text, signal);\n}\n\nasync function previewPatch(\n args: Record<string, unknown>,\n workspaceRoot: string,\n signal?: AbortSignal,\n): Promise<MutationPreview> {\n const parsed = parsePatch(args.patch);\n if ('version' in parsed) failWith(parsed);\n const targets = parsed.operations.map((operation) =>\n resolveTarget(workspaceRoot, operation.path),\n );\n // The tool refuses a patch that names one file twice, before touching anything.\n const seen = new Set<string>();\n for (const target of targets) {\n const key =\n process.platform === 'win32' ? target.canonicalPath.toLowerCase() : target.canonicalPath;\n if (seen.has(key)) fail('A patch may contain only one operation per file');\n seen.add(key);\n }\n const files: MutationPreviewFile[] = [];\n for (let index = 0; index < parsed.operations.length; index++) {\n files.push(await previewPatchOperation(parsed.operations[index], targets[index], signal));\n }\n return { files };\n}\n\n/**\n * Compute the diff a pending mutation would produce, or `null` when the tool\n * is not one this module understands. Never throws for a bad call: every\n * failure the tool would report comes back as {@link MutationPreview.error}.\n * Only an aborted `signal` rejects.\n */\nexport async function previewMutation(\n toolCall: ToolCall,\n workspaceRoot: string,\n signal?: AbortSignal,\n): Promise<MutationPreview | null> {\n const args = toolCall.arguments ?? {};\n try {\n switch (canonicalToolName(toolCall.name)) {\n case 'Write':\n return await previewWrite(args, workspaceRoot, signal);\n case 'Edit':\n return await previewEdits(args, [editSpec(args)], false, workspaceRoot, signal);\n case 'MultiEdit':\n return await previewEdits(args, multiEditSpecs(args), true, workspaceRoot, signal);\n case 'ApplyPatch':\n return await previewPatch(args, workspaceRoot, signal);\n default:\n return null;\n }\n } catch (error) {\n if (signal?.aborted) throw error;\n if (error instanceof PreviewError) return { files: [], error: error.message };\n return {\n files: [],\n error: `Preview failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n","import { Box, Text } from 'ink';\nimport { useTheme } from '../theme.js';\nimport { SHEET_COLUMN_GAP, sheetContentWidth } from '../layout.js';\nimport { builtinHelpGroups, type HelpEntry, type HelpGroup } from '../help-catalog.js';\nimport { SoftPanel } from './chrome.js';\nimport { displayWidth, padDisplay, truncateDisplay } from './word-wrap.js';\n\n/**\n * Content width at which the groups flow into two columns. Below it the list\n * runs one column and grows taller than a 44-row terminal, so its head scrolled\n * away; at a 100-column terminal it now fits.\n */\nconst TWO_COLUMN_MIN = 88;\n\n/** What the name column prints: the syntax only when there is room to spare. */\nfunction entryLabel(entry: HelpEntry, showHints: boolean): { name: string; hint: string } {\n return {\n name: entry.name,\n hint: showHints && entry.argumentHint ? ` ${entry.argumentHint}` : '',\n };\n}\n\n/**\n * One name column for a whole column of groups, so descriptions line up down\n * the sheet instead of jumping with each group's longest syntax. It is capped,\n * and a longer syntax is cut, so one `/memory [status|inbox|…]` cannot push\n * every description to the far edge.\n */\nfunction nameColumnWidth(groups: readonly HelpGroup[], width: number, showHints: boolean): number {\n const widest = Math.max(\n 1,\n ...groups.flatMap((group) =>\n group.entries.map((entry) => {\n const label = entryLabel(entry, showHints);\n return displayWidth(label.name + label.hint);\n }),\n ),\n );\n return Math.min(widest, Math.max(12, Math.floor(width * 0.42)));\n}\n\nfunction GroupBlock({\n group,\n width,\n nameWidth,\n showHints,\n}: {\n group: HelpGroup;\n width: number;\n nameWidth: number;\n showHints: boolean;\n}) {\n const theme = useTheme();\n const descWidth = Math.max(8, width - nameWidth - 2);\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={theme.subtle}>\n {group.title}\n </Text>\n {group.entries.map((entry: HelpEntry) => {\n const label = entryLabel(entry, showHints);\n const shownName = truncateDisplay(label.name, nameWidth);\n const shownHint = truncateDisplay(\n label.hint,\n Math.max(0, nameWidth - displayWidth(shownName)),\n );\n return (\n <Box key={entry.name}>\n <Text color={theme.text}>{shownName}</Text>\n <Text color={theme.inactive}>\n {padDisplay(shownHint, nameWidth - displayWidth(shownName))}\n </Text>\n <Text\n color={theme.inactive}\n >{` ${truncateDisplay(entry.description, descWidth)}`}</Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n\n/**\n * /help: every built-in command, generated from the command registry and set\n * in groups, with the name in ink and its syntax and description quiet, in\n * aligned columns. Custom commands follow in their own group. From a\n * 92-column terminal the groups flow into two columns, so the list fits on\n * one screen.\n */\nexport function HelpPanel({\n width,\n customCommands = [],\n}: {\n width: number;\n customCommands?: ReadonlyArray<{ name: string; description: string; argumentHint?: string }>;\n}) {\n const groups = builtinHelpGroups();\n if (customCommands.length > 0) {\n groups.push({\n title: 'Custom',\n entries: customCommands.map((command) => ({\n name: `/${command.name}`,\n argumentHint: command.argumentHint,\n description: command.description,\n })),\n });\n }\n const count = groups.reduce((sum, group) => sum + group.entries.length, 0);\n const contentWidth = sheetContentWidth(width, 20);\n const twoColumns = contentWidth >= TWO_COLUMN_MIN;\n const columnWidth = twoColumns ? Math.floor((contentWidth - SHEET_COLUMN_GAP) / 2) : contentWidth;\n // Split so both columns hold about the same number of rows.\n const rowsOf = (group: HelpGroup) => group.entries.length + 2;\n const total = groups.reduce((sum, group) => sum + rowsOf(group), 0);\n let running = 0;\n const left: HelpGroup[] = [];\n const right: HelpGroup[] = [];\n for (const group of groups) {\n if (!twoColumns || running + rowsOf(group) / 2 <= total / 2) left.push(group);\n else right.push(group);\n running += rowsOf(group);\n }\n // Two columns leave no room for the syntax; the command menu shows it on\n // the row you land on, which is where it is needed.\n const showHints = !twoColumns;\n const column = (list: HelpGroup[]) => {\n const nameWidth = nameColumnWidth(list, columnWidth, showHints);\n return list.map((group) => (\n <GroupBlock\n key={group.title}\n group={group}\n width={columnWidth}\n nameWidth={nameWidth}\n showHints={showHints}\n />\n ));\n };\n return (\n <SoftPanel title=\"Commands\" meta={`${count} · Esc to close`} width={width}>\n <Box columnGap={SHEET_COLUMN_GAP}>\n <Box flexDirection=\"column\" width={columnWidth}>\n {column(left)}\n </Box>\n {twoColumns ? (\n <Box flexDirection=\"column\" width={columnWidth}>\n {column(right)}\n </Box>\n ) : null}\n </Box>\n </SoftPanel>\n );\n}\n","import { BUILTIN_COMMAND_DEFINITIONS } from '../commands/builtins.js';\n\n/** One command as /help lists it. */\nexport interface HelpEntry {\n /** `/clear`, with its visible aliases: `/clear, /new`. */\n name: string;\n argumentHint?: string;\n description: string;\n}\n\nexport interface HelpGroup {\n title: string;\n entries: HelpEntry[];\n}\n\n/**\n * The groups /help sets the built-in commands in, in reading order. A command\n * not named here lands in a trailing \"More\" group, so a new command still shows\n * up in /help the day it is added; the old hand-written list had fallen behind\n * the registry by five commands.\n */\nconst GROUPS: ReadonlyArray<{ title: string; names: readonly string[] }> = [\n {\n title: 'Conversation',\n names: ['clear', 'resume', 'compact', 'rewind', 'queue', 'export', 'exit'],\n },\n { title: 'Model', names: ['model', 'providers', 'effort'] },\n { title: 'Context', names: ['context', 'usage', 'cost', 'status', 'memory'] },\n { title: 'Code', names: ['diff', 'review', 'security-review', 'init'] },\n { title: 'Agents', names: ['agents', 'agent', 'tasks', 'jobs', 'task'] },\n { title: 'Setup', names: ['config', 'permissions', 'skills', 'reload-skills', 'mcp'] },\n { title: 'Book', names: ['help', 'release-notes', 'feedback'] },\n];\n\n/** The built-in commands, grouped for /help, with visible aliases folded into each name. */\nexport function builtinHelpGroups(): HelpGroup[] {\n const visible = BUILTIN_COMMAND_DEFINITIONS.filter((definition) => !definition.isHidden);\n const entryFor = (definition: (typeof visible)[number]): HelpEntry => {\n const aliases = (definition.aliases ?? [])\n .filter((alias) => !alias.isHidden)\n .map((alias) => `/${alias.name}`);\n return {\n name: [`/${definition.name}`, ...aliases].join(', '),\n argumentHint: definition.argumentHint,\n description: definition.description,\n };\n };\n const placed = new Set<string>();\n const groups: HelpGroup[] = [];\n for (const group of GROUPS) {\n const entries = group.names.flatMap((name) => {\n const definition = visible.find((candidate) => candidate.name === name);\n if (!definition) return [];\n placed.add(name);\n return [entryFor(definition)];\n });\n if (entries.length > 0) groups.push({ title: group.title, entries });\n }\n const rest = visible.filter((definition) => !placed.has(definition.name)).map(entryFor);\n if (rest.length > 0) groups.push({ title: 'More', entries: rest });\n return groups;\n}\n","import { Box, Text, useInput } from 'ink';\nimport TextInput from './TextInputField.js';\nimport { useCallback, useRef, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useReportLayout } from '../hooks/useReportLayout.js';\nimport { useTheme } from '../theme.js';\nimport type { PlanApprovalResult } from '../../types/tools.js';\nimport { createUiDebugLogger } from '../../debug-log.js';\nimport { useDebugMount } from '../debug.js';\nimport { MarkdownBlock } from './MarkdownBlock.js';\nimport { wordWrap } from './word-wrap.js';\nimport { ChoiceList, DecisionSheet, type Choice } from './chrome.js';\nimport { PANEL_CHROME, frameGrid } from '../layout.js';\nimport { PILCROW } from '../marks.js';\n\nconst uiLog = createUiDebugLogger('tui:planapproval');\n\ninterface PlanApprovalProps {\n plan: string;\n screenReader?: boolean;\n terminalWidth?: number;\n}\n\ninterface PlanApprovalActionsProps extends PlanApprovalProps {\n onResolve: (result: PlanApprovalResult) => void;\n /**\n * Called when the sheet's height may have changed: when it opens, when the\n * feedback editor opens or closes, and when its error row appears or goes. The\n * transcript above measures its viewport only on its own layout changes, so\n * the one-row error landed on the plan row above it.\n */\n onLayoutChange?: () => void;\n /**\n * Called when the feedback editor takes or gives up the focus. While it holds\n * it, Ctrl+U and Ctrl+D are the editor's kills rather than the transcript's\n * half-page scrolls.\n */\n onEditorFocusChange?: (focused: boolean) => void;\n}\n\nconst BUTTONS = [\n {\n label: 'Approve plan',\n value: 'approve' as const,\n key: 'a',\n detail: 'implement it in this conversation',\n },\n {\n label: 'Approve, fresh context',\n value: 'approve-fresh' as const,\n key: 'f',\n detail: 'implement it clean, without the planning talk',\n },\n { label: 'Adjust plan', value: 'revise' as const, key: 'e', detail: 'say what should change' },\n { label: 'Reject plan', value: 'reject' as const, key: 'r', detail: 'stay in plan mode' },\n];\n\nfunction countSteps(lines: string[]): number {\n return lines.filter((line) => /^\\d+[\\.\\)]\\s/.test(line)).length;\n}\n\nfunction normalizePlanMarkdown(lines: string[]): string {\n return lines\n .map((line) => {\n const indentedHeading = line.match(/^(\\s+)#{1,3}\\s+(.*)$/);\n return indentedHeading ? `${indentedHeading[1]}${indentedHeading[2]}` : line;\n })\n .join('\\n');\n}\n\nexport function PlanApprovalDetails({\n plan,\n screenReader = false,\n terminalWidth,\n}: PlanApprovalProps) {\n const theme = useTheme();\n const lines = plan.split('\\n');\n const stepCount = countSteps(lines);\n const normalizedPlan = normalizePlanMarkdown(lines);\n\n if (screenReader) return <Text>{plan}</Text>;\n\n // The plan is set under a rule like every decision surface, in plan mode's\n // own tone, with its step count as the rule's note.\n const width = frameGrid(Math.max(20, Math.floor(terminalWidth ?? 80))).width;\n return (\n <DecisionSheet\n label=\"Plan\"\n tone={theme.planMode}\n meta={\n stepCount > 0\n ? `${stepCount} step${stepCount === 1 ? '' : 's'} · awaiting approval`\n : 'awaiting approval'\n }\n width={width}\n >\n <MarkdownBlock content={normalizedPlan} terminalWidth={Math.max(12, width - PANEL_CHROME)} />\n </DecisionSheet>\n );\n}\n\nexport function PlanApprovalActions({\n plan,\n onResolve,\n screenReader = false,\n terminalWidth,\n onLayoutChange,\n onEditorFocusChange,\n}: PlanApprovalActionsProps) {\n const theme = useTheme();\n // `useKeyState` rather than `useState`: both of these are read back by the\n // key handler, and Ink delivers a whole stdin chunk in one React batch. With\n // plain state a batched `→`+Enter resolved the button that was armed before\n // the arrow — approving a plan the user had moved off.\n const [selected, setSelected, currentSelected] = useKeyState(0);\n const [feedbackMode, setFeedbackMode, inFeedbackMode] = useKeyState(false);\n const [feedback, setFeedback] = useState('');\n const [feedbackError, setFeedbackError] = useState<string | null>(null);\n const resolvedRef = useRef(false);\n const lines = plan.split('\\n');\n useDebugMount(uiLog, {\n planLength: plan.length,\n lineCount: lines.length,\n stepCount: countSteps(lines),\n });\n\n const resolveOnce = useCallback(\n (value: PlanApprovalResult) => {\n if (resolvedRef.current) return;\n resolvedRef.current = true;\n uiLog.event('resolve', { result: value, selected: currentSelected() });\n onResolve(value);\n },\n [onResolve, currentSelected],\n );\n\n useInput((input, key) => {\n if (inFeedbackMode()) {\n if (key.escape) {\n setFeedbackMode(false);\n setFeedbackError(null);\n }\n return;\n }\n\n if (key.leftArrow || key.upArrow || (key.shift && key.tab)) {\n setSelected((currentSelected() - 1 + BUTTONS.length) % BUTTONS.length);\n } else if (key.rightArrow || key.downArrow || key.tab) {\n setSelected((currentSelected() + 1) % BUTTONS.length);\n } else if (key.return || input === ' ') {\n const value = BUTTONS[currentSelected()].value;\n if (value === 'revise') {\n setFeedbackMode(true);\n setFeedbackError(null);\n } else {\n resolveOnce(value);\n }\n } else if (key.escape) {\n resolveOnce('reject');\n } else if (input.toLowerCase() === 'a') {\n resolveOnce('approve');\n } else if (input.toLowerCase() === 'f') {\n resolveOnce('approve-fresh');\n } else if (input.toLowerCase() === 'e') {\n setSelected(BUTTONS.findIndex((button) => button.value === 'revise'));\n setFeedbackMode(true);\n setFeedbackError(null);\n } else if (['r', 's'].includes(input.toLowerCase())) {\n resolveOnce('reject');\n }\n });\n\n // Everything that changes how many rows the sheet draws: the two sheets are\n // different shapes, the error row is one row, and the width a plan wraps to is\n // a different number of rows again.\n //\n // The plan itself is not in the shape, and cannot be: `PlanApprovalActions`\n // draws the buttons and the hint only, never the plan — `PlanApprovalDetails`\n // draws that, above. Its rows are the caller's business, not this sheet's.\n //\n // What replaces it is the feedback editor's row count. The editor takes up to\n // 2000 characters, so it wraps, and a keystroke that pushes the value onto one\n // more line grows the sheet. Reporting the count rather than the text keeps\n // that from becoming a re-measure per keystroke.\n const feedbackRows = feedbackMode\n ? wordWrap(\n feedback,\n Math.max(12, frameGrid(Math.max(20, Math.floor(terminalWidth ?? 80))).width - PANEL_CHROME),\n ).split('\\n').length\n : 0;\n const layoutShape = [\n feedbackMode ? 1 : 0,\n feedbackRows,\n feedbackError ?? '',\n screenReader ? 1 : 0,\n Math.floor(terminalWidth ?? 80),\n ].join(':');\n useReportLayout(layoutShape, {\n onLayoutChange,\n editorFocused: feedbackMode,\n onEditorFocusChange,\n });\n\n if (screenReader && !feedbackMode) {\n return (\n <Text>\n Plan approval required. Press A to approve, F to approve and implement with a fresh context,\n E to request adjustments, or R or Escape to reject.\n </Text>\n );\n }\n\n const width = frameGrid(Math.max(20, Math.floor(terminalWidth ?? 80))).width;\n const contentWidth = Math.max(12, width - PANEL_CHROME);\n\n if (feedbackMode) {\n return (\n <DecisionSheet label=\"Adjust the plan\" tone={theme.warning} width={width}>\n <Text color={theme.subtle}>Tell Book what should change before implementation starts.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.border}>{'─'.repeat(contentWidth)}</Text>\n <Box>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <TextInput\n value={feedback}\n placeholder=\"Add feedback for the revised plan\"\n onChange={(value) => {\n setFeedback(value.slice(0, 2000));\n if (feedbackError) setFeedbackError(null);\n }}\n onSubmit={(value) => {\n const normalized = value.trim();\n if (!normalized) {\n setFeedbackError('Add feedback before requesting changes.');\n return;\n }\n resolveOnce({ decision: 'revise', feedback: normalized });\n }}\n />\n </Box>\n </Box>\n {feedbackError ? <Text color={theme.error}>{feedbackError}</Text> : null}\n <Box marginTop={1}>\n <Text color={theme.inactive}>Enter send feedback · Esc return to choices</Text>\n </Box>\n </DecisionSheet>\n );\n }\n\n const choices: Choice[] = BUTTONS.map((button) => ({\n label: button.label,\n // The key first, so a narrow row truncates the explanation, never the key.\n detail: `${button.key.toUpperCase()} ${button.detail}`,\n }));\n return (\n <DecisionSheet label=\"Plan approval\" tone={theme.planMode} width={width}>\n <ChoiceList choices={choices} selected={selected} width={contentWidth} numbered={false} />\n <Box marginTop={1}>\n <Text color={theme.inactive}>\n ↑↓ select · Enter confirm · A/F/E/R shortcuts · Esc reject\n </Text>\n </Box>\n </DecisionSheet>\n );\n}\n\n/** Backward-compatible combined surface used by focused component tests. */\nexport function PlanApprovalButtons(props: PlanApprovalActionsProps) {\n return (\n <Box flexDirection=\"column\">\n <PlanApprovalDetails\n plan={props.plan}\n screenReader={props.screenReader}\n terminalWidth={props.terminalWidth}\n />\n <PlanApprovalActions {...props} />\n </Box>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport TextInput from './TextInputField.js';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useReportLayout } from '../hooks/useReportLayout.js';\nimport type { UserQuestion, UserQuestionRequest, UserQuestionResponse } from '../../types/tools.js';\nimport { useTheme } from '../theme.js';\nimport { truncateDisplay, wordWrap } from './word-wrap.js';\nimport { ChoiceList, DecisionSheet, floatingFrameMetrics, type Choice } from './chrome.js';\nimport { PILCROW } from '../marks.js';\n\ninterface AskUserQuestionWizardProps {\n request: UserQuestionRequest;\n queueLength?: number;\n terminalWidth?: number;\n onResolve: (response: UserQuestionResponse) => void;\n screenReader?: boolean;\n /**\n * Called when the sheet's height may have changed: when it opens, when the\n * question changes, when the `Other` editor opens or closes, and when a notice\n * appears or goes. The transcript above measures its viewport only on its own\n * layout changes, so a taller question covered its last rows — the question\n * the model asked and the tool row that asked it.\n */\n onLayoutChange?: () => void;\n /**\n * Called when the `Other` editor takes or gives up the focus. While it holds\n * it, Ctrl+U and Ctrl+D are the editor's kills rather than the transcript's\n * half-page scrolls.\n */\n onEditorFocusChange?: (focused: boolean) => void;\n}\n\n/**\n * Option labels chosen (single-select) or toggled (multi-select), by question\n * index. Keyed by index rather than by question text so a question the model\n * happened to call `constructor` or `__proto__` cannot read an inherited member\n * of `Object.prototype` where an array was expected.\n */\ntype Choices = Record<number, string[]>;\n\n/** The Other-row text, by question index. Kept apart from the labels: see {@link answerValues}. */\ntype CustomAnswers = Record<number, string>;\n\nfunction sourceLabel(request: UserQuestionRequest): string {\n if (request.source.kind === 'root') return 'Book';\n return request.source.agentPath.join(' / ');\n}\n\n/** The host validator compares answers this way; matching it here keeps a duplicate from leaving. */\nfunction normalizeLabel(value: string): string {\n return value.trim().toLocaleLowerCase();\n}\n\n/**\n * The value a question is answered with. Custom text lives beside the toggled\n * labels rather than among them, so toggling an option can never delete it and\n * an exact-match filter can never mistake one for the other.\n */\nfunction answerValues(\n question: UserQuestion,\n index: number,\n choices: Choices,\n custom: CustomAnswers,\n): string[] {\n const labels = choices[index] ?? [];\n const text = custom[index];\n if (question.multiSelect) return text ? [...labels, text] : labels;\n return text ? [text] : labels;\n}\n\nfunction normalizeAnswers(\n questions: UserQuestion[],\n choices: Choices,\n custom: CustomAnswers,\n): Record<string, string | string[]> | null {\n const entries: [string, string | string[]][] = [];\n for (const [index, question] of questions.entries()) {\n const values = answerValues(question, index, choices, custom);\n if (values.length === 0) return null;\n entries.push([question.question, question.multiSelect ? values : values[0]]);\n }\n // fromEntries defines own properties, so a question literally named\n // `__proto__` lands as an answer key rather than replacing the prototype.\n return Object.fromEntries(entries);\n}\n\nexport function AskUserQuestionWizard({\n request,\n queueLength = 1,\n terminalWidth = 80,\n onResolve,\n screenReader = false,\n onLayoutChange,\n onEditorFocusChange,\n}: AskUserQuestionWizardProps) {\n const theme = useTheme();\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\n const frame = floatingFrameMetrics(outerWidth);\n const contentWidth = Math.max(14, frame.width - 4);\n const compact = outerWidth < 60;\n // Everything the key handler reads back is batch-safe: Ink delivers a whole\n // stdin chunk in one React batch, so plain state would still show the value\n // from before the first key. Helpers take the question *index* and resolve it\n // against `request.questions` (props), never against `question` below, which\n // is one batch behind after a back + Enter.\n const [questionIndex, setQuestionIndex, currentQuestion] = useKeyState(0);\n const [cursor, setCursor, currentCursor] = useKeyState(0);\n const [choices, setChoices, currentChoices] = useKeyState<Choices>({});\n const [customAnswers, setCustomAnswers, currentCustom] = useKeyState<CustomAnswers>({});\n const [otherMode, setOtherMode, inOtherMode] = useKeyState(false);\n const [otherValue, setOtherValue, currentOtherValue] = useKeyState('');\n const [notice, setNotice] = useState<string | null>(null);\n const resolvedRef = useRef(false);\n const question = request.questions[questionIndex];\n const selected = choices[questionIndex] ?? [];\n const customAnswer = customAnswers[questionIndex];\n\n const resolveOnce = useCallback(\n (response: UserQuestionResponse) => {\n if (resolvedRef.current) return;\n resolvedRef.current = true;\n onResolve(response);\n },\n [onResolve],\n );\n\n const setChoice = useCallback(\n (index: number, labels: string[]) => {\n setChoices({ ...currentChoices(), [index]: labels });\n },\n [currentChoices, setChoices],\n );\n\n const setCustom = useCallback(\n (index: number, text: string | undefined) => {\n const next = { ...currentCustom() };\n if (text === undefined) delete next[index];\n else next[index] = text;\n setCustomAnswers(next);\n },\n [currentCustom, setCustomAnswers],\n );\n\n const advance = useCallback(() => {\n const index = currentQuestion();\n if (index === request.questions.length - 1) {\n const normalized = normalizeAnswers(request.questions, currentChoices(), currentCustom());\n if (!normalized) {\n setNotice('Choose at least one answer to continue.');\n return;\n }\n resolveOnce({ action: 'answer', answers: normalized });\n return;\n }\n setQuestionIndex(index + 1);\n setCursor(0);\n setNotice(null);\n }, [\n currentQuestion,\n currentChoices,\n currentCustom,\n request.questions,\n resolveOnce,\n setQuestionIndex,\n setCursor,\n ]);\n\n const chooseKnownOption = useCallback(\n (index: number, optionIndex: number) => {\n const target = request.questions[index];\n const label = target?.options[optionIndex]?.label;\n if (!label) return;\n setNotice(null);\n if (!target.multiSelect) {\n setCustom(index, undefined);\n setChoice(index, [label]);\n advance();\n return;\n }\n const labels = currentChoices()[index] ?? [];\n setChoice(\n index,\n labels.includes(label) ? labels.filter((value) => value !== label) : [...labels, label],\n );\n },\n [request.questions, currentChoices, setChoice, setCustom, advance],\n );\n\n const openOther = useCallback(\n (index: number) => {\n setOtherValue(currentCustom()[index] ?? '');\n setOtherMode(true);\n setNotice(null);\n },\n [currentCustom, setOtherValue, setOtherMode],\n );\n\n const submitOther = useCallback(\n (index: number) => {\n const target = request.questions[index];\n if (!target) return;\n const text = currentOtherValue().trim();\n if (!text) {\n setNotice('Type an answer before continuing.');\n return;\n }\n setOtherMode(false);\n setOtherValue('');\n // Text that names an option is that option. Stored as custom text it\n // would reach the host as a duplicate, and the validator then discards\n // every answer in the request.\n const key = normalizeLabel(text);\n const match = target.options.findIndex((option) => normalizeLabel(option.label) === key);\n if (match >= 0) {\n if (!target.multiSelect) {\n chooseKnownOption(index, match);\n return;\n }\n const label = target.options[match].label;\n const labels = currentChoices()[index] ?? [];\n setCustom(index, undefined);\n setChoice(index, labels.includes(label) ? labels : [...labels, label]);\n advance();\n return;\n }\n if (!target.multiSelect) setChoice(index, []);\n setCustom(index, text);\n advance();\n },\n [\n request.questions,\n currentOtherValue,\n currentChoices,\n setOtherMode,\n setOtherValue,\n setChoice,\n setCustom,\n chooseKnownOption,\n advance,\n ],\n );\n\n useInput((input, key) => {\n const index = currentQuestion();\n if (inOtherMode()) {\n // This handler is the only owner of Enter while the editor is open; the\n // TextInput below has no onSubmit. Two listeners on one keypress meant\n // the second saw the mode flag already flipped and answered the next\n // question with its first option before it was ever shown.\n if (key.return) submitOther(index);\n else if (key.escape) {\n setOtherMode(false);\n setNotice(null);\n }\n return;\n }\n\n const activeQuestion = request.questions[index];\n if (!activeQuestion) return;\n\n const activeCursor = currentCursor();\n const otherRow = activeQuestion.options.length;\n const rowCount = otherRow + 1;\n\n // A single digit, not anything Number() would coerce: a pasted line that\n // starts with \" 1\" or \"1.0\" is text, not the quick-choose the footer offers.\n if (/^[1-9]$/.test(input) && Number(input) <= otherRow) {\n setCursor(Number(input) - 1);\n chooseKnownOption(index, Number(input) - 1);\n return;\n }\n if (key.upArrow || (key.shift && key.tab)) {\n setCursor((activeCursor - 1 + rowCount) % rowCount);\n setNotice(null);\n } else if (key.downArrow || key.tab) {\n setCursor((activeCursor + 1) % rowCount);\n setNotice(null);\n } else if (input === ' ' && activeQuestion.multiSelect) {\n if (activeCursor === otherRow) {\n if (currentCustom()[index]) setCustom(index, undefined);\n else openOther(index);\n } else {\n chooseKnownOption(index, activeCursor);\n }\n } else if (key.return) {\n if (activeCursor === otherRow) {\n openOther(index);\n } else if (activeQuestion.multiSelect) {\n const values = answerValues(activeQuestion, index, currentChoices(), currentCustom());\n if (values.length === 0) setNotice('Select one or more options first.');\n else advance();\n } else {\n chooseKnownOption(index, activeCursor);\n }\n } else if (input.toLowerCase() === 'o') {\n setCursor(otherRow);\n openOther(index);\n } else if ((input.toLowerCase() === 'b' || key.leftArrow) && index > 0) {\n setQuestionIndex(index - 1);\n setCursor(0);\n setNotice(null);\n } else if (input.toLowerCase() === 'd') {\n resolveOnce({ action: 'decline' });\n } else if (key.escape) {\n resolveOnce({ action: 'cancel' });\n }\n });\n\n const selectedSet = useMemo(() => new Set(selected), [selected]);\n const fromAgent = request.source.kind !== 'root';\n const progress =\n request.questions.length > 1 ? ` · ${questionIndex + 1} of ${request.questions.length}` : '';\n const queueText = queueLength > 1 ? ` · ${queueLength - 1} waiting` : '';\n\n // Everything the sheet draws that changes how many rows it takes: which\n // question is up, whether the editor under the choices is open, the notice row\n // and the width the question wraps to.\n //\n // The editor's *text* is not here but the number of rows it takes is: a\n // 2000-character answer wraps, so a keystroke that pushes the value onto one\n // more line grows the sheet, and the transcript above has to re-measure. What\n // is reported is the row count, so a keystroke inside a wrapped line — the\n // common case — reports nothing.\n const otherRows = otherMode ? wordWrap(otherValue, contentWidth).split('\\n').length : 0;\n const layoutShape = [\n questionIndex,\n question.question,\n question.options.length,\n question.multiSelect,\n otherMode ? 1 : 0,\n otherRows,\n notice ?? '',\n contentWidth,\n progress,\n queueText,\n fromAgent ? 1 : 0,\n ].join(':');\n useReportLayout(layoutShape, {\n onLayoutChange,\n editorFocused: otherMode,\n onEditorFocusChange,\n });\n\n const choiceRows: Choice[] = [\n ...question.options.map((option) => ({\n label: option.label,\n detail: option.description,\n checked: selectedSet.has(option.label),\n })),\n {\n label: customAnswer\n ? `Other: ${truncateDisplay(customAnswer, Math.max(8, contentWidth - 24))}`\n : 'Other…',\n detail: customAnswer ? undefined : 'write your own answer',\n checked: Boolean(customAnswer),\n numeral: '+',\n },\n ];\n\n // The same sheet as a permission: a rule naming who asks (only when it is not\n // Book itself) and what, the question in bold, then the choices.\n return (\n <DecisionSheet\n label={fromAgent ? `${sourceLabel(request)} asks` : 'Question'}\n tone={theme.text}\n meta={`${question.header}${progress}${queueText}`}\n width={frame.width}\n marginX={frame.marginX}\n >\n <Text bold color={theme.text} wrap=\"wrap\">\n {question.question}\n </Text>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <ChoiceList\n choices={choiceRows}\n selected={cursor}\n width={contentWidth}\n // A column for the ✓ on every question, so an answer already given\n // shows when you step back to it.\n marks\n active={!otherMode}\n />\n </Box>\n\n {otherMode ? (\n // Your own answer is written the way everything else you write is:\n // after a pilcrow, under a hairline, like the composer.\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.border}>{'─'.repeat(Math.max(8, contentWidth))}</Text>\n <Box>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <TextInput\n value={otherValue}\n placeholder=\"Write your own answer\"\n onChange={(value) => setOtherValue(value.slice(0, 2000))}\n />\n </Box>\n <Text color={theme.inactive}>Enter use answer · Esc return to choices</Text>\n </Box>\n ) : null}\n\n {notice ? <Text color={theme.warning}>! {notice}</Text> : null}\n\n {!otherMode ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.inactive}>\n {screenReader\n ? question.multiSelect\n ? 'Use Up and Down to move. Space or number keys toggle choices. Enter confirms. O writes another answer. Escape cancels.'\n : 'Use Up and Down to move. Number keys choose. Enter confirms. O writes another answer. Escape cancels.'\n : compact\n ? question.multiSelect\n ? '↑↓ move · Space toggle · Enter next'\n : '↑↓ move · Enter choose · O custom'\n : question.multiSelect\n ? '↑↓ move · Space toggle · Enter continue · 1-4 quick toggle'\n : '↑↓ move · Enter choose · 1-4 quick choose · O custom'}\n </Text>\n <Text color={theme.inactive}>\n {questionIndex > 0 ? '←/B back · ' : ''}D decline · Esc cancel\n {!compact ? ' · Keep secrets private' : ''}\n </Text>\n </Box>\n ) : null}\n </DecisionSheet>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport TextInput from './TextInputField.js';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useReportLayout } from '../hooks/useReportLayout.js';\nimport {\n coerceElicitationValue,\n elicitationDefaults,\n validateElicitationField,\n} from '../../mcp-elicitation.js';\nimport type {\n ElicitationField,\n ElicitationRequest,\n ElicitationResponse,\n ElicitationValue,\n} from '../../types/tools.js';\nimport { useTheme } from '../theme.js';\nimport { truncateDisplay, wordWrap } from './word-wrap.js';\nimport { ChoiceList, DecisionSheet, floatingFrameMetrics, type Choice } from './chrome.js';\nimport { PILCROW } from '../marks.js';\n\ninterface McpElicitationFormProps {\n request: ElicitationRequest;\n queueLength?: number;\n terminalWidth?: number;\n onResolve: (response: ElicitationResponse) => void;\n screenReader?: boolean;\n /**\n * Called when the sheet's height may have changed: when it opens, when a field\n * editor opens or closes, when a filter narrows the option list to a different\n * number of rows, and when the validation notice appears or goes. The\n * transcript above measures its viewport only on its own layout changes, so\n * each of those landed on top of a transcript row that was there a moment\n * earlier.\n */\n onLayoutChange?: () => void;\n /**\n * Called when the field's editor takes or gives up the focus. While it holds\n * it, Ctrl+U and Ctrl+D are the editor's kills rather than the transcript's\n * half-page scrolls.\n */\n onEditorFocusChange?: (focused: boolean) => void;\n}\n\n/** Visible option rows for an enum field; longer lists scroll under the cursor. */\nconst OPTION_WINDOW = 6;\n\nfunction displayValue(field: ElicitationField, value: ElicitationValue | undefined): string {\n if (value === undefined || value === '') return '—';\n if (field.kind === 'boolean') return value ? 'yes' : 'no';\n if (field.kind === 'enum') {\n const option = field.options.find((entry) => entry.value === value);\n return option?.label ?? String(value);\n }\n return String(value);\n}\n\nfunction matchingOptions(\n field: Extract<ElicitationField, { kind: 'enum' }>,\n filter: string,\n): Array<{ value: string; label: string }> {\n const needle = filter.trim().toLowerCase();\n if (!needle) return field.options;\n return field.options.filter(\n (option) =>\n option.label.toLowerCase().includes(needle) || option.value.toLowerCase().includes(needle),\n );\n}\n\n/** Offset that keeps the cursor inside a fixed-height window over a long list. */\nexport function optionWindowStart(cursor: number, total: number, size = OPTION_WINDOW): number {\n if (total <= size) return 0;\n const half = Math.floor(size / 2);\n return Math.min(Math.max(0, cursor - half), total - size);\n}\n\n/**\n * Form for an MCP `elicitation/create` request: the server asks, the user\n * answers, and the answer travels back inside the still-open tool call.\n */\nexport function McpElicitationForm({\n request,\n queueLength = 1,\n terminalWidth = 80,\n onResolve,\n screenReader = false,\n onLayoutChange,\n onEditorFocusChange,\n}: McpElicitationFormProps) {\n const theme = useTheme();\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\n const frame = floatingFrameMetrics(outerWidth);\n const contentWidth = Math.max(14, frame.width - 4);\n const compact = outerWidth < 60;\n const [values, setValues] = useState<Record<string, ElicitationValue>>(() =>\n elicitationDefaults(request.fields),\n );\n // Read back by the key handler. Ink delivers a whole stdin chunk in one React\n // batch, so with plain state a batched arrow+Enter opened the field the cursor\n // had left — or submitted the form, when the arrow had moved off the submit\n // row.\n const [cursor, setCursor, currentCursor] = useKeyState(0);\n // `editing` deliberately stays plain render state. The enum row's Enter\n // belongs to the filter input's `onSubmit`, and the guard below relies on\n // still reading `true` when Ink's handler sees the same keypress. Making it\n // batch-safe let the handler fall through and advance a second time, which\n // skipped the next field entirely.\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState('');\n const [optionCursor, setOptionCursor, currentOption] = useKeyState(0);\n const [notice, setNotice] = useState<string | null>(null);\n const [resolved, setResolved] = useState(false);\n\n const rowCount = request.fields.length + 1;\n const submitRow = request.fields.length;\n const field = request.fields[cursor];\n const options = useMemo(\n () => (field?.kind === 'enum' ? matchingOptions(field, editing ? draft : '') : []),\n [field, editing, draft],\n );\n\n // Everything that changes how many rows the sheet draws: the editor replaces\n // the list, a filter leaves a different number of option rows, the notice is a\n // row, and a different field kind draws a different row. `draft` is\n // deliberately absent — the filter is measured by how many options it left,\n // so typing a letter does not re-measure the transcript when the row count it\n // produces has not moved.\n // A text field's draft wraps like any other, so the number of rows it takes is\n // part of the shape even though the text is not: a keystroke that pushes the\n // value onto one more line grows the sheet.\n const draftRows =\n editing && field?.kind !== 'enum' ? wordWrap(draft, contentWidth).split('\\n').length : 0;\n const layoutShape = [\n editing ? 1 : 0,\n editing && field?.kind === 'enum' ? options.length : draftRows,\n notice ?? '',\n field?.name ?? '',\n field?.kind ?? '',\n compact ? 1 : 0,\n contentWidth,\n queueLength,\n ].join(':');\n useReportLayout(layoutShape, {\n onLayoutChange,\n editorFocused: editing,\n onEditorFocusChange,\n });\n\n const resolveOnce = useCallback(\n (response: ElicitationResponse) => {\n if (resolved) return;\n setResolved(true);\n onResolve(response);\n },\n [onResolve, resolved],\n );\n\n const submit = useCallback(() => {\n for (const [index, entry] of request.fields.entries()) {\n const error = validateElicitationField(entry, values[entry.name]);\n if (error) {\n setCursor(index);\n setNotice(error);\n return;\n }\n }\n const content: Record<string, ElicitationValue> = {};\n for (const entry of request.fields) {\n const value = values[entry.name];\n if (value === undefined || value === '') continue;\n content[entry.name] = value;\n }\n resolveOnce({ action: 'accept', content });\n }, [request.fields, resolveOnce, values]);\n\n // Takes the row rather than closing over `field`. The caller is a key handler\n // that may have moved the cursor earlier in the same React batch, so the\n // field this opens has to be resolved from the batch-safe cursor — otherwise\n // an arrow off the send row left `field` undefined and opened nothing.\n const beginEdit = useCallback(\n (row: number) => {\n const target = request.fields[row];\n if (!target) return;\n setNotice(null);\n if (target.kind === 'boolean') {\n setValues((current) => ({ ...current, [target.name]: !current[target.name] }));\n return;\n }\n if (target.kind === 'enum') {\n const current = values[target.name];\n const index = target.options.findIndex((option) => option.value === current);\n setOptionCursor(Math.max(0, index));\n setDraft('');\n setEditing(true);\n return;\n }\n const current = values[target.name];\n setDraft(current === undefined ? '' : String(current));\n setEditing(true);\n },\n [request.fields, values, setOptionCursor],\n );\n\n const commitOption = useCallback(() => {\n if (field?.kind !== 'enum') return;\n const option = options[optionCursor];\n if (!option) {\n setNotice('No matching choice.');\n return;\n }\n setValues((current) => ({ ...current, [field.name]: option.value }));\n setEditing(false);\n setDraft('');\n setNotice(null);\n setCursor(Math.min(currentCursor() + 1, submitRow));\n }, [field, options, optionCursor, submitRow]);\n\n const commitText = useCallback(\n (raw: string) => {\n if (!field || field.kind === 'boolean' || field.kind === 'enum') return;\n const parsed = coerceElicitationValue(field, raw);\n if (typeof parsed === 'number' && Number.isNaN(parsed)) {\n setNotice(`${field.title} must be a number`);\n return;\n }\n const error = validateElicitationField(field, parsed);\n if (error) {\n setNotice(error);\n return;\n }\n setValues((current) => {\n const next = { ...current };\n if (parsed === undefined) delete next[field.name];\n else next[field.name] = parsed;\n return next;\n });\n setEditing(false);\n setDraft('');\n setNotice(null);\n setCursor(Math.min(currentCursor() + 1, submitRow));\n },\n [field, submitRow],\n );\n\n useInput((input, key) => {\n if (editing) {\n if (key.escape) {\n setEditing(false);\n setDraft('');\n setNotice(null);\n return;\n }\n if (field?.kind === 'enum') {\n // Enter belongs to the filter input's onSubmit; handling it here too\n // would commit the choice twice and skip a field.\n if (key.upArrow) setOptionCursor(Math.max(0, currentOption() - 1));\n else if (key.downArrow) {\n setOptionCursor(Math.min(Math.max(0, options.length - 1), currentOption() + 1));\n }\n return;\n }\n return;\n }\n\n if (key.upArrow || (key.shift && key.tab)) {\n setCursor((currentCursor() - 1 + rowCount) % rowCount);\n setNotice(null);\n } else if (key.downArrow || key.tab) {\n setCursor((currentCursor() + 1) % rowCount);\n setNotice(null);\n } else if (key.return || input === ' ') {\n if (currentCursor() === submitRow) submit();\n else beginEdit(currentCursor());\n } else if (input.toLowerCase() === 'd') {\n resolveOnce({ action: 'decline' });\n } else if (key.escape) {\n resolveOnce({ action: 'cancel' });\n }\n });\n\n // `field` is undefined while the cursor rests on the send row — that is a\n // normal state, not a reason to stop rendering the form.\n const queueText = queueLength > 1 ? ` · ${queueLength - 1} waiting` : '';\n const windowStart = optionWindowStart(optionCursor, options.length);\n const windowed = options.slice(windowStart, windowStart + OPTION_WINDOW);\n\n const choices: Choice[] = [\n ...request.fields.map((entry) => ({\n label: `${entry.title}${entry.required ? '*' : ''}`,\n detail: displayValue(entry, values[entry.name]),\n })),\n { label: `Send to ${request.server}`, detail: 'when every * field is filled' },\n ];\n\n // The same sheet as every other decision: a rule naming who asks, the\n // message in bold, then the fields as rows you move between.\n return (\n <DecisionSheet\n label={`${truncateDisplay(request.server, Math.max(8, contentWidth - 30))} asks`}\n tone={theme.text}\n meta={`MCP request${queueText}`}\n width={frame.width}\n marginX={frame.marginX}\n >\n <Text bold color={theme.text} wrap=\"wrap\">\n {request.message}\n </Text>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <ChoiceList\n choices={choices}\n selected={cursor}\n width={contentWidth}\n numbered={false}\n active={!editing}\n />\n </Box>\n\n {editing && field ? (\n // A field is edited the way everything you write is: after a pilcrow,\n // under a hairline, like the composer.\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.border}>{'─'.repeat(Math.max(8, contentWidth))}</Text>\n <Text bold color={theme.text}>\n {field.title}\n </Text>\n {field.description ? (\n <Text color={theme.inactive}>{truncateDisplay(field.description, contentWidth)}</Text>\n ) : null}\n {field.kind === 'enum' ? (\n <Box flexDirection=\"column\">\n <Box>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <TextInput\n value={draft}\n placeholder=\"type to filter\"\n onChange={(value) => {\n setDraft(value);\n setOptionCursor(0);\n }}\n onSubmit={commitOption}\n />\n </Box>\n {windowed.map((option, index) => {\n const active = windowStart + index === optionCursor;\n return (\n <Text key={option.value}>\n <Text color={theme.brand}>{active ? '› ' : ' '}</Text>\n <Text bold={active} color={active ? theme.selectionText : theme.text}>\n {truncateDisplay(option.label, contentWidth - 4)}\n </Text>\n </Text>\n );\n })}\n {options.length > windowed.length ? (\n <Text color={theme.inactive}>\n {options.length} choices · showing {windowStart + 1}-\n {windowStart + windowed.length}\n </Text>\n ) : null}\n </Box>\n ) : (\n <Box>\n <Text color={theme.brand}>{`${PILCROW} `}</Text>\n <TextInput\n value={draft}\n onChange={(value) => setDraft(value.slice(0, 2000))}\n onSubmit={commitText}\n />\n </Box>\n )}\n <Text color={theme.inactive}>\n {field.kind === 'enum'\n ? '↑↓ move · type to filter · Enter choose · Esc back'\n : 'Enter save · Esc back'}\n </Text>\n </Box>\n ) : null}\n\n {notice ? <Text color={theme.warning}>! {notice}</Text> : null}\n\n {!editing ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.inactive}>\n {screenReader\n ? 'Use Up and Down to move between fields. Enter edits a field or sends the form. D declines. Escape cancels.'\n : compact\n ? '↑↓ move · Enter edit/send'\n : '↑↓ move · Enter edit field or send · * required'}\n </Text>\n <Text color={theme.inactive}>\n D decline · Esc cancel\n {!compact ? ' · Keep secrets private' : ''}\n </Text>\n </Box>\n ) : null}\n </DecisionSheet>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useTheme } from '../theme.js';\nimport type { McpHostServerSnapshot } from '../../mcp-host.js';\nimport { ChoiceList, DecisionSheet, type Choice } from './chrome.js';\nimport { PANEL_CHROME, frameGrid } from '../layout.js';\n\ninterface McpServerApprovalPromptProps {\n server: McpHostServerSnapshot;\n /** Additional servers still waiting after this one. */\n remainingCount: number;\n onApprove: () => { ok: boolean; error?: string };\n onReject: () => { ok: boolean; error?: string };\n onDefer: () => void;\n /** Terminal columns; the sheet's rule spans them. */\n terminalWidth?: number;\n}\n\nconst OPTIONS = [\n {\n key: 'approve' as const,\n label: 'Approve and connect',\n hint: 'saved to .book/settings.local.json',\n },\n { key: 'reject' as const, label: 'Reject', hint: 'saved; will not connect in this project' },\n];\n\n/**\n * One-time trust prompt for a server declared in the workspace `.mcp.json`.\n * The full non-secret connection target is always shown. Header names are\n * listed separately while their values remain redacted.\n */\nexport function McpServerApprovalPrompt({\n server,\n remainingCount,\n onApprove,\n onReject,\n onDefer,\n terminalWidth = 80,\n}: McpServerApprovalPromptProps) {\n const theme = useTheme();\n const [selected, setSelected, currentSelected] = useKeyState(0);\n const [error, setError] = useState<string>();\n\n const decide = (key: (typeof OPTIONS)[number]['key']) => {\n const result = key === 'approve' ? onApprove() : onReject();\n if (!result.ok) setError(result.error ?? 'Could not save the decision.');\n };\n\n useInput((input, key) => {\n if (key.escape) return onDefer();\n if (key.upArrow || key.downArrow) {\n setSelected((currentSelected() + 1) % OPTIONS.length);\n setError(undefined);\n return;\n }\n // `currentSelected()`, not `selected`: a batched `↓`+Enter — one paste, one\n // fast repeat — used to confirm the option armed before the arrow, which on\n // a two-option trust gate means approving the server the user moved off.\n if (key.return) return decide(OPTIONS[currentSelected()].key);\n if (input === 'y' || input === 'Y') return decide('approve');\n if (input === 'n' || input === 'N') return decide('reject');\n });\n\n const width = frameGrid(Math.max(20, Math.floor(terminalWidth))).width;\n const contentWidth = Math.max(12, width - PANEL_CHROME);\n const waiting =\n remainingCount > 0\n ? ` · ${remainingCount} more server${remainingCount === 1 ? '' : 's'} waiting`\n : '';\n const choices: Choice[] = OPTIONS.map((option) => ({ label: option.label, detail: option.hint }));\n // Trusting a server a repository declares is a permission like any other, so\n // it gets the permission sheet's tone.\n return (\n <DecisionSheet\n label=\"MCP server\"\n tone={theme.permission}\n meta={`${server.name}${waiting}`}\n width={width}\n >\n <Text bold color={theme.text}>\n Use “{server.name}” from this project?\n </Text>\n <Text color={theme.subtle} wrap=\"wrap\">\n {server.path} declares this server. Approving connects using the configuration below.\n </Text>\n {server.configChangedSinceApproval ? (\n <Text color={theme.warning}>\n ! Its connection configuration changed since you last decided, so approval is required\n again.\n </Text>\n ) : null}\n <Box marginTop={1} flexDirection=\"column\">\n <Text wrap=\"wrap\">\n <Text color={theme.inactive}>{'target '}</Text>\n <Text color={theme.text}>{server.target}</Text>\n </Text>\n {server.envKeys.length > 0 ? (\n <Text wrap=\"wrap\">\n <Text color={theme.inactive}>{'env '}</Text>\n <Text color={theme.text}>{server.envKeys.join(', ')}</Text>\n </Text>\n ) : null}\n {server.headerKeys.length > 0 ? (\n <Text wrap=\"wrap\">\n <Text color={theme.inactive}>{'headers '}</Text>\n <Text color={theme.text}>{server.headerKeys.join(', ')}</Text>\n <Text color={theme.inactive}> (values hidden)</Text>\n </Text>\n ) : null}\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <ChoiceList choices={choices} selected={selected} width={contentWidth} numbered={false} />\n </Box>\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\n <Box marginTop={1}>\n <Text color={theme.inactive}>\n ↑↓ select · Enter confirm · y approve · n reject · Esc not now\n </Text>\n </Box>\n </DecisionSheet>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { planWasLost } from '../../agent/session-state.js';\nimport type { Message, Usage, LocalCommandDisplay } from '../../types/messages.js';\nimport type {\n ElicitationHandler,\n ElicitationResponse,\n NestedToolInvocation,\n ToolDefinition,\n ToolResult,\n PermissionDecision,\n PermissionResult,\n PlanApprovalResult,\n UserQuestionResponse,\n} from '../../types/tools.js';\nimport type { PermissionMode, RetryPhase } from '../../types/runtime.js';\nimport { createAgentRunContext, type AgentRunContext } from '../../types/runs.js';\nimport type { CommandContext } from '../../types/commands.js';\nimport type {\n SessionMeta,\n SessionRecord,\n SessionStoreInterface,\n CompactResult,\n CompactTrigger,\n CompactBoundary,\n RewindAction,\n RewindRecordData,\n RewindSnapshotStoreInterface,\n RewindTarget,\n PlanRecordData,\n} from '../../types/sessions.js';\nimport { compactionGate, usageAtGate, usagePressureTokens } from '../../agent/compact.js';\nimport { addUsage } from '../../pricing.js';\nimport { maskAtGate } from '../../agent/tool-output-masking.js';\nimport { resolveContextLimit } from '../../models.js';\nimport { applyModelDefaults, resolveModelProviderConfig } from '../../config.js';\nimport type { Todo } from '../../tools/todo.js';\nimport type { AgentConfig } from '../../types/runtime.js';\nimport {\n compactionPlacement,\n freshStreamOutput,\n makeMessage,\n removeTrailingEmptyAssistantPlaceholder,\n resetStreamedContent,\n type StreamOutput,\n} from './streaming-state.js';\nimport { createDebugLoggerWithCounter, createUiDebugLogger } from '../../debug-log.js';\nimport { loadMemoryContext } from '../../memory-store.js';\nimport {\n readSettingsGlobal,\n removeProviderGlobal,\n persistAgentProfileModel,\n persistSettingsGlobal,\n persistUserSettingClearingLocal,\n persistPermissionRuleLocal,\n removePermissionRuleLocal,\n persistSkillActivationLocal,\n persistSkillExecutionLocal,\n persistSkillsEnabledLocal,\n clearLocalSettings,\n} from '../persist.js';\nimport {\n DEFAULT_SETTINGS,\n providerConfigSchema,\n type ResolvedSettings,\n type SkillActivation,\n type SkillExecution,\n} from '../../settings.js';\nimport { resolveSettings, applySettingsEnvOverrides } from '../../settings-loader.js';\nimport { providerConfigFromDraft, type ProviderSaveRequest } from '../model-options.js';\nimport type { ProviderRemovalResult } from '../components/ModelPicker.js';\nimport { updateEffortLevel } from '../../commands/effort.js';\nimport { seedObservationLedger } from '../../tools/file-provenance.js';\nimport type { SessionBootstrap } from '../../session/resolve.js';\nimport { normalizeWorkspace } from '../../session/store.js';\nimport {\n AgentSession,\n type AgentSessionSendControl,\n type AgentSessionSendResult,\n} from '../../session/agent-session.js';\nimport { normalizePersistedTodos } from '../../tools/todo.js';\nimport { SessionRuntime } from '../../session/runtime.js';\nimport { createInteractiveAgentSession } from '../../session/interactive-session.js';\nimport type { AgentCompletionNotification } from '../../agents/types.js';\nimport { buildAgentCompletionMessage } from '../../agents/completion-notification.js';\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\nimport { resolvePermissionMode } from '../../permission-mode.js';\n\nconst log = createDebugLoggerWithCounter('tui:agent');\nconst uiLog = createUiDebugLogger('tui:agent');\nimport { createMessageAccumulator } from './message-accumulator.js';\nimport type { MessageAccumulator } from './message-accumulator.js';\n\nexport function didSendMessageComplete(result: AgentSessionSendResult): boolean {\n return result.status === 'completed';\n}\n\nexport function shouldDiscardOptimisticMessages(result: AgentSessionSendResult): boolean {\n if (result.status === 'cancelled') return !result.messages;\n return result.status === 'failed' && result.phase !== 'run';\n}\n\n/** The card for a manual compaction the user cancelled: not a failure to report. */\nfunction cancelledCompactUi(preMessages: number) {\n return {\n phase: 'skipped',\n trigger: 'manual',\n preMessages,\n message: 'Compaction cancelled.',\n } as const;\n}\n\nexport interface UseAgentSessionOptions extends SessionBootstrap {\n permissionMode?: PermissionMode;\n store?: SessionStoreInterface;\n timelineStore?: SessionStoreInterface;\n snapshotStore?: RewindSnapshotStoreInterface;\n /** Live extra tools (e.g. MCP) merged into each per-send registry. */\n additionalTools?: () => ToolDefinition[];\n}\n\nfunction providerIdFromSelection(selection: string): string | undefined {\n const slash = selection.indexOf('/');\n return slash > 0 ? selection.slice(0, slash) : undefined;\n}\n\n// BYOK providers are persisted to the user-global ~/.book/settings.json so they\n// are shared across every project. Only providers present in that file were\n// added by the user and are therefore removable; providers inherited from a\n// project layer or --settings override are not.\nfunction readOwnedProviders(): {\n ids: Set<string>;\n modelCounts: Map<string, number>;\n} {\n const global = readSettingsGlobal();\n const provider = global.provider;\n if (typeof provider !== 'object' || provider === null || Array.isArray(provider)) {\n return { ids: new Set(), modelCounts: new Map() };\n }\n const registry = provider as Record<string, unknown>;\n const ids = new Set(Object.keys(registry));\n const modelCounts = new Map<string, number>();\n for (const providerId of ids) {\n const entry = registry[providerId];\n const models =\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n ? (entry as Record<string, unknown>).models\n : undefined;\n modelCounts.set(\n providerId,\n typeof models === 'object' && models !== null && !Array.isArray(models)\n ? Object.keys(models).length\n : 0,\n );\n }\n return { ids, modelCounts };\n}\n\nexport function resolveConfigAfterProviderRemoval(\n current: AgentConfig,\n settings: ResolvedSettings,\n providerId: string,\n): {\n config: AgentConfig;\n activeModel: string;\n switched: boolean;\n inheritedProviderRevealed: boolean;\n} {\n const currentSelection = current.modelSelection ?? current.model;\n const configuredDefault = settings.model;\n const defaultIsStale =\n configuredDefault !== undefined &&\n providerIdFromSelection(configuredDefault) === providerId &&\n !settings.provider[providerId];\n const effectiveDefault = !configuredDefault || defaultIsStale ? 'gpt-4o' : configuredDefault;\n const activeProviderRemoved = providerIdFromSelection(currentSelection) === providerId;\n const nextSelection = activeProviderRemoved ? effectiveDefault : currentSelection;\n const next = applyModelDefaults(\n resolveModelProviderConfig({ ...current, settings }, nextSelection),\n );\n const activeModel = next.modelSelection ?? next.model;\n\n return {\n config: next,\n activeModel,\n switched: activeProviderRemoved && activeModel !== currentSelection,\n inheritedProviderRevealed: Boolean(settings.provider[providerId]),\n };\n}\n\n/** UI-only compact status — never appended to provider history. */\nexport type CompactUiState = {\n phase: 'working' | 'diff' | 'done' | 'error' | 'skipped';\n trigger: CompactTrigger;\n preMessages?: number;\n preContextTokens?: number;\n message?: string;\n degraded?: boolean;\n warning?: string;\n strategy?: Extract<CompactResult, { status: 'compacted' }>['strategy'];\n modelCalls?: number;\n /** The reducer ran while the turn went on and a judge read the steps taken meanwhile. */\n judge?: Extract<CompactResult, { status: 'compacted' }>['judge'];\n};\n\nfunction buildObservationLedger(messages: Message[]) {\n return seedObservationLedger(\n new Map<string, NonNullable<Message['fileObservations']>[number]>(),\n messages,\n );\n}\n\nfunction withoutRuntimeState(config: AgentConfig): AgentConfig {\n return { ...config };\n}\n\ninterface SendMessageOptions {\n contextMessage?: string;\n kind?: Message['kind'];\n agentNotifications?: Message['agentNotifications'];\n attachments?: Message['attachments'];\n /** Managed-continuation linkage back to the originating root and parent run. */\n rootRunId?: string;\n parentRunId?: string;\n}\n\n/** Short transcript line shown for a fresh-context handoff (the full plan is the context). */\nconst HANDOFF_DISPLAY_MESSAGE = 'Implementing the approved plan with a fresh context.';\n\n/** Frames the approved plan as authoritative task intent for the reseeded implementation turn. */\nfunction buildHandoffPrompt(plan: string): string {\n return [\n 'You are implementing a plan that was just approved in a planning session.',\n 'This is a handoff to a fresh context: the plan below is your complete and',\n 'authoritative source of task intent. Implement it step by step. If a step is',\n 'ambiguous, make the reasonable choice and keep going.',\n '',\n '<approved-plan>',\n plan,\n '</approved-plan>',\n ].join('\\n');\n}\n\n/**\n * Build the session runtime with the plan a resumed session persisted.\n *\n * Seeded by pushing into the runtime's own arrays: the tools mutate those arrays\n * in place, so replacing them here would detach the runtime from what the loop\n * reads.\n */\nfunction createSeededRuntime(\n session: UseAgentSessionOptions,\n initialTranscript: Message[],\n): SessionRuntime {\n const runtime = new SessionRuntime({\n fileObservationLedger: buildObservationLedger(initialTranscript),\n history: initialTranscript,\n });\n runtime.todos.push(...normalizePersistedTodos(session.plan?.todos));\n if (session.plan?.tasks?.length) runtime.tasks.push(...session.plan.tasks);\n runtime.planUnrestored = planWasLost({\n planRecordExisted: session.plan !== undefined,\n priorMessages: initialTranscript.length,\n todos: runtime.todos.length,\n tasks: runtime.tasks.length,\n });\n return runtime;\n}\n\nexport function useAgent(config: AgentConfig, session: UseAgentSessionOptions) {\n const initialTranscript = session.transcript ?? session.history;\n const initialContext = session.contextHistory ?? session.history;\n const [messages, setMessages] = useState<Message[]>(initialTranscript);\n const [compactBoundaries, setCompactBoundaries] = useState<CompactBoundary[]>(\n session.compactBoundaries ?? [],\n );\n const [rewindTargets, setRewindTargets] = useState<RewindTarget[]>(session.rewindTargets ?? []);\n const [isThinking, setIsThinking] = useState(false);\n /** Local messages produced mid-turn, replayed in order once the turn ends. */\n const pendingLocalMessages = useRef<\n Array<{ text: string; localCommand?: LocalCommandDisplay; sessionId: string }>\n >([]);\n const [isCompacting, setIsCompacting] = useState(false);\n // True once the compaction's record is written, so the app stops offering to cancel it: the\n // PostCompact hooks left are the same signal's and are not cancelled.\n const [isCompactCommitted, setIsCompactCommitted] = useState(false);\n const [isRewinding, setIsRewinding] = useState(false);\n const [compactUi, setCompactUi] = useState<CompactUiState | null>(null);\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [currentTurn, setCurrentTurn] = useState(0);\n const [usage, setUsage] = useState<Usage | null>(null);\n /**\n * Every response this session has spent, cumulatively — what `/cost` and\n * `/usage` price. `usage` stays exactly as it is (per-request, cleared on a\n * send and a compaction) because the context meter and `/context` read it;\n * pricing a bill from it reported only the last turn's tokens (#370).\n *\n * Reset only where the session itself changes — a clear, a new conversation, a\n * resume. A `/rewind` projects the same session back to an earlier turn and\n * keeps it: the spend before the rewind was really spent.\n */\n const [sessionUsage, setSessionUsage] = useState<Usage | null>(null);\n /**\n * The bill counts from a resume in this process rather than from the session's\n * first turn. The persisted carry is deliberately not seeded (it is\n * root-inclusive of delegated spend, which is counted separately), so the\n * reports say what the figure covers instead of implying it is everything.\n */\n const [sessionUsageSinceResume, setSessionUsageSinceResume] = useState(false);\n const [mode, setMode] = useState<PermissionMode>(() =>\n resolvePermissionMode(config.settings, session.permissionMode),\n );\n const [agentSession] = useState(() =>\n createInteractiveAgentSession({\n runtime: createSeededRuntime(session, initialTranscript),\n additionalTools: session.additionalTools,\n }),\n );\n // The plan a resumed session persisted is the plan on screen from the first\n // frame: the Steps sheet (Ctrl+T) and the working line both read this, and a\n // session that is halfway through step 3 must not look like one that has no\n // plan until its next tool call happens to report it back.\n const [agentTodos, setAgentTodos] = useState<Todo[]>(() => [...agentSession.getRuntime().todos]);\n // Whether the agent wrote its plan during the current prompt. The working\n // line and the status line only name a step from a plan that is current: a\n // step left in progress by an interrupted or finished turn is not the work a\n // later prompt is doing.\n const [agentPlanCurrent, setAgentPlanCurrent] = useState(false);\n // The plan on screen, as JSON, and the plan the accepted send started from.\n // Both are read synchronously -- `onTodos` runs mid-turn, once per tool call,\n // and a mirror updated from a `useEffect` would be a render behind it.\n const agentTodosKeyRef = useRef(JSON.stringify(agentSession.getRuntime().todos));\n const planKeyAtSendRef = useRef(agentTodosKeyRef.current);\n // Every write to the plan goes through here, so the key that decides whether\n // a later report is news can never fall behind the state it describes.\n const projectAgentPlan = useCallback((todos: Todo[]) => {\n agentTodosKeyRef.current = JSON.stringify(todos);\n setAgentTodos(todos);\n }, []);\n // A new session, a cleared one, or one reseeded for a handoff: no plan, and\n // nothing that claims the new turn wrote one.\n const resetAgentPlan = useCallback(() => {\n projectAgentPlan([]);\n setAgentPlanCurrent(false);\n }, [projectAgentPlan]);\n // Set when the user approves a plan with \"fresh context\"; a post-send effect\n // starts a new conversation seeded with the approved plan.\n const [pendingHandoff, setPendingHandoff] = useState<{\n plan: string;\n mode: PermissionMode;\n generation: number;\n } | null>(null);\n // Guards single execution of the handoff reseed. State (not a ref) so releasing it\n // re-runs the effect to pick up a handoff raised during a prior reseed.\n const [handoffInFlight, setHandoffInFlight] = useState(false);\n // R1: liveConfig is the mutable config the agent loop reads. `config` (the\n // prop) is the startup snapshot; setModel/setEffort/persistPermissionRule\n // mutate liveConfig so subsequent runAgentLoop calls pick up the change.\n // Without this, /model would silently no-op (send closes over `config`).\n const [liveConfig, setLiveConfig] = useState<AgentConfig>(() => withoutRuntimeState(config));\n const [ownedProviders, setOwnedProviders] = useState(() => readOwnedProviders());\n const { interactions, operations } = agentSession;\n const [interactionSnapshot, setInteractionSnapshot] = useState(() => interactions.getSnapshot());\n const { pendingPermission, pendingPlanApproval, pendingUserQuestions, pendingElicitations } =\n interactionSnapshot;\n const [turnDurationMs, setTurnDurationMs] = useState<number>(0);\n const [sessionId, setSessionId] = useState(session.sessionId);\n const [sessionName, setSessionName] = useState(session.sessionName);\n\n // Retry state for the spinner label.\n const [retryPhase, setRetryPhase] = useState<RetryPhase>('none');\n const [retryAttempt, setRetryAttempt] = useState(0);\n const [retryMax, setRetryMax] = useState(0);\n const [retryCountdownMs, setRetryCountdownMs] = useState(0);\n\n // Mutable id of the assistant message currently being streamed into.\n // Callbacks read this ref (not state) so multi-turn updates always target\n // the latest in-progress message without stale-closure issues.\n const streamingIdRef = useRef<string | null>(null);\n // What the streaming message holds (see StreamOutput), tracked as events arrive.\n const streamOutputRef = useRef<StreamOutput>(freshStreamOutput());\n const messagesRef = useRef<Message[]>(initialTranscript);\n const contextHistoryRef = useRef<Message[]>(initialContext);\n const sessionIdRef = useRef(session.sessionId);\n const sessionNameRef = useRef(session.sessionName);\n const resumedFromRunIdRef = useRef<string | undefined>(undefined);\n const sessionGenerationRef = useRef(0);\n const modeRef = useRef(mode);\n const liveConfigRef = useRef(liveConfig);\n const ownedProvidersRef = useRef(ownedProviders);\n const turnStartRef = useRef(Date.now());\n // Countdown timer ref for retry countdown.\n const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Message accumulator for batched streaming updates.\n const accumulatorRef = useRef<MessageAccumulator | null>(null);\n const hostUsageRef = useRef<Usage | null>(null);\n const lastHostCompactAttemptRef = useRef<string | null>(null);\n // Plan-handoff request captured from the loop's onPlanHandoff callback, consumed\n // once the plan-approving send settles.\n const pendingHandoffRef = useRef<{ plan: string; mode: PermissionMode } | null>(null);\n const timelineStore = session.timelineStore ?? session.store;\n\n useEffect(() => interactions.subscribe(setInteractionSnapshot), [interactions]);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n useEffect(() => {\n liveConfigRef.current = liveConfig;\n }, [liveConfig]);\n\n useEffect(() => {\n modeRef.current = mode;\n }, [mode]);\n\n useEffect(() => {\n ownedProvidersRef.current = ownedProviders;\n }, [ownedProviders]);\n\n const settlePermission = useCallback(\n (decision: PermissionResult | PermissionDecision, via: string) => {\n return interactions.settlePermission(decision, via);\n },\n [interactions],\n );\n\n const settlePlanApproval = useCallback(\n (result: PlanApprovalResult, via: string) => {\n return interactions.settlePlanApproval(result, via);\n },\n [interactions],\n );\n\n const settleUserQuestion = useCallback(\n (result: UserQuestionResponse, via: string, requestId?: string) =>\n interactions.settleUserQuestion(result, via, requestId),\n [interactions],\n );\n\n useEffect(() => {\n agentSession\n .startLifecycle(liveConfigRef.current, session.sessionId, session.source)\n .catch((err) => {\n log.warn('SessionStart hook failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }, [agentSession, session.sessionId, session.source]);\n\n useEffect(() => {\n return () => {\n agentSession\n .endLifecycle(liveConfigRef.current, sessionIdRef.current, 'exit')\n .catch((err) => {\n log.warn('SessionEnd hook failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n };\n }, [agentSession]);\n\n // Clean up timers / pending prompts / in-flight work on unmount.\n useEffect(() => {\n return () => {\n if (countdownRef.current) {\n clearInterval(countdownRef.current);\n countdownRef.current = null;\n }\n accumulatorRef.current?.stop();\n accumulatorRef.current = null;\n // Abort work and deny/reject prompts so no session promise survives unmount.\n agentSession.dispose('unmount');\n };\n }, [agentSession]);\n\n const clearCountdown = useCallback(() => {\n if (countdownRef.current) {\n clearInterval(countdownRef.current);\n countdownRef.current = null;\n }\n }, []);\n\n useEffect(\n () =>\n agentSession.subscribe((snapshot) => {\n if (\n snapshot.status !== 'completed' &&\n snapshot.status !== 'failed' &&\n snapshot.status !== 'cancelled' &&\n snapshot.status !== 'timed_out' &&\n snapshot.status !== 'interrupted'\n )\n return;\n if (snapshot.sessionId !== sessionIdRef.current) return;\n setIsThinking(false);\n clearCountdown();\n setRetryPhase('none');\n setRetryCountdownMs(0);\n if (\n (snapshot.status === 'failed' ||\n snapshot.status === 'timed_out' ||\n snapshot.status === 'interrupted') &&\n snapshot.error\n ) {\n setError(snapshot.error);\n }\n }),\n [agentSession, clearCountdown],\n );\n\n const finalizeStreamingMessages = useCallback(() => {\n setMessages((prev) => {\n const next = removeTrailingEmptyAssistantPlaceholder(prev);\n messagesRef.current = next;\n return next;\n });\n }, []);\n\n const prepareConversationProjection = useCallback(() => {\n sessionGenerationRef.current++;\n accumulatorRef.current?.discard();\n accumulatorRef.current = null;\n clearCountdown();\n }, [clearCountdown]);\n\n const projectConversationState = useCallback(\n (\n nextId: string,\n nextName: string | undefined,\n transcript: Message[],\n contextHistory: Message[] = transcript,\n boundaries: CompactBoundary[] = [],\n targets: RewindTarget[] = [],\n plan?: PlanRecordData,\n opts: { sinceResume?: boolean } = {},\n ) => {\n // A rewind reaches here with the same id it already had: the conversation\n // moved, the session did not, and its bill goes with it (#370).\n const newSession = sessionIdRef.current !== nextId;\n sessionIdRef.current = nextId;\n sessionNameRef.current = nextName;\n messagesRef.current = transcript;\n contextHistoryRef.current = contextHistory;\n streamingIdRef.current = null;\n setSessionId(nextId);\n setSessionName(nextName);\n setMessages(transcript);\n setCompactBoundaries(boundaries);\n setRewindTargets(targets);\n setIsThinking(false);\n setStreamingMessageId(null);\n setError(null);\n setCurrentTurn(0);\n setUsage(null);\n // A resume re-counts from the resume even when it lands on the id already\n // open, so it is named the same way as a session change. Only a change of\n // that kind rewrites the scope: a same-session rewind keeps the bill, so it\n // must keep saying where the bill starts too (#370).\n if (newSession || opts.sinceResume) {\n setSessionUsage(null);\n setSessionUsageSinceResume(opts.sinceResume === true);\n }\n hostUsageRef.current = null;\n lastHostCompactAttemptRef.current = null;\n setTurnDurationMs(0);\n setRetryPhase('none');\n setRetryAttempt(0);\n setRetryMax(0);\n setRetryCountdownMs(0);\n const nextRuntime = agentSession.replaceRuntime(\n {\n fileObservationLedger: buildObservationLedger(transcript),\n // The projected conversation is the runtime's: a resumed or rewound\n // session keeps the tool history that memory quarantine reads.\n history: transcript,\n },\n 'session_transition',\n );\n // `replaceRuntime` hands back empty lists, so without this a transition into\n // a session drops its persisted plan on the floor — and, because the flag\n // stays false too, says nothing about having done so.\n nextRuntime.todos.push(...normalizePersistedTodos(plan?.todos));\n if (plan?.tasks?.length) nextRuntime.tasks.push(...plan.tasks);\n nextRuntime.planUnrestored = planWasLost({\n planRecordExisted: plan !== undefined,\n priorMessages: transcript.length,\n todos: nextRuntime.todos.length,\n tasks: nextRuntime.tasks.length,\n });\n // The session the conversation is now in did not write this plan; the\n // first turn that reports a change to it is the one that earns the step.\n projectAgentPlan([...nextRuntime.todos]);\n setAgentPlanCurrent(false);\n setLiveConfig((current) => ({\n ...current,\n memoryContext: current.settings.memory.enabled\n ? loadMemoryContext(current.workspace)\n : undefined,\n }));\n },\n [agentSession, projectAgentPlan],\n );\n\n const resetConversationState = useCallback(\n (\n nextId: string,\n nextName: string | undefined,\n transcript: Message[],\n contextHistory: Message[] = transcript,\n boundaries: CompactBoundary[] = [],\n targets: RewindTarget[] = [],\n opts: { preserveOperation?: boolean } = {},\n ) => {\n prepareConversationProjection();\n if (opts.preserveOperation) interactions.cancelAll('session-reset');\n else agentSession.reset('session-reset');\n projectConversationState(nextId, nextName, transcript, contextHistory, boundaries, targets);\n },\n [agentSession, interactions, prepareConversationProjection, projectConversationState],\n );\n\n const endCurrentSession = useCallback(\n (reason: 'clear' | 'resume' | 'exit' | 'completion') =>\n agentSession.endLifecycle(liveConfigRef.current, sessionIdRef.current, reason),\n [agentSession],\n );\n\n /**\n * A root the session owns for a subtree the host runs itself — a `/review`'s\n * reviewer agents, which no turn of the root would ever report.\n *\n * Returns the attribution to spawn them under, exactly as print mode does\n * (`print-dispatch.ts`): without a `rootRunId` each agent becomes its own root,\n * and a root the session never registered is spend no flush can write. The\n * registration is what makes it durable, so both halves are returned together\n * and a caller cannot take the root without the tracking.\n */\n const startHostRun = useCallback(() => {\n const rootRunId = crypto.randomUUID();\n const runId = crypto.randomUUID();\n if (timelineStore) {\n agentSession.trackRunUsage(rootRunId, {\n sessionId: sessionIdRef.current,\n timelineStore,\n });\n }\n return { rootRunId, runId };\n }, [agentSession, timelineStore]);\n\n const startNewConversation = useCallback(\n async (previousName?: string) => {\n await agentSession.clearSession({\n config: liveConfigRef.current,\n currentSessionId: sessionIdRef.current,\n store: session.store,\n timelineStore,\n previousName,\n onTransitionStart: prepareConversationProjection,\n onTransition: (bootstrap) => {\n resumedFromRunIdRef.current = undefined;\n projectConversationState(\n bootstrap.sessionId,\n bootstrap.sessionName,\n bootstrap.transcript ?? bootstrap.history,\n bootstrap.contextHistory ?? bootstrap.history,\n bootstrap.compactBoundaries,\n bootstrap.rewindTargets,\n bootstrap.plan,\n );\n },\n });\n },\n [\n agentSession,\n prepareConversationProjection,\n projectConversationState,\n session.store,\n timelineStore,\n ],\n );\n\n const resumeConversation = useCallback(\n async (selector: string) => {\n await agentSession.resumeSession({\n config: liveConfigRef.current,\n currentSessionId: sessionIdRef.current,\n store: session.store,\n timelineStore,\n selector,\n onTransitionStart: prepareConversationProjection,\n onTransition: (bootstrap) => {\n resumedFromRunIdRef.current = [...(bootstrap.transcript ?? bootstrap.history)]\n .reverse()\n .find((message) => message.role === 'user')?.id;\n projectConversationState(\n bootstrap.sessionId,\n bootstrap.sessionName,\n bootstrap.transcript ?? bootstrap.history,\n bootstrap.contextHistory ?? bootstrap.history,\n bootstrap.compactBoundaries,\n bootstrap.rewindTargets,\n bootstrap.plan,\n { sinceResume: true },\n );\n },\n });\n },\n [\n agentSession,\n prepareConversationProjection,\n projectConversationState,\n session.store,\n timelineStore,\n ],\n );\n\n const listSessions = useCallback((): SessionMeta[] => {\n if (!session.store) return [];\n const cwd = normalizeWorkspace(liveConfig.workspace);\n return session.store.list().filter((meta) => meta.cwd === cwd);\n }, [liveConfig.workspace, session.store]);\n\n const projectCompactResult = useCallback(\n (result: Extract<CompactResult, { status: 'compacted' }>, boundary: CompactBoundary) => {\n contextHistoryRef.current = result.replacementHistory;\n setCompactBoundaries((current) => [...current, boundary]);\n setUsage(null);\n hostUsageRef.current = null;\n },\n [],\n );\n\n /**\n * A compaction's own model calls — the summarizer, and the judge in the\n * deferred flow — are real spend, and run accounting already charges them to\n * the root run (#370). The session bill had no way to hear about them, so\n * `/cost` named a figure below what the session had actually spent. It reaches\n * the bill only: `usage` stays the context meter's per-request value.\n */\n const recordCompactionUsage = useCallback((u: Usage) => {\n setSessionUsage((current) => addUsage(current, u));\n }, []);\n\n // Unconditional append, shared by the immediate and the deferred path so a\n // replayed message is byte-identical to one that was never blocked.\n const appendLocalMessage = useCallback(\n (text: string, localCommand?: LocalCommandDisplay) => {\n const msg = {\n ...makeMessage('assistant', text, undefined, false),\n kind: 'local' as const,\n localCommand,\n };\n if (timelineStore) {\n timelineStore.append(sessionIdRef.current, {\n type: 'local',\n eventId: msg.id,\n timestamp: msg.timestamp,\n data: { id: msg.id, content: msg.content, kind: 'local', includeInContext: false },\n });\n }\n setMessages((prev) => {\n const next = [...prev, msg];\n messagesRef.current = next;\n return next;\n });\n },\n [timelineStore],\n );\n\n const sendMessage = useCallback(\n async (\n userMessage: string,\n commandContext?: CommandContext,\n messageOptions?: SendMessageOptions,\n ): Promise<AgentSessionSendResult> => {\n setCompactUi(null);\n\n const generation = sessionGenerationRef.current;\n const activeSessionId = sessionIdRef.current;\n let operationIsCurrent = () => false;\n const stillCurrent = () =>\n sessionGenerationRef.current === generation && operationIsCurrent();\n let activeAccumulator: MessageAccumulator | null = null;\n // A fresh streaming message for the turn's next output: at each turn after the first, and\n // after a compaction that committed behind output the same turn then continues.\n const openStreamingMessage = (reason: 'new-turn' | 'after-compaction') => {\n activeAccumulator?.stop();\n uiLog.event('accumulator:stopped', { reason });\n const next = makeMessage('assistant', '', undefined, true);\n streamingIdRef.current = next.id;\n streamOutputRef.current = freshStreamOutput();\n setStreamingMessageId(next.id);\n setMessages((prev) => {\n const updated = [...prev, next];\n messagesRef.current = updated;\n return updated;\n });\n activeAccumulator = createMessageAccumulator(next.id, setMessages, messagesRef, 32);\n accumulatorRef.current = activeAccumulator;\n activeAccumulator.start();\n uiLog.event('accumulator:started', { flushIntervalMs: 32, reason });\n };\n // Output of the streaming message: once a compaction committed behind it, it opens a new one.\n const noteStreamOutput = (tool: boolean) => {\n if (streamOutputRef.current.closed) openStreamingMessage('after-compaction');\n streamOutputRef.current.any = true;\n if (tool) streamOutputRef.current.tools = true;\n };\n let activeUserMessage: Message | undefined;\n let placeholder: Message | undefined;\n let activeRunContext: AgentRunContext | undefined;\n let activeSignal: AbortSignal | undefined;\n\n log.info('send message', {\n len: userMessage.length,\n mode: modeRef.current,\n hasCommandContext: !!commandContext,\n sessionId: activeSessionId,\n });\n uiLog.event('send:start', {\n len: userMessage.length,\n mode: modeRef.current,\n hasCommandContext: !!commandContext,\n });\n\n const beforePrepare = async (control: AgentSessionSendControl) => {\n operationIsCurrent = control.isCurrent;\n activeRunContext = control.runContext;\n activeSignal = control.signal;\n // The plan this turn started from, read from the runtime — the loop\n // mutates that array in place, so it is the plan the turn is actually\n // working through, not a render-old copy of it.\n //\n // Taken here, and only here, because `beforePrepare` runs once the send\n // has been accepted. A send rejected as already in flight (the\n // managed-agent completion and background-shell paths both retry while\n // a turn is running) never reaches this line, so a retry cannot reset\n // the flag or move the baseline out from under the turn it retried.\n planKeyAtSendRef.current = JSON.stringify(agentSession.getRuntime().todos);\n setAgentPlanCurrent(false);\n // Cross-turn auto-compact before appending the new user message -- masking\n // first, as in the loop: when it alone brings the last request's count\n // under the gate, nothing is summarized.\n if (\n liveConfig.autoCompactEnabled !== false &&\n usageAtGate(hostUsageRef.current, liveConfig)\n ) {\n const pressure = usagePressureTokens(hostUsageRef.current);\n const gate = compactionGate(liveConfig);\n const masked = maskAtGate(contextHistoryRef.current, gate, pressure, gate);\n if (masked.maskedCount > 0) {\n contextHistoryRef.current = masked.history;\n if (masked.underLine) hostUsageRef.current = null;\n }\n }\n const contextLimit = resolveContextLimit(liveConfig);\n const hostCompactAttemptKey = `${usagePressureTokens(hostUsageRef.current)}:${contextHistoryRef.current.length}`;\n if (\n liveConfig.autoCompactEnabled !== false &&\n contextLimit != null &&\n usageAtGate(hostUsageRef.current, liveConfig) &&\n lastHostCompactAttemptRef.current !== hostCompactAttemptKey\n ) {\n lastHostCompactAttemptRef.current = hostCompactAttemptKey;\n try {\n setIsCompacting(true);\n setCompactUi({\n phase: 'working',\n trigger: 'auto',\n preMessages: contextHistoryRef.current.length,\n preContextTokens: usagePressureTokens(hostUsageRef.current),\n });\n const autoOutcome = await agentSession.compact({\n config: liveConfig,\n history: contextHistoryRef.current,\n compactBoundaries,\n sessionId: activeSessionId,\n transcriptOrdinal: messagesRef.current.length,\n runContext: control.runContext,\n runtime: agentSession.getRuntime(),\n timelineStore,\n isCurrent: stillCurrent,\n onUsage: (u: Usage) => {\n if (stillCurrent()) recordCompactionUsage(u);\n },\n onCommitted: projectCompactResult,\n options: {\n trigger: 'auto',\n preContextTokens: usagePressureTokens(hostUsageRef.current),\n upcomingUserIntent: messageOptions?.contextMessage ?? userMessage,\n // Esc on this row's \"Esc to cancel\" must stop the reducer, not only the send:\n // without the turn's signal the model kept being called after the send was gone.\n signal: control.signal,\n },\n });\n const autoResult = autoOutcome.result;\n if (stillCurrent() && autoResult.status === 'compacted' && autoOutcome.boundary) {\n setCompactUi({\n phase: 'diff',\n trigger: 'auto',\n preMessages: autoResult.preMessageCount,\n preContextTokens: autoResult.preContextTokens,\n message: autoResult.degraded\n ? 'Conversation compacted with reduced fidelity'\n : 'Conversation compacted',\n degraded: autoResult.degraded,\n warning: autoResult.warning,\n strategy: autoResult.strategy,\n modelCalls: autoResult.modelCalls,\n });\n } else if (stillCurrent()) {\n // A PreCompact hook that refused is the one skip worth a line: the\n // user's own script made a decision on evidence they cannot see\n // otherwise, and the oversized request that follows will not say why.\n setCompactUi(\n autoResult.status === 'skipped' && autoResult.reason === 'blocked'\n ? {\n phase: 'skipped',\n trigger: 'auto',\n message: autoResult.message ?? 'Compaction blocked by PreCompact hook.',\n }\n : null,\n );\n }\n if (control.signal?.aborted) {\n // A cancelled attempt is not an attempt: keeping its key would skip the compaction\n // on the next send and send the oversized history.\n lastHostCompactAttemptRef.current = null;\n }\n } catch (err) {\n log.warn('pre-turn auto-compact failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n if (stillCurrent()) setCompactUi(null);\n if (control.signal?.aborted) lastHostCompactAttemptRef.current = null;\n } finally {\n if (stillCurrent()) setIsCompacting(false);\n }\n }\n };\n\n const createUserMessage = () => {\n const message = makeMessage('user', userMessage, messageOptions?.contextMessage, true);\n message.kind = messageOptions?.kind ?? 'conversation';\n // A command context means `userMessage` is a resolved command body -- which for a\n // project command is repository-authored text, and for a builtin is Book's own.\n message.derivedContent = commandContext ? true : undefined;\n message.agentNotifications = messageOptions?.agentNotifications;\n message.attachments = messageOptions?.attachments;\n activeUserMessage = message;\n return message;\n };\n\n const projectPreparingSend = (userMsg: Message, control: AgentSessionSendControl) => {\n operationIsCurrent = control.isCurrent;\n // Render the user's message immediately and stream into a fresh placeholder.\n placeholder = makeMessage('assistant', '', undefined, true);\n streamingIdRef.current = placeholder.id;\n streamOutputRef.current = freshStreamOutput();\n setStreamingMessageId(placeholder.id);\n setIsThinking(true);\n setError(null);\n setCurrentTurn(0);\n setUsage(null);\n setRetryPhase('none');\n setRetryAttempt(0);\n setRetryMax(0);\n setRetryCountdownMs(0);\n setMessages((prev) => {\n const next = [...prev, userMsg, placeholder!];\n messagesRef.current = next;\n return next;\n });\n };\n\n const removeOptimisticMessages = () => {\n if (!activeUserMessage || !placeholder) return;\n setMessages((prev) => {\n const next = prev.filter(\n (message) => message.id !== activeUserMessage?.id && message.id !== placeholder?.id,\n );\n messagesRef.current = next;\n return next;\n });\n };\n\n const projectPreparedSend = (\n prepared: Extract<Awaited<ReturnType<AgentSession['prepareSend']>>, { status: 'prepared' }>,\n ) => {\n if (prepared.sessionName !== sessionNameRef.current) {\n sessionNameRef.current = prepared.sessionName;\n setSessionName(prepared.sessionName);\n }\n setRewindTargets((current) => [prepared.rewindTarget, ...current]);\n // Ink layout plus markdown parsing commonly takes longer than a 60fps\n // frame on a real transcript. A 32ms cadence keeps streaming responsive\n // without making the terminal renderer compete with every token delta.\n activeAccumulator = createMessageAccumulator(placeholder!.id, setMessages, messagesRef, 32);\n accumulatorRef.current = activeAccumulator;\n activeAccumulator.start();\n uiLog.event('accumulator:started', { flushIntervalMs: 32 });\n };\n\n const sendResult = await agentSession.send({\n config: liveConfig,\n displayMessage: userMessage,\n contextMessage: messageOptions?.contextMessage,\n createUserMessage,\n history: () => contextHistoryRef.current,\n compactBoundaries,\n mode: modeRef.current,\n sessionId: activeSessionId,\n source: 'tui',\n resumedFromRunId:\n messageOptions?.kind === 'agent-notification' ? undefined : resumedFromRunIdRef.current,\n rootRunId:\n messageOptions?.kind === 'agent-notification' ? messageOptions?.rootRunId : undefined,\n parentRunId:\n messageOptions?.kind === 'agent-notification' ? messageOptions?.parentRunId : undefined,\n sessionName: sessionNameRef.current,\n snapshotStore: session.snapshotStore,\n timelineStore,\n registryStore: timelineStore,\n isCurrent: () => sessionGenerationRef.current === generation,\n runtime: agentSession.getRuntime(),\n beforePrepare,\n onPreparing: projectPreparingSend,\n onPrepared: projectPreparedSend,\n callbacks: {\n onEvent: (event) => {\n if (!stillCurrent()) return;\n switch (event.type) {\n case 'text':\n if (event.content !== '') noteStreamOutput(false);\n activeAccumulator?.addText(event.content);\n break;\n case 'reasoning':\n if (event.content !== '') noteStreamOutput(false);\n activeAccumulator?.addReasoning(event.content);\n break;\n case 'tool_use':\n noteStreamOutput(true);\n activeAccumulator?.addToolCall(event.toolCall);\n break;\n case 'tool_result':\n streamOutputRef.current.any = true;\n streamOutputRef.current.tools = true;\n activeAccumulator?.addToolResult(event.toolResult);\n break;\n case 'notice':\n appendLocalMessage(event.message);\n break;\n case 'attempt_discarded': {\n // Land anything still queued before clearing, or it would flush\n // the abandoned attempt back in on top of the reset.\n activeAccumulator?.flush();\n // Since a compaction committed behind the streaming message, any output would\n // have opened a new one: the discarded attempt streamed nothing, and what the\n // message holds came before the row.\n if (!streamOutputRef.current.closed) {\n const streamingId = streamingIdRef.current;\n // The reset clears the attempt's text and reasoning, not the turn's tool rows.\n streamOutputRef.current.any = streamOutputRef.current.tools;\n if (streamingId) {\n setMessages((prev) => {\n const next = resetStreamedContent(prev, streamingId);\n messagesRef.current = next;\n return next;\n });\n }\n }\n uiLog.event('attempt:discarded', { reason: event.reason });\n break;\n }\n case 'error':\n log.warn('agent error', { error: event.error });\n break;\n }\n },\n onTodos: (todos) => {\n if (!stillCurrent()) return;\n // The loop reports the plan after EVERY tool call, not just after\n // TodoWrite, and hands over a fresh copy each time. Compare the\n // report with the one already on screen before writing anything: a\n // 200-tool turn must not re-render the app 200 times for a plan\n // that has not moved, and a re-report is not the agent writing a\n // plan, so it must not light up the working line either.\n const key = JSON.stringify(todos);\n if (key === agentTodosKeyRef.current) return;\n projectAgentPlan(todos as Todo[]);\n if (key !== planKeyAtSendRef.current) setAgentPlanCurrent(true);\n },\n onTurnStart: (turn) => {\n if (!stillCurrent()) return;\n log.debug('TUI turn start', { turn });\n setCurrentTurn(turn);\n turnStartRef.current = Date.now();\n if (turn > 1) openStreamingMessage('new-turn');\n },\n onDone: () => {\n if (!stillCurrent()) return;\n log.info('agent done', { durationMs: Date.now() - turnStartRef.current });\n uiLog.event('send:done', { durationMs: Date.now() - turnStartRef.current });\n setTurnDurationMs(Date.now() - turnStartRef.current);\n },\n onUsage: (u: Usage) => {\n if (!stillCurrent()) return;\n hostUsageRef.current = u;\n lastHostCompactAttemptRef.current = null;\n setUsage(u);\n setSessionUsage((current) => addUsage(current, u));\n },\n getMode: () => modeRef.current,\n onModeChange: (newMode: PermissionMode) => {\n if (!stillCurrent()) return;\n modeRef.current = newMode;\n setMode(newMode);\n },\n onPlanHandoff: (handoff) => {\n if (!stillCurrent()) return;\n // Consumed after this send settles (see the pending-handoff effect).\n pendingHandoffRef.current = handoff;\n },\n onCompact: async (history, usage, hints) => {\n if (!stillCurrent()) {\n return { status: 'skipped', reason: 'disabled', message: 'Session changed.' };\n }\n const placement = compactionPlacement(\n messagesRef.current,\n streamingIdRef.current,\n streamOutputRef.current.any,\n );\n const outcome = await agentSession.compact({\n config: liveConfigRef.current,\n history,\n compactBoundaries,\n sessionId: activeSessionId,\n transcriptOrdinal: placement.ordinal,\n runContext: activeRunContext,\n runtime: agentSession.getRuntime(),\n timelineStore,\n isCurrent: stillCurrent,\n onUsage: (u: Usage) => {\n if (stillCurrent()) recordCompactionUsage(u);\n },\n onCommitted: projectCompactResult,\n options: {\n ...hints,\n trigger: 'auto',\n preContextTokens: usage ? usagePressureTokens(usage) : undefined,\n // The loop's own compaction answers to the turn's Esc, like the pre-turn one.\n signal: activeSignal,\n },\n });\n const result = outcome.result;\n if (!stillCurrent()) return result;\n if (result.status === 'compacted' && outcome.boundary) {\n // The row sits below this message; the turn's next output goes below the row.\n if (placement.afterStreaming) streamOutputRef.current.closed = true;\n setCompactUi({\n phase: 'diff',\n trigger: 'auto',\n preMessages: result.preMessageCount,\n preContextTokens: result.preContextTokens,\n message: result.degraded\n ? 'Conversation compacted with reduced fidelity'\n : 'Conversation compacted',\n degraded: result.degraded,\n warning: result.warning,\n strategy: result.strategy,\n modelCalls: result.modelCalls,\n });\n } else if (result.status === 'skipped' && result.reason === 'blocked') {\n // Same as the pre-turn path: a hook's refusal is shown, with its reason.\n setCompactUi({\n phase: 'skipped',\n trigger: 'auto',\n message: result.message ?? 'Compaction blocked by PreCompact hook.',\n });\n }\n return result;\n },\n // Deferred compaction (plans/async-compaction-plan.md): the reducer\n // runs on a snapshot while the turn goes on; the commit, at the next\n // boundary, judges the checkpoint against the steps taken meanwhile.\n prepareCompact: async (snapshot, usage, hints) => {\n if (!stillCurrent()) {\n return { status: 'skipped', reason: 'disabled', message: 'Session changed.' };\n }\n const outcome = await agentSession.prepareCompact({\n config: liveConfigRef.current,\n history: snapshot,\n compactBoundaries,\n sessionId: activeSessionId,\n transcriptOrdinal: messagesRef.current.length,\n runContext: activeRunContext,\n runtime: agentSession.getRuntime(),\n onUsage: (u: Usage) => {\n if (stillCurrent()) recordCompactionUsage(u);\n },\n options: {\n ...hints,\n trigger: 'auto',\n preContextTokens: usage ? usagePressureTokens(usage) : undefined,\n },\n });\n if (outcome.status !== 'prepared') {\n if (\n stillCurrent() &&\n outcome.result.status === 'skipped' &&\n outcome.result.reason === 'blocked'\n ) {\n setCompactUi({\n phase: 'skipped',\n trigger: 'auto',\n message: outcome.result.message ?? 'Compaction blocked by PreCompact hook.',\n });\n }\n return outcome.result;\n }\n return outcome.prepared;\n },\n commitCompact: async (prepared, history, hints) => {\n if (!stillCurrent()) {\n return { status: 'skipped', reason: 'disabled', message: 'Session changed.' };\n }\n const placement = compactionPlacement(\n messagesRef.current,\n streamingIdRef.current,\n streamOutputRef.current.any,\n );\n const outcome = await agentSession.commitCompact({\n prepared,\n history,\n config: liveConfigRef.current,\n sessionId: activeSessionId,\n transcriptOrdinal: placement.ordinal,\n runContext: activeRunContext,\n runtime: agentSession.getRuntime(),\n timelineStore,\n isCurrent: stillCurrent,\n onUsage: (u: Usage) => {\n if (stillCurrent()) recordCompactionUsage(u);\n },\n onCommitted: projectCompactResult,\n options: { signal: hints?.signal },\n });\n const result = outcome.result;\n if (!stillCurrent()) return result;\n if (result.status === 'compacted' && outcome.boundary) {\n // The row sits below this message; the turn's next output goes below the row.\n if (placement.afterStreaming) streamOutputRef.current.closed = true;\n setCompactUi({\n phase: 'diff',\n trigger: 'auto',\n preMessages: result.preMessageCount,\n preContextTokens: result.preContextTokens,\n message: result.degraded\n ? 'Conversation compacted with reduced fidelity'\n : 'Conversation compacted',\n degraded: result.degraded,\n warning: result.warning,\n strategy: result.strategy,\n modelCalls: result.modelCalls,\n judge: result.judge,\n });\n }\n return result;\n },\n onRetry: (phase, attempt, max, delayMs) => {\n if (!stillCurrent()) return;\n setRetryPhase(phase);\n setRetryAttempt(attempt);\n setRetryMax(max);\n setRetryCountdownMs(delayMs);\n\n // Start countdown timer.\n clearCountdown();\n countdownRef.current = setInterval(() => {\n setRetryCountdownMs((prev) => {\n const next = prev - 1000;\n if (next <= 0) {\n clearCountdown();\n return 0;\n }\n return next;\n });\n }, 1000);\n },\n onStreamStall: (countdownMs) => {\n if (!stillCurrent()) return;\n setRetryPhase('stalled');\n setRetryCountdownMs(countdownMs);\n clearCountdown();\n countdownRef.current = setInterval(() => {\n setRetryCountdownMs((prev) => {\n const next = prev - 1000;\n if (next <= 0) {\n clearCountdown();\n return 0;\n }\n return next;\n });\n }, 1000);\n },\n onStreamResume: () => {\n if (!stillCurrent()) return;\n setRetryPhase('none');\n clearCountdown();\n },\n onPersistPermissionRule: (rule: string) => {\n persistPermissionRule(rule);\n },\n },\n options: {\n nestedToolObserver: {\n onToolCall: (invocation: NestedToolInvocation) => {\n if (stillCurrent()) activeAccumulator?.addNestedToolCall(invocation);\n },\n onToolResult: (traceId: string, result: ToolResult) => {\n if (stillCurrent()) activeAccumulator?.addNestedToolResult(traceId, result);\n },\n },\n manageSessionHooks: false,\n assistantMessageId: () => streamingIdRef.current ?? undefined,\n allowedTools: commandContext?.allowedTools,\n modelOverride: commandContext?.modelOverride,\n commands: commandContext ? [commandContext.command] : undefined,\n parentSessionId: activeSessionId,\n },\n });\n if (messageOptions?.kind !== 'agent-notification' && sendResult.status !== 'rejected') {\n resumedFromRunIdRef.current = undefined;\n }\n\n const hostStillCurrent = sessionGenerationRef.current === generation;\n if (sendResult.status === 'rejected') {\n uiLog.event('send:rejected', {\n reason: sendResult.activeKind === 'compact' ? 'compacting' : 'already-in-flight',\n len: userMessage.length,\n });\n return sendResult;\n }\n if (hostStillCurrent && 'messages' in sendResult && sendResult.messages) {\n // Nested tool traces remain display-only; the returned history is provider context.\n contextHistoryRef.current = sendResult.messages;\n }\n // A fresh-context plan approval sets this late in the loop. Always drop it on any\n // terminal outcome of this send so it can't leak into a later turn; reseed only\n // when this send completed as the current generation.\n if (pendingHandoffRef.current) {\n const handoff = pendingHandoffRef.current;\n pendingHandoffRef.current = null;\n if (hostStillCurrent && sendResult.status === 'completed') {\n setPendingHandoff({ ...handoff, generation });\n }\n }\n if (hostStillCurrent && shouldDiscardOptimisticMessages(sendResult)) {\n if (sendResult.status === 'failed') {\n setError(\n sendResult.error instanceof Error ? sendResult.error.message : String(sendResult.error),\n );\n }\n setIsThinking(false);\n removeOptimisticMessages();\n }\n if (hostStillCurrent && placeholder) {\n accumulatorRef.current?.stop();\n uiLog.event('accumulator:stopped', { reason: 'done' });\n if (accumulatorRef.current === activeAccumulator) accumulatorRef.current = null;\n finalizeStreamingMessages();\n streamingIdRef.current = null;\n setStreamingMessageId(null);\n }\n // A run that ended badly used to leave no trace at all: the loop skips\n // `onAssistantMessageComplete` on its error path, which is the only writer\n // to the session store, and the transient banner is cleared by the next\n // send. A run that stopped for a reason the user never saw looks exactly\n // like a model that decided it was finished. Record it in the transcript\n // instead, after the placeholder cleanup so it is the last row.\n //\n // Keyed on the settled outcome rather than on `onError`, which also fires\n // for problems the run recovers from — a skill that fails to activate is\n // reported to the model in the prompt and the turn carries on — so an\n // error event would stamp a failure notice onto turns that succeeded.\n // `cancelled` is the user's own doing, and the outcomes for a session the\n // user left carry no message, so both stay silent.\n // A prepare-phase failure carries no outcome; it is already reported by\n // the banner, which `shouldDiscardOptimisticMessages` admits for it.\n const settled = 'outcome' in sendResult ? sendResult.outcome : undefined;\n if (\n hostStillCurrent &&\n settled?.message &&\n settled.status !== 'completed' &&\n settled.status !== 'cancelled'\n ) {\n uiLog.event('run-failure:surfaced', { reason: settled.reason });\n appendLocalMessage(`✕ ${settled.message}`);\n // The terminal snapshot already put this same text in the transient\n // banner above the composer, synchronously, before this teardown ran.\n // Two copies of one failure reads as two failures, so the banner gives\n // way to the transcript row, which is the copy that survives a resume.\n setError(null);\n }\n uiLog.event('send:finally', { durationMs: Date.now() - turnStartRef.current });\n return sendResult;\n },\n [\n liveConfig,\n clearCountdown,\n compactBoundaries,\n finalizeStreamingMessages,\n appendLocalMessage,\n timelineStore,\n projectCompactResult,\n session.snapshotStore,\n agentSession,\n ],\n );\n\n const send = useCallback(\n async (\n userMessage: string,\n commandContext?: CommandContext,\n attachments?: Message['attachments'],\n ) => {\n return sendMessage(userMessage, commandContext, { attachments });\n },\n [sendMessage],\n );\n\n // Fresh-context plan handoff: once the plan-approving turn settles, start a new\n // conversation and reseed it with only the approved plan (like Codex/Claude Code).\n useEffect(() => {\n if (!pendingHandoff || handoffInFlight) return;\n // Abandon if the session moved on (clear/resume/rewind) before we could reseed.\n if (sessionGenerationRef.current !== pendingHandoff.generation) {\n setPendingHandoff(null);\n return;\n }\n const handoff = pendingHandoff;\n setHandoffInFlight(true);\n const { plan, mode: handoffMode } = handoff;\n void (async () => {\n try {\n log.info('plan handoff: starting fresh conversation');\n await startNewConversation();\n modeRef.current = handoffMode;\n setMode(handoffMode);\n await sendMessage(HANDOFF_DISPLAY_MESSAGE, undefined, {\n contextMessage: buildHandoffPrompt(plan),\n kind: 'conversation',\n });\n } catch (err) {\n log.warn('plan handoff failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n // Surface the loss: the approved plan was not implemented.\n setError('Failed to start fresh-context implementation; the approved plan was not run.');\n } finally {\n // Clear only this request, so a handoff raised during the reseed above survives\n // and is picked up when handoffInFlight is released.\n setPendingHandoff((current) => (current === handoff ? null : current));\n setHandoffInFlight(false);\n }\n })();\n }, [pendingHandoff, handoffInFlight, startNewConversation, sendMessage]);\n\n const sendAgentCompletions = useCallback(\n async (notifications: AgentCompletionNotification[]): Promise<boolean> => {\n if (notifications.length === 0) return false;\n const recordedDeliveryIds = new Set(\n messagesRef.current.flatMap((message) =>\n (message.agentNotifications ?? [])\n .map((notification) => notification.deliveryId)\n .filter((id): id is string => Boolean(id)),\n ),\n );\n const fresh = notifications.filter(\n (notification) => !recordedDeliveryIds.has(notification.deliveryId),\n );\n if (fresh.length === 0) return true;\n const built = fresh.map(buildAgentCompletionMessage);\n // Parent linkage is only truthful when every batched completion shares one root.\n const sharedRootRunId =\n fresh[0]?.rootRunId &&\n fresh.every((notification) => notification.rootRunId === fresh[0]?.rootRunId)\n ? fresh[0]?.rootRunId\n : undefined;\n const result = await sendMessage(\n built.map((item) => item.displayMessage).join('\\n'),\n undefined,\n {\n contextMessage: built.map((item) => item.contextMessage).join('\\n'),\n kind: 'agent-notification',\n agentNotifications: built.map((item) => item.display),\n rootRunId: sharedRootRunId,\n parentRunId: sharedRootRunId ? fresh[0]?.runId : undefined,\n },\n );\n return didSendMessageComplete(result);\n },\n [sendMessage],\n );\n\n const sendBackgroundShellCompletion = useCallback(\n async (shell: BackgroundShellRecord): Promise<boolean> => {\n const tail = agentSession.getRuntime().shellManager.readTail(shell.id, 4_000) ?? '';\n const exit = shell.exitCode !== undefined ? ` exit=${shell.exitCode ?? 'none'}` : '';\n const display = `Background shell ${shell.title || shell.id} ${shell.status}${exit}.`;\n const context = [\n '<background-shell-completion>',\n `id: ${shell.id}`,\n `title: ${shell.title || shell.command}`,\n `status: ${shell.status}${exit}`,\n `elapsed_ms: ${(shell.finishedAt ?? Date.now()) - shell.startedAt}`,\n tail ? 'output_tail:' : undefined,\n tail || undefined,\n '</background-shell-completion>',\n ]\n .filter((line): line is string => line !== undefined)\n .join('\\n');\n const result = await sendMessage(display, undefined, {\n contextMessage: context,\n kind: 'agent-notification',\n });\n return didSendMessageComplete(result);\n },\n [agentSession, sendMessage],\n );\n\n const resolvePermission = useCallback(\n (decision: PermissionResult | PermissionDecision) => {\n settlePermission(decision, 'resolve');\n },\n [settlePermission],\n );\n\n const cancelPermission = useCallback(() => {\n settlePermission('deny', 'cancel-permission');\n }, [settlePermission]);\n\n const resolvePlanApproval = useCallback(\n (result: PlanApprovalResult) => {\n settlePlanApproval(result, 'resolve');\n },\n [settlePlanApproval],\n );\n\n const resolveUserQuestion = useCallback(\n (result: UserQuestionResponse) => {\n settleUserQuestion(result, 'resolve');\n },\n [settleUserQuestion],\n );\n\n const resolveElicitation = useCallback(\n (result: ElicitationResponse) => {\n interactions.settleElicitation(result, 'resolve');\n },\n [interactions],\n );\n\n /** Installed on the MCP host so servers can prompt through this session. */\n const elicitationHandler = useCallback<ElicitationHandler>(\n (request) => interactions.requestElicitation(request),\n [interactions],\n );\n\n // Abort the in-flight agent stream (Esc while thinking) or compact request.\n // The active lease stays held until its finally block; only its signal is aborted.\n const cancel = useCallback(() => {\n const activeKind = operations.activeKind;\n const hadAccumulator = accumulatorRef.current !== null;\n const cancelled = agentSession.cancel('cancel');\n uiLog.event('cancel', {\n activeKind,\n aborted: cancelled.operation.aborted,\n hadAccumulator,\n inFlight: activeKind === 'send',\n });\n // The active lease stays held until its finally block finishes unwinding.\n clearCountdown();\n setRetryPhase('none');\n }, [agentSession, clearCountdown, operations]);\n\n // Manually compact the conversation (summarize older turns).\n const compact = useCallback(\n async (focus?: string) => {\n const operation = operations.tryStart('compact', true);\n if (!operation) {\n setCompactUi({\n phase: 'skipped',\n trigger: 'manual',\n message: 'Cannot compact while a turn is in progress.',\n });\n return;\n }\n const generation = sessionGenerationRef.current;\n const activeSessionId = sessionIdRef.current;\n const stillCurrent = () =>\n sessionGenerationRef.current === generation && operation.isCurrent();\n const preMessages = contextHistoryRef.current.length;\n const preContextTokens = usagePressureTokens(hostUsageRef.current);\n\n setIsCompacting(true);\n setCompactUi({\n phase: 'working',\n trigger: 'manual',\n preMessages,\n preContextTokens,\n });\n\n try {\n const runContext = createAgentRunContext({\n sessionId: activeSessionId,\n source: 'tui',\n });\n const outcome = await agentSession.compact({\n config: liveConfigRef.current,\n history: contextHistoryRef.current,\n compactBoundaries,\n sessionId: activeSessionId,\n transcriptOrdinal: messagesRef.current.length,\n runContext,\n runtime: agentSession.getRuntime(),\n timelineStore,\n isCurrent: stillCurrent,\n onUsage: (u: Usage) => {\n if (stillCurrent()) recordCompactionUsage(u);\n },\n onCommitted: (result, boundary) => {\n projectCompactResult(result, boundary);\n setIsCompactCommitted(true);\n },\n options: {\n trigger: 'manual',\n focus,\n preContextTokens,\n signal: operation.signal,\n },\n });\n const result = outcome.result;\n\n if (!stillCurrent()) return;\n\n if (result.status === 'skipped') {\n setCompactUi({\n phase: 'skipped',\n trigger: 'manual',\n preMessages,\n message: result.message ?? 'Not enough messages to compact.',\n });\n return;\n }\n // A cancelled compaction (Esc or Ctrl+C) ends on its aborted reducer stream, which is\n // not a failure to report.\n if (result.status === 'failed') {\n setCompactUi(\n operation.signal?.aborted\n ? cancelledCompactUi(preMessages)\n : { phase: 'error', trigger: 'manual', preMessages, message: result.error },\n );\n return;\n }\n\n if (!outcome.boundary) return;\n if (!stillCurrent()) return;\n setCompactUi({\n phase: 'diff',\n trigger: 'manual',\n preMessages: result.preMessageCount,\n preContextTokens: result.preContextTokens,\n message: result.degraded\n ? 'Conversation compacted with reduced fidelity'\n : 'Conversation compacted',\n degraded: result.degraded,\n warning: result.warning,\n strategy: result.strategy,\n modelCalls: result.modelCalls,\n });\n } catch (e) {\n if (stillCurrent()) {\n setCompactUi(\n operation.signal?.aborted\n ? cancelledCompactUi(preMessages)\n : {\n phase: 'error',\n trigger: 'manual',\n preMessages,\n message: e instanceof Error ? e.message : String(e),\n },\n );\n }\n } finally {\n setIsCompactCommitted(false);\n if (stillCurrent()) setIsCompacting(false);\n operation.release();\n }\n },\n [\n agentSession,\n compactBoundaries,\n operations,\n projectCompactResult,\n recordCompactionUsage,\n timelineStore,\n ],\n );\n\n const getRewindTargets = useCallback((): RewindTarget[] => {\n const currentGitHead = session.snapshotStore?.getCurrentGitHead();\n return rewindTargets.map((target) => {\n if (target.codeUnavailableReason) return { ...target, codeAvailable: false };\n const manifest = target.snapshotId\n ? session.snapshotStore?.getManifest(target.snapshotId)\n : undefined;\n const availability = !session.snapshotStore\n ? { available: false, reason: 'Filesystem checkpoint storage is unavailable.' }\n : !manifest\n ? session.snapshotStore.getAvailability(target.snapshotId, target.gitHead)\n : currentGitHead !== target.gitHead\n ? {\n available: false,\n reason: 'Git HEAD changed since this prompt; rewind never moves HEAD or the index.',\n }\n : { available: true };\n return {\n ...target,\n codeAvailable: availability.available,\n codeUnavailableReason: availability.available ? undefined : availability.reason,\n };\n });\n }, [rewindTargets, session.snapshotStore]);\n\n const rewind = useCallback(\n async (\n targetId: string,\n action: RewindAction,\n ): Promise<\n | { ok: true; restoredPrompt?: string; restoredAttachments?: Message['attachments'] }\n | { ok: false; error: string }\n > => {\n const operation = operations.tryStart('rewind');\n if (!operation) {\n return { ok: false, error: 'Rewind is unavailable while another operation is active.' };\n }\n if (!timelineStore) {\n operation.release();\n return { ok: false, error: 'Rewind timeline storage is unavailable.' };\n }\n const target = getRewindTargets().find((candidate) => candidate.id === targetId);\n if (!target) {\n operation.release();\n return { ok: false, error: 'The selected rewind target is no longer active.' };\n }\n if ((action === 'code' || action === 'both') && !target.codeAvailable) {\n operation.release();\n return {\n ok: false,\n error: target.codeUnavailableReason ?? 'Code rewind is unavailable for this prompt.',\n };\n }\n\n setIsRewinding(true);\n const activeSessionId = sessionIdRef.current;\n let safetySnapshotId: string | undefined;\n try {\n if (action === 'code' || action === 'both') {\n const restored = session.snapshotStore?.restore(target.snapshotId!);\n if (!restored)\n return { ok: false, error: 'Filesystem checkpoint storage is unavailable.' };\n if (!restored.ok) {\n return {\n ok: false,\n error: restored.rollbackError\n ? `${restored.error} Rollback also failed: ${restored.rollbackError}`\n : restored.error,\n };\n }\n safetySnapshotId = restored.safetySnapshotId;\n }\n\n timelineStore.append(activeSessionId, {\n type: 'rewind',\n eventId: crypto.randomUUID(),\n timestamp: Date.now(),\n data: {\n version: 1,\n action,\n targetId: target.id,\n targetUserEventId: target.userEventId,\n } satisfies RewindRecordData,\n } satisfies SessionRecord);\n\n if (action === 'conversation' || action === 'both') {\n const loaded = timelineStore.load(activeSessionId);\n resetConversationState(\n activeSessionId,\n sessionName,\n loaded.transcript,\n loaded.contextHistory,\n loaded.compactBoundaries,\n loaded.rewindTargets,\n { preserveOperation: true },\n );\n }\n if (safetySnapshotId) session.snapshotStore?.discardManifest(safetySnapshotId);\n return {\n ok: true,\n ...(action === 'code'\n ? {}\n : {\n restoredPrompt: target.prompt,\n ...(target.attachments?.length ? { restoredAttachments: target.attachments } : {}),\n }),\n };\n } catch (rewindError) {\n let rollbackMessage = '';\n if (safetySnapshotId) {\n const rollback = session.snapshotStore?.rollback(safetySnapshotId);\n if (rollback && !rollback.ok) rollbackMessage = ` Rollback failed: ${rollback.error}`;\n }\n return {\n ok: false,\n error: `${rewindError instanceof Error ? rewindError.message : String(rewindError)}${rollbackMessage}`,\n };\n } finally {\n operation.release();\n setIsRewinding(false);\n }\n },\n [\n getRewindTargets,\n operations,\n resetConversationState,\n session.snapshotStore,\n sessionName,\n timelineStore,\n ],\n );\n\n const clear = useCallback(() => {\n // Abort + stop accumulator BEFORE wiping message state so no late flush\n // can resurrect content into a cleared conversation.\n accumulatorRef.current?.stop();\n accumulatorRef.current = null;\n agentSession.cancel('clear');\n messagesRef.current = [];\n contextHistoryRef.current = [];\n setMessages([]);\n setCompactBoundaries([]);\n setRewindTargets([]);\n setError(null);\n setCurrentTurn(0);\n setUsage(null);\n setSessionUsage(null);\n setSessionUsageSinceResume(false);\n hostUsageRef.current = null;\n lastHostCompactAttemptRef.current = null;\n resetAgentPlan();\n streamingIdRef.current = null;\n setStreamingMessageId(null);\n // The send lease is released by send()'s finally after abort.\n if (!operations.isRunning('send')) setIsThinking(false);\n clearCountdown();\n setRetryPhase('none');\n setRetryCountdownMs(0);\n }, [agentSession, clearCountdown, operations, resetAgentPlan]);\n\n const cycleMode = useCallback(() => {\n const modes: PermissionMode[] = [\n 'default',\n 'auto',\n 'plan',\n 'accept-edits',\n 'dontAsk',\n 'bypassPermissions',\n ].filter(\n (candidate) =>\n candidate !== 'bypassPermissions' ||\n liveConfigRef.current.settings.disableBypassPermissionsMode !== true,\n ) as PermissionMode[];\n const idx = modes.indexOf(modeRef.current);\n const nextMode = modes[(idx + 1) % modes.length];\n modeRef.current = nextMode;\n setMode(nextMode);\n }, []);\n\n // Surface a local-only assistant message WITHOUT an agent round-trip.\n // Precedent: compact() mutates messages directly via setMessages. Unlike\n // send(), this never invokes runAgentLoop — used by /diff /config /cost\n // /init-pre /memory-noop to show output instantly, and by /review to deliver\n // a report its agents produced minutes after the command was typed.\n const addLocalMessage = useCallback(\n (text: string, localCommand?: LocalCommandDisplay) => {\n const sendInFlight = operations.isRunning('send');\n if (sendInFlight || isThinking) {\n // Deferred, not dropped. Callers that finish on their own schedule —\n // `/review` runs for minutes in background agents — cannot time their\n // output around a turn the user starts meanwhile, and discarding it\n // threw away the entire deliverable of that work.\n uiLog.event('local-message:deferred', {\n reason: sendInFlight ? 'in-flight' : 'is-thinking',\n preview: text.slice(0, 40),\n });\n pendingLocalMessages.current.push({\n text,\n localCommand,\n sessionId: sessionIdRef.current,\n });\n return; // don't clobber a streaming turn\n }\n uiLog.event('local-message:added', {\n preview: text.slice(0, 40),\n presentation: localCommand?.kind ?? 'text',\n });\n appendLocalMessage(text, localCommand);\n },\n [appendLocalMessage, isThinking, operations],\n );\n\n // Drain deferred local messages once the turn that blocked them is over.\n // Deliberately unconditional: the send lease is a plain object, not reactive\n // state, so there is no dependency that reliably changes when it is released\n // — and a drain that misses its wake-up is the bug this replaced. The guard\n // makes the common (empty) case two boolean reads.\n useEffect(() => {\n if (pendingLocalMessages.current.length === 0) return;\n if (isThinking || operations.isRunning('send')) return;\n const queued = pendingLocalMessages.current;\n pendingLocalMessages.current = [];\n for (const item of queued) {\n // Output owed to a conversation the user has since left is dropped on\n // purpose: replaying it into an unrelated session is worse than losing it.\n if (item.sessionId !== sessionIdRef.current) {\n uiLog.event('local-message:discarded', {\n reason: 'session-changed',\n preview: item.text.slice(0, 40),\n });\n continue;\n }\n uiLog.event('local-message:added', {\n preview: item.text.slice(0, 40),\n presentation: item.localCommand?.kind ?? 'text',\n deferred: true,\n });\n appendLocalMessage(item.text, item.localCommand);\n }\n });\n\n // Switch the active model for the rest of the session, optionally persisting\n // it to the user-global settings layer (~/.book/settings.json) so the choice\n // follows the user across projects. BOOK_MODEL can still override settings on\n // the next startup; app.tsx surfaces that warning.\n const setModel = useCallback(\n (name: string, options: { persist?: boolean } = {}) => {\n let next: AgentConfig;\n try {\n next = applyModelDefaults(resolveModelProviderConfig(liveConfigRef.current, name));\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n if (options.persist !== false) {\n const result = persistUserSettingClearingLocal(config.workspace, 'model', name);\n if (!result.ok) return result;\n }\n setLiveConfig(next);\n return { ok: true };\n },\n [config.workspace],\n );\n\n const upsertProviderAndSelect = useCallback(\n (request: ProviderSaveRequest) => {\n const providerId = request.providerId;\n let savedProvider;\n try {\n const existing = liveConfigRef.current.settings.provider[providerId];\n savedProvider = providerConfigSchema.parse(\n providerConfigFromDraft(request, existing, request.replaceModels),\n );\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n\n const selection = `${providerId}/${request.activeModelId}`;\n const activate = request.activate !== false;\n const result = persistSettingsGlobal({\n [`provider.${providerId}`]: savedProvider,\n ...(activate ? { model: selection } : {}),\n });\n if (!result.ok) return result;\n // Drop any stale per-project entries for this provider (and the active\n // model when we just set it) so this folder inherits the global value\n // instead of a local override shadowing it.\n clearLocalSettings(config.workspace, [\n `provider.${providerId}`,\n ...(activate ? ['model'] : []),\n ]);\n\n setLiveConfig((current) => {\n const withProvider: AgentConfig = {\n ...current,\n settings: {\n ...current.settings,\n ...(activate ? { model: selection } : {}),\n provider: {\n ...current.settings.provider,\n [providerId]: savedProvider,\n },\n },\n };\n return activate\n ? applyModelDefaults(resolveModelProviderConfig(withProvider, selection))\n : withProvider;\n });\n const nextOwnedProviders = {\n ids: new Set(ownedProvidersRef.current.ids).add(providerId),\n modelCounts: new Map(ownedProvidersRef.current.modelCounts).set(\n providerId,\n Object.keys(savedProvider.models).length,\n ),\n };\n ownedProvidersRef.current = nextOwnedProviders;\n setOwnedProviders(nextOwnedProviders);\n return { ok: true };\n },\n [config.workspace],\n );\n\n const removeProvider = useCallback(\n (providerId: string): ProviderRemovalResult => {\n if (!ownedProvidersRef.current.ids.has(providerId)) {\n return { ok: false, error: 'Only BYOK providers you added can be removed.' };\n }\n\n const persisted = removeProviderGlobal(providerId);\n if (!persisted.ok) return { ok: false, error: persisted.error };\n\n let resolvedSettings: ResolvedSettings;\n let resolvedRuntime: ReturnType<typeof resolveConfigAfterProviderRemoval>;\n try {\n // The re-read has to answer with the settings the session is running\n // under, not the files' contents: resolving without the environment's\n // override put the file's value back into `liveConfig`, so `/config`\n // showed a splash state this session was not launched with.\n resolvedSettings = applySettingsEnvOverrides(\n config.settingsContext?.noSettings\n ? structuredClone(DEFAULT_SETTINGS)\n : resolveSettings(config.workspace, config.settingsContext?.overridePath),\n );\n resolvedRuntime = resolveConfigAfterProviderRemoval(\n liveConfigRef.current,\n resolvedSettings,\n providerId,\n );\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n\n liveConfigRef.current = resolvedRuntime.config;\n setLiveConfig(resolvedRuntime.config);\n const nextOwnedProviderIds = new Set(ownedProvidersRef.current.ids);\n const nextOwnedProviderModelCounts = new Map(ownedProvidersRef.current.modelCounts);\n nextOwnedProviderIds.delete(providerId);\n nextOwnedProviderModelCounts.delete(providerId);\n const nextOwnedProviders = {\n ids: nextOwnedProviderIds,\n modelCounts: nextOwnedProviderModelCounts,\n };\n ownedProvidersRef.current = nextOwnedProviders;\n setOwnedProviders(nextOwnedProviders);\n\n return {\n ok: true,\n providerId,\n removedModelCount: persisted.removedModelCount,\n activeModel: resolvedRuntime.activeModel,\n switched: resolvedRuntime.switched,\n inheritedProviderRevealed: resolvedRuntime.inheritedProviderRevealed,\n };\n },\n [config.settingsContext?.noSettings, config.settingsContext?.overridePath, config.workspace],\n );\n\n const setEffort = useCallback(\n (level: NonNullable<AgentConfig['effort']>) =>\n updateEffortLevel(\n liveConfigRef.current,\n level,\n (selected) => persistUserSettingClearingLocal(config.workspace, 'effort', selected),\n (selected) =>\n setLiveConfig((current) => ({\n ...current,\n effort: selected,\n effortExplicit: true,\n })),\n ),\n [config.workspace],\n );\n\n const setAgentProfileModel = useCallback(\n (profile: string, model?: string) => {\n const persisted = persistAgentProfileModel(config.workspace, profile, model);\n if (!persisted.ok) return persisted;\n\n setLiveConfig((current) => {\n const profiles = { ...current.settings.agents.profiles };\n const existing = { ...(profiles[profile] ?? {}) };\n existing.model = model ?? 'inherit';\n if (Object.keys(existing).length > 0) profiles[profile] = existing;\n else delete profiles[profile];\n return {\n ...current,\n settings: {\n ...current.settings,\n agents: { ...current.settings.agents, profiles },\n },\n };\n });\n return { ok: true };\n },\n [config.workspace],\n );\n\n const setCompactModel = useCallback(\n (model: string) => {\n const result = persistUserSettingClearingLocal(config.workspace, 'compactModel', model);\n if (!result.ok) return result;\n setLiveConfig((current) => ({\n ...current,\n compactModel: model,\n settings: { ...current.settings, compactModel: model },\n }));\n return { ok: true };\n },\n [config.workspace],\n );\n\n const setSkillActivation = useCallback(\n (skillName: string, activation: SkillActivation) => {\n const persisted = persistSkillActivationLocal(config.workspace, skillName, activation);\n if (!persisted.ok) return persisted;\n\n setLiveConfig((current) => ({\n ...current,\n settings: {\n ...current.settings,\n skills: {\n ...current.settings.skills,\n overrides: {\n ...current.settings.skills.overrides,\n [skillName]: activation,\n },\n },\n },\n }));\n return { ok: true };\n },\n [config.workspace],\n );\n\n const setSkillExecution = useCallback(\n (skillName: string, execution: SkillExecution) => {\n const persisted = persistSkillExecutionLocal(config.workspace, skillName, execution);\n if (!persisted.ok) return persisted;\n\n setLiveConfig((current) => ({\n ...current,\n settings: {\n ...current.settings,\n skills: {\n ...current.settings.skills,\n execution: {\n ...current.settings.skills.execution,\n [skillName]: execution,\n },\n },\n },\n }));\n return { ok: true };\n },\n [config.workspace],\n );\n\n const setSkillsEnabled = useCallback(\n (enabled: boolean) => {\n const persisted = persistSkillsEnabledLocal(config.workspace, enabled);\n if (!persisted.ok) return persisted;\n setLiveConfig((current) => ({\n ...current,\n settings: {\n ...current.settings,\n skills: { ...current.settings.skills, enabled },\n },\n }));\n return { ok: true };\n },\n [config.workspace],\n );\n\n const setMemoryAutoSave = useCallback(\n (enabled: boolean) => {\n setLiveConfig((c) => ({\n ...c,\n settings: {\n ...c.settings,\n memory: { ...c.settings.memory, autoSave: enabled },\n },\n }));\n persistUserSettingClearingLocal(config.workspace, 'memory.autoSave', enabled);\n },\n [config.workspace],\n );\n\n /**\n * Flip a boolean setting, reading the value that is actually current.\n *\n * The callers used to compute `!liveConfig.settings…` from the value captured\n * at render. Two flips inside one React batch — which is what an accelerator\n * that acts on a row followed by Enter on the same row produces — then both\n * read the pre-batch value and both persist the same absolute result, so two\n * presses moved the setting once and wrote the wrong value to disk.\n *\n * Reading `liveConfigRef` is not enough on its own: it is mirrored in an\n * effect, so inside a batch it is exactly as stale as the render value. The\n * ref is therefore written here, synchronously, next to the state update.\n */\n const toggleSetting = useCallback(\n (\n read: (config: AgentConfig) => boolean,\n write: (config: AgentConfig, value: boolean) => AgentConfig,\n persist: (value: boolean) => { ok: boolean; error?: string },\n /**\n * Target value, for the callers that name one rather than flip. `/config\n * ui.showThinking=false` has to land in the same place the menu row does,\n * or the typed and pointed halves of one command disagree again.\n */\n target?: boolean,\n ) => {\n const next = target ?? !read(liveConfigRef.current);\n const result = persist(next);\n if (!result.ok) return result;\n liveConfigRef.current = write(liveConfigRef.current, next);\n setLiveConfig(liveConfigRef.current);\n return { ok: true } as const;\n },\n [],\n );\n\n const toggleShowThinking = useCallback(\n (target?: boolean) =>\n toggleSetting(\n (c) => c.settings.ui.showThinking === true,\n (c, value) => ({\n ...c,\n settings: { ...c.settings, ui: { ...c.settings.ui, showThinking: value } },\n }),\n (value) => persistUserSettingClearingLocal(config.workspace, 'ui.showThinking', value),\n target,\n ),\n [toggleSetting, config.workspace],\n );\n\n const toggleStartupAnimation = useCallback(\n (target?: boolean) =>\n toggleSetting(\n (c) => c.settings.ui.startupAnimation !== false,\n (c, value) => ({\n ...c,\n settings: { ...c.settings, ui: { ...c.settings.ui, startupAnimation: value } },\n }),\n (value) => persistUserSettingClearingLocal(config.workspace, 'ui.startupAnimation', value),\n target,\n ),\n [toggleSetting, config.workspace],\n );\n\n const toggleMemoryAutoSave = useCallback(\n (target?: boolean) =>\n toggleSetting(\n (c) => c.settings.memory.autoSave === true,\n (c, value) => ({\n ...c,\n settings: { ...c.settings, memory: { ...c.settings.memory, autoSave: value } },\n }),\n (value) => persistUserSettingClearingLocal(config.workspace, 'memory.autoSave', value),\n target,\n ),\n [toggleSetting, config.workspace],\n );\n\n // Add an allow rule from the \"Always allow\" approval flow (CC-aligned) and\n // surface it live in settings so the next call is auto-allowed.\n const persistPermissionRule = useCallback(\n (rule: string) => {\n setLiveConfig((c) => {\n const allow = c.settings.permissions.allow.includes(rule)\n ? c.settings.permissions.allow\n : [...c.settings.permissions.allow, rule];\n return {\n ...c,\n settings: {\n ...c.settings,\n permissions: { ...c.settings.permissions, allow },\n },\n };\n });\n persistPermissionRuleLocal(config.workspace, 'allow', rule);\n },\n [config.workspace],\n );\n\n // The counterpart to the above, for the /permissions sheet. Without it a rule\n // was one keystroke to add and a hand-edited JSON file to remove.\n const removePermissionRule = useCallback(\n (entry: { list: 'allow' | 'ask' | 'deny'; rule: string }) => {\n const result = removePermissionRuleLocal(config.workspace, entry.list, entry.rule);\n if (!result.ok) return result;\n setLiveConfig((c) => ({\n ...c,\n settings: {\n ...c.settings,\n permissions: {\n ...c.settings.permissions,\n [entry.list]: c.settings.permissions[entry.list].filter((r) => r !== entry.rule),\n },\n },\n }));\n return result;\n },\n [config.workspace],\n );\n\n const setDefaultPermissionMode = useCallback(\n (nextMode: PermissionMode) => {\n const storedMode = nextMode === 'accept-edits' ? 'acceptEdits' : nextMode;\n const result = persistUserSettingClearingLocal(config.workspace, 'defaultMode', storedMode);\n if (!result.ok) return result;\n setLiveConfig((current) => ({\n ...current,\n settings: { ...current.settings, defaultMode: storedMode },\n }));\n return { ok: true };\n },\n [config.workspace],\n );\n\n return {\n messages,\n compactBoundaries,\n contextHistory: contextHistoryRef.current,\n isThinking,\n isCompacting,\n isCompactCommitted,\n isRewinding,\n compactUi,\n setCompactUi,\n streamingMessageId,\n error,\n currentTurn,\n tokenCount: usage?.totalTokens ?? 0,\n usage,\n sessionUsage,\n sessionUsageSinceResume,\n mode,\n pendingPermission,\n pendingPlanApproval,\n pendingUserQuestion: pendingUserQuestions[0] ?? null,\n pendingUserQuestionCount: pendingUserQuestions.length,\n pendingElicitation: pendingElicitations[0] ?? null,\n pendingElicitationCount: pendingElicitations.length,\n agentTodos,\n agentPlanCurrent,\n turnDurationMs,\n retryPhase,\n retryAttempt,\n retryMax,\n retryCountdownMs,\n liveConfig,\n runtime: agentSession.getRuntime(),\n removableProviderIds: ownedProviders.ids,\n removableProviderModelCounts: ownedProviders.modelCounts,\n sessionId,\n sessionName,\n send,\n sendAgentCompletions,\n sendBackgroundShellCompletion,\n startHostRun,\n clear,\n startNewConversation,\n resumeConversation,\n listSessions,\n endCurrentSession,\n resolvePermission,\n cancelPermission,\n resolvePlanApproval,\n resolveUserQuestion,\n resolveElicitation,\n elicitationHandler,\n cancel,\n compact,\n rewind,\n getRewindTargets,\n cycleMode,\n addLocalMessage,\n setModel,\n upsertProviderAndSelect,\n removeProvider,\n setEffort,\n setAgentProfileModel,\n setCompactModel,\n setSkillActivation,\n setSkillExecution,\n setSkillsEnabled,\n setMemoryAutoSave,\n toggleMemoryAutoSave,\n toggleShowThinking,\n toggleStartupAnimation,\n\n /** Reload the memory snapshot after approve/discard so the next agent turn picks up changes. */\n refreshMemoryContext: () => {\n setLiveConfig((c) => ({\n ...c,\n memoryContext: c.settings.memory.enabled ? loadMemoryContext(config.workspace) : undefined,\n }));\n },\n\n persistPermissionRule,\n removePermissionRule,\n setDefaultPermissionMode,\n };\n}\n","import type { Message } from '../../types/messages.js';\nimport type { NestedToolInvocation, ToolCall, ToolResult } from '../../types/tools.js';\n\nexport function makeMessage(\n role: 'user' | 'assistant',\n content: string,\n contextContent?: string,\n includeInContext = false,\n): Message {\n return {\n id: crypto.randomUUID(),\n role,\n content,\n contextContent,\n includeInContext,\n timestamp: Date.now(),\n };\n}\n\nfunction findMessageIndex(messages: Message[], id: string): number {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i].id === id) return i;\n }\n return -1;\n}\n\n/** True when an assistant message has no text and no tool activity. */\nexport function isTotallyEmptyAssistant(message: Message): boolean {\n if (message.role !== 'assistant') return false;\n if (message.content !== '') return false;\n if (message.reasoningContent) return false;\n if ((message.toolCalls?.length ?? 0) > 0) return false;\n if ((message.toolResults?.length ?? 0) > 0) return false;\n if ((message.nestedToolInvocations?.length ?? 0) > 0) return false;\n return true;\n}\n\n/**\n * Drop only a trailing totally-empty assistant placeholder.\n * Partial content, tools, or non-trailing empties are left untouched.\n */\nexport function removeTrailingEmptyAssistantPlaceholder(messages: Message[]): Message[] {\n if (messages.length === 0) return messages;\n const last = messages[messages.length - 1];\n if (!isTotallyEmptyAssistant(last)) return messages;\n return messages.slice(0, -1);\n}\n\n/**\n * Clear the text and reasoning streamed into a message, keeping the message.\n *\n * Used when the loop abandons an attempt and retries the same turn: the deltas\n * are already on screen and cannot be unsent, so the host drops them and lets the\n * replacement stream into the same row. Tool activity is left alone — a retry\n * only happens when the attempt produced none.\n */\nexport function resetStreamedContent(messages: Message[], id: string): Message[] {\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const message = messages[index];\n if (message.content === '' && !message.reasoningContent) return messages;\n const next = messages.slice();\n next[index] = { ...message, content: '', reasoningContent: undefined };\n return next;\n}\n\nexport function appendContentToMessage(\n messages: Message[],\n id: string,\n content: string,\n): Message[] {\n if (content === '') return messages;\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const next = messages.slice();\n const message = messages[index];\n next[index] = { ...message, content: message.content + content };\n return next;\n}\n\nexport function appendReasoningToMessage(\n messages: Message[],\n id: string,\n reasoning: string,\n): Message[] {\n if (reasoning === '') return messages;\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const next = messages.slice();\n const message = messages[index];\n next[index] = {\n ...message,\n reasoningContent: (message.reasoningContent ?? '') + reasoning,\n };\n return next;\n}\n\n/** Upsert a top-level tool call by stable `call.id` (append-only for new ids). */\nexport function appendToolCallToMessage(\n messages: Message[],\n id: string,\n call: ToolCall,\n): Message[] {\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const message = messages[index];\n const existing = message.toolCalls ?? [];\n const existingIndex = existing.findIndex((item) => item.id === call.id);\n let toolCalls: ToolCall[];\n if (existingIndex === -1) {\n toolCalls = [...existing, call];\n } else if (existing[existingIndex] === call) {\n return messages;\n } else {\n toolCalls = existing.slice();\n toolCalls[existingIndex] = call;\n }\n const next = messages.slice();\n next[index] = { ...message, toolCalls };\n return next;\n}\n\n/** Upsert a top-level tool result by stable `toolCallId`. */\nexport function appendToolResultToMessage(\n messages: Message[],\n id: string,\n result: ToolResult,\n): Message[] {\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const message = messages[index];\n const existing = message.toolResults ?? [];\n const existingIndex = existing.findIndex((item) => item.toolCallId === result.toolCallId);\n let toolResults: ToolResult[];\n if (existingIndex === -1) {\n toolResults = [...existing, result];\n } else if (existing[existingIndex] === result) {\n return messages;\n } else {\n toolResults = existing.slice();\n toolResults[existingIndex] = result;\n }\n const next = messages.slice();\n next[index] = { ...message, toolResults };\n return next;\n}\n\n/** Upsert a nested tool invocation by stable `traceId`. */\nexport function appendNestedToolInvocationToMessage(\n messages: Message[],\n id: string,\n invocation: NestedToolInvocation,\n): Message[] {\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const message = messages[index];\n const existing = message.nestedToolInvocations ?? [];\n const existingIndex = existing.findIndex((item) => item.traceId === invocation.traceId);\n let nestedToolInvocations: NestedToolInvocation[];\n if (existingIndex === -1) {\n nestedToolInvocations = [...existing, invocation];\n } else {\n const prev = existing[existingIndex];\n // Preserve an already-attached result unless the upsert carries a newer one.\n const merged: NestedToolInvocation = {\n ...prev,\n ...invocation,\n result: invocation.result ?? prev.result,\n };\n if (\n prev.traceId === merged.traceId &&\n prev.parentTraceId === merged.parentTraceId &&\n prev.call === merged.call &&\n prev.result === merged.result\n ) {\n return messages;\n }\n nestedToolInvocations = existing.slice();\n nestedToolInvocations[existingIndex] = merged;\n }\n const next = messages.slice();\n next[index] = { ...message, nestedToolInvocations };\n return next;\n}\n\n/** Attach/replace a nested tool result by stable `traceId`. */\nexport function appendNestedToolResultToMessage(\n messages: Message[],\n id: string,\n traceId: string,\n result: ToolResult,\n): Message[] {\n const index = findMessageIndex(messages, id);\n if (index === -1) return messages;\n const message = messages[index];\n const invocations = message.nestedToolInvocations ?? [];\n const invocationIndex = invocations.findIndex((invocation) => invocation.traceId === traceId);\n if (invocationIndex === -1) return messages;\n if (invocations[invocationIndex].result === result) return messages;\n\n const nestedToolInvocations = invocations.slice();\n nestedToolInvocations[invocationIndex] = {\n ...nestedToolInvocations[invocationIndex],\n result,\n };\n const next = messages.slice();\n next[index] = { ...message, nestedToolInvocations };\n return next;\n}\n\n/** What the streaming message holds, tracked as events arrive: the accumulator applies them a flush later. */\nexport interface StreamOutput {\n /** Text, reasoning or tool activity since the message was created. */\n any: boolean;\n /** Tool calls or results, which a discarded attempt leaves in place. */\n tools: boolean;\n /** A compaction committed behind this message's output: the turn's next output opens a new message. */\n closed: boolean;\n}\n\nexport function freshStreamOutput(): StreamOutput {\n return { any: false, tools: false, closed: false };\n}\n\n/**\n * Where a compaction's transcript row goes, and whether that is after the streaming message. While\n * the message has streamed nothing (a compaction at its turn's preflight gate, or an overflow\n * recovery that retries the turn) the row goes before it, because the turn's reply streams into it.\n * Once it has output the row goes after it, and the turn's next output opens a message of its own.\n * A streaming message not in `messages` yet is still being appended, and lands at `messages.length`.\n */\nexport function compactionPlacement(\n messages: readonly Message[],\n streamingId: string | null | undefined,\n hasOutput: boolean,\n): { ordinal: number; afterStreaming: boolean } {\n if (!streamingId) return { ordinal: messages.length, afterStreaming: false };\n const index = messages.findIndex((message) => message.id === streamingId);\n if (!hasOutput) return { ordinal: index >= 0 ? index : messages.length, afterStreaming: false };\n return { ordinal: index >= 0 ? messages.length : messages.length + 1, afterStreaming: true };\n}\n","/**\n * Persist settings from inside the Ink TUI without killing the app.\n *\n * Mirrors the write path of cli/config-cmd.ts but returns {ok, error?} instead\n * of calling console.log / process.exit(). Settings are layered user (global) →\n * project → local. Two write targets are exposed:\n * - `*Local` → <workspace>/.book/settings.local.json (per-project, gitignored)\n * - `*Global` → ~/.book/settings.json (shared across every project)\n * The split is by whose choice it is. A preference about how Book behaves for\n * *you* - provider registries, API keys, model, effort, compaction model,\n * permission default mode, thinking display, startup animation, memory\n * auto-save - is global, so it follows you across folders rather than being\n * re-set per project. What stays local is what is genuinely about *this*\n * repository: which skills are on, and the permission rules approved for its\n * tools.\n */\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport {\n formatSettingsDiagnostics,\n readSettingsDocument,\n SettingsRepository,\n} from '../settings-repository.js';\nimport { resolveBookHome } from '../book-home.js';\nimport type { SkillActivation, SkillExecution } from '../settings.js';\nimport { blockedWorkspaceSettingWrite } from '../settings-scope.js';\n\nconst LOCAL_DIR = '.book';\nconst LOCAL_FILE = 'settings.local.json';\nconst GLOBAL_FILE = 'settings.json';\n\n/** Absolute path to the per-project local settings file. */\nfunction localSettingsPath(workspace: string): string {\n return join(workspace, LOCAL_DIR, LOCAL_FILE);\n}\n\n/** Absolute path to the user-global settings file (~/.book/settings.json). */\nfunction globalSettingsPath(): string {\n return join(resolveBookHome(), GLOBAL_FILE);\n}\n\n/** Human-readable labels used in provider-removal diagnostics. */\nconst LOCAL_LABEL = `${LOCAL_DIR}/${LOCAL_FILE}`;\nconst GLOBAL_LABEL = `~/${LOCAL_DIR}/${GLOBAL_FILE}`;\n\nexport type RemoveLocalProviderResult =\n | {\n ok: true;\n providerId: string;\n removedModelCount: number;\n localDefaultCleared: boolean;\n localProviderExisted: true;\n }\n | {\n ok: false;\n providerId: string;\n removedModelCount: number;\n localDefaultCleared: false;\n localProviderExisted: boolean;\n error: string;\n };\n\n/** Read a settings document at `path` as a plain object ({} if absent/invalid). */\nfunction readSettingsAt(path: string): Record<string, unknown> {\n const result = readSettingsDocument(path);\n return result.status === 'valid' ? result.document : {};\n}\n\n/** Read the project-local settings.local.json as a plain object. */\nexport function readSettingsLocal(workspace: string): Record<string, unknown> {\n return readSettingsAt(localSettingsPath(workspace));\n}\n\n/** Read the user-global ~/.book/settings.json as a plain object. */\nexport function readSettingsGlobal(): Record<string, unknown> {\n return readSettingsAt(globalSettingsPath());\n}\n\n/**\n * Set one or more dot-path keys in the settings file at `path` and persist it.\n * Returns {ok:false, error} on a filesystem or write failure (never throws).\n * Values are stored verbatim — number/bool/object callers should pre-serialize,\n * but a non-string is also stored as-is.\n */\nfunction persistSettingsAt(\n path: string,\n values: Record<string, unknown>,\n): { ok: boolean; error?: string } {\n const result = new SettingsRepository(path).set(values);\n return result.ok\n ? { ok: true }\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\n}\n\n/** Persist keys to the project-local layer (.book/settings.local.json). */\nexport function persistSettingsLocal(\n workspace: string,\n values: Record<string, unknown>,\n): { ok: boolean; error?: string } {\n for (const [key, value] of Object.entries(values)) {\n // The value decides for the sandbox, so it is passed rather than the path\n // alone: refusing `sandbox.enabled` outright would block the one value a\n // workspace layer may set (#373).\n const blocked = blockedWorkspaceSettingWrite(key, value);\n if (blocked) return { ok: false, error: blocked };\n }\n return persistSettingsAt(localSettingsPath(workspace), values);\n}\n\n/** Persist keys to the user-global layer (~/.book/settings.json). */\nexport function persistSettingsGlobal(values: Record<string, unknown>): {\n ok: boolean;\n error?: string;\n} {\n return persistSettingsAt(globalSettingsPath(), values);\n}\n\nexport function persistSettingLocal(\n workspace: string,\n key: string,\n value: unknown,\n): { ok: boolean; error?: string } {\n return persistSettingsLocal(workspace, { [key]: value });\n}\n\nexport function persistSettingGlobal(key: string, value: unknown): { ok: boolean; error?: string } {\n return persistSettingsGlobal({ [key]: value });\n}\n\n/**\n * Write a user-global preference and drop the workspace-local value it would\n * otherwise lose to.\n *\n * The local layer resolves last, so a stale override there survives the global\n * write and silently decides the *next* session — the setting moves in front of\n * the user, then moves back when they restart. `setModel` had carried the\n * `clearLocalSettings` call for exactly this reason and the other six user-layer\n * writes had not, which is how `compactModel` and `effort` came to revert:\n * an earlier version of `/config <key>=<value>` put every typed setting in the\n * local file, so the stale value is one those users are especially likely to\n * have. One helper rather than seven call sites is what keeps that from being\n * true again of the eighth.\n */\nexport function persistUserSettingClearingLocal(\n workspace: string,\n key: string,\n value: unknown,\n): { ok: boolean; error?: string } {\n const result = persistSettingsGlobal({ [key]: value });\n if (!result.ok) return result;\n clearLocalSettings(workspace, [key]);\n return { ok: true };\n}\n\n/** Persist a profile model without treating dots in the profile name as path separators. */\nexport function persistAgentProfileModel(\n workspace: string,\n profile: string,\n model?: string,\n): { ok: boolean; error?: string } {\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\n const agents =\n candidate.agents && typeof candidate.agents === 'object' && !Array.isArray(candidate.agents)\n ? (candidate.agents as Record<string, unknown>)\n : {};\n const profiles =\n agents.profiles && typeof agents.profiles === 'object' && !Array.isArray(agents.profiles)\n ? (agents.profiles as Record<string, Record<string, unknown>>)\n : {};\n const existing =\n profiles[profile] && typeof profiles[profile] === 'object' ? { ...profiles[profile] } : {};\n\n // \"inherit\" must be explicit so it can override project/global settings and frontmatter.\n existing.model = model ?? 'inherit';\n profiles[profile] = existing;\n candidate.agents = { ...agents, profiles };\n });\n return result.ok\n ? { ok: true }\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\n}\n\n/** Persist a skill override without treating dots in a skill name as path separators. */\nexport function persistSkillActivationLocal(\n workspace: string,\n skillName: string,\n activation: SkillActivation,\n): { ok: boolean; error?: string } {\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\n const skills =\n candidate.skills && typeof candidate.skills === 'object' && !Array.isArray(candidate.skills)\n ? (candidate.skills as Record<string, unknown>)\n : {};\n const overrides =\n skills.overrides && typeof skills.overrides === 'object' && !Array.isArray(skills.overrides)\n ? (skills.overrides as Record<string, unknown>)\n : {};\n overrides[skillName] = activation;\n candidate.skills = { ...skills, overrides };\n });\n return result.ok\n ? { ok: true }\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\n}\n\n/** Persist a per-skill consent policy without splitting dotted names into paths. */\nexport function persistSkillExecutionLocal(\n workspace: string,\n skillName: string,\n execution: SkillExecution,\n): { ok: boolean; error?: string } {\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\n const skills =\n candidate.skills && typeof candidate.skills === 'object' && !Array.isArray(candidate.skills)\n ? (candidate.skills as Record<string, unknown>)\n : {};\n const policies =\n skills.execution && typeof skills.execution === 'object' && !Array.isArray(skills.execution)\n ? (skills.execution as Record<string, unknown>)\n : {};\n policies[skillName] = execution;\n candidate.skills = { ...skills, execution: policies };\n });\n return result.ok\n ? { ok: true }\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\n}\n\nexport function persistSkillsEnabledLocal(\n workspace: string,\n enabled: boolean,\n): { ok: boolean; error?: string } {\n return persistSettingLocal(workspace, 'skills.enabled', enabled);\n}\n\n/**\n * Remove dot-path keys from the project-local layer if present. Used after a\n * value has been written to the global layer to clear a stale per-project\n * override that would otherwise shadow the new global value (local wins for\n * scalars during resolution). A no-op when the local file is absent; never\n * throws. Empty parent objects (e.g. an emptied provider registry) are pruned.\n */\nexport function clearLocalSettings(\n workspace: string,\n paths: string[],\n): { ok: boolean; error?: string } {\n const path = localSettingsPath(workspace);\n if (!existsSync(path)) return { ok: true };\n const result = new SettingsRepository(path).remove(paths);\n return result.ok\n ? { ok: true }\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\n}\n\n/** Remove one provider from the settings file at `path` and any default targeting it. */\nfunction removeProviderAt(\n path: string,\n label: string,\n providerId: string,\n): RemoveLocalProviderResult {\n if (!existsSync(path)) {\n return {\n ok: false,\n providerId,\n removedModelCount: 0,\n localDefaultCleared: false,\n localProviderExisted: false,\n error: `Provider \"${providerId}\" is not configured in ${label}.`,\n };\n }\n const source = readSettingsDocument(path);\n if (source.status !== 'valid') {\n return {\n ok: false,\n providerId,\n removedModelCount: 0,\n localDefaultCleared: false,\n localProviderExisted: false,\n error: source.status === 'absent' ? `${label} settings are absent.` : source.error,\n };\n }\n const existing = source.document;\n\n const registry = existing.provider;\n const ownsProvider =\n typeof registry === 'object' &&\n registry !== null &&\n !Array.isArray(registry) &&\n Object.prototype.hasOwnProperty.call(registry, providerId);\n if (!ownsProvider) {\n return {\n ok: false,\n providerId,\n removedModelCount: 0,\n localDefaultCleared: false,\n localProviderExisted: false,\n error: `Provider \"${providerId}\" is not configured in ${label}.`,\n };\n }\n\n const provider = (registry as Record<string, unknown>)[providerId];\n const models =\n typeof provider === 'object' && provider !== null && !Array.isArray(provider)\n ? (provider as Record<string, unknown>).models\n : undefined;\n const removedModelCount =\n typeof models === 'object' && models !== null && !Array.isArray(models)\n ? Object.keys(models).length\n : 0;\n const localDefaultCleared =\n typeof existing.model === 'string' && existing.model.startsWith(`${providerId}/`);\n\n const result = new SettingsRepository(path).update((candidate) => {\n const candidateProviders = candidate.provider as Record<string, unknown>;\n delete candidateProviders[providerId];\n if (Object.keys(candidateProviders).length === 0) delete candidate.provider;\n if (localDefaultCleared) delete candidate.model;\n });\n if (result.ok) {\n return {\n ok: true,\n providerId,\n removedModelCount,\n localDefaultCleared,\n localProviderExisted: true,\n };\n }\n return {\n ok: false,\n providerId,\n removedModelCount,\n localDefaultCleared: false,\n localProviderExisted: true,\n error: formatSettingsDiagnostics(result.diagnostics),\n };\n}\n\n/** Remove one workspace-local provider and any local default that targets it. */\nexport function removeProviderLocal(\n workspace: string,\n providerId: string,\n): RemoveLocalProviderResult {\n return removeProviderAt(localSettingsPath(workspace), LOCAL_LABEL, providerId);\n}\n\n/** Remove one user-global provider and any global default that targets it. */\nexport function removeProviderGlobal(providerId: string): RemoveLocalProviderResult {\n return removeProviderAt(globalSettingsPath(), GLOBAL_LABEL, providerId);\n}\n\n/**\n * Append a permission rule to settings.permissions.<list> in the local layer.\n * Dedupes exact-string matches. Used by the \"Always allow\" approval flow\n * (the Claude-Code-aligned way rules get added, rather than a /permissions\n * string parser).\n */\nexport function persistPermissionRuleLocal(\n workspace: string,\n list: 'allow' | 'ask' | 'deny',\n rule: string,\n): { ok: boolean; error?: string } {\n const existing = readSettingsLocal(workspace);\n const perms = (existing.permissions ?? {}) as Record<string, unknown[]>;\n const arr = Array.isArray(perms[list]) ? [...(perms[list] as unknown[])] : [];\n if (!arr.includes(rule)) arr.push(rule);\n perms[list] = arr;\n return persistSettingLocal(workspace, 'permissions', perms);\n}\n\n/**\n * Remove one permission rule from the local layer.\n *\n * The counterpart to {@link persistPermissionRuleLocal}, which had none: a rule\n * went in on one keystroke at a tool prompt and came out only by hand-editing\n * `.book/settings.local.json`, since `book config unset permissions.allow`\n * drops the whole list. A rule the user cannot see themselves removing is a\n * rule they cannot safely grant.\n *\n * Only the local layer is writable here, so a rule inherited from the project\n * or user-global layer reports `notLocal` rather than silently doing nothing.\n */\nexport function removePermissionRuleLocal(\n workspace: string,\n list: 'allow' | 'ask' | 'deny',\n rule: string,\n): { ok: boolean; error?: string; notLocal?: boolean } {\n const existing = readSettingsLocal(workspace);\n const perms = (existing.permissions ?? {}) as Record<string, unknown[]>;\n const arr = Array.isArray(perms[list]) ? [...(perms[list] as unknown[])] : [];\n if (!arr.includes(rule)) return { ok: false, notLocal: true };\n perms[list] = arr.filter((entry) => entry !== rule);\n return persistSettingLocal(workspace, 'permissions', perms);\n}\n","import { createDefaultRegistry } from '../tools/registry.js';\nimport { AgentSession, type AgentSessionDependencies } from './agent-session.js';\nimport type { ToolDefinition } from '../types/tools.js';\n\nexport interface InteractiveAgentSessionDependencies extends AgentSessionDependencies {\n /**\n * Extra tool definitions merged into each per-send registry. Evaluated on\n * every send so late-arriving surfaces (e.g. MCP servers that finish\n * connecting in the background) join the next turn without a restart.\n */\n additionalTools?: () => ToolDefinition[];\n}\n\n/** Compose the interactive tool surface outside React host code. */\nexport function createInteractiveAgentSession(\n dependencies: InteractiveAgentSessionDependencies = {},\n): AgentSession {\n const { additionalTools, ...sessionDependencies } = dependencies;\n return new AgentSession({\n ...sessionDependencies,\n registryFactory:\n dependencies.registryFactory ??\n ((request) => {\n const registry = createDefaultRegistry({\n agents: request.config.settings.agents.mode !== 'off',\n ...(request.registryStore\n ? {\n sessionHistory: {\n store: request.registryStore,\n sessionId: () => request.sessionId,\n },\n }\n : {}),\n });\n const extra = additionalTools?.() ?? [];\n if (extra.length > 0) registry.registerAll(extra);\n return registry;\n }),\n });\n}\n","import type { NestedToolInvocation, ToolCall, ToolResult } from '../../types/tools.js';\nimport {\n appendContentToMessage,\n appendReasoningToMessage,\n appendNestedToolInvocationToMessage,\n appendNestedToolResultToMessage,\n appendToolCallToMessage,\n appendToolResultToMessage,\n} from './streaming-state.js';\nimport type { Message } from '../../types/messages.js';\n\n/**\n * A single queued streaming operation.\n *\n * Text ops are coalesced during flush; tool call/result ops are applied\n * individually to preserve identity.\n */\nexport type AccumulatorOp =\n | { type: 'text'; content: string }\n | { type: 'reasoning'; content: string }\n | { type: 'toolCall'; call: ToolCall }\n | { type: 'toolResult'; result: ToolResult }\n | { type: 'nestedToolCall'; invocation: NestedToolInvocation }\n | { type: 'nestedToolResult'; traceId: string; result: ToolResult };\n\n/**\n * Batched message accumulator for streaming events.\n *\n * Collects text deltas, tool calls, and tool results in a queue and flushes\n * them on a bounded cadence. Consecutive text ops are coalesced into a single\n * appendContentToMessage call, and no timer stays active while the queue is idle.\n *\n * The flush callback is a `setMessages`-style state updater so React can\n * batch the update with other state changes.\n */\nexport interface MessageAccumulator {\n /** Queue a text delta (appended to the streaming message). */\n addText: (content: string) => void;\n /** Queue a provider-native reasoning delta. */\n addReasoning: (content: string) => void;\n /** Queue a tool call. */\n addToolCall: (call: ToolCall) => void;\n /** Queue a tool result. */\n addToolResult: (result: ToolResult) => void;\n /** Queue a display-only tool call from a Task subagent. */\n addNestedToolCall: (invocation: NestedToolInvocation) => void;\n /** Queue a result for a display-only subagent tool call. */\n addNestedToolResult: (traceId: string, result: ToolResult) => void;\n /** Flush all queued ops immediately (called by timer and stop). */\n flush: () => void;\n /** Enable scheduled flushing. Queued work starts the timer on demand. */\n start: () => void;\n /** Stop the timer, flush remaining ops. Idempotent. */\n stop: () => void;\n /** Stop the timer and drop queued ops without flushing. Idempotent. */\n discard: () => void;\n}\n\ninterface AccumulatorState {\n queue: AccumulatorOp[];\n timerId: ReturnType<typeof setTimeout> | null;\n stopped: boolean;\n intervalMs: number;\n}\n\n/**\n * Create a message accumulator for the given message ID.\n *\n * @param messageId - ID of the assistant message being streamed into.\n * @param setMessages - React state setter (updater form).\n * @param messagesRef - Mutable ref mirror of the messages array, kept in sync.\n * @param flushIntervalMs - Flush cadence in milliseconds (default 16 ≈ 60fps).\n */\nexport function createMessageAccumulator(\n messageId: string,\n setMessages: (updater: (prev: Message[]) => Message[]) => void,\n messagesRef: { current: Message[] },\n flushIntervalMs = 16,\n): MessageAccumulator {\n const state: AccumulatorState = {\n queue: [],\n timerId: null,\n stopped: false,\n intervalMs: flushIntervalMs,\n };\n\n function scheduleNext(): void {\n if (state.stopped || state.timerId !== null || state.queue.length === 0) return;\n state.timerId = setTimeout(() => {\n state.timerId = null;\n flush();\n scheduleNext();\n }, state.intervalMs);\n }\n\n function flush(): void {\n if (state.queue.length === 0) return;\n\n // Drain the queue so new ops added during setMessages are captured\n // in the next flush.\n const ops = state.queue;\n state.queue = [];\n\n // Coalesce consecutive text/reasoning ops into a single append operation.\n // Tool calls and results are applied individually.\n const coalesced: AccumulatorOp[] = [];\n for (const op of ops) {\n if (\n (op.type === 'text' || op.type === 'reasoning') &&\n coalesced.length > 0 &&\n coalesced[coalesced.length - 1].type === op.type\n ) {\n (\n coalesced[coalesced.length - 1] as { type: 'text' | 'reasoning'; content: string }\n ).content += op.content;\n } else {\n coalesced.push(op);\n }\n }\n\n if (coalesced.length === 0) return;\n\n const startedAt = performance.now();\n setMessages((prev: Message[]) => {\n let messageIndex = -1;\n for (let index = prev.length - 1; index >= 0; index--) {\n if (prev[index].id === messageId) {\n messageIndex = index;\n break;\n }\n }\n if (messageIndex < 0) return prev;\n\n let active = [prev[messageIndex]];\n for (const op of coalesced) {\n if (op.type === 'text') {\n active = appendContentToMessage(active, messageId, op.content);\n } else if (op.type === 'reasoning') {\n active = appendReasoningToMessage(active, messageId, op.content);\n } else if (op.type === 'toolCall') {\n active = appendToolCallToMessage(active, messageId, op.call);\n } else if (op.type === 'toolResult') {\n active = appendToolResultToMessage(active, messageId, op.result);\n } else if (op.type === 'nestedToolCall') {\n active = appendNestedToolInvocationToMessage(active, messageId, op.invocation);\n } else {\n active = appendNestedToolResultToMessage(active, messageId, op.traceId, op.result);\n }\n }\n if (active[0] === prev[messageIndex]) return prev;\n const next = prev.slice();\n next[messageIndex] = active[0];\n messagesRef.current = next;\n return next;\n });\n const transcriptPressure = Math.floor(messagesRef.current.length / 250) * 8;\n // React/Ink commits after the state setter returns. Sample on the next\n // macrotask so the cadence reflects actual render pressure, not just the\n // time spent constructing the next message array.\n setImmediate(() => {\n if (state.stopped) return;\n const renderPressure = performance.now() - startedAt;\n state.intervalMs = Math.min(\n 48,\n Math.max(\n flushIntervalMs,\n Math.ceil(renderPressure * 1.5),\n flushIntervalMs + transcriptPressure,\n ),\n );\n });\n }\n\n function addText(content: string): void {\n if (state.stopped) return;\n state.queue.push({ type: 'text', content });\n scheduleNext();\n }\n\n function addReasoning(content: string): void {\n if (state.stopped) return;\n state.queue.push({ type: 'reasoning', content });\n scheduleNext();\n }\n\n function addToolCall(call: ToolCall): void {\n if (state.stopped) return;\n state.queue.push({ type: 'toolCall', call });\n scheduleNext();\n }\n\n function addToolResult(result: ToolResult): void {\n if (state.stopped) return;\n state.queue.push({ type: 'toolResult', result });\n scheduleNext();\n }\n\n function addNestedToolCall(invocation: NestedToolInvocation): void {\n if (state.stopped) return;\n state.queue.push({ type: 'nestedToolCall', invocation });\n scheduleNext();\n }\n\n function addNestedToolResult(traceId: string, result: ToolResult): void {\n if (state.stopped) return;\n state.queue.push({ type: 'nestedToolResult', traceId, result });\n scheduleNext();\n }\n\n function start(): void {\n state.stopped = false;\n scheduleNext();\n }\n\n function stop(): void {\n if (state.stopped) return;\n state.stopped = true;\n if (state.timerId !== null) {\n clearTimeout(state.timerId);\n state.timerId = null;\n }\n // Final flush of any remaining ops and pending text.\n flush();\n }\n\n function discard(): void {\n state.stopped = true;\n state.queue = [];\n if (state.timerId !== null) {\n clearTimeout(state.timerId);\n state.timerId = null;\n }\n }\n\n return {\n addText,\n addReasoning,\n addToolCall,\n addToolResult,\n addNestedToolCall,\n addNestedToolResult,\n flush,\n start,\n stop,\n discard,\n };\n}\n","import { useState, useCallback } from 'react';\n\nexport interface Task {\n id: string;\n subject: string;\n status: 'pending' | 'in_progress' | 'completed';\n createdAt: number;\n}\n\nexport function useTasks() {\n const [tasks, setTasks] = useState<Task[]>([]);\n\n const addTask = useCallback((data: { subject: string; status: Task['status'] }) => {\n const task: Task = {\n id: crypto.randomUUID(),\n subject: data.subject,\n status: data.status,\n createdAt: Date.now(),\n };\n setTasks((prev) => [...prev, task]);\n }, []);\n\n const updateTaskStatus = useCallback((id: string, status: Task['status']) => {\n setTasks((prev) => prev.map((t) => (t.id === id ? { ...t, status } : t)));\n }, []);\n\n const removeTask = useCallback((id: string) => {\n setTasks((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const clearTasks = useCallback(() => {\n setTasks([]);\n }, []);\n\n return { tasks, addTask, updateTaskStatus, removeTask, clearTasks };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { AgentManager } from '../../agents/manager.js';\nimport type {\n AgentActivity,\n AgentCompletionNotification,\n AgentRecord,\n AgentRuntimeEvent,\n AgentSummary,\n} from '../../agents/types.js';\nimport { projectAgentSummary } from '../../agents/projections.js';\nimport type { UserQuestionResponse } from '../../types/tools.js';\n\nexport type ManagedAgentSurface = 'main' | 'tasks' | 'detail';\n\nexport interface QueuedAgentCompletion {\n id: string;\n notification: AgentCompletionNotification;\n}\n\nexport interface ManagedAgentState {\n summaries: AgentSummary[];\n records: Map<string, AgentRecord>;\n activities: Map<string, AgentActivity[]>;\n liveText: Map<string, string>;\n selectedAgentId?: string;\n surface: ManagedAgentSurface;\n pendingPermissions: AgentRuntimeEvent[];\n pendingQuestions: Array<{\n agentId: string;\n request: NonNullable<AgentRecord['pendingQuestion']>;\n }>;\n pendingCompletions: QueuedAgentCompletion[];\n persistenceEvent?: Extract<AgentRuntimeEvent, { type: 'agent_persistence' }>;\n /**\n * The lines managed children have raised for the operator, each already carrying the child's\n * name, oldest first. Held rather than pushed straight into the transcript, because this hook\n * does not own the transcript: `app.tsx` takes them, and only when the session is idle.\n *\n * A queue and not a single slot, because the drain waits for idle and children run\n * concurrently: two children refusing something in the same turn would otherwise leave one\n * notice, and the operator would never learn a step did not happen.\n */\n noticeQueue: Extract<AgentRuntimeEvent, { type: 'agent_notice' }>[];\n /** Take the next held notice, leaving the rest for the following drain. */\n takeNotice: () => void;\n setSurface: (surface: ManagedAgentSurface) => void;\n selectAgent: (agentId?: string) => void;\n send: (message: string) => Promise<void>;\n stopOrDismiss: (agentId?: string) => Promise<void>;\n resolvePermission: (requestId: string, response: 'allow' | 'deny' | 'always') => Promise<void>;\n resolveQuestion: (agentId: string, response: UserQuestionResponse) => Promise<void>;\n acknowledgeCompletions: (ids: string[]) => Promise<void>;\n refresh: () => Promise<void>;\n}\n\nfunction upsertSummary(current: AgentSummary[], next: AgentSummary): AgentSummary[] {\n const filtered = current.filter((summary) => summary.agentId !== next.agentId);\n return [next, ...filtered].sort((left, right) => {\n const leftDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(left.status);\n const rightDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(right.status);\n if (leftDone !== rightDone) return leftDone ? 1 : -1;\n return right.updatedAt - left.updatedAt;\n });\n}\n\nexport function useManagedAgents(\n manager: AgentManager,\n parentSessionId?: string,\n): ManagedAgentState {\n const [summaries, setSummaries] = useState<AgentSummary[]>([]);\n const [records, setRecords] = useState<Map<string, AgentRecord>>(() => new Map());\n const [activities, setActivities] = useState<Map<string, AgentActivity[]>>(() => new Map());\n const [liveText, setLiveText] = useState<Map<string, string>>(() => new Map());\n const [selectedAgentId, setSelectedAgentId] = useState<string>();\n const [surface, setSurface] = useState<ManagedAgentSurface>('main');\n const [pendingCompletions, setPendingCompletions] = useState<QueuedAgentCompletion[]>([]);\n const [persistenceEvent, setPersistenceEvent] = useState<\n Extract<AgentRuntimeEvent, { type: 'agent_persistence' }> | undefined\n >();\n const [noticeQueue, setNoticeQueue] = useState<\n Extract<AgentRuntimeEvent, { type: 'agent_notice' }>[]\n >([]);\n const seenCompletions = useRef(new Set<string>());\n const deferredDismissals = useRef(new Set<string>());\n const visibleAgentIds = useRef(new Set<string>());\n\n const belongsToCurrentSession = useCallback(\n (candidateParentSessionId: string | undefined) =>\n parentSessionId === undefined || candidateParentSessionId === parentSessionId,\n [parentSessionId],\n );\n\n const enqueueCompletion = useCallback(\n (notification: AgentCompletionNotification) => {\n if (!belongsToCurrentSession(notification.parentSessionId)) return;\n const id = notification.deliveryId;\n if (seenCompletions.current.has(id)) return;\n seenCompletions.current.add(id);\n setPendingCompletions((current) => [...current, { id, notification }]);\n },\n [belongsToCurrentSession],\n );\n\n const refresh = useCallback(async () => {\n const pendingPromise =\n typeof manager.listPendingCompletions === 'function'\n ? manager.listPendingCompletions()\n : Promise.resolve([]);\n const [nextRecords, nextCompletions] = await Promise.all([manager.list(), pendingPromise]);\n const scopedRecords = nextRecords.filter((record) =>\n belongsToCurrentSession(record.parentSessionId),\n );\n visibleAgentIds.current = new Set(scopedRecords.map((record) => record.id));\n setRecords(new Map(scopedRecords.map((record) => [record.id, record])));\n setSummaries(\n scopedRecords\n .filter((record) => {\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(\n record.status,\n );\n return (\n !terminal ||\n deferredDismissals.current.has(record.id) ||\n (record.completionSequence ?? 0) > (record.completionDeliveredSequence ?? 0)\n );\n })\n .map(projectAgentSummary)\n .sort((left, right) => {\n const leftDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(left.status);\n const rightDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(\n right.status,\n );\n if (leftDone !== rightDone) return leftDone ? 1 : -1;\n return right.updatedAt - left.updatedAt;\n }),\n );\n for (const notification of nextCompletions) enqueueCompletion(notification);\n }, [enqueueCompletion, manager]);\n\n useEffect(() => {\n setSummaries([]);\n setRecords(new Map());\n setActivities(new Map());\n setLiveText(new Map());\n setSelectedAgentId(undefined);\n setSurface('main');\n setPendingCompletions([]);\n setPersistenceEvent(undefined);\n setNoticeQueue([]);\n seenCompletions.current.clear();\n deferredDismissals.current.clear();\n visibleAgentIds.current.clear();\n void refresh().catch(() => {});\n const unsubscribe = manager.subscribe(\n (event) => {\n if (event.type === 'agent_persistence') {\n setPersistenceEvent(event);\n return;\n }\n if (event.type === 'agent_notice') {\n // Only a child of this session, and only one the operator can see the row for: a\n // notice about an agent from another session would name something they cannot open.\n if (!visibleAgentIds.current.has(event.agentId)) return;\n setNoticeQueue((queued) => [...queued, event]);\n return;\n }\n if (event.type === 'agent_status') {\n if (!belongsToCurrentSession(event.parentSessionId)) return;\n visibleAgentIds.current.add(event.agent.agentId);\n setSummaries((current) => upsertSummary(current, event.agent));\n return;\n }\n if (event.type === 'agent_activity') {\n if (!visibleAgentIds.current.has(event.agentId)) return;\n setActivities((current) => {\n const next = new Map(current);\n const agentActivities = [...(next.get(event.agentId) ?? [])];\n const index = agentActivities.findIndex(\n (activity) => activity.id === event.activity.id,\n );\n if (index >= 0) agentActivities[index] = event.activity;\n else agentActivities.push(event.activity);\n next.set(event.agentId, agentActivities);\n return next;\n });\n setRecords((current) => {\n const record = current.get(event.agentId);\n if (!record) return current;\n return new Map(current).set(event.agentId, {\n ...record,\n currentActivity: event.activity,\n updatedAt: Math.max(\n record.updatedAt,\n event.activity.finishedAt ?? event.activity.startedAt,\n ),\n });\n });\n setSummaries((current) => {\n const summary = current.find((candidate) => candidate.agentId === event.agentId);\n if (!summary) return current;\n return upsertSummary(current, {\n ...summary,\n currentActivity: event.activity,\n updatedAt: Math.max(\n summary.updatedAt,\n event.activity.finishedAt ?? event.activity.startedAt,\n ),\n });\n });\n return;\n }\n if (event.type === 'agent_update' || event.type === 'agent_start') {\n if (!belongsToCurrentSession(event.agent.parentSessionId)) return;\n visibleAgentIds.current.add(event.agent.id);\n setRecords((current) => new Map(current).set(event.agent.id, event.agent));\n setSummaries((current) => upsertSummary(current, projectAgentSummary(event.agent)));\n return;\n }\n if (event.type === 'agent_result') {\n if (!belongsToCurrentSession(event.agent.parentSessionId)) return;\n visibleAgentIds.current.add(event.agent.id);\n setRecords((current) => new Map(current).set(event.agent.id, event.agent));\n // A Task child's result goes back through Task's own tool row and raises no completion,\n // and acknowledging a completion is what clears a finished row. Clear it here instead;\n // the record stays, so the Task row can still open the child's transcript.\n if (event.agent.parentToolCallId && !deferredDismissals.current.has(event.agent.id)) {\n const agentId = event.agent.id;\n setSummaries((current) => current.filter((summary) => summary.agentId !== agentId));\n return;\n }\n setSummaries((current) => upsertSummary(current, projectAgentSummary(event.agent)));\n return;\n }\n if (event.type === 'agent_completion') {\n enqueueCompletion(event.notification);\n return;\n }\n if (event.type === 'agent_message') {\n if (!visibleAgentIds.current.has(event.agentId)) return;\n setRecords((current) => {\n const record = current.get(event.agentId);\n if (!record || record.transcript.some((message) => message.id === event.message.id)) {\n return current;\n }\n return new Map(current).set(event.agentId, {\n ...record,\n transcript: [...record.transcript, event.message],\n });\n });\n // The deltas that built this message are now in the transcript. Left\n // in the live buffer they render a second time under it, and keep\n // accumulating across the child's later turns.\n setLiveText((current) => {\n if (!current.has(event.agentId)) return current;\n const next = new Map(current);\n next.delete(event.agentId);\n return next;\n });\n return;\n }\n if (event.type === 'agent_text_delta') {\n if (!visibleAgentIds.current.has(event.agentId)) return;\n setLiveText((current) => {\n const next = new Map(current);\n next.set(event.agentId, `${next.get(event.agentId) ?? ''}${event.text}`.slice(-12000));\n return next;\n });\n }\n },\n { snapshot: true },\n );\n manager.setInteractivePermissions(true);\n return () => {\n unsubscribe();\n manager.setInteractivePermissions(false);\n };\n }, [belongsToCurrentSession, enqueueCompletion, manager, refresh]);\n\n useEffect(() => {\n if (persistenceEvent?.state !== 'recovered') return;\n const timer = setTimeout(() => setPersistenceEvent(undefined), 3_000);\n return () => clearTimeout(timer);\n }, [persistenceEvent]);\n\n const pendingPermissions = useMemo(\n () =>\n Array.from(records.values())\n .filter((record) => record.pendingPermission)\n .sort(\n (left, right) =>\n (left.pendingPermission?.createdAt ?? 0) - (right.pendingPermission?.createdAt ?? 0),\n )\n .map((record) => ({\n type: 'agent_permission' as const,\n agentId: record.id,\n request: record.pendingPermission!,\n })),\n [records],\n );\n const pendingQuestions = useMemo(\n () =>\n Array.from(records.values())\n .filter((record) => record.pendingQuestion)\n .sort((left, right) => {\n const age =\n (left.pendingQuestionCreatedAt ?? left.updatedAt) -\n (right.pendingQuestionCreatedAt ?? right.updatedAt);\n return age || left.id.localeCompare(right.id);\n })\n .map((record) => ({ agentId: record.id, request: record.pendingQuestion! })),\n [records],\n );\n\n const send = useCallback(\n async (message: string) => {\n if (!selectedAgentId) return;\n deferredDismissals.current.delete(selectedAgentId);\n const next = await manager.send(selectedAgentId, message);\n setRecords((current) => new Map(current).set(next.id, next));\n setSummaries((current) => upsertSummary(current, projectAgentSummary(next)));\n },\n [manager, selectedAgentId],\n );\n\n const stopOrDismiss = useCallback(\n async (agentId?: string) => {\n const targetAgentId = agentId ?? selectedAgentId;\n if (!targetAgentId) return;\n const record = await manager.get(targetAgentId);\n if (!record) return;\n if (['completed', 'failed', 'stopped', 'interrupted'].includes(record.status)) {\n const completionPending =\n (record.completionSequence ?? 0) > (record.completionDeliveredSequence ?? 0);\n if (!completionPending) await manager.dismiss(targetAgentId);\n setRecords((current) => {\n const next = new Map(current);\n if (!completionPending) next.delete(targetAgentId);\n return next;\n });\n setSummaries((current) => current.filter((summary) => summary.agentId !== targetAgentId));\n setSelectedAgentId((current) => (current === targetAgentId ? undefined : current));\n return;\n }\n const next = await manager.stop(targetAgentId);\n setRecords((current) => new Map(current).set(next.id, next));\n setSummaries((current) => current.filter((summary) => summary.agentId !== targetAgentId));\n setSelectedAgentId((current) => (current === targetAgentId ? undefined : current));\n },\n [manager, selectedAgentId],\n );\n\n const resolvePermission = useCallback(\n async (requestId: string, response: 'allow' | 'deny' | 'always') => {\n const request = pendingPermissions.find(\n (event) => event.type === 'agent_permission' && event.request.id === requestId,\n );\n if (!request || request.type !== 'agent_permission') return;\n const next = await manager.resolvePermission(request.agentId, requestId, response);\n setRecords((current) => new Map(current).set(next.id, next));\n },\n [manager, pendingPermissions],\n );\n\n const resolveQuestion = useCallback(\n async (agentId: string, response: UserQuestionResponse) => {\n const next = await manager.resolveQuestion(agentId, response);\n setRecords((current) => new Map(current).set(next.id, next));\n },\n [manager],\n );\n\n const acknowledgeCompletions = useCallback(\n async (ids: string[]) => {\n if (ids.length === 0) return;\n const acknowledged = new Set(ids);\n const items = pendingCompletions.filter((item) => acknowledged.has(item.id));\n if (typeof manager.acknowledgeCompletion === 'function') {\n await Promise.all(\n items.map((item) => manager.acknowledgeCompletion(item.notification.deliveryId)),\n );\n }\n const completedAgentIds = new Set(items.map((item) => item.notification.completion.agentId));\n const heldAgentIds = new Set<string>();\n if (\n surface === 'detail' &&\n selectedAgentId !== undefined &&\n completedAgentIds.has(selectedAgentId)\n ) {\n heldAgentIds.add(selectedAgentId);\n deferredDismissals.current.add(selectedAgentId);\n }\n setSummaries((current) =>\n current.filter(\n (summary) => !completedAgentIds.has(summary.agentId) || heldAgentIds.has(summary.agentId),\n ),\n );\n setSelectedAgentId((current) =>\n current && completedAgentIds.has(current) && !heldAgentIds.has(current)\n ? undefined\n : current,\n );\n setPendingCompletions((current) => current.filter((item) => !acknowledged.has(item.id)));\n },\n [manager, pendingCompletions, selectedAgentId, surface],\n );\n\n const changeSurface = useCallback((nextSurface: ManagedAgentSurface) => {\n if (nextSurface === 'main' && deferredDismissals.current.size > 0) {\n const dismissed = new Set(deferredDismissals.current);\n deferredDismissals.current.clear();\n setSummaries((current) => current.filter((summary) => !dismissed.has(summary.agentId)));\n setSelectedAgentId((current) => (current && dismissed.has(current) ? undefined : current));\n }\n setSurface(nextSurface);\n }, []);\n\n return {\n summaries,\n records,\n activities,\n liveText,\n selectedAgentId,\n surface,\n pendingPermissions,\n pendingQuestions,\n pendingCompletions,\n noticeQueue,\n takeNotice: () => setNoticeQueue((queued) => queued.slice(1)),\n persistenceEvent,\n setSurface: changeSurface,\n selectAgent: setSelectedAgentId,\n send,\n stopOrDismiss,\n resolvePermission,\n resolveQuestion,\n acknowledgeCompletions,\n refresh,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\nimport { isTerminalShellStatus, type ShellJobManager } from '../../jobs/shell-manager.js';\n\n/**\n * Output chunks arrive at raw process frequency (hundreds/s for chatty\n * commands); every un-coalesced refresh forces a full App render + Yoga\n * layout pass. Consumers read live output via readTail/readOutput, never from\n * this list, so output events only need a slow safety-net refresh.\n */\nconst OUTPUT_REFRESH_COALESCE_MS = 250;\n\n/**\n * Field-wise equality over everything the shell list UI renders. Deliberately\n * ignores output, readOffset, and outputRevision: cloneRecord makes every\n * list() call referentially fresh, and without this bail each output chunk\n * would re-render the whole App with no visible change.\n */\nfunction shellListEquals(left: BackgroundShellRecord[], right: BackgroundShellRecord[]): boolean {\n if (left.length !== right.length) return false;\n for (let index = 0; index < left.length; index++) {\n const previous = left[index];\n const next = right[index];\n if (\n previous.id !== next.id ||\n previous.status !== next.status ||\n previous.title !== next.title ||\n previous.command !== next.command ||\n previous.lifetime !== next.lifetime ||\n previous.notify !== next.notify ||\n previous.pid !== next.pid ||\n previous.startedAt !== next.startedAt ||\n previous.finishedAt !== next.finishedAt ||\n previous.exitCode !== next.exitCode ||\n previous.truncatedBytes !== next.truncatedBytes\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport interface BackgroundShellState {\n shells: BackgroundShellRecord[];\n lastCompletion?: BackgroundShellRecord;\n pendingUiCompletions: BackgroundShellRecord[];\n pendingAgentCompletions: BackgroundShellRecord[];\n refresh: () => void;\n /** Resolves with the reason the stop or dismiss failed, or `undefined` when it did not. */\n stopOrDismiss: (shellId: string) => Promise<string | undefined>;\n acknowledge: (shellId: string) => void;\n acknowledgeAgentCompletion: (shellId: string, sequence?: number) => void;\n}\n\nexport function useBackgroundShells(\n manager: ShellJobManager,\n parentSessionId: string,\n): BackgroundShellState {\n const visible = useCallback(\n () => manager.list().filter((shell) => !isTerminalShellStatus(shell.status)),\n [manager],\n );\n const [shells, setShells] = useState<BackgroundShellRecord[]>(visible);\n const [pendingUiCompletions, setPendingUiCompletions] = useState<BackgroundShellRecord[]>(() =>\n manager.listPendingUiCompletions(),\n );\n const [pendingAgentCompletions, setPendingAgentCompletions] = useState<BackgroundShellRecord[]>(\n () => manager.listPendingAgentCompletions(parentSessionId),\n );\n const lastCompletion = pendingUiCompletions[0];\n const refresh = useCallback(() => {\n setShells((current) => {\n const next = visible();\n return shellListEquals(current, next) ? current : next;\n });\n }, [visible]);\n const outputRefreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n refresh();\n setPendingUiCompletions(manager.listPendingUiCompletions());\n setPendingAgentCompletions(manager.listPendingAgentCompletions(parentSessionId));\n const scheduleOutputRefresh = () => {\n if (outputRefreshTimerRef.current !== null) return;\n outputRefreshTimerRef.current = setTimeout(() => {\n outputRefreshTimerRef.current = null;\n refresh();\n }, OUTPUT_REFRESH_COALESCE_MS);\n };\n const unsubscribe = manager.subscribe((event) => {\n if (event.type === 'background_job_output') {\n // Refresh on a timer only: the list renders nothing from output, but\n // the periodic pass still picks up side effects such as truncation\n // counters and persistent-job status reconciliation.\n scheduleOutputRefresh();\n return;\n }\n if (event.type === 'background_job_result') {\n if (event.job.notify !== 'none') {\n setPendingUiCompletions((current) => [\n ...current.filter((shell) => shell.id !== event.job.id),\n event.job,\n ]);\n }\n if (\n event.job.notify === 'agent' &&\n event.job.parentSessionId === parentSessionId &&\n (event.job.completionSequence ?? 0) > (event.job.completionDeliveredSequence ?? 0)\n ) {\n setPendingAgentCompletions((current) => [\n ...current.filter((shell) => shell.id !== event.job.id),\n event.job,\n ]);\n }\n }\n refresh();\n });\n return () => {\n unsubscribe();\n if (outputRefreshTimerRef.current !== null) {\n clearTimeout(outputRefreshTimerRef.current);\n outputRefreshTimerRef.current = null;\n }\n };\n }, [manager, parentSessionId, refresh]);\n\n // A stop that cannot even be requested (its control file is unwritable) rejects. The TUI calls\n // this without awaiting, so a rejection here would be unhandled and end Book; it reports instead.\n const stopOrDismiss = useCallback(\n async (shellId: string): Promise<string | undefined> => {\n const shell = manager.get(shellId);\n if (!shell) return undefined;\n try {\n if (isTerminalShellStatus(shell.status)) {\n manager.dismiss(shellId);\n } else {\n await manager.stop(shellId);\n }\n return undefined;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n } finally {\n refresh();\n }\n },\n [manager, refresh],\n );\n\n const acknowledge = useCallback(\n (shellId: string) => {\n manager.acknowledgeCompletion(shellId);\n setPendingUiCompletions((current) => current.filter((shell) => shell.id !== shellId));\n refresh();\n },\n [manager, refresh],\n );\n\n const acknowledgeAgentCompletion = useCallback(\n (shellId: string, sequence?: number) => {\n manager.acknowledgeCompletion(shellId, sequence, 'agent');\n setPendingAgentCompletions((current) => current.filter((shell) => shell.id !== shellId));\n },\n [manager],\n );\n\n return {\n shells,\n lastCompletion,\n pendingUiCompletions,\n pendingAgentCompletions,\n refresh,\n stopOrDismiss,\n acknowledge,\n acknowledgeAgentCompletion,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { execFile } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { isTranscriptScrollActive } from '../scroll-activity.js';\nimport { buildChildEnv } from '../../child-env.js';\nimport { hardenedGitArgs, hardenedGitEnv } from '../../tools/git.js';\n\n/**\n * Whether `dir` sits anywhere inside a working tree, without spawning anything.\n *\n * Probing only `<workspace>/.git` succeeds at the repository root alone, so\n * launching from a subdirectory reported no branch. Asking `git rev-parse`\n * instead fixed that but made every poll spawn children even where there is no\n * repository at all: three processes every five seconds, forever, in any plain\n * directory. Walking up for the entry costs a handful of `stat` calls and gets\n * the subdirectory case right. A worktree or submodule stores `.git` as a file\n * rather than a directory, so the entry is what is checked, not its type.\n */\nexport function isInsideWorkTree(\n dir: string,\n exists: (path: string) => boolean = existsSync,\n): boolean {\n let current = resolve(dir);\n for (;;) {\n if (exists(join(current, '.git'))) return true;\n const parent = dirname(current);\n if (parent === current) return false;\n current = parent;\n }\n}\n\nexport interface GitStatus {\n branch: string;\n status: string; // '\\u2713' clean, '+2 ~1' staged/modified\n error?: string;\n}\n\n/**\n * Replace state only when the reported status actually changed.\n *\n * The poll allocates a fresh object every tick, so returning it unconditionally\n * made React re-render the whole app twelve times a minute in an idle session\n * for no visual change.\n */\nexport function sameStatus(left: GitStatus, right: GitStatus): boolean {\n return left.branch === right.branch && left.status === right.status && left.error === right.error;\n}\n\nexport function useGitStatus(workspace: string): GitStatus {\n const [status, setStatus] = useState<GitStatus>({ branch: '?', status: '' });\n const update = useCallback((next: GitStatus) => {\n setStatus((current) => (sameStatus(current, next) ? current : next));\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n let running = false;\n let activeController: AbortController | undefined;\n\n async function check(): Promise<void> {\n if (isTranscriptScrollActive()) return;\n if (running) return;\n running = true;\n if (!isInsideWorkTree(workspace)) {\n if (!cancelled) update({ branch: '?', status: '' });\n running = false;\n return;\n }\n activeController = new AbortController();\n\n try {\n const branch = await runGit(\n ['rev-parse', '--abbrev-ref', 'HEAD'],\n workspace,\n activeController.signal,\n );\n const short = await runGit(['status', '--short'], workspace, activeController.signal);\n\n if (!short) {\n if (!cancelled) update({ branch, status: '\\u2713' });\n return;\n }\n\n const lines = short.split('\\n').filter(Boolean);\n let staged = 0;\n let modified = 0;\n for (const line of lines) {\n const stagedChar = line[0];\n const modChar = line[1];\n if (stagedChar !== ' ' && stagedChar !== '?') staged++;\n if (modChar !== ' ') modified++;\n }\n\n const parts: string[] = [];\n if (staged > 0) parts.push(`+${staged}`);\n if (modified > 0) parts.push(`~${modified}`);\n\n if (!cancelled) update({ branch, status: parts.join(' ') });\n } catch {\n // Not a repository, or git is unavailable — both mean \"no branch\".\n if (!cancelled) update({ branch: '?', status: '', error: 'git error' });\n } finally {\n running = false;\n activeController = undefined;\n }\n }\n\n void check();\n const interval = setInterval(() => void check(), 5000);\n return () => {\n cancelled = true;\n activeController?.abort();\n clearInterval(interval);\n };\n }, [update, workspace]);\n\n return status;\n}\n\n/**\n * One poll's `git` call, hardened.\n *\n * The poll is not a tool call: nothing asks before it runs, and it runs every five seconds for as\n * long as the session lasts, in whatever repository was opened. A clone brings `.git/config` with\n * it, and `core.fsmonitor` there names a program `git status` executes — so without\n * `hardenedGitArgs` a checkout that sets it runs that program as soon as Book opens it. Every\n * call here is read-only, so the read-only hardening is the right one; the pager and the\n * credential prompt it cannot wait on come with it, as in `readOnlyGit`.\n */\nfunction runGit(args: string[], cwd: string, signal: AbortSignal): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n 'git',\n hardenedGitArgs(args),\n {\n cwd,\n timeout: 5_000,\n encoding: 'utf8',\n windowsHide: true,\n signal,\n env: buildChildEnv(process.env, hardenedGitEnv()),\n },\n (error, stdout) => (error ? reject(error) : resolve(stdout.trim())),\n );\n });\n}\n","import { useEffect, useRef } from 'react';\nimport type { AgentCompletionNotification } from '../../agents/types.js';\nimport { takeAgentCompletionBatch } from '../../agents/completion-notification.js';\nimport type { QueuedAgentCompletion } from './useManagedAgents.js';\n\nexport function useAgentCompletionDelivery(options: {\n pending: QueuedAgentCompletion[];\n parentSessionId: string;\n blocked: boolean;\n deliver: (notifications: AgentCompletionNotification[]) => Promise<boolean>;\n acknowledge: (ids: string[]) => Promise<void>;\n}): void {\n const deliveryInFlight = useRef(false);\n const deliveredIds = useRef(new Set<string>());\n const mounted = useRef(true);\n const retryAttempts = useRef(0);\n const retryTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const pendingKey = useRef('');\n const latest = useRef(options);\n const drain = useRef<() => void>(() => {});\n latest.current = options;\n\n const scheduleRetry = () => {\n if (!mounted.current || retryTimer.current || retryAttempts.current >= 5) return;\n const delayMs = Math.min(1000 * 2 ** retryAttempts.current, 16_000);\n retryAttempts.current++;\n retryTimer.current = setTimeout(() => {\n retryTimer.current = undefined;\n drain.current();\n }, delayMs);\n };\n\n drain.current = () => {\n const current = latest.current;\n if (!mounted.current || current.blocked || deliveryInFlight.current || retryTimer.current)\n return;\n const pending = current.pending.filter(\n (item) =>\n item.notification.parentSessionId === current.parentSessionId &&\n !deliveredIds.current.has(item.id),\n );\n if (pending.length === 0) return;\n\n const batchNotifications = takeAgentCompletionBatch(pending.map((item) => item.notification));\n const batchIds = new Set(batchNotifications.map((notification) => notification.deliveryId));\n const batch = pending.filter((item) => batchIds.has(item.notification.deliveryId));\n deliveryInFlight.current = true;\n let acknowledged = false;\n void current\n .deliver(batchNotifications)\n .then(async (nextAccepted) => {\n if (!nextAccepted || !mounted.current) {\n scheduleRetry();\n return;\n }\n const ids = batch.map((item) => item.id);\n try {\n await current.acknowledge(ids);\n } catch {\n scheduleRetry();\n return;\n }\n if (!mounted.current) return;\n retryAttempts.current = 0;\n for (const id of ids) deliveredIds.current.add(id);\n acknowledged = true;\n })\n .catch(() => {\n scheduleRetry();\n })\n .finally(() => {\n deliveryInFlight.current = false;\n if (acknowledged) queueMicrotask(() => drain.current());\n });\n };\n\n useEffect(() => {\n const nextKey = options.pending.map((item) => item.id).join('\\0');\n if (nextKey !== pendingKey.current) {\n pendingKey.current = nextKey;\n retryAttempts.current = 0;\n if (retryTimer.current) clearTimeout(retryTimer.current);\n retryTimer.current = undefined;\n }\n drain.current();\n }, [options.blocked, options.parentSessionId, options.pending]);\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n if (retryTimer.current) clearTimeout(retryTimer.current);\n retryTimer.current = undefined;\n };\n }, []);\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useEffect, useMemo } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport type { AgentSummary } from '../../agents/types.js';\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\nimport { useTheme } from '../theme.js';\nimport { CONTENT_COLUMN } from '../layout.js';\nimport { SECTION_SIGN } from '../marks.js';\nimport { SheetRule } from './chrome.js';\nimport { SubagentRow } from './SubagentRow.js';\nimport { BackgroundShellRow } from './BackgroundShellRow.js';\n\n// A stable default: a fresh `[]` per render re-ran the selection-reset effect after every key.\nconst NO_SHELLS: BackgroundShellRecord[] = [];\n\nexport function SubagentPanel({\n agents,\n shells = NO_SHELLS,\n selectedJobId,\n selectedAgentId,\n isActive = false,\n onSelect,\n onOpen,\n onClose,\n onCancel,\n onStopOrDismiss,\n width = 80,\n reducedMotion = false,\n screenReader = false,\n}: {\n agents: AgentSummary[];\n shells?: BackgroundShellRecord[];\n selectedJobId?: string;\n selectedAgentId?: string;\n isActive?: boolean;\n onSelect?: (id?: string) => void;\n onOpen?: (id: string) => void;\n onClose?: () => void;\n onCancel?: () => void;\n onStopOrDismiss?: (id: string) => void;\n width?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n}) {\n const theme = useTheme();\n const [selectedIndex, setSelectedIndex, currentIndex] = useKeyState(0);\n const orderedAgents = useMemo(\n () =>\n [...agents].sort((left, right) => {\n const terminal = (status: AgentSummary['status']) =>\n ['completed', 'failed', 'stopped', 'interrupted'].includes(status);\n const leftTerminal = terminal(left.status);\n const rightTerminal = terminal(right.status);\n if (leftTerminal !== rightTerminal) return leftTerminal ? 1 : -1;\n return right.updatedAt - left.updatedAt;\n }),\n [agents],\n );\n const orderedShells = useMemo(\n () =>\n [...shells].sort((left, right) => {\n const terminal = (status: BackgroundShellRecord['status']) =>\n ['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(status);\n const leftTerminal = terminal(left.status);\n const rightTerminal = terminal(right.status);\n if (leftTerminal !== rightTerminal) return leftTerminal ? 1 : -1;\n return (right.finishedAt ?? right.startedAt) - (left.finishedAt ?? left.startedAt);\n }),\n [shells],\n );\n const jobs = useMemo(\n () => [\n ...orderedAgents.map((agent) => ({ id: agent.agentId, kind: 'agent' as const, agent })),\n ...orderedShells.map((shell) => ({ id: shell.id, kind: 'shell' as const, shell })),\n ],\n [orderedAgents, orderedShells],\n );\n const rows = useMemo(() => [undefined, ...jobs.map((job) => job.id)], [jobs]);\n // Keyed on content, not identity: a parent passing a fresh `agents` array on every render must\n // not reset the selection between keys, which Ink 7 flushes effects between.\n const rowsKey = rows.map((row) => row ?? '').join('\\u0000');\n useEffect(() => {\n const selected = selectedJobId ?? selectedAgentId;\n const next = selected ? rowsKey.split('\\u0000').indexOf(selected) : 0;\n const resolved = next >= 0 ? next : 0;\n setSelectedIndex(resolved);\n }, [rowsKey, selectedAgentId, selectedJobId, setSelectedIndex]);\n useInput(\n (input, key) => {\n if (!isActive) return;\n if (key.escape) return onCancel?.();\n if (key.upArrow) {\n const next = (currentIndex() - 1 + rows.length) % rows.length;\n setSelectedIndex(next);\n onSelect?.(rows[next]);\n } else if (key.downArrow || key.tab) {\n const next = (currentIndex() + 1) % rows.length;\n setSelectedIndex(next);\n onSelect?.(rows[next]);\n } else if (key.return) {\n const id = rows[currentIndex()];\n if (id) onOpen?.(id);\n else onClose?.();\n } else if (input === 'x') {\n const id = rows[currentIndex()];\n if (id) onStopOrDismiss?.(id);\n }\n },\n { isActive },\n );\n const tiny = width < 42;\n const maxVisible = 5;\n // Keep the focused agent inside the window so Tab-cycling never highlights a\n // row that has scrolled out of view.\n const selected = selectedJobId ?? selectedAgentId;\n const focusedAgentIndex = selected ? jobs.findIndex((job) => job.id === selected) : -1;\n const windowStart =\n focusedAgentIndex < 0\n ? 0\n : Math.min(\n Math.max(0, focusedAgentIndex - (maxVisible - 1)),\n Math.max(0, jobs.length - maxVisible),\n );\n const visible = tiny\n ? [jobs.find((job) => job.id === selected) ?? jobs[0]].filter(Boolean)\n : jobs.slice(windowStart, windowStart + maxVisible);\n const activeRowId = rows[selectedIndex];\n const selectedMain = activeRowId === undefined;\n if (jobs.length === 0 && !isActive) return null;\n return (\n <Box flexDirection=\"column\" width={width} marginTop={1}>\n <SheetRule\n mark={SECTION_SIGN}\n label=\"Background tasks\"\n tone={theme.text}\n meta={jobs.length > 0 ? String(jobs.length) : ''}\n width={width}\n />\n <Box>\n <Text color={selectedMain ? theme.text : theme.subtle} bold={selectedMain}>\n {selectedMain ? '› ' : ' '}● main\n </Text>\n <Text color={theme.subtle}> current conversation</Text>\n </Box>\n {jobs.length === 0 ? (\n <Box paddingLeft={CONTENT_COLUMN}>\n <Text color={theme.subtle}>No background tasks.</Text>\n </Box>\n ) : null}\n {visible.map((job) =>\n job.kind === 'agent' ? (\n <SubagentRow\n key={job.id}\n agent={job.agent}\n selected={job.id === activeRowId}\n width={Math.max(20, width - 2)}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n />\n ) : (\n <BackgroundShellRow\n key={job.id}\n shell={job.shell}\n selected={job.id === activeRowId}\n width={Math.max(20, width - 2)}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n />\n ),\n )}\n {jobs.length > visible.length ? (\n <Box paddingLeft={CONTENT_COLUMN}>\n <Text color={theme.subtle}>+{jobs.length - visible.length} more tasks</Text>\n </Box>\n ) : null}\n <Box paddingLeft={CONTENT_COLUMN}>\n <Text color={theme.subtle}>\n {isActive\n ? 'Tab/↑↓ select · Enter open · x stop/dismiss · Esc cancel'\n : 'Tab switch job · /jobs manage'}\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Text } from 'ink';\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\nimport { useTheme } from '../theme.js';\nimport { useUiClock } from '../ui-clock.js';\nimport { formatElapsedDuration } from './SubagentRow.js';\nimport { truncateDisplay } from './word-wrap.js';\n\nfunction glyph(shell: BackgroundShellRecord, reducedMotion: boolean): string {\n if (shell.status === 'exited') return '✓';\n if (shell.status === 'failed' || shell.status === 'timed_out' || shell.status === 'lost')\n return '✕';\n if (shell.status === 'killed') return '■';\n return reducedMotion ? '*' : '●';\n}\n\nexport function BackgroundShellRow({\n shell,\n selected = false,\n width = 80,\n reducedMotion = false,\n screenReader = false,\n}: {\n shell: BackgroundShellRecord;\n selected?: boolean;\n width?: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n}) {\n const theme = useTheme();\n const terminal = ['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(shell.status);\n const tick = useUiClock('slow', !terminal);\n void tick;\n const elapsed = Math.max(\n 0,\n Math.floor(((shell.finishedAt ?? Date.now()) - shell.startedAt) / 1000),\n );\n const unread =\n (shell.completionSequence ?? 0) > (shell.completionAcknowledgedSequence ?? 0) ? ' !' : '';\n const lifetime = shell.lifetime === 'persistent' ? ' | persistent' : '';\n const suffix = ` | ${formatElapsedDuration(elapsed)}${lifetime}${unread}`;\n const title = shell.title || shell.command;\n const color =\n shell.status === 'exited'\n ? theme.success\n : shell.status === 'failed' || shell.status === 'timed_out' || shell.status === 'lost'\n ? theme.error\n : theme.brand;\n\n if (screenReader) {\n return (\n <Text>\n {title}. shell. {shell.status}. {formatElapsedDuration(elapsed)}.\n </Text>\n );\n }\n\n return (\n <Text color={selected ? theme.text : color} bold={selected}>\n {selected ? '› ' : ' '}\n {glyph(shell, reducedMotion)} shell{' '}\n {truncateDisplay(title, Math.max(1, width - 11 - suffix.length))}\n <Text color={theme.subtle}>{suffix}</Text>\n </Text>\n );\n}\n","import { Box, Text } from 'ink';\nimport { useMemo } from 'react';\nimport type { AgentRecord } from '../../agents/types.js';\nimport type { Message } from '../../types/messages.js';\nimport type { TranscriptMode } from '../tool-presentation.js';\nimport { useTheme } from '../theme.js';\nimport { AgentMessage } from './AgentMessage.js';\nimport { ChatPanel } from './ChatPanel.js';\n\n/**\n * The child's in-flight turn, shaped as the assistant message it will become.\n *\n * A managed child streams its text out of band (`agent_text_delta`) and files\n * the finished message afterwards, so while a turn is open there is no\n * `Message` for the transcript to render. Printing the raw buffer under the\n * panel put the child's private reasoning on screen verbatim — a router that\n * inlines thinking as `<think>…</think>` produced a wall of tags — while the\n * same text one row up, in the settled transcript, was collapsed to a\n * `thought` row. Rendering it as a streaming `AgentMessage` gives the live turn\n * the same reasoning split, markdown, and width as every settled one.\n */\nfunction liveMessage(agentId: string, text: string): Message {\n return {\n id: `${agentId}:live`,\n role: 'assistant',\n content: text,\n includeInContext: false,\n timestamp: 0,\n };\n}\n\nexport function SubagentDetail({\n record,\n liveText,\n width,\n height,\n reducedMotion = false,\n screenReader = false,\n transcriptMode = 'compact',\n automaticToolCallId,\n toolExpansionOverrides,\n showAllToolOutput = false,\n showAllToolOutputIds,\n showThinking = true,\n}: {\n record: AgentRecord;\n liveText?: string;\n width: number;\n height: number;\n reducedMotion?: boolean;\n screenReader?: boolean;\n transcriptMode?: TranscriptMode;\n automaticToolCallId?: string | null;\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\n showAllToolOutput?: boolean;\n showAllToolOutputIds?: ReadonlySet<string>;\n showThinking?: boolean;\n}) {\n const theme = useTheme();\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(record.status);\n const hasTranscript = record.transcript.length > 0;\n const streaming = Boolean(liveText) && !terminal;\n const live = useMemo(\n () => (streaming ? liveMessage(record.id, liveText!) : undefined),\n [liveText, record.id, streaming],\n );\n return (\n <Box flexDirection=\"column\" width={width}>\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1}>\n <Text color={theme.brand} bold>\n main &gt; {record.displayName ?? record.name}\n </Text>\n <Text color={theme.subtle}>\n {record.profile ?? record.name} | {record.resolvedModel ?? 'unknown'} |{' '}\n {record.isolation ?? 'worktree'} | {record.status}\n </Text>\n {record.referencedEvidenceIds.length > 0 ? (\n <Text color={theme.subtle}>Evidence: {record.referencedEvidenceIds.join(', ')}</Text>\n ) : null}\n <Text color={theme.subtle}>\n Type a follow-up to resume this child · Tab switch · Esc main · /tasks list\n </Text>\n </Box>\n {/*\n ChatPanel renders nothing for an empty managed transcript, so the\n placeholder / live stream below owns the empty state. Ordering: live\n stream while the child is producing output, then a status placeholder\n only when there is no transcript yet.\n */}\n <ChatPanel\n messages={record.transcript}\n terminalWidth={width}\n terminalHeight={height}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n model={record.resolvedModel}\n mode=\"managed\"\n transcriptMode={transcriptMode}\n automaticToolCallId={automaticToolCallId}\n toolExpansionOverrides={toolExpansionOverrides}\n showAllToolOutput={showAllToolOutput}\n showAllToolOutputIds={showAllToolOutputIds}\n showThinking={showThinking}\n />\n {live ? (\n <Box flexDirection=\"column\" marginTop={hasTranscript ? 1 : 0}>\n <AgentMessage\n message={live}\n isStreaming\n hideStreamingSpinner\n transcriptMode={transcriptMode}\n reducedMotion={reducedMotion}\n screenReader={screenReader}\n terminalWidth={width}\n showThinking={showThinking}\n />\n </Box>\n ) : !hasTranscript ? (\n <Box paddingX={1}>\n <Text color={theme.subtle}>\n {terminal ? 'No transcript recorded.' : 'Waiting for the subagent to produce output…'}\n </Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport { useEffect, useState } from 'react';\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\nimport { useTheme } from '../theme.js';\nimport { useUiClock } from '../ui-clock.js';\nimport { formatElapsedDuration } from './SubagentRow.js';\n\n/** Live-output poll cadence. Reading the tail can hit the filesystem for\n * persistent jobs, so it must happen in an effect, never during render. */\nconst OUTPUT_POLL_MS = 250;\n\nfunction sanitizeOutput(value: string): string {\n return value.replace(/\\x1b\\[[0-?]*[ -/]*[@-~]/g, '').replace(/\\x1b\\][^\\x07]*(?:\\x07|$)/g, '');\n}\n\nexport function BackgroundShellDetail({\n shell,\n readTail,\n width,\n}: {\n shell: BackgroundShellRecord;\n /** Stable callback returning the current output tail for this shell. */\n readTail: () => string;\n width: number;\n}) {\n const theme = useTheme();\n const running = shell.finishedAt === undefined;\n useUiClock('slow', running);\n const [output, setOutput] = useState(readTail);\n useEffect(() => {\n setOutput(readTail());\n if (!running) return;\n const timer = setInterval(() => setOutput(readTail()), OUTPUT_POLL_MS);\n return () => clearInterval(timer);\n }, [readTail, running]);\n const elapsed = Math.max(\n 0,\n Math.floor(((shell.finishedAt ?? Date.now()) - shell.startedAt) / 1000),\n );\n const exit = shell.exitCode !== undefined ? ` | exit ${shell.exitCode ?? 'none'}` : '';\n return (\n <Box flexDirection=\"column\" width={width} paddingX={1}>\n <Text color={theme.brand} bold>\n main &gt; {shell.title || shell.command}\n </Text>\n <Text color={theme.subtle}>\n shell | {shell.status} | {shell.lifetime ?? 'session'} | {formatElapsedDuration(elapsed)}\n {exit}\n </Text>\n <Text color={theme.subtle}>\n pid {shell.pid ?? 'unknown'} | {shell.sandboxed ? 'sandboxed' : 'unsandboxed'} | notify{' '}\n {shell.notify ?? 'ui'}\n </Text>\n <Text color={theme.subtle}>cwd {shell.workdir}</Text>\n <Text>{shell.command}</Text>\n {shell.truncatedBytes > 0 ? (\n <Text color={theme.warning}>\n {shell.truncatedBytes} older output characters were truncated.\n </Text>\n ) : null}\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={theme.subtle}>Output tail</Text>\n <Text>{sanitizeOutput(output) || '(no output yet)'}</Text>\n </Box>\n <Text color={theme.subtle}>Tab switch | x stop/dismiss | Esc main | /jobs list</Text>\n </Box>\n );\n}\n","import type { AgentActivity, AgentRecord } from '../agents/types.js';\nimport type { Message } from '../types/messages.js';\nimport type { ToolCall, ToolResult } from '../types/tools.js';\n\nexport interface ManagedAgentToolUse {\n id: string;\n call: ToolCall;\n result?: ToolResult;\n status: 'running' | 'completed' | 'failed';\n startedAt: number;\n finishedAt?: number;\n}\n\nexport interface ManagedAgentTrace {\n agentId: string;\n parentToolCallId: string;\n profile: string;\n purpose: string;\n status: AgentRecord['status'];\n startedAt: number;\n finishedAt?: number;\n toolUses: ManagedAgentToolUse[];\n /**\n * The parent turn is blocked on this child rather than running alongside it —\n * foreground delegation, where the lead has genuinely stopped. Drives the\n * \"lead paused\" wording; a background spawn leaves this false and the lead\n * keeps working.\n */\n blocking?: boolean;\n /**\n * Whether Tab can open this child. Tab cycles through the Background panel's\n * rows, and a finished child's row is cleared once its completion is\n * acknowledged, or for a `Task` child once its result arrives. Undefined when\n * the caller did not say, which keeps the hint.\n */\n openable?: boolean;\n}\n\nfunction spawnAgentId(result: ToolResult | undefined): string | undefined {\n if (!result || typeof result.data !== 'object' || result.data === null) return undefined;\n const candidate = (result.data as { agentId?: unknown }).agentId;\n return typeof candidate === 'string' ? candidate : undefined;\n}\n\nfunction activityResult(activity: AgentActivity): ToolResult | undefined {\n return activity.result;\n}\n\nfunction activityCall(activity: AgentActivity): ToolCall | undefined {\n if (activity.kind !== 'tool' || !activity.toolCall) return undefined;\n return activity.toolCall;\n}\n\nfunction activityStatus(activity: AgentActivity): ManagedAgentToolUse['status'] {\n return activity.status === 'failed'\n ? 'failed'\n : activity.status === 'completed'\n ? 'completed'\n : 'running';\n}\n\nfunction resultStatus(result: ToolResult | undefined): ManagedAgentToolUse['status'] | undefined {\n if (!result) return undefined;\n return result.status === 'success' ? 'completed' : 'failed';\n}\n\nfunction projectChildToolUses(\n record: AgentRecord,\n activities: AgentActivity[],\n): ManagedAgentToolUse[] {\n const byId = new Map<string, ManagedAgentToolUse>();\n let order = 0;\n\n const upsert = (use: ManagedAgentToolUse): void => {\n const existing = byId.get(use.id);\n if (!existing) {\n byId.set(use.id, use);\n return;\n }\n byId.set(use.id, {\n ...existing,\n call: use.call,\n result: use.result ?? existing.result,\n status:\n use.status === 'running' && existing.status !== 'running' ? existing.status : use.status,\n startedAt: Math.min(existing.startedAt, use.startedAt),\n finishedAt: use.finishedAt ?? existing.finishedAt,\n });\n };\n\n for (const activity of activities) {\n const call = activityCall(activity);\n if (!call) continue;\n upsert({\n id: call.id,\n call,\n result: activityResult(activity),\n status: activityStatus(activity),\n startedAt: activity.startedAt || order++,\n finishedAt: activity.finishedAt,\n });\n order++;\n }\n\n for (const message of record.transcript) {\n for (const call of message.toolCalls ?? []) {\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\n const status = resultStatus(result) ?? byId.get(call.id)?.status ?? 'running';\n upsert({\n id: call.id,\n call,\n result,\n status,\n startedAt: byId.get(call.id)?.startedAt ?? message.timestamp + order,\n finishedAt: byId.get(call.id)?.finishedAt ?? (result ? message.timestamp : undefined),\n });\n order++;\n }\n }\n\n return [...byId.values()].sort((left, right) => left.startedAt - right.startedAt);\n}\n\nconst EMPTY_TRACES: ReadonlyMap<string, ManagedAgentTrace> = new Map();\n\n/**\n * Build UI-only traces for managed delegation. Parent Message objects are left\n * untouched so child activity never enters provider context or persistence.\n *\n * Two linkages, because the two delegation modes publish the child id at\n * different times. Background (`AgentSpawn`) returns it in the settled tool\n * result. Foreground (`Task`) does not settle until the child is finished, so it\n * stamps `parentToolCallId` on the record at spawn time instead — the only link\n * available during the window the child is actually running.\n */\nexport function projectManagedAgentTraces(\n messages: Message[],\n records: ReadonlyMap<string, AgentRecord>,\n activities: ReadonlyMap<string, AgentActivity[]>,\n openableAgentIds?: ReadonlySet<string>,\n): ReadonlyMap<string, ManagedAgentTrace> {\n // Traces require a live agent record; skip the transcript scan entirely (and\n // keep a stable identity) while no managed agents exist.\n if (records.size === 0) return EMPTY_TRACES;\n const byParentToolCall = new Map<string, AgentRecord>();\n for (const record of records.values()) {\n if (record.parentToolCallId) byParentToolCall.set(record.parentToolCallId, record);\n }\n const traces = new Map<string, ManagedAgentTrace>();\n const add = (callId: string, record: AgentRecord, blocking: boolean): void => {\n traces.set(callId, {\n agentId: record.id,\n parentToolCallId: callId,\n profile: record.profile ?? record.name,\n purpose: record.displayName ?? record.purpose ?? record.prompt,\n status: record.status,\n startedAt: record.startedAt ?? record.createdAt,\n finishedAt: record.finishedAt,\n toolUses: projectChildToolUses(record, activities.get(record.id) ?? []),\n blocking,\n openable: openableAgentIds?.has(record.id),\n });\n };\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const call of message.toolCalls ?? []) {\n const foreground = byParentToolCall.get(call.id);\n if (foreground) {\n // The parent row is still open exactly while its result is absent, which\n // is the same condition as the lead still being blocked on the child.\n const settled = message.toolResults?.some((candidate) => candidate.toolCallId === call.id);\n add(call.id, foreground, !settled);\n continue;\n }\n if (call.name !== 'AgentSpawn') continue;\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\n const agentId = spawnAgentId(result);\n const record = agentId ? records.get(agentId) : undefined;\n if (!agentId || !record) continue;\n add(call.id, record, false);\n }\n }\n return traces;\n}\n","/**\n * Wrap arbitrary text so a markdown renderer shows it verbatim.\n *\n * Local transcript messages (`addLocalMessage`) are prose: they go through\n * `MarkdownBlock`, so any text interpolated into one is markdown. A background\n * shell command is not — a command carrying a `KILLPROBE` block comment lost\n * both of its asterisks to the `em` token, and the completion row disagreed\n * with the tool row directly above it about which command had just finished.\n * Asterisks are only the visible half of the class: `#`, `[x](y)`, `~~` and `_`\n * are all live in prose too.\n *\n * A code span is the escape hatch, but only if the fence survives the content:\n *\n * - **Line breaks first.** Block parsing runs before inline parsing, so a `#`\n * or a fence line at the start of an embedded line splits the paragraph and\n * strands the opening backtick as a literal. Flatten to one line and the\n * fence has a single paragraph to live in.\n * - **Fence longer than any run inside.** ``echo `date` `` needs a two-backtick\n * fence, or the span closes on the command's own backtick.\n * - **Pad when the edges collide.** A leading or trailing backtick would fuse\n * with the fence; CommonMark strips one space from each end when both are\n * present, so the padding does not survive into the rendered text.\n */\nexport function inlineCode(text: string): string {\n const oneLine = text.replace(/\\r\\n|\\r|\\n/g, ' ');\n // Nothing to quote. An empty span is not a code span at all, so a fence here\n // would leave two stray backticks sitting in the row.\n if (!oneLine.trim()) return '';\n\n const longestRun = [...oneLine.matchAll(/`+/g)].reduce(\n (longest, match) => Math.max(longest, match[0].length),\n 0,\n );\n const fence = '`'.repeat(longestRun + 1);\n const pad = /^[`\\s]|[`\\s]$/.test(oneLine) ? ' ' : '';\n return `${fence}${pad}${oneLine}${pad}${fence}`;\n}\n","import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs';\nimport { basename, extname, join } from 'path';\nimport { parseFrontmatter } from '../frontmatter.js';\nimport { normalizeAgentTool } from '../subagent-discovery.js';\n\nconst MUTATION_TOOLS = new Set([\n 'ApplyPatch',\n 'Write',\n 'Edit',\n 'MultiEdit',\n 'NotebookEdit',\n 'Bash',\n]);\nconst SAFE_AGENT_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\n\nfunction assertSafeAgentName(name: string): void {\n if (!SAFE_AGENT_NAME.test(name) || name === '.' || name === '..') {\n throw new Error(\n `Unsafe agent name \"${name}\". Names must start with a letter or number and contain only letters, numbers, dots, underscores, or hyphens.`,\n );\n }\n}\n\nexport interface AgentImportPreview {\n sourcePath: string;\n name: string;\n description: string;\n body: string;\n tools: string[];\n unsupportedTools: string[];\n missingTools: boolean;\n model?: string;\n maxTurns?: number;\n warnings: string[];\n}\n\nfunction sourceFiles(path: string): string[] {\n if (!existsSync(path)) throw new Error(`Agent import path does not exist: ${path}`);\n if (statSync(path).isFile()) return extname(path) === '.md' ? [path] : [];\n const files: string[] = [];\n const visit = (directory: string) => {\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const fullPath = join(directory, entry.name);\n if (entry.isDirectory()) visit(fullPath);\n else if (entry.isFile() && extname(entry.name) === '.md') files.push(fullPath);\n }\n };\n visit(path);\n return files.sort();\n}\n\nfunction rawTools(value: unknown): string[] {\n if (Array.isArray(value))\n return value\n .map(String)\n .map((tool) => tool.trim())\n .filter(Boolean);\n if (typeof value === 'string')\n return value\n .split(',')\n .map((tool) => tool.trim())\n .filter(Boolean);\n return [];\n}\n\nexport function previewAgentImport(path: string): AgentImportPreview[] {\n return sourceFiles(path).map((sourcePath) => {\n const { body, frontmatter } = parseFrontmatter(readFileSync(sourcePath, 'utf8'));\n const requestedTools = rawTools(frontmatter.tools ?? frontmatter['allowed-tools']);\n const tools = requestedTools\n .map(normalizeAgentTool)\n .filter((tool): tool is string => Boolean(tool));\n const unsupportedTools = requestedTools.filter((tool) => !normalizeAgentTool(tool));\n const name = String(frontmatter.name ?? basename(sourcePath, '.md'));\n const description = String(frontmatter.description ?? name);\n const warnings: string[] = [];\n if (!SAFE_AGENT_NAME.test(name) || name === '.' || name === '..') {\n warnings.push(`Unsafe agent name: ${name}. Installation will be refused.`);\n }\n if (requestedTools.length === 0)\n warnings.push('No tools were declared; the imported profile denies all tools.');\n if (unsupportedTools.length > 0)\n warnings.push(`Unsupported tools: ${unsupportedTools.join(', ')}.`);\n const readOnlyNominal = /explor|review|research|read.?only/i.test(`${name} ${description}`);\n const risky = tools.filter((tool) => MUTATION_TOOLS.has(tool.split('(')[0]));\n if (readOnlyNominal && risky.length > 0) {\n warnings.push(`Nominally read-only profile includes mutation tools: ${risky.join(', ')}.`);\n }\n const modelValue = typeof frontmatter.model === 'string' ? frontmatter.model.trim() : undefined;\n return {\n sourcePath,\n name,\n description,\n body,\n tools: Array.from(new Set(tools)),\n unsupportedTools,\n missingTools: requestedTools.length === 0,\n model: modelValue && modelValue !== 'inherit' ? modelValue : undefined,\n maxTurns:\n typeof frontmatter.maxTurns === 'number'\n ? frontmatter.maxTurns\n : typeof frontmatter.maxTurns === 'string'\n ? Number.parseInt(frontmatter.maxTurns, 10) || undefined\n : undefined,\n warnings,\n };\n });\n}\n\nexport function installAgentImports(\n previews: AgentImportPreview[],\n targetDirectory: string,\n): string[] {\n const names = new Set<string>();\n const targets = previews.map((preview) => {\n assertSafeAgentName(preview.name);\n if (names.has(preview.name)) {\n throw new Error(`Duplicate imported agent name: ${preview.name}.`);\n }\n names.add(preview.name);\n const target = join(targetDirectory, `${preview.name}.md`);\n if (existsSync(target)) {\n throw new Error(`Agent definition already exists: ${target}. Remove or rename it first.`);\n }\n return target;\n });\n mkdirSync(targetDirectory, { recursive: true });\n return previews.map((preview, index) => {\n const target = targets[index];\n const frontmatter = [\n '---',\n `name: ${preview.name}`,\n `description: ${preview.description}`,\n 'tools:',\n ...preview.tools.map((tool) => `- ${tool}`),\n ...(preview.model ? [`model: ${preview.model}`] : []),\n ...(preview.maxTurns ? [`maxTurns: ${preview.maxTurns}`] : []),\n '---',\n preview.body,\n '',\n ].join('\\n');\n writeFileSync(target, frontmatter, { encoding: 'utf8', flag: 'wx' });\n return target;\n });\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useKeyState } from '../hooks/useKeyState.js';\nimport { useTheme } from '../theme.js';\nimport type { PermissionMode } from '../../types/runtime.js';\nimport { panelContentWidth } from '../layout.js';\nimport { truncateDisplay } from './word-wrap.js';\n\nexport type PermissionList = 'allow' | 'ask' | 'deny';\n\nexport interface PermissionRuleEntry {\n list: PermissionList;\n rule: string;\n}\n\nexport interface RemoveRuleResult {\n ok: boolean;\n error?: string;\n /** The rule is inherited from a layer this panel cannot write. */\n notLocal?: boolean;\n}\n\ninterface PermissionsPanelProps {\n mode: PermissionMode;\n permissions: Record<PermissionList, readonly string[]>;\n /** Removes a rule from the local layer. Absent while another surface owns input. */\n onRemove?: (entry: PermissionRuleEntry) => RemoveRuleResult;\n /** False while a modal or picker owns the keyboard. */\n active?: boolean;\n terminalWidth?: number;\n screenReader?: boolean;\n}\n\nconst LISTS: readonly PermissionList[] = ['allow', 'ask', 'deny'];\n\n/** Flatten the three lists into the order the panel renders them. */\nexport function flattenPermissionRules(\n permissions: Record<PermissionList, readonly string[]>,\n): PermissionRuleEntry[] {\n return LISTS.flatMap((list) => permissions[list].map((rule) => ({ list, rule })));\n}\n\n/**\n * The `/permissions` sheet.\n *\n * It used to be static text captioned \"add via the Always allow option at tool\n * prompts\" — accurate, and the whole problem: a rule went in on one keystroke\n * and came out only by hand-editing `.book/settings.local.json`. Adding a\n * permission was cheap and removing one was not, which is the wrong way round\n * for the surface that decides what the agent may do unattended.\n */\nexport function PermissionsPanel({\n mode,\n permissions,\n onRemove,\n active = true,\n terminalWidth = 80,\n screenReader = false,\n}: PermissionsPanelProps) {\n const theme = useTheme();\n const entries = useMemo(() => flattenPermissionRules(permissions), [permissions]);\n const [selected, setSelected, currentSelected] = useKeyState(0);\n // The keyed actions read the cursor from a ref: arrows and `x` arriving in\n // one React batch would otherwise remove the row the cursor was on before\n // the arrows moved it.\n const move = (next: (current: number) => number) => {\n setSelected(entries.length === 0 ? 0 : next(currentSelected()));\n };\n const [notice, setNotice] = useState<string | null>(null);\n // The interior of the bordered box app.tsx wraps this in, taken from the same\n // panel grid that sizes the box -- so the rules stop exactly where it does.\n const width = panelContentWidth(terminalWidth);\n\n // Removing the last rule, or a reload shrinking the list, must not leave the\n // cursor pointing past the end.\n useEffect(() => {\n setSelected(Math.max(0, Math.min(currentSelected(), entries.length - 1)));\n }, [entries.length]);\n\n const canEdit = Boolean(onRemove) && entries.length > 0 && active && !screenReader;\n\n useInput(\n (input, key) => {\n if (key.upArrow) {\n setNotice(null);\n move((s) => (s - 1 + entries.length) % entries.length);\n return;\n }\n if (key.downArrow) {\n setNotice(null);\n move((s) => (s + 1) % entries.length);\n return;\n }\n if (input === 'x' || input === 'X') {\n const entry = entries[currentSelected()];\n if (!entry) return;\n const result = onRemove!(entry);\n if (result.ok) setNotice(`Removed ${entry.rule}`);\n else if (result.notLocal)\n setNotice(`${entry.rule} comes from a settings file this panel cannot edit.`);\n else setNotice(result.error ?? `Could not remove ${entry.rule}`);\n }\n },\n { isActive: canEdit },\n );\n\n // One key column for the mode rows and the rule lists, so every value on the\n // sheet starts at the same place.\n const keyWidth = 8;\n const valueWidth = Math.max(8, width - keyWidth);\n const keyCell = (key: string) => (\n <Box width={keyWidth} flexShrink={0}>\n <Text color={theme.inactive}>{key}</Text>\n </Box>\n );\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n {keyCell('mode')}\n <Text color={theme.text} bold>\n {truncateDisplay(mode, valueWidth)}\n </Text>\n </Box>\n <Box>\n {keyCell('modes')}\n <Text color={theme.subtle}>\n {truncateDisplay(\n 'default · auto · plan · accept-edits · dontAsk · bypassPermissions',\n valueWidth,\n )}\n </Text>\n </Box>\n <Box>\n {keyCell('switch')}\n <Text color={theme.subtle}>Alt+M or Shift+Tab</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n {LISTS.map((list) => (\n <Box key={list}>\n {keyCell(list)}\n <Box flexDirection=\"column\">\n {permissions[list].length === 0 ? (\n <Text color={theme.inactive}>none</Text>\n ) : (\n permissions[list].map((rule) => {\n const index = entries.findIndex(\n (entry) => entry.list === list && entry.rule === rule,\n );\n const isSelected = canEdit && index === selected;\n return (\n <Text key={`${list}-${rule}`}>\n <Text color={theme.brand}>{isSelected ? '› ' : ' '}</Text>\n <Text color={isSelected ? theme.selectionText : theme.text} bold={isSelected}>\n {truncateDisplay(rule, Math.max(4, valueWidth - 2))}\n </Text>\n </Text>\n );\n })\n )}\n </Box>\n </Box>\n ))}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {entries.length === 0 ? (\n <Text color={theme.inactive}>\n {truncateDisplay('No rules yet. \"Always allow\" at a tool prompt adds one.', width)}\n </Text>\n ) : canEdit ? (\n <Text color={theme.inactive}>↑↓ select · x remove</Text>\n ) : null}\n {notice ? <Text color={theme.warning}>{truncateDisplay(notice, width)}</Text> : null}\n </Box>\n </Box>\n );\n}\n","import type { ImageAttachment } from '../types/messages.js';\n\nexport const MAX_QUEUED_INPUTS = 10;\n\nexport interface QueuedInput {\n id: string;\n sessionId: string;\n value: string;\n attachments?: ImageAttachment[];\n createdAt: number;\n}\n\nexport function createQueuedInput(\n value: string,\n sessionId: string,\n attachmentsOrExisting: ImageAttachment[] | Pick<QueuedInput, 'id' | 'createdAt'> = [],\n existing?: Pick<QueuedInput, 'id' | 'createdAt'>,\n): QueuedInput {\n const attachments = Array.isArray(attachmentsOrExisting) ? attachmentsOrExisting : [];\n const identity = Array.isArray(attachmentsOrExisting) ? existing : attachmentsOrExisting;\n return {\n id: identity?.id ?? crypto.randomUUID(),\n sessionId,\n value,\n ...(attachments.length > 0 ? { attachments } : {}),\n createdAt: identity?.createdAt ?? Date.now(),\n };\n}\n\nexport function enqueueQueuedInput(\n queue: readonly QueuedInput[],\n input: QueuedInput,\n capacity = MAX_QUEUED_INPUTS,\n): { accepted: boolean; queue: QueuedInput[] } {\n if (queue.length >= capacity) return { accepted: false, queue: [...queue] };\n return { accepted: true, queue: [...queue, input] };\n}\n\nexport function recallNewestQueuedInput(\n queue: readonly QueuedInput[],\n excludedId?: string,\n): { queue: QueuedInput[]; recalled?: QueuedInput } {\n let index = -1;\n for (let candidate = queue.length - 1; candidate >= 0; candidate--) {\n if (queue[candidate].id !== excludedId) {\n index = candidate;\n break;\n }\n }\n if (index < 0) return { queue: [...queue] };\n return {\n queue: queue.filter((_, itemIndex) => itemIndex !== index),\n recalled: queue[index],\n };\n}\n\nexport function restoreQueuedInputText(queue: readonly QueuedInput[], draft: string): string {\n return [...queue.map((item) => item.value), draft]\n .filter((value) => value.trim().length > 0)\n .join('\\n\\n');\n}\n\nexport function restoreQueuedInputAttachments(\n queue: readonly QueuedInput[],\n draft: readonly ImageAttachment[] = [],\n): ImageAttachment[] {\n return [...queue.flatMap((item) => item.attachments ?? []), ...draft];\n}\n\nexport function shouldRequeueQueuedSend(result: {\n status: 'completed' | 'cancelled' | 'failed' | 'rejected';\n phase?: 'before-prepare' | 'prepare' | 'run';\n userMessagePersisted?: boolean;\n}): boolean {\n return (\n result.status === 'rejected' ||\n result.status === 'cancelled' ||\n (result.status === 'failed' &&\n (result.phase === 'before-prepare' ||\n (result.phase === 'prepare' && result.userMessagePersisted === false)))\n );\n}\n","import { spawn } from 'child_process';\nimport { buildChildEnv } from '../child-env.js';\n\nexport const MAX_CLIPBOARD_IMAGE_BYTES = 8 * 1024 * 1024;\n\nexport interface ClipboardImage {\n bytes: Uint8Array;\n mediaType: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';\n}\n\ninterface CommandResult {\n code: number | null;\n stdout: Buffer;\n stderr: string;\n}\n\nfunction run(command: string, args: string[], timeoutMs = 5_000): Promise<CommandResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n windowsHide: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n env: buildChildEnv(),\n });\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n let size = 0;\n const timer = setTimeout(() => child.kill(), timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_CLIPBOARD_IMAGE_BYTES * 2) {\n child.kill();\n reject(new Error('Clipboard image exceeds the 8 MB limit.'));\n return;\n }\n stdout.push(chunk);\n });\n child.stderr.on('data', (chunk: Buffer) => stderr.push(chunk));\n child.once('error', (error) => {\n clearTimeout(timer);\n reject(error);\n });\n child.once('close', (code) => {\n clearTimeout(timer);\n resolve({ code, stdout: Buffer.concat(stdout), stderr: Buffer.concat(stderr).toString() });\n });\n });\n}\n\nexport function detectImageMediaType(bytes: Uint8Array): ClipboardImage['mediaType'] | null {\n if (\n bytes.length >= 8 &&\n bytes[0] === 0x89 &&\n bytes[1] === 0x50 &&\n bytes[2] === 0x4e &&\n bytes[3] === 0x47\n ) {\n return 'image/png';\n }\n if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff) {\n return 'image/jpeg';\n }\n const header = Buffer.from(bytes.subarray(0, 12)).toString('ascii');\n if (header.startsWith('GIF87a') || header.startsWith('GIF89a')) return 'image/gif';\n if (header.startsWith('RIFF') && header.slice(8, 12) === 'WEBP') return 'image/webp';\n return null;\n}\n\nfunction validated(bytes: Uint8Array): ClipboardImage {\n if (bytes.byteLength === 0) throw new Error('No image is available on the clipboard.');\n if (bytes.byteLength > MAX_CLIPBOARD_IMAGE_BYTES) {\n throw new Error('Clipboard image exceeds the 8 MB limit.');\n }\n const mediaType = detectImageMediaType(bytes);\n if (!mediaType)\n throw new Error('Clipboard image format is unsupported. Use PNG, JPEG, GIF, or WebP.');\n return { bytes, mediaType };\n}\n\nasync function readWindowsClipboard(): Promise<ClipboardImage> {\n const script = [\n 'Add-Type -AssemblyName System.Windows.Forms',\n 'Add-Type -AssemblyName System.Drawing',\n 'if (-not [System.Windows.Forms.Clipboard]::ContainsImage()) { exit 3 }',\n '$image = [System.Windows.Forms.Clipboard]::GetImage()',\n '$stream = New-Object System.IO.MemoryStream',\n '$image.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)',\n '[Console]::Out.Write([Convert]::ToBase64String($stream.ToArray()))',\n ].join('; ');\n let lastError: unknown;\n for (const command of ['pwsh.exe', 'powershell.exe']) {\n try {\n const result = await run(command, [\n '-NoProfile',\n '-NonInteractive',\n '-Sta',\n '-Command',\n script,\n ]);\n if (result.code === 3) throw new Error('No image is available on the clipboard.');\n if (result.code !== 0) throw new Error(result.stderr.trim() || 'Clipboard helper failed.');\n return validated(Buffer.from(result.stdout.toString().trim(), 'base64'));\n } catch (error) {\n lastError = error;\n if (error instanceof Error && /No image is available/.test(error.message)) throw error;\n }\n }\n throw new Error(\n `Unable to read the Windows clipboard${lastError instanceof Error ? `: ${lastError.message}` : '.'}`,\n );\n}\n\nasync function readUnixClipboard(): Promise<ClipboardImage> {\n const candidates: Array<[string, string[]]> =\n process.platform === 'darwin'\n ? [['pngpaste', ['-']]]\n : [\n ['wl-paste', ['--no-newline', '--type', 'image/png']],\n ['wl-paste', ['--no-newline', '--type', 'image/jpeg']],\n ['wl-paste', ['--no-newline', '--type', 'image/webp']],\n ['xclip', ['-selection', 'clipboard', '-t', 'image/png', '-o']],\n ['xclip', ['-selection', 'clipboard', '-t', 'image/jpeg', '-o']],\n ['xclip', ['-selection', 'clipboard', '-t', 'image/webp', '-o']],\n ];\n let lastError: unknown;\n for (const [command, args] of candidates) {\n try {\n const result = await run(command, args);\n if (result.code === 0 && result.stdout.length > 0) return validated(result.stdout);\n lastError = new Error(result.stderr.trim() || `${command} found no clipboard image.`);\n } catch (error) {\n lastError = error;\n }\n }\n const installHint =\n process.platform === 'darwin' ? 'Install pngpaste' : 'Install wl-paste or xclip';\n throw new Error(\n `${installHint} to paste images${lastError instanceof Error ? `: ${lastError.message}` : '.'}`,\n );\n}\n\nexport async function readClipboardImage(): Promise<ClipboardImage> {\n return process.platform === 'win32' ? readWindowsClipboard() : readUnixClipboard();\n}\n"],"mappings":"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AQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA;AAAA,EACf,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,OAAS,KAAO;AAAA;AAAA,EACjB,CAAC,QAAS,MAAO;AAAA;AAAA,EACjB,CAAC,QAAS,MAAO;AAAA,EACjB,CAAC,QAAS,MA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","names":["Box","Text","useStdout","useApp","useState","useCallback","useEffect","useMemo","useRef","useSyncExternalStore","Box","Text","React","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","Text","Box","React","useMemo","useState","useEffect","useRef","frame","useState","useRef","useEffect","Text","Box","React","useEffect","useLayoutEffect","useMemo","useRef","Text","Box","useMemo","jsx","jsxs","oldIndex","newIndex","row","useMemo","Box","Text","Text","Box","useMemo","useRef","useState","useEffect","createContext","useContext","useEffect","useSyncExternalStore","subscribeNoop","gutterWidth","lines","jsx","jsxs","useState","useRef","useEffect","run","Text","Box","MarkdownRenderer","useMemo","mutation","foldControlCharacters","statusMetadata","duration","hasDetails","Text","jsx","jsxs","Text","createContext","useContext","Fragment","jsx","jsxs","useRef","useEffect","jsxs","Box","Text","jsx","useMemo","useLayoutEffect","Fragment","React","Box","Text","useMemo","Box","Text","Fragment","jsx","jsxs","Box","Text","tail","Fragment","jsx","jsxs","formatDuration","Box","Text","useMemo","usage","Box","Text","jsx","jsxs","useCurrentTime","statusGlyph","Box","Text","Box","Text","React","jsx","jsxs","Box","Text","React","cache","run","useRef","useEffect","log","useRef","useEffect","jsx","jsxs","Box","jsx","Box","Text","jsxs","useMemo","React","Box","Text","React","Fragment","jsx","jsxs","Box","Text","React","Box","Text","basename","useLayoutEffect","Fragment","jsx","jsxs","basename","Box","Text","useLayoutEffect","Box","React","useCallback","useContext","useEffect","useLayoutEffect","useMemo","useRef","useState","jsx","useRef","useState","useMemo","cache","itemKeys","estimatedRows","measurementKeys","estimatedTotalRows","useEffect","useLayoutEffect","useContext","useCallback","React","VirtualTranscriptRow","Box","jsx","jsxs","renderLog","formatTurnTime","Box","Text","useState","useRef","useEffect","useLayoutEffect","useMemo","useCallback","React","cache","Box","Text","useState","useCallback","useEffect","useLayoutEffect","useRef","useMemo","useInput","Box","Text","useMemo","jsx","jsxs","renderLog","useMemo","Text","Box","Text","useMemo","jsx","useMemo","Text","Text","useMemo","jsx","useMemo","Text","Text","useInput","useEffect","useRef","jsx","jsxs","useRef","useEffect","useInput","cursor","Text","jsx","jsxs","uiLog","useState","useRef","useCallback","useMemo","useEffect","useLayoutEffect","nextValue","useInput","action","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","useMemo","Fragment","jsx","jsxs","renderLog","useMemo","run","Box","Text","Box","Text","useLayoutEffect","useRef","useState","stringArg","jsx","jsxs","useRef","useState","useLayoutEffect","hint","Box","Text","Box","Text","useEffect","useRef","useState","glyph","glyph","_","jsx","useRef","useState","useEffect","Box","run","Text","Box","Text","useEffect","jsx","jsxs","useEffect","Box","Text","Box","Text","useInput","jsx","jsxs","uiLog","line","useInput","Box","Text","Box","Text","jsx","jsxs","Text","Box","Box","Text","jsx","jsxs","Text","Box","Box","Text","useInput","Text","useInput","useCallback","useReducer","useRef","jsx","useRef","useReducer","useCallback","useInput","Text","useState","useCallback","useRef","useEffect","useMemo","useCallback","useRef","useState","resolve","Box","Text","useInput","useCallback","useMemo","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useMemo","useCallback","useInput","Text","Box","jsx","jsxs","plural","useState","useRef","useMemo","useEffect","useCallback","useInput","Text","Box","useMemo","useState","Box","Text","useInput","useEffect","useMemo","jsx","jsxs","useMemo","useEffect","useInput","Text","Box","jsx","useState","useMemo","useMemo","useState","jsx","DESCRIPTIONS","useState","useMemo","Box","Text","useInput","jsx","jsxs","useInput","index","Text","Box","Box","Text","useInput","useEffect","useMemo","useState","jsx","jsxs","useState","useMemo","useEffect","useInput","Text","Box","useMemo","jsx","useMemo","useMemo","jsx","useMemo","Box","Text","useInput","useMemo","useState","Fragment","jsx","jsxs","useState","useMemo","useInput","Text","Box","Box","Text","measureElement","useInput","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","run","resolve","graphemeSegmenter","graphemeSegmenter","jsx","jsxs","TranscriptContent","pagerChordsAvailable","useRef","useState","useMemo","useCallback","measureElement","useLayoutEffect","useEffect","span","focusY","range","useInput","Box","Text","Box","Text","useInput","useCallback","useMemo","useRef","useEffect","useState","useEffect","useLayoutEffect","useRef","stringArg","jsx","jsxs","uiLog","useRef","useMemo","useState","useEffect","uiLog","useCallback","useInput","jsxs","Box","Text","jsx","Box","Text","jsx","jsxs","Box","Text","Box","Text","useInput","useCallback","useRef","useState","jsx","jsxs","uiLog","BUTTONS","Text","useState","useRef","useCallback","useInput","Box","Box","Text","useInput","useCallback","useMemo","useRef","useState","jsx","jsxs","sourceLabel","useState","useRef","useCallback","useInput","useMemo","Text","Box","Box","Text","useInput","useCallback","useMemo","useState","jsx","jsxs","useState","useMemo","draftRows","useCallback","current","useInput","Text","Box","Box","Text","useInput","useState","jsx","jsxs","useState","useInput","Text","Box","useState","useCallback","useRef","useEffect","uiLog","useState","useRef","usage","useCallback","useEffect","result","error","useState","useCallback","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useCallback","useEffect","useMemo","next","useCallback","useEffect","useRef","useState","useCallback","useState","useRef","useEffect","useState","useEffect","useCallback","existsSync","join","resolve","existsSync","resolve","join","useState","useCallback","useEffect","runGit","useEffect","useRef","useRef","useEffect","Box","Text","useInput","useEffect","useMemo","Text","jsx","jsxs","Text","jsx","jsxs","useMemo","useEffect","selected","useInput","Box","Text","Box","Text","useMemo","jsx","jsxs","useMemo","Box","Text","Box","Text","useEffect","useState","jsx","jsxs","useState","useEffect","Box","Text","existsSync","basename","join","existsSync","join","basename","join","Box","Text","useInput","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useInput","Box","Text","spawn","resolve","spawn","jsx","jsxs","uiLog","usage","useMemo","useState","useRef","useCallback","useEffect","useApp","error","useStdout","useSyncExternalStore","join","Box","Text","result"]}