@letrquan/book 0.2.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 (103) hide show
  1. package/CHANGELOG.md +2504 -0
  2. package/LICENSE +123 -0
  3. package/README.md +1383 -0
  4. package/dist/app-MOXXWEOY.js +18945 -0
  5. package/dist/app-MOXXWEOY.js.map +1 -0
  6. package/dist/chunk-24AXE6SP.js +12 -0
  7. package/dist/chunk-24AXE6SP.js.map +1 -0
  8. package/dist/chunk-3U5IBM24.js +213 -0
  9. package/dist/chunk-3U5IBM24.js.map +1 -0
  10. package/dist/chunk-574C6MQR.js +743 -0
  11. package/dist/chunk-574C6MQR.js.map +1 -0
  12. package/dist/chunk-5GDZ22YP.js +449 -0
  13. package/dist/chunk-5GDZ22YP.js.map +1 -0
  14. package/dist/chunk-5KLVH3PY.js +167 -0
  15. package/dist/chunk-5KLVH3PY.js.map +1 -0
  16. package/dist/chunk-5RDRAO4B.js +92 -0
  17. package/dist/chunk-5RDRAO4B.js.map +1 -0
  18. package/dist/chunk-7N4J557C.js +10 -0
  19. package/dist/chunk-7N4J557C.js.map +1 -0
  20. package/dist/chunk-A7JLBK2Y.js +3506 -0
  21. package/dist/chunk-A7JLBK2Y.js.map +1 -0
  22. package/dist/chunk-ANSJPYGI.js +84 -0
  23. package/dist/chunk-ANSJPYGI.js.map +1 -0
  24. package/dist/chunk-BTZZUCLI.js +264 -0
  25. package/dist/chunk-BTZZUCLI.js.map +1 -0
  26. package/dist/chunk-C7D4NJ2D.js +217 -0
  27. package/dist/chunk-C7D4NJ2D.js.map +1 -0
  28. package/dist/chunk-CAGOB2N4.js +208 -0
  29. package/dist/chunk-CAGOB2N4.js.map +1 -0
  30. package/dist/chunk-DGMQEI6Y.js +98 -0
  31. package/dist/chunk-DGMQEI6Y.js.map +1 -0
  32. package/dist/chunk-E75IPST5.js +289 -0
  33. package/dist/chunk-E75IPST5.js.map +1 -0
  34. package/dist/chunk-EYGD6X2T.js +180 -0
  35. package/dist/chunk-EYGD6X2T.js.map +1 -0
  36. package/dist/chunk-GTVB4HEM.js +765 -0
  37. package/dist/chunk-GTVB4HEM.js.map +1 -0
  38. package/dist/chunk-J7MIZ5CA.js +1907 -0
  39. package/dist/chunk-J7MIZ5CA.js.map +1 -0
  40. package/dist/chunk-KWHQ2XXL.js +626 -0
  41. package/dist/chunk-KWHQ2XXL.js.map +1 -0
  42. package/dist/chunk-L6LK2QIQ.js +657 -0
  43. package/dist/chunk-L6LK2QIQ.js.map +1 -0
  44. package/dist/chunk-MAQXCUR4.js +1007 -0
  45. package/dist/chunk-MAQXCUR4.js.map +1 -0
  46. package/dist/chunk-S4XL7HOM.js +402 -0
  47. package/dist/chunk-S4XL7HOM.js.map +1 -0
  48. package/dist/chunk-URLQAXTR.js +60 -0
  49. package/dist/chunk-URLQAXTR.js.map +1 -0
  50. package/dist/chunk-V4BOYR52.js +3504 -0
  51. package/dist/chunk-V4BOYR52.js.map +1 -0
  52. package/dist/chunk-VZQXX3WW.js +210 -0
  53. package/dist/chunk-VZQXX3WW.js.map +1 -0
  54. package/dist/chunk-WKBO5R4O.js +34 -0
  55. package/dist/chunk-WKBO5R4O.js.map +1 -0
  56. package/dist/chunk-XIFFTATU.js +15753 -0
  57. package/dist/chunk-XIFFTATU.js.map +1 -0
  58. package/dist/command-approvals-6Y57VCWZ.js +28 -0
  59. package/dist/command-approvals-6Y57VCWZ.js.map +1 -0
  60. package/dist/context-ZC5IFEAX.js +25 -0
  61. package/dist/context-ZC5IFEAX.js.map +1 -0
  62. package/dist/hook-approvals-CTUFKEJT.js +22 -0
  63. package/dist/hook-approvals-CTUFKEJT.js.map +1 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +2582 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/interactive-assets-CCAAWVKH.js +31 -0
  68. package/dist/interactive-assets-CCAAWVKH.js.map +1 -0
  69. package/dist/job-runner.d.ts +2 -0
  70. package/dist/job-runner.js +235 -0
  71. package/dist/job-runner.js.map +1 -0
  72. package/dist/loader-4IDS2RIE.js +15 -0
  73. package/dist/loader-4IDS2RIE.js.map +1 -0
  74. package/dist/mcp-approvals-WNPH65BK.js +18 -0
  75. package/dist/mcp-approvals-WNPH65BK.js.map +1 -0
  76. package/dist/mcp-config-YIJIES2C.js +16 -0
  77. package/dist/mcp-config-YIJIES2C.js.map +1 -0
  78. package/dist/model-window-store-YFVNXCIP.js +27 -0
  79. package/dist/model-window-store-YFVNXCIP.js.map +1 -0
  80. package/dist/openai-compatible-RHZUBHV6.js +10 -0
  81. package/dist/openai-compatible-RHZUBHV6.js.map +1 -0
  82. package/dist/permission-approvals-76PVREFD.js +14 -0
  83. package/dist/permission-approvals-76PVREFD.js.map +1 -0
  84. package/dist/permissions-CHCKTFQQ.js +28 -0
  85. package/dist/permissions-CHCKTFQQ.js.map +1 -0
  86. package/dist/sandbox-CNVAQDA7.js +23 -0
  87. package/dist/sandbox-CNVAQDA7.js.map +1 -0
  88. package/dist/scrollback-LUKLIBVI.js +136 -0
  89. package/dist/scrollback-LUKLIBVI.js.map +1 -0
  90. package/dist/sdk.d.ts +4574 -0
  91. package/dist/sdk.js +665 -0
  92. package/dist/sdk.js.map +1 -0
  93. package/dist/settings-loader-M2QP5TX2.js +21 -0
  94. package/dist/settings-loader-M2QP5TX2.js.map +1 -0
  95. package/dist/settings-removed-JWWPT4WA.js +19 -0
  96. package/dist/settings-removed-JWWPT4WA.js.map +1 -0
  97. package/dist/shell-selection-V6QAYXPX.js +17 -0
  98. package/dist/shell-selection-V6QAYXPX.js.map +1 -0
  99. package/package.json +143 -0
  100. package/patches/ink+6.8.0.patch +13 -0
  101. package/scripts/apply-ink-patch.mjs +29 -0
  102. package/scripts/ink-patch.mjs +59 -0
  103. package/scripts/verify-ink-patch.mjs +11 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tui/app.tsx","../src/tui/layout.ts","../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/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/components/markdown-layout.ts","../src/tui/components/tool-output.ts","../src/tui/file-mutation-display.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/tool-traces.ts","../src/tui/components/ManagedAgentActivityBlock.tsx","../src/tui/debug.ts","../src/tui/components/UserMessage.tsx","../src/tui/components/TurnRule.tsx","../src/tui/components/WelcomeScreen.tsx","../src/tui/components/Bookplate.tsx","../src/tui/components/transcript-messages.ts","../src/tui/components/virtual-transcript.tsx","../src/tui/components/InputBar.tsx","../src/tui/components/CommandMenu.tsx","../src/tui/components/chrome.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/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/AgentTodoList.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/ThemePicker.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/tools/mutation-preview.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, useInput, useStdout, useApp } from 'ink';\r\nimport {\r\n useState,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useSyncExternalStore,\r\n type ReactNode,\r\n} from 'react';\r\nimport { panelGrid } from './layout.js';\r\nimport { ChatPanel } from './components/ChatPanel.js';\r\nimport { InputBar } from './components/InputBar.js';\r\nimport { QueuedInputPreview } from './components/QueuedInputPreview.js';\r\nimport { StatusLine } from './components/StatusLine.js';\r\nimport { WorkingIndicator } from './components/WorkingIndicator.js';\r\nimport { StartupFire } from './components/StartupFire.js';\r\nimport { CompactDiffCard } from './components/CompactDiffCard.js';\r\nimport { ErrorBoundary } from './components/ErrorBoundary.js';\r\nimport { TaskList } from './components/TaskList.js';\r\nimport { AgentTodoList, shouldShowAgentPlan } from './components/AgentTodoList.js';\r\nimport { ModelPicker, type ProviderRemovalResult } from './components/ModelPicker.js';\r\nimport { EffortPicker } from './components/EffortPicker.js';\r\nimport { PermissionModePicker } from './components/PermissionModePicker.js';\r\nimport { ThemePicker } from './components/ThemePicker.js';\r\nimport { ConfigMenu, type ConfigSection } from './components/ConfigMenu.js';\r\nimport { SkillManager } from './components/SkillManager.js';\r\nimport { AgentProfilePicker } from './components/AgentProfilePicker.js';\r\nimport { SessionPicker } from './components/SessionPicker.js';\r\nimport { RewindPicker } from './components/RewindPicker.js';\r\nimport { TranscriptView } from './components/TranscriptView.js';\r\nimport { PermissionButtons } from './components/PermissionButtons.js';\r\nimport { PlanApprovalActions, PlanApprovalDetails } from './components/PlanApprovalButtons.js';\r\nimport { AskUserQuestionWizard } from './components/AskUserQuestionWizard.js';\r\nimport { McpElicitationForm } from './components/McpElicitationForm.js';\r\nimport { McpServerApprovalPrompt } from './components/McpServerApprovalPrompt.js';\r\nimport { useAgent } from './hooks/useAgent.js';\r\nimport { useTasks } from './hooks/useTasks.js';\r\nimport { useManagedAgents } from './hooks/useManagedAgents.js';\r\nimport { useBackgroundShells } from './hooks/useBackgroundShells.js';\r\nimport { useGitStatus } from './hooks/useGitStatus.js';\r\nimport { useAgentCompletionDelivery } from './hooks/useAgentCompletionDelivery.js';\r\nimport { SubagentPanel } from './components/SubagentPanel.js';\r\nimport { SubagentDetail } from './components/SubagentDetail.js';\r\nimport { BackgroundShellDetail } from './components/BackgroundShellDetail.js';\r\nimport { projectManagedAgentTraces } from './managed-agent-transcript.js';\r\nimport { inlineCode } from './markdown-inline.js';\r\nimport {\r\n ThemeContext,\r\n listCustomThemes,\r\n resolveTheme,\r\n APPLE_THEME,\r\n type ThemeTokens,\r\n type ResolvedTheme,\r\n} from './theme.js';\r\nimport type { AgentConfig, PermissionMode } from '../types/runtime.js';\r\nimport type { McpHostSnapshot, McpSessionHost } from '../mcp-host.js';\r\nimport { resolvePermissionMode } from '../permission-mode.js';\r\nimport type { ImageAttachment } from '../types/messages.js';\r\nimport type { CommandContext } from '../types/commands.js';\r\nimport type { RewindSnapshotStoreInterface, SessionStoreInterface } from '../types/sessions.js';\r\nimport type { SessionBootstrap } from '../session/resolve.js';\r\nimport { displaySessionName } from '../session/name.js';\r\nimport { DensityContext, resolveTuiDensity } from './density.js';\r\nimport { discoverCommands, resolveCommandBody } from '../commands/loader.js';\r\nimport { commandEnforcementContext, parseSlashInput } from '../commands/resolve.js';\r\nimport {\r\n createBuiltinCommandRegistry,\r\n type BuiltinCommandContext,\r\n type BuiltinCommandEffect,\r\n} from '../commands/builtins.js';\r\nimport { discoverSkills, type Skill } from '../skills.js';\r\nimport { runGit } from '../tools/git.js';\r\nimport { getMemoryIndex } from '../memory-display.js';\r\nimport { discoverClaudeMd } from '../claude-md.js';\r\nimport { discoverAgents } from '../subagent-discovery.js';\r\nimport { withBuiltInAgents } from '../agents/profiles.js';\r\nimport { ShellJobManager } from '../jobs/shell-manager.js';\r\nimport { persistSettingLocal } from './persist.js';\r\nimport { buildModelOptions } from './model-options.js';\r\nimport { createUiDebugLogger } from '../debug-log.js';\r\nimport { createDefaultRegistry } from '../tools/registry.js';\r\nimport { getOrCreateAgentManager, type AgentManager } from '../agents/manager.js';\r\nimport { installAgentImports, previewAgentImport } from '../agents/importer.js';\r\nimport { runHostReview } from '../review/host.js';\r\nimport { fixRunnerFor, reviewRunnerFor } from '../review/runner.js';\r\nimport type { ReviewScope } from '../review/types.js';\r\nimport { join } from 'path';\r\nimport { selectExpandedToolId, selectLatestToolId } from './tool-traces.js';\r\nimport {\r\n getTranscriptShortcutAction,\r\n isShortcutsToggleKey,\r\n type TranscriptMode,\r\n} from './tool-presentation.js';\r\nimport { permissionResultOf } from '../permissions.js';\r\nimport { PermissionsPanel } from './components/PermissionsPanel.js';\r\nimport { useDebugMount, useDebugValueChange } from './debug.js';\r\nimport { getAvailableEffortLevels, getEffortUnavailableError } from '../commands/effort.js';\r\nimport type { InteractiveAssets } from './interactive-assets.js';\r\nimport { resolveContextWindow } from '../models.js';\r\nimport { wordWrap } from './components/word-wrap.js';\r\nimport {\r\n createQueuedInput,\r\n enqueueQueuedInput,\r\n recallNewestQueuedInput,\r\n restoreQueuedInputAttachments,\r\n restoreQueuedInputText,\r\n shouldRequeueQueuedSend,\r\n type QueuedInput,\r\n} from './queued-inputs.js';\r\nimport { readClipboardImage } from '../input/clipboard-image.js';\r\nimport { stripSgrMouseSequences } from './mouse.js';\r\n\r\nconst uiLog = createUiDebugLogger('tui:app');\r\nconst MAIN_TRANSCRIPT_SCOPE = 'main';\r\nconst EMPTY_TOOL_EXPANSION_OVERRIDES = new Map<string, boolean>();\r\nconst EMPTY_SHOW_ALL_TOOL_OUTPUT_IDS = new Set<string>();\r\n\r\nexport function ownsModalInput(\r\n pendingPermission: unknown,\r\n pendingPlanApproval: unknown,\r\n showModelPicker: boolean,\r\n showSessionPicker = false,\r\n pendingUserQuestion?: unknown,\r\n showEffortPicker = false,\r\n showThemePicker = false,\r\n showRewindPicker = false,\r\n showConfigPicker = false,\r\n showAgentProfilePicker = false,\r\n showPermissionModePicker = false,\r\n showSkills = false,\r\n pendingMcpApproval: unknown = undefined,\r\n pendingElicitation: unknown = undefined,\r\n): boolean {\r\n return Boolean(\r\n pendingPermission ||\r\n pendingPlanApproval ||\r\n pendingUserQuestion ||\r\n pendingElicitation ||\r\n showModelPicker ||\r\n showSessionPicker ||\r\n showEffortPicker ||\r\n showPermissionModePicker ||\r\n showThemePicker ||\r\n showRewindPicker ||\r\n showConfigPicker ||\r\n showAgentProfilePicker ||\r\n showSkills ||\r\n pendingMcpApproval,\r\n );\r\n}\r\n\r\nexport function shouldPlayStartupFire(config: AgentConfig, session: SessionBootstrap): boolean {\r\n return Boolean(\r\n config.settings.ui.startupAnimation &&\r\n !config.accessibility.screenReader &&\r\n !config.accessibility.reducedMotion &&\r\n session.source === 'startup' &&\r\n session.created &&\r\n (session.transcript ?? session.history).length === 0,\r\n );\r\n}\r\n\r\nfunction containsDraftInput(input: string): boolean {\r\n return Array.from(input).some((character) => {\r\n const codePoint = character.codePointAt(0) ?? 0;\r\n return codePoint >= 0x20 && codePoint !== 0x7f;\r\n });\r\n}\r\n\r\ntype ApplyThemeResult = { ok: true; theme: ResolvedTheme } | { ok: false; error: string };\r\n\r\n/**\r\n * The read-only reference sheets, at most one of which is open at a time.\r\n *\r\n * They are all the same kind of surface — a pinned block of text the user opened\r\n * deliberately and expects Esc to close — so they share one slot rather than a\r\n * boolean each.\r\n */\r\ntype ReferencePanel = 'help' | 'status' | 'permissions' | 'shortcuts';\r\n\r\nfunction themeAppliedMessage(theme: ResolvedTheme): string {\r\n if (theme.preference === 'auto') {\r\n return `Theme set to auto (currently ${theme.resolvedName}) and saved as default.`;\r\n }\r\n return `Switched to ${theme.preference} theme (saved as default).`;\r\n}\r\n\r\nexport function providerRemovalMessage(\r\n result: Extract<ProviderRemovalResult, { ok: true }>,\r\n): string {\r\n if (result.inheritedProviderRevealed) {\r\n return `Removed the local ${result.providerId} override; the inherited ${result.providerId} provider remains configured.`;\r\n }\r\n if (result.switched) {\r\n return `Removed local BYOK provider ${result.providerId} and switched to ${result.activeModel}.`;\r\n }\r\n const models = `${result.removedModelCount} model${result.removedModelCount === 1 ? '' : 's'}`;\r\n return `Removed local BYOK provider ${result.providerId} and its ${models}.`;\r\n}\r\n\r\n/**\r\n * Sequencing lives in `review/host.ts` so print mode runs the identical steps.\r\n * The TUI is the host that can apply patches, so it is the one that supplies a\r\n * fix runner, and it renders each segment as it is produced rather than waiting\r\n * for the (minutes-long) fix pass to finish.\r\n *\r\n * `parentSessionId` is what puts the reviewer, lens, verifier and patcher agents\r\n * in this session's agent panel and status line while they work; the runner\r\n * suppresses their completion notifications separately, so live progress costs\r\n * no extra model turn.\r\n */\r\nasync function runReviewCommand(\r\n scope: ReviewScope,\r\n manager: AgentManager,\r\n workspace: string,\r\n sessionId: string,\r\n report: (message: string) => void,\r\n signal: AbortSignal,\r\n): Promise<void> {\r\n const attribution = { parentSessionId: sessionId };\r\n await runHostReview({\r\n scope,\r\n workspace,\r\n runner: reviewRunnerFor(manager, attribution),\r\n fixRunner: fixRunnerFor(manager, attribution),\r\n onSegment: report,\r\n signal,\r\n });\r\n}\r\n\r\n/** Status text for a review in flight. Names the passes so the wait has a shape. */\r\nfunction reviewStatusLabel(scope: ReviewScope): string {\r\n if (scope.fix) return 'Reviewing, then applying verified fixes';\r\n if (scope.deep) return 'Deep review: four lenses, then verification';\r\n return 'Review in progress';\r\n}\r\n\r\nconst EMPTY_MCP_SNAPSHOT: McpHostSnapshot = { servers: [], pendingApprovals: [], events: [] };\r\n\r\ninterface AppProps {\r\n config: AgentConfig;\r\n permissionMode?: PermissionMode;\r\n interactiveAssets?: InteractiveAssets;\r\n /** Session MCP owner; servers connect in the background and tools join per send. */\r\n mcp?: McpSessionHost;\r\n session: SessionBootstrap & {\r\n store?: SessionStoreInterface;\r\n timelineStore?: SessionStoreInterface;\r\n snapshotStore?: RewindSnapshotStoreInterface;\r\n };\r\n redrawViewport?: () => void;\r\n}\r\n\r\n/**\r\n * Full-screen interactive TUI with an application-owned transcript viewport.\r\n *\r\n * The transcript scrolls independently while approvals, input, and status stay\r\n * visible. The default CLI enters the alternate screen; --scrollback preserves\r\n * linear terminal-owned history as an accessibility/fallback mode.\r\n *\r\n * Layout (top to bottom):\r\n * 1. Scrollable transcript and informational panels\r\n * 2. Fixed approval/picker interaction area\r\n * 3. Working indicator, input bar, and status line\r\n *\r\n * Keyboard shortcuts:\r\n * Esc — cancel permission / abort stream\r\n * Ctrl+C — abort stream\r\n * Ctrl+T — toggle task list\r\n * Ctrl+O — toggle detailed transcript\r\n * Ctrl+E — expand the current tool output\r\n * Ctrl+L — redraw\r\n * Ctrl+J — insert newline\r\n * PgUp/PgDn, Ctrl+U/Ctrl+D — scroll transcript\r\n * Ctrl+Home/Ctrl+End — jump to transcript start/latest\r\n * Mouse wheel — scroll transcript\r\n * Drag — select and copy visible text\r\n * Shift+drag — terminal-native selection fallback\r\n * Alt+M — cycle permission mode\r\n * Alt+P — open model picker\r\n * Alt+V — attach clipboard image\r\n * Shift+Tab — cycle permission mode\r\n * Ctrl+/ — toggle keyboard shortcuts reference\r\n */\r\nexport function App({\r\n config,\r\n permissionMode,\r\n session,\r\n redrawViewport,\r\n interactiveAssets,\r\n mcp,\r\n}: AppProps) {\r\n const {\r\n messages,\r\n contextHistory,\r\n compactBoundaries,\r\n isThinking,\r\n isCompacting,\r\n isRewinding,\r\n compactUi,\r\n streamingMessageId,\r\n error,\r\n currentTurn,\r\n tokenCount,\r\n usage,\r\n mode,\r\n pendingPermission,\r\n pendingPlanApproval,\r\n pendingUserQuestion,\r\n pendingUserQuestionCount,\r\n pendingElicitation,\r\n pendingElicitationCount,\r\n resolveElicitation,\r\n elicitationHandler,\r\n agentTodos,\r\n liveConfig,\r\n runtime,\r\n removableProviderIds,\r\n removableProviderModelCounts,\r\n sessionId,\r\n sessionName,\r\n send,\r\n sendAgentCompletions,\r\n sendBackgroundShellCompletion,\r\n clear,\r\n startNewConversation,\r\n resumeConversation,\r\n listSessions,\r\n endCurrentSession,\r\n resolvePermission,\r\n resolvePlanApproval,\r\n resolveUserQuestion,\r\n cancel,\r\n compact,\r\n rewind,\r\n getRewindTargets,\r\n cycleMode,\r\n addLocalMessage,\r\n setModel,\r\n upsertProviderAndSelect,\r\n removeProvider,\r\n setEffort,\r\n setAgentProfileModel,\r\n setCompactModel,\r\n setSkillActivation,\r\n setSkillExecution,\r\n setSkillsEnabled,\r\n setMemoryAutoSave,\r\n toggleMemoryAutoSave,\r\n toggleShowThinking,\r\n toggleStartupAnimation,\r\n refreshMemoryContext,\r\n persistPermissionRule,\r\n removePermissionRule,\r\n setDefaultPermissionMode,\r\n turnDurationMs,\r\n retryPhase,\r\n retryAttempt,\r\n retryMax,\r\n retryCountdownMs,\r\n } = useAgent(config, {\r\n ...session,\r\n permissionMode,\r\n additionalTools: mcp ? () => mcp.getToolDefinitions() : undefined,\r\n });\r\n\r\n const managedAgentManager = useMemo(\r\n () =>\r\n getOrCreateAgentManager(\r\n liveConfig,\r\n createDefaultRegistry({ agents: true }).getDefinitions(),\r\n {\r\n runtime,\r\n permissionMode: mode,\r\n persistPermissionRule,\r\n },\r\n ),\r\n [liveConfig, mode, persistPermissionRule, runtime],\r\n );\r\n const managedAgents = useManagedAgents(managedAgentManager, sessionId);\r\n const shellManager = useMemo(() => {\r\n const resolved = runtime?.shellManager ?? new ShellJobManager({ nextId: 1, shells: new Map() });\r\n resolved.configureWorkspace(liveConfig.workspace);\r\n return resolved;\r\n }, [liveConfig.workspace, runtime]);\r\n const backgroundShells = useBackgroundShells(shellManager, sessionId);\r\n // Branch and dirty state are what people glance at the footer for; the hook\r\n // existed with no consumer before the status line was reworked.\r\n const gitStatus = useGitStatus(config.workspace);\r\n\r\n const [showTasks, setShowTasks] = useState(false);\r\n const [startupFireActive, setStartupFireActive] = useState(() =>\r\n shouldPlayStartupFire(config, session),\r\n );\r\n // The four reference sheets share one slot. They were four independent\r\n // booleans, so `/help` then `/status` pinned 43 rows of chrome above the\r\n // composer and pushed the conversation off a 40-row terminal entirely. One\r\n // slot makes that impossible rather than merely discouraged, and gives Esc a\r\n // single thing to close.\r\n const [referencePanel, setReferencePanel] = useState<ReferencePanel | null>(null);\r\n const showHelp = referencePanel === 'help';\r\n const showShortcuts = referencePanel === 'shortcuts';\r\n const showStatus = referencePanel === 'status';\r\n const [showAllDetailedOutput, setShowAllDetailedOutput] = useState(false);\r\n const [showAllToolOutputIdsByTranscript, setShowAllToolOutputIdsByTranscript] = useState<\r\n Map<string, Set<string>>\r\n >(() => new Map());\r\n const [transcriptMode, setTranscriptMode] = useState<TranscriptMode>('compact');\r\n const [toolExpansionOverridesByTranscript, setToolExpansionOverridesByTranscript] = useState<\r\n Map<string, Map<string, boolean>>\r\n >(() => new Map());\r\n const [focusedToolIdsByTranscript, setFocusedToolIdsByTranscript] = useState<Map<string, string>>(\r\n () => new Map(),\r\n );\r\n const showPermissions = referencePanel === 'permissions';\r\n const [showSkills, setShowSkills] = useState(false);\r\n const [showModelPicker, setShowModelPicker] = useState(false);\r\n const [showEffortPicker, setShowEffortPicker] = useState(false);\r\n const [showPermissionModePicker, setShowPermissionModePicker] = useState(false);\r\n const [showThemePicker, setShowThemePicker] = useState(false);\r\n const [showConfigPicker, setShowConfigPicker] = useState(false);\r\n const [showAgentProfilePicker, setShowAgentProfilePicker] = useState(false);\r\n /**\r\n * The `/config` row a sub-picker was opened from, or null when it was opened\r\n * directly by its own command.\r\n *\r\n * `/config` is the only surface that exists to be *browsed* — it is the one\r\n * place the two settings with no command of their own (compact model,\r\n * subagent profiles) can be found — and it used to close the moment a row was\r\n * chosen, so browsing it was impossible and changing two settings meant\r\n * opening it twice. Two rows already came back, but only because\r\n * `selectingCompactModel` and `agentProfileForModel` happened to imply where\r\n * the picker had been opened from. Recording the origin explicitly is what\r\n * lets the other five come back too, and it is a ref rather than state\r\n * because the close handlers read it back inside their own keypress batch.\r\n */\r\n const configReturnRow = useRef<number | null>(null);\r\n const [configInitialRow, setConfigInitialRow] = useState(0);\r\n\r\n /** Reopen `/config` on the row a picker was launched from, if it was. */\r\n const returnToConfig = useCallback((): void => {\r\n const row = configReturnRow.current;\r\n configReturnRow.current = null;\r\n if (row === null) return;\r\n setConfigInitialRow(row);\r\n setShowConfigPicker(true);\r\n }, []);\r\n\r\n /**\r\n * Forget the origin, for the paths that must end at the composer: a picker\r\n * opened by its own command, and `/skills`'s \"use this skill\", which exists\r\n * to put text in the input bar.\r\n */\r\n const forgetConfigOrigin = useCallback(() => {\r\n configReturnRow.current = null;\r\n }, []);\r\n const [agentProfileForModel, setAgentProfileForModel] = useState<string>();\r\n const [selectingCompactModel, setSelectingCompactModel] = useState(false);\r\n const [showSessionPicker, setShowSessionPicker] = useState(false);\r\n const [showRewindPicker, setShowRewindPicker] = useState(false);\r\n const [isResolvingCommand, setIsResolvingCommand] = useState(false);\r\n /** Set for the lifetime of a `/review`; drives its status line and Esc. */\r\n const [reviewStatus, setReviewStatus] = useState<string | undefined>(undefined);\r\n const reviewAbortRef = useRef<AbortController | null>(null);\r\n /** The conversation currently on screen, for routing a review's late output. */\r\n const reviewSessionRef = useRef(sessionId);\r\n const [draftRestore, setDraftRestore] = useState<{\r\n key: number;\r\n value: string;\r\n attachments?: ImageAttachment[];\r\n }>();\r\n const [queuedInputs, setQueuedInputs] = useState<QueuedInput[]>([]);\r\n const [editingQueuedInput, setEditingQueuedInput] = useState<QueuedInput | undefined>(undefined);\r\n const [queueNotice, setQueueNotice] = useState<string | undefined>(undefined);\r\n const [copyNotice, setCopyNotice] = useState<string | undefined>(undefined);\r\n const copyNoticeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const handleCopiedNotice = useCallback((message: string) => {\r\n setCopyNotice(message);\r\n if (copyNoticeTimerRef.current) clearTimeout(copyNoticeTimerRef.current);\r\n copyNoticeTimerRef.current = setTimeout(() => {\r\n copyNoticeTimerRef.current = null;\r\n setCopyNotice(undefined);\r\n }, 2_000);\r\n }, []);\r\n const [sendInFlight, setSendInFlight] = useState(false);\r\n const [, setQueueDrainTick] = useState(0);\r\n const [shellCompletionRetryTick, setShellCompletionRetryTick] = useState(0);\r\n const [followRequestKey, setFollowRequestKey] = useState(0);\r\n const [detailTaskPickerOpen, setDetailTaskPickerOpen] = useState(false);\r\n const [detailTaskPickerAgentId, setDetailTaskPickerAgentId] = useState<string | undefined>(\r\n undefined,\r\n );\r\n const [selectedShellId, setSelectedShellId] = useState<string>();\r\n const commandResolutionRef = useRef<AbortController | null>(null);\r\n const queuedInputsRef = useRef<QueuedInput[]>([]);\r\n const editingQueuedInputRef = useRef<QueuedInput | undefined>(undefined);\r\n const dispatchingQueuedIdRef = useRef<string | undefined>(undefined);\r\n const draftRef = useRef('');\r\n const startupDraftRef = useRef('');\r\n const draftAttachmentsRef = useRef<ImageAttachment[]>([]);\r\n const queueDrainRunningRef = useRef(false);\r\n const shellCompletionDeliveryRef = useRef(false);\r\n const shellCompletionRetryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const queueDrainPausedRef = useRef(false);\r\n const queueInterruptEpochRef = useRef(0);\r\n const queueSessionRef = useRef(sessionId);\r\n const [currentTheme, setCurrentTheme] = useState<ResolvedTheme>(\r\n () =>\r\n interactiveAssets?.initialTheme ??\r\n resolveTheme(config.workspace, config.settings.theme ?? 'apple') ?? {\r\n preference: 'apple',\r\n resolvedName: 'apple',\r\n tokens: APPLE_THEME,\r\n },\r\n );\r\n const [customThemes, setCustomThemes] = useState<string[]>(\r\n () => interactiveAssets?.customThemes ?? listCustomThemes(config.workspace),\r\n );\r\n const { tasks, addTask, updateTaskStatus, removeTask, clearTasks } = useTasks();\r\n const theme = currentTheme.tokens;\r\n const { exit: exitApp } = useApp();\r\n const replaceQueuedInputs = useCallback((next: QueuedInput[]) => {\r\n queuedInputsRef.current = next;\r\n setQueuedInputs(next);\r\n }, []);\r\n const replaceEditingQueuedInput = useCallback((next?: QueuedInput) => {\r\n editingQueuedInputRef.current = next;\r\n setEditingQueuedInput(next);\r\n }, []);\r\n const dispatchAgentSend = useCallback(\r\n async (value: string, commandContext?: CommandContext, attachments?: ImageAttachment[]) => {\r\n setSendInFlight(true);\r\n try {\r\n if (attachments && attachments.length > 0) {\r\n return await send(value, commandContext, attachments);\r\n }\r\n return commandContext === undefined ? await send(value) : await send(value, commandContext);\r\n } finally {\r\n setSendInFlight(false);\r\n }\r\n },\r\n [send],\r\n );\r\n const enqueueFollowUp = useCallback(\r\n (value: string, attachments: ImageAttachment[] = []): boolean => {\r\n const edited = editingQueuedInputRef.current;\r\n const input = createQueuedInput(value, sessionId, attachments, edited);\r\n const result = enqueueQueuedInput(queuedInputsRef.current, input);\r\n if (!result.accepted) {\r\n setQueueNotice('Queue is full. Edit or clear a queued message before adding another.');\r\n return false;\r\n }\r\n replaceQueuedInputs(result.queue);\r\n replaceEditingQueuedInput(undefined);\r\n queueDrainPausedRef.current = false;\r\n setQueueNotice(undefined);\r\n return true;\r\n },\r\n [replaceEditingQueuedInput, replaceQueuedInputs, sessionId],\r\n );\r\n const recallQueuedInput = useCallback(():\r\n { value: string; attachments?: ImageAttachment[] } | undefined => {\r\n const result = recallNewestQueuedInput(queuedInputsRef.current, dispatchingQueuedIdRef.current);\r\n if (!result.recalled) return undefined;\r\n replaceQueuedInputs(result.queue);\r\n replaceEditingQueuedInput(result.recalled);\r\n queueDrainPausedRef.current = true;\r\n setQueueNotice('Editing queued input. Enter resubmits; Esc removes it.');\r\n return { value: result.recalled.value, attachments: result.recalled.attachments };\r\n }, [replaceEditingQueuedInput, replaceQueuedInputs]);\r\n const cancelQueuedEdit = useCallback(() => {\r\n replaceEditingQueuedInput(undefined);\r\n queueDrainPausedRef.current = false;\r\n setQueueNotice('Queued input removed.');\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: '',\r\n }));\r\n }, [replaceEditingQueuedInput]);\r\n const pasteClipboardImage = useCallback(async (): Promise<ImageAttachment> => {\r\n if (liveConfig.modelInfo?.vision === false) {\r\n throw new Error(`${liveConfig.model} does not support image input.`);\r\n }\r\n const store = session.timelineStore ?? session.store;\r\n if (!store?.saveImageAttachment) {\r\n throw new Error('Session attachment storage is unavailable.');\r\n }\r\n const image = await readClipboardImage();\r\n return store.saveImageAttachment(sessionId, {\r\n bytes: image.bytes,\r\n mediaType: image.mediaType,\r\n displayName: `clipboard-${Date.now()}.${image.mediaType.split('/')[1]}`,\r\n });\r\n }, [\r\n liveConfig.model,\r\n liveConfig.modelInfo?.vision,\r\n session.store,\r\n session.timelineStore,\r\n sessionId,\r\n ]);\r\n const interrupt = useCallback(() => {\r\n queueInterruptEpochRef.current += 1;\r\n commandResolutionRef.current?.abort();\r\n commandResolutionRef.current = null;\r\n const pending = queuedInputsRef.current;\r\n if (pending.length > 0) {\r\n const restored = restoreQueuedInputText(pending, draftRef.current);\r\n replaceQueuedInputs([]);\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: restored,\r\n attachments: restoreQueuedInputAttachments(pending, draftAttachmentsRef.current),\r\n }));\r\n setQueueNotice('Queued inputs restored to the composer after interrupt.');\r\n }\r\n replaceEditingQueuedInput(undefined);\r\n queueDrainPausedRef.current = true;\r\n cancel();\r\n }, [cancel, replaceEditingQueuedInput, replaceQueuedInputs]);\r\n\r\n useEffect(() => {\r\n return () => commandResolutionRef.current?.abort();\r\n }, []);\r\n\r\n /**\r\n * Start a review and keep a handle on it.\r\n *\r\n * A review outlives the keystroke that started it by minutes, so the session\r\n * has to hold onto something cancellable: without it the only way out of a\r\n * wrong or wedged review was Ctrl+C, which exits Book and orphans the agents\r\n * it spawned.\r\n */\r\n const startReview = useCallback(\r\n (scope: ReviewScope) => {\r\n if (reviewAbortRef.current) {\r\n addLocalMessage('A review is already running. Cancel it with Esc before starting another.');\r\n return;\r\n }\r\n const controller = new AbortController();\r\n reviewAbortRef.current = controller;\r\n setReviewStatus(reviewStatusLabel(scope));\r\n // A review's output belongs to the conversation that asked for it. Its\r\n // last segments can still arrive after a `/new`, and appending them to an\r\n // unrelated transcript is worse than dropping them.\r\n const startedIn = sessionId;\r\n const report = (message: string) => {\r\n if (reviewSessionRef.current !== startedIn) return;\r\n addLocalMessage(message);\r\n };\r\n void runReviewCommand(\r\n scope,\r\n managedAgentManager,\r\n config.workspace,\r\n sessionId,\r\n report,\r\n controller.signal,\r\n )\r\n .catch((reviewError) =>\r\n report(`✕ ${reviewError instanceof Error ? reviewError.message : String(reviewError)}`),\r\n )\r\n .finally(() => {\r\n if (reviewAbortRef.current !== controller) return;\r\n reviewAbortRef.current = null;\r\n setReviewStatus(undefined);\r\n // An ordinary agent leaves the panel when its completion is\r\n // acknowledged. These have no completion by design, so without this\r\n // every finished lens and verifier would stay pinned there — and in\r\n // the status-line count — for the rest of the session.\r\n void managedAgents.refresh().catch(() => {});\r\n });\r\n },\r\n [addLocalMessage, config.workspace, managedAgentManager, managedAgents.refresh, sessionId],\r\n );\r\n\r\n /** Returns whether a review was actually cancelled, so callers can fall through. */\r\n const cancelReview = useCallback((): boolean => {\r\n const controller = reviewAbortRef.current;\r\n if (!controller || controller.signal.aborted) return false;\r\n controller.abort();\r\n setReviewStatus('Cancelling review — stopping its agents');\r\n return true;\r\n }, []);\r\n\r\n // Abort on unmount so a review cannot keep spawning agents into a dead UI.\r\n useEffect(() => {\r\n return () => reviewAbortRef.current?.abort();\r\n }, []);\r\n\r\n /**\r\n * End a review when the conversation it belongs to does.\r\n *\r\n * A review is scoped to the session that started it: its agents are owned by\r\n * that `parentSessionId`, so after a `/new` or `/resume` they are invisible,\r\n * and its report would be appended to a conversation that never asked for it.\r\n * The run also holds the single-review slot, so leaving it alive would refuse\r\n * a `/review` typed in the new session.\r\n */\r\n useEffect(() => {\r\n if (reviewSessionRef.current === sessionId) return;\r\n reviewSessionRef.current = sessionId;\r\n const controller = reviewAbortRef.current;\r\n if (!controller) return;\r\n controller.abort();\r\n reviewAbortRef.current = null;\r\n setReviewStatus(undefined);\r\n }, [sessionId]);\r\n\r\n useEffect(() => {\r\n setDetailTaskPickerOpen(false);\r\n setDetailTaskPickerAgentId(undefined);\r\n setSelectedShellId(undefined);\r\n managedAgents.setSurface('main');\r\n managedAgents.selectAgent(undefined);\r\n }, [managedAgents.selectAgent, managedAgents.setSurface, sessionId]);\r\n\r\n useEffect(() => {\r\n if (queueSessionRef.current === sessionId) return;\r\n queueSessionRef.current = sessionId;\r\n queueInterruptEpochRef.current += 1;\r\n replaceQueuedInputs([]);\r\n replaceEditingQueuedInput(undefined);\r\n dispatchingQueuedIdRef.current = undefined;\r\n queueDrainRunningRef.current = false;\r\n queueDrainPausedRef.current = false;\r\n setQueueNotice(undefined);\r\n draftRef.current = '';\r\n }, [replaceEditingQueuedInput, replaceQueuedInputs, sessionId]);\r\n\r\n useAgentCompletionDelivery({\r\n pending: managedAgents.pendingCompletions,\r\n parentSessionId: sessionId,\r\n blocked: Boolean(\r\n isThinking ||\r\n isCompacting ||\r\n isRewinding ||\r\n isResolvingCommand ||\r\n pendingPermission ||\r\n pendingPlanApproval ||\r\n pendingUserQuestion ||\r\n pendingElicitation,\r\n ),\r\n deliver: sendAgentCompletions,\r\n acknowledge: managedAgents.acknowledgeCompletions,\r\n });\r\n\r\n const [commands, setCommands] = useState(\r\n () => interactiveAssets?.commands ?? discoverCommands(config.workspace),\r\n );\r\n const builtinCommandRegistry = useMemo(() => createBuiltinCommandRegistry(), []);\r\n const [skills, setSkills] = useState(\r\n () =>\r\n interactiveAssets?.skills ??\r\n discoverSkills(config.workspace, config.settings.skills.overrides, {\r\n executionOverrides: config.settings.skills.execution,\r\n enabled: config.settings.skills.enabled,\r\n }),\r\n );\r\n const [skillCatalogDirty, setSkillCatalogDirty] = useState(false);\r\n const [skillWatcherError, setSkillWatcherError] = useState<string>();\r\n useEffect(() => {\r\n if (!runtime) return;\r\n return runtime.subscribeSkillChanges(\r\n config.workspace,\r\n () => {\r\n const watcherError = runtime.skillWatcherError;\r\n setSkillWatcherError(watcherError);\r\n if (!watcherError) setSkillCatalogDirty(true);\r\n },\r\n liveConfig.settings.skills.enabled,\r\n );\r\n }, [config.workspace, liveConfig.settings.skills.enabled, runtime]);\r\n useEffect(() => {\r\n if (!runtime || !skillCatalogDirty || isThinking) return;\r\n const refreshed = runtime.consumeSkillChanges(config.workspace, liveConfig.settings.skills);\r\n setSkills(refreshed.list());\r\n setSkillWatcherError(undefined);\r\n setSkillCatalogDirty(false);\r\n }, [config.workspace, isThinking, liveConfig.settings.skills, runtime, skillCatalogDirty]);\r\n const [agentProfiles, setAgentProfiles] = useState(() =>\r\n withBuiltInAgents(discoverAgents(config.workspace)),\r\n );\r\n const modelOptions = useMemo(() => buildModelOptions(liveConfig.settings), [liveConfig.settings]);\r\n const configuredAgentModels = useMemo(\r\n () =>\r\n Object.fromEntries(\r\n Object.entries(liveConfig.settings.agents.profiles).map(([name, profile]) => [\r\n name,\r\n profile.model,\r\n ]),\r\n ),\r\n [liveConfig.settings.agents.profiles],\r\n );\r\n const activeAgentProfile = agentProfileForModel\r\n ? agentProfiles.find((profile) => profile.name === agentProfileForModel)\r\n : undefined;\r\n const modelPickerSelection = selectingCompactModel\r\n ? (liveConfig.compactModel ??\r\n liveConfig.settings.compactModel ??\r\n liveConfig.modelSelection ??\r\n liveConfig.model)\r\n : activeAgentProfile\r\n ? (configuredAgentModels[activeAgentProfile.name] ??\r\n activeAgentProfile.model ??\r\n liveConfig.modelSelection ??\r\n liveConfig.model)\r\n : (liveConfig.modelSelection ?? liveConfig.model);\r\n const effortLevels = useMemo(() => getAvailableEffortLevels(liveConfig), [liveConfig.modelInfo]);\r\n\r\n const { stdout } = useStdout();\r\n const readTerminalSize = useCallback(\r\n () => ({\r\n columns: Math.max(20, stdout?.columns ?? 80),\r\n rows: Math.max(8, stdout?.rows ?? 24),\r\n }),\r\n [stdout],\r\n );\r\n const [terminalSize, setTerminalSize] = useState(readTerminalSize);\r\n const lastAppliedSizeRef = useRef(terminalSize);\r\n const resizeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const applyTerminalSize = useCallback(\r\n (nextSize: { columns: number; rows: number }, redraw: boolean) => {\r\n const previousSize = lastAppliedSizeRef.current;\r\n if (nextSize.columns === previousSize.columns && nextSize.rows === previousSize.rows) return;\r\n if (redraw) redrawViewport?.();\r\n lastAppliedSizeRef.current = nextSize;\r\n setTerminalSize(nextSize);\r\n },\r\n [redrawViewport],\r\n );\r\n\r\n useEffect(() => {\r\n // Reconcile dimensions that changed between the initial render and effect\r\n // registration without destructively clearing the first frame.\r\n applyTerminalSize(readTerminalSize(), false);\r\n\r\n const updateSize = () => {\r\n if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current);\r\n resizeTimerRef.current = setTimeout(() => {\r\n resizeTimerRef.current = null;\r\n applyTerminalSize(readTerminalSize(), true);\r\n }, 50);\r\n };\r\n\r\n stdout?.on?.('resize', updateSize);\r\n return () => {\r\n stdout?.off?.('resize', updateSize);\r\n if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current);\r\n };\r\n }, [applyTerminalSize, readTerminalSize, stdout]);\r\n\r\n const termWidth = terminalSize.columns;\r\n const termHeight = terminalSize.rows;\r\n const isNarrow = termWidth < 64;\r\n const isTiny = termWidth < 42 || termHeight < 12;\r\n const maxCommandMenuRows = Math.max(2, Math.min(isTiny ? 3 : 8, Math.floor(termHeight / 3)));\r\n const compactStatus = isNarrow || isTiny;\r\n const density = resolveTuiDensity(termHeight);\r\n const reducedMotion = Boolean(config.accessibility?.reducedMotion);\r\n // Keep the whole live region quiescent while the terminal viewport belongs\r\n // to the user reviewing a plan. Any animation repaint can snap scrollback.\r\n const motionDisabled =\r\n reducedMotion || Boolean(pendingPlanApproval || pendingUserQuestion || pendingElicitation);\r\n const screenReader = Boolean(config.accessibility?.screenReader);\r\n const managedAgentUiEnabled = liveConfig.settings.agents.ui.enabled;\r\n const childPermission = managedAgents.pendingPermissions.find(\r\n (event) => event.type === 'agent_permission',\r\n );\r\n const childQuestion = managedAgents.pendingQuestions[0];\r\n\r\n const subscribeMcp = useCallback(\r\n (listener: () => void) => mcp?.subscribe(listener) ?? (() => {}),\r\n [mcp],\r\n );\r\n const readMcpSnapshot = useCallback(() => mcp?.getSnapshot() ?? EMPTY_MCP_SNAPSHOT, [mcp]);\r\n const mcpSnapshot = useSyncExternalStore(subscribeMcp, readMcpSnapshot);\r\n // Servers connect in the background; this binds their elicitation prompts to\r\n // this session's interaction queue once the UI exists to answer them.\r\n useEffect(() => {\r\n if (!mcp) return;\r\n mcp.setElicitationHandler(elicitationHandler);\r\n return () => mcp.setElicitationHandler(undefined);\r\n }, [mcp, elicitationHandler]);\r\n const pendingMcpApproval = mcpSnapshot.pendingApprovals[0];\r\n // The trust prompt yields to every other modal surface and reappears once idle.\r\n const showMcpApproval =\r\n Boolean(pendingMcpApproval) &&\r\n !ownsModalInput(\r\n pendingPermission ?? childPermission ?? childQuestion,\r\n pendingPlanApproval,\r\n showModelPicker,\r\n showSessionPicker,\r\n pendingUserQuestion,\r\n showEffortPicker,\r\n showThemePicker,\r\n showRewindPicker,\r\n showConfigPicker,\r\n showAgentProfilePicker,\r\n showPermissionModePicker,\r\n showSkills,\r\n undefined,\r\n pendingElicitation,\r\n );\r\n\r\n // Surface connection outcomes as transcript notices once the turn is idle;\r\n // addLocalMessage drops messages mid-turn, so consumption waits for idle.\r\n const lastMcpEventIdRef = useRef(0);\r\n useEffect(() => {\r\n const events = mcpSnapshot.events;\r\n const fresh = events.filter((event) => event.id > lastMcpEventIdRef.current);\r\n if (fresh.length === 0) return;\r\n if (isThinking || sendInFlight) return;\r\n lastMcpEventIdRef.current = fresh[fresh.length - 1].id;\r\n for (const event of fresh) {\r\n if (event.type === 'connected') {\r\n addLocalMessage(\r\n `MCP: connected to \"${event.server}\" (${event.toolCount} tool${event.toolCount === 1 ? '' : 's'}).`,\r\n );\r\n } else if (event.type === 'failed') {\r\n addLocalMessage(`MCP: failed to connect \"${event.server}\": ${event.error}`);\r\n } else if (event.type === 'disconnected') {\r\n addLocalMessage(`MCP: \"${event.server}\" disconnected.`);\r\n } else {\r\n addLocalMessage(`MCP: \"${event.server}\" tool list updated (${event.toolCount} tools).`);\r\n }\r\n }\r\n }, [mcpSnapshot, isThinking, sendInFlight, addLocalMessage]);\r\n const queueDrainBlocked = Boolean(\r\n isThinking ||\r\n sendInFlight ||\r\n isCompacting ||\r\n isRewinding ||\r\n isResolvingCommand ||\r\n pendingPermission ||\r\n pendingPlanApproval ||\r\n pendingUserQuestion ||\r\n pendingElicitation ||\r\n childPermission ||\r\n childQuestion ||\r\n editingQueuedInput ||\r\n managedAgents.surface !== 'main',\r\n );\r\n\r\n const scheduleShellCompletionRetry = useCallback(() => {\r\n if (shellCompletionRetryTimerRef.current) {\r\n clearTimeout(shellCompletionRetryTimerRef.current);\r\n }\r\n shellCompletionRetryTimerRef.current = setTimeout(() => {\r\n shellCompletionRetryTimerRef.current = null;\r\n setShellCompletionRetryTick((current) => current + 1);\r\n }, 1_000);\r\n }, []);\r\n\r\n useEffect(\r\n () => () => {\r\n if (shellCompletionRetryTimerRef.current) {\r\n clearTimeout(shellCompletionRetryTimerRef.current);\r\n }\r\n },\r\n [],\r\n );\r\n\r\n useEffect(() => {\r\n const completion = backgroundShells.pendingAgentCompletions[0];\r\n if (!completion || queueDrainBlocked || shellCompletionDeliveryRef.current) return;\r\n shellCompletionDeliveryRef.current = true;\r\n void sendBackgroundShellCompletion(completion)\r\n .then((accepted) => {\r\n if (accepted) {\r\n if (shellCompletionRetryTimerRef.current) {\r\n clearTimeout(shellCompletionRetryTimerRef.current);\r\n shellCompletionRetryTimerRef.current = null;\r\n }\r\n backgroundShells.acknowledgeAgentCompletion(completion.id, completion.completionSequence);\r\n } else {\r\n scheduleShellCompletionRetry();\r\n }\r\n })\r\n .catch(() => scheduleShellCompletionRetry())\r\n .finally(() => {\r\n shellCompletionDeliveryRef.current = false;\r\n });\r\n }, [\r\n backgroundShells.acknowledgeAgentCompletion,\r\n backgroundShells.pendingAgentCompletions,\r\n queueDrainBlocked,\r\n scheduleShellCompletionRetry,\r\n sendBackgroundShellCompletion,\r\n shellCompletionRetryTick,\r\n ]);\r\n const managedAgentTraces = useMemo(\r\n () => projectManagedAgentTraces(messages, managedAgents.records, managedAgents.activities),\r\n [managedAgents.activities, managedAgents.records, messages],\r\n );\r\n const returnToMain = useCallback(() => {\r\n setDetailTaskPickerOpen(false);\r\n setDetailTaskPickerAgentId(undefined);\r\n setSelectedShellId(undefined);\r\n managedAgents.setSurface('main');\r\n managedAgents.selectAgent(undefined);\r\n }, [managedAgents.selectAgent, managedAgents.setSurface]);\r\n\r\n const selectBackgroundJob = useCallback(\r\n (jobId?: string) => {\r\n if (!jobId) {\r\n setSelectedShellId(undefined);\r\n managedAgents.selectAgent(undefined);\r\n return;\r\n }\r\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\r\n setSelectedShellId(jobId);\r\n managedAgents.selectAgent(undefined);\r\n } else {\r\n setSelectedShellId(undefined);\r\n managedAgents.selectAgent(jobId);\r\n }\r\n },\r\n [backgroundShells.shells, managedAgents.selectAgent],\r\n );\r\n\r\n // Terminal jobs are removed from the active list as soon as they finish or\r\n // stop. Leave their detail view even when notifications are disabled.\r\n useEffect(() => {\r\n if (selectedShellId && !backgroundShells.shells.some((shell) => shell.id === selectedShellId)) {\r\n returnToMain();\r\n }\r\n }, [backgroundShells.shells, returnToMain, selectedShellId]);\r\n\r\n useEffect(() => {\r\n const completed = backgroundShells.lastCompletion;\r\n if (!completed) return;\r\n const exit = completed.exitCode !== undefined ? ` (exit ${completed.exitCode ?? 'none'})` : '';\r\n // The title defaults to the whole command, and this row is what a user\r\n // reads to confirm *which* command finished — so it has to survive the\r\n // prose renderer that the rest of this sentence is written for. Inline\r\n // code also matches the `ToolCallBlock` that started the job.\r\n addLocalMessage(\r\n `${completed.status === 'exited' ? '✓' : '✕'} Background shell ${inlineCode(completed.title || completed.id)} ${completed.status}${exit}.`,\r\n );\r\n backgroundShells.acknowledge(completed.id);\r\n if (selectedShellId === completed.id) returnToMain();\r\n }, [\r\n addLocalMessage,\r\n backgroundShells.acknowledge,\r\n backgroundShells.lastCompletion,\r\n returnToMain,\r\n selectedShellId,\r\n ]);\r\n\r\n const readSelectedShellTail = useCallback(\r\n () => (selectedShellId ? (shellManager.readTail(selectedShellId, 16_000) ?? '') : ''),\r\n [selectedShellId, shellManager],\r\n );\r\n\r\n // Tab cycles focus flatly through [main, ...spawned agents], opening each\r\n // child's transcript directly. Wrapping past the last agent returns to main.\r\n // Returns false when there is nothing to cycle so InputBar can fall back to\r\n // its default Tab behavior.\r\n const cycleAgentFocus = useCallback((): boolean => {\r\n if (!managedAgentUiEnabled) return false;\r\n const jobIds = [\r\n ...managedAgents.summaries.map((agent) => agent.agentId),\r\n ...backgroundShells.shells.map((shell) => shell.id),\r\n ];\r\n if (jobIds.length === 0) return false;\r\n const rows: Array<string | undefined> = [undefined, ...jobIds];\r\n const currentId =\r\n managedAgents.surface === 'detail'\r\n ? (selectedShellId ?? managedAgents.selectedAgentId)\r\n : undefined;\r\n const currentIndex = currentId ? rows.indexOf(currentId) : 0;\r\n const next = rows[((currentIndex < 0 ? 0 : currentIndex) + 1) % rows.length];\r\n if (next === undefined) {\r\n returnToMain();\r\n } else {\r\n selectBackgroundJob(next);\r\n managedAgents.setSurface('detail');\r\n }\r\n return true;\r\n }, [\r\n backgroundShells.shells,\r\n managedAgentUiEnabled,\r\n managedAgents,\r\n returnToMain,\r\n selectBackgroundJob,\r\n selectedShellId,\r\n ]);\r\n\r\n useEffect(() => {\r\n if (\r\n queueDrainBlocked ||\r\n queueDrainRunningRef.current ||\r\n queueDrainPausedRef.current ||\r\n queuedInputs.length === 0\r\n ) {\r\n return;\r\n }\r\n\r\n const item = queuedInputsRef.current[0];\r\n if (!item) return;\r\n if (item.sessionId !== sessionId) {\r\n replaceQueuedInputs(queuedInputsRef.current.slice(1));\r\n setQueueNotice('Discarded a queued input from a previous session.');\r\n return;\r\n }\r\n\r\n queueDrainRunningRef.current = true;\r\n dispatchingQueuedIdRef.current = item.id;\r\n const interruptEpoch = queueInterruptEpochRef.current;\r\n replaceQueuedInputs(queuedInputsRef.current.slice(1));\r\n setQueueNotice('Sending queued follow-up...');\r\n\r\n void (async () => {\r\n try {\r\n const result = await dispatchAgentSend(item.value, undefined, item.attachments);\r\n if (queueInterruptEpochRef.current !== interruptEpoch && shouldRequeueQueuedSend(result)) {\r\n if (queueSessionRef.current === item.sessionId) {\r\n const restored = restoreQueuedInputText([item], draftRef.current);\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: restored,\r\n attachments: restoreQueuedInputAttachments([item], draftAttachmentsRef.current),\r\n }));\r\n setQueueNotice('Interrupted queued input restored to the composer.');\r\n }\r\n return;\r\n }\r\n if (shouldRequeueQueuedSend(result)) {\r\n replaceQueuedInputs([item, ...queuedInputsRef.current]);\r\n queueDrainPausedRef.current = true;\r\n setQueueNotice(\r\n 'Queued send did not start. Press Up to edit it or Enter another message.',\r\n );\r\n } else if (result.status === 'failed') {\r\n queueDrainPausedRef.current = true;\r\n setQueueNotice('Queued send failed. Automatic queue dispatch is paused.');\r\n } else {\r\n setQueueNotice(undefined);\r\n }\r\n } catch (sendError) {\r\n replaceQueuedInputs([item, ...queuedInputsRef.current]);\r\n queueDrainPausedRef.current = true;\r\n setQueueNotice(\r\n `Queued send failed before dispatch: ${\r\n sendError instanceof Error ? sendError.message : String(sendError)\r\n }`,\r\n );\r\n } finally {\r\n dispatchingQueuedIdRef.current = undefined;\r\n queueDrainRunningRef.current = false;\r\n setQueueDrainTick((tick) => tick + 1);\r\n }\r\n })();\r\n }, [dispatchAgentSend, queueDrainBlocked, queuedInputs.length, replaceQueuedInputs, sessionId]);\r\n\r\n useDebugMount(uiLog, {\r\n workspace: config.workspace,\r\n model: config.model,\r\n provider: config.provider,\r\n commandsLen: commands.length,\r\n skillsLen: skills.length,\r\n });\r\n useDebugValueChange(uiLog, 'layout:width', termWidth);\r\n useDebugValueChange(uiLog, 'layout:height', termHeight);\r\n useDebugValueChange(uiLog, 'layout:compactStatus', compactStatus, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showTasks', showTasks, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showHelp', showHelp, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showShortcuts', showShortcuts, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showStatus', showStatus, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showAllDetailedOutput', showAllDetailedOutput, (v) => String(v));\r\n useDebugValueChange(uiLog, 'transcriptMode', transcriptMode);\r\n useDebugValueChange(uiLog, 'showPermissions', showPermissions, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showSkills', showSkills, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showModelPicker', showModelPicker, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showEffortPicker', showEffortPicker, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showPermissionModePicker', showPermissionModePicker, (v) =>\r\n String(v),\r\n );\r\n useDebugValueChange(uiLog, 'showThemePicker', showThemePicker, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showConfigPicker', showConfigPicker, (v) => String(v));\r\n useDebugValueChange(uiLog, 'showAgentProfilePicker', showAgentProfilePicker, (v) => String(v));\r\n\r\n useInput((input, key) => {\r\n if (startupFireActive) {\r\n if (key.ctrl && input === 'c') {\r\n uiLog.event('input:Ctrl+C', { action: 'exit-startup-fire' });\r\n void endCurrentSession('exit').finally(exitApp);\r\n return;\r\n }\r\n if (key.escape) {\r\n uiLog.event('input:Escape', { action: 'skip-startup-fire' });\r\n setStartupFireActive(false);\r\n return;\r\n }\r\n const draftInput = stripSgrMouseSequences(input);\r\n if (!key.ctrl && !key.meta && containsDraftInput(draftInput)) {\r\n uiLog.event('input:printable', { action: 'skip-startup-fire' });\r\n // React may deliver several stdin chunks before the splash dismissal commits.\r\n startupDraftRef.current += draftInput;\r\n const startupDraft = startupDraftRef.current;\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: startupDraft,\r\n }));\r\n setStartupFireActive(false);\r\n return;\r\n }\r\n return;\r\n }\r\n\r\n // Modal prompts own the keyboard until they resolve. Let their own\r\n // useInput handlers receive the event, but do not open another modal or\r\n // mutate surrounding UI state from this global handler.\r\n if (\r\n ownsModalInput(\r\n pendingPermission ?? childPermission ?? childQuestion,\r\n pendingPlanApproval,\r\n showModelPicker,\r\n showSessionPicker,\r\n pendingUserQuestion,\r\n showEffortPicker,\r\n showThemePicker,\r\n showRewindPicker,\r\n showConfigPicker,\r\n showAgentProfilePicker,\r\n showPermissionModePicker,\r\n showSkills,\r\n showMcpApproval,\r\n pendingElicitation,\r\n )\r\n ) {\r\n if (key.escape) {\r\n uiLog.event('input:Escape', { action: 'noop-modal-active' });\r\n } else if (key.ctrl && input === 'c') {\r\n if (pendingUserQuestion || pendingElicitation) {\r\n uiLog.event('input:Ctrl+C', { action: 'cancel-question-turn' });\r\n interrupt();\r\n } else {\r\n uiLog.event('input:Ctrl+C', { action: 'noop-modal-active' });\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (transcriptMode === 'detailed') {\r\n const transcriptAction = getTranscriptShortcutAction(transcriptMode, input, key);\r\n if (transcriptAction === 'exit-detailed') {\r\n uiLog.event('input:detail-exit', {\r\n key: key.ctrl ? 'Ctrl+O' : key.escape ? 'Escape' : 'q',\r\n });\r\n setTranscriptMode('compact');\r\n setShowAllDetailedOutput(false);\r\n return;\r\n }\r\n if (transcriptAction === 'expand-output') {\r\n uiLog.event('input:Ctrl+E', { action: 'show-all-detailed-output' });\r\n setShowAllDetailedOutput(true);\r\n return;\r\n }\r\n }\r\n\r\n if (key.escape && detailTaskPickerOpen) {\r\n setDetailTaskPickerOpen(false);\r\n setDetailTaskPickerAgentId(undefined);\r\n return;\r\n }\r\n if (key.escape && managedAgents.surface === 'detail') {\r\n returnToMain();\r\n return;\r\n }\r\n if (key.escape && managedAgents.surface === 'tasks') {\r\n managedAgents.setSurface('main');\r\n return;\r\n }\r\n\r\n if (key.escape && editingQueuedInput) {\r\n uiLog.event('input:Escape', { action: 'cancel-queued-edit' });\r\n cancelQueuedEdit();\r\n return;\r\n }\r\n\r\n // Escape aborts an in-flight stream when no prompt owns the keyboard.\r\n // A streaming turn outranks a background review: cancelling the thing the\r\n // user is watching is the established meaning of Esc.\r\n if (key.escape) {\r\n if (isThinking || sendInFlight || isResolvingCommand) {\r\n uiLog.event('input:Escape', { action: 'cancel-stream' });\r\n interrupt();\r\n return;\r\n }\r\n if (cancelReview()) {\r\n uiLog.event('input:Escape', { action: 'cancel-review' });\r\n return;\r\n }\r\n // Nothing is in flight, so Esc falls through to the reference sheet the\r\n // user opened. It ranks last deliberately: a panel is a static block of\r\n // text, and Esc must never stop meaning \"cancel the running turn\".\r\n if (referencePanel) {\r\n uiLog.event('input:Escape', { action: 'close-panel', panel: referencePanel });\r\n setReferencePanel(null);\r\n return;\r\n }\r\n uiLog.event('input:Escape', { action: 'noop-idle' });\r\n }\r\n // Ctrl+C — cancel in-flight work; otherwise preserve normal terminal exit.\r\n if (key.ctrl && input === 'c') {\r\n if (isThinking || sendInFlight || isResolvingCommand) {\r\n uiLog.event('input:Ctrl+C', { action: 'cancel-stream' });\r\n interrupt();\r\n return;\r\n }\r\n // A review is in-flight work too, and exiting here would orphan the\r\n // agents it spawned. A second Ctrl+C still exits, as it does mid-stream.\r\n if (cancelReview()) {\r\n uiLog.event('input:Ctrl+C', { action: 'cancel-review' });\r\n return;\r\n }\r\n uiLog.event('input:Ctrl+C', { action: 'exit' });\r\n void endCurrentSession('exit').finally(exitApp);\r\n return;\r\n }\r\n // Ctrl+T — toggle task list\r\n if (key.ctrl && input === 't') {\r\n uiLog.event('input:Ctrl+T', { action: 'toggle-tasks' });\r\n setShowTasks((s) => !s);\r\n return;\r\n }\r\n // Alt+M — cycle mode\r\n if (key.meta && input === 'm') {\r\n uiLog.event('input:Alt+M', { action: 'cycle-mode' });\r\n cycleMode();\r\n return;\r\n }\r\n // Alt+P — open model picker\r\n if (key.meta && input === 'p') {\r\n uiLog.event('input:Alt+P', { action: 'open-model-picker' });\r\n setShowModelPicker(true);\r\n return;\r\n }\r\n // Ctrl+L — clear the visible viewport and force a fresh Ink frame.\r\n if (key.ctrl && input === 'l') {\r\n uiLog.event('input:Ctrl+L', { action: 'redraw' });\r\n redrawViewport?.();\r\n return;\r\n }\r\n });\r\n\r\n // Log slash-command dispatches at a coarse level (command name + arg).\r\n // The detailed branching in handleSubmit stays unchanged; this only emits\r\n // one event per submit to make the dispatch traceable.\r\n useEffect(() => {\r\n if (isThinking) {\r\n uiLog.event('state:thinking', { messages: messages.length, currentTurn });\r\n }\r\n }, [isThinking, messages.length, currentTurn]);\r\n\r\n // Active tools open automatically; completed file mutations use their own default policy.\r\n const expandedToolId = useMemo(() => selectExpandedToolId(messages), [messages]);\r\n const showAgentPlan = shouldShowAgentPlan(agentTodos, showTasks);\r\n const selectedManagedAgentRecord = managedAgents.selectedAgentId\r\n ? managedAgents.records.get(managedAgents.selectedAgentId)\r\n : undefined;\r\n const selectedManagedAgentLiveText = managedAgents.selectedAgentId\r\n ? managedAgents.liveText.get(managedAgents.selectedAgentId)\r\n : undefined;\r\n const activeTranscriptMessages =\r\n managedAgents.surface === 'detail' && !selectedShellId && selectedManagedAgentRecord\r\n ? selectedManagedAgentRecord.transcript\r\n : messages;\r\n const activeTranscriptScope =\r\n activeTranscriptMessages === messages\r\n ? MAIN_TRANSCRIPT_SCOPE\r\n : `managed:${selectedManagedAgentRecord!.id}`;\r\n const activeExpandedToolId = useMemo(\r\n () =>\r\n activeTranscriptMessages === messages\r\n ? expandedToolId\r\n : selectExpandedToolId(activeTranscriptMessages),\r\n [activeTranscriptMessages, expandedToolId, messages],\r\n );\r\n const toolExpansionOverrides =\r\n toolExpansionOverridesByTranscript.get(activeTranscriptScope) ?? EMPTY_TOOL_EXPANSION_OVERRIDES;\r\n const focusedToolId = focusedToolIdsByTranscript.get(activeTranscriptScope) ?? null;\r\n const showAllToolOutputIds =\r\n showAllToolOutputIdsByTranscript.get(activeTranscriptScope) ?? EMPTY_SHOW_ALL_TOOL_OUTPUT_IDS;\r\n const updateToolExpansionOverrides = useCallback(\r\n (update: (current: Map<string, boolean>) => Map<string, boolean>) => {\r\n setToolExpansionOverridesByTranscript((current) => {\r\n const currentOverrides = current.get(activeTranscriptScope) ?? new Map<string, boolean>();\r\n const nextOverrides = update(currentOverrides);\r\n if (nextOverrides === currentOverrides) return current;\r\n return new Map(current).set(activeTranscriptScope, nextOverrides);\r\n });\r\n },\r\n [activeTranscriptScope],\r\n );\r\n const focusTool = useCallback(\r\n (toolId: string) => {\r\n setFocusedToolIdsByTranscript((current) =>\r\n new Map(current).set(activeTranscriptScope, toolId),\r\n );\r\n },\r\n [activeTranscriptScope],\r\n );\r\n const showAllToolOutput = useCallback(\r\n (toolId: string) => {\r\n setShowAllToolOutputIdsByTranscript((current) => {\r\n const nextIds = new Set(current.get(activeTranscriptScope) ?? []).add(toolId);\r\n return new Map(current).set(activeTranscriptScope, nextIds);\r\n });\r\n },\r\n [activeTranscriptScope],\r\n );\r\n // The live turn renders as a streaming AgentMessage; its exact height depends\r\n // on markdown and reasoning collapse, so this is only a change signal.\r\n const selectedManagedAgentLiveRows = selectedManagedAgentLiveText\r\n ? wordWrap(selectedManagedAgentLiveText, Math.max(1, termWidth - 2)).split('\\n').length\r\n : 0;\r\n const transcriptLayoutRevision = useMemo(\r\n () =>\r\n JSON.stringify([\r\n error ?? '',\r\n streamingMessageId ?? '',\r\n transcriptMode,\r\n activeExpandedToolId ?? '',\r\n [...toolExpansionOverrides.entries()].sort(([left], [right]) =>\r\n left < right ? -1 : left > right ? 1 : 0,\r\n ),\r\n showAllDetailedOutput,\r\n [...showAllToolOutputIds].sort(),\r\n liveConfig.settings.ui.showThinking,\r\n pendingPermission?.toolCall.id ?? '',\r\n managedAgents.surface,\r\n managedAgents.selectedAgentId ?? '',\r\n selectedManagedAgentRecord?.status ?? '',\r\n selectedManagedAgentRecord?.referencedEvidenceIds.length ?? 0,\r\n selectedManagedAgentLiveRows,\r\n showAgentPlan\r\n ? agentTodos.map((todo) => [todo.status, todo.content, todo.activeForm ?? ''])\r\n : [],\r\n showTasks ? tasks.map((task) => [task.id, task.status, task.subject]) : [],\r\n showHelp,\r\n showStatus,\r\n showPermissions,\r\n showSkills,\r\n showShortcuts,\r\n pendingPlanApproval?.plan ?? '',\r\n ]),\r\n [\r\n error,\r\n streamingMessageId,\r\n transcriptMode,\r\n activeExpandedToolId,\r\n toolExpansionOverrides,\r\n showAllDetailedOutput,\r\n showAllToolOutputIds,\r\n liveConfig.settings.ui.showThinking,\r\n pendingPermission,\r\n managedAgents.surface,\r\n managedAgents.selectedAgentId,\r\n selectedManagedAgentRecord,\r\n selectedManagedAgentLiveRows,\r\n showAgentPlan,\r\n agentTodos,\r\n showTasks,\r\n tasks,\r\n showHelp,\r\n showStatus,\r\n showPermissions,\r\n showSkills,\r\n showShortcuts,\r\n pendingPlanApproval,\r\n ],\r\n );\r\n\r\n useEffect(() => {\r\n setTranscriptMode('compact');\r\n setShowAllDetailedOutput(false);\r\n setShowAllToolOutputIdsByTranscript(new Map());\r\n setToolExpansionOverridesByTranscript(new Map());\r\n setFocusedToolIdsByTranscript(new Map());\r\n }, [sessionId]);\r\n\r\n useEffect(\r\n () => () => {\r\n if (copyNoticeTimerRef.current) clearTimeout(copyNoticeTimerRef.current);\r\n },\r\n [],\r\n );\r\n\r\n const toggleToolExpansion = useCallback(\r\n (toolId: string, expanded: boolean) => {\r\n focusTool(toolId);\r\n updateToolExpansionOverrides((current) => new Map(current).set(toolId, !expanded));\r\n },\r\n [focusTool, updateToolExpansionOverrides],\r\n );\r\n\r\n const applyThemePreference = useCallback(\r\n (preference: string): ApplyThemeResult => {\r\n const resolved = resolveTheme(config.workspace, preference);\r\n if (!resolved) {\r\n return {\r\n ok: false,\r\n error: `Theme \"${preference}\" was not found. Choose apple, dark, light, auto, catppuccin, nord, gruvbox, solarized-dark, or a theme from .book/themes.`,\r\n };\r\n }\r\n const persisted = persistSettingLocal(config.workspace, 'theme', resolved.preference);\r\n if (!persisted.ok) {\r\n return {\r\n ok: false,\r\n error: `Could not save theme: ${persisted.error ?? 'unknown settings error'}`,\r\n };\r\n }\r\n setCurrentTheme(resolved);\r\n return { ok: true, theme: resolved };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const handleSubmit = useCallback(\r\n async (value: string, attachments: ImageAttachment[] = []) => {\r\n if (attachments.length > 0 && liveConfig.modelInfo?.vision === false) {\r\n addLocalMessage(`${liveConfig.model} does not support image input.`);\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value,\r\n attachments,\r\n }));\r\n return;\r\n }\r\n setFollowRequestKey((key) => key + 1);\r\n const selectedChild = managedAgents.selectedAgentId\r\n ? managedAgents.records.get(managedAgents.selectedAgentId)\r\n : undefined;\r\n if (\r\n managedAgents.surface === 'detail' &&\r\n !value.startsWith('/') &&\r\n selectedChild &&\r\n attachments.length === 0\r\n ) {\r\n await managedAgents.send(value);\r\n return;\r\n }\r\n if (managedAgents.surface === 'detail' && attachments.length > 0) {\r\n addLocalMessage('Image attachments are sent to the main conversation.');\r\n returnToMain();\r\n }\r\n if (\r\n managedAgents.surface === 'detail' &&\r\n !value.startsWith('/') &&\r\n (!selectedChild || selectedShellId)\r\n ) {\r\n returnToMain();\r\n }\r\n if (managedAgents.surface === 'detail' && value.startsWith('/')) {\r\n addLocalMessage('Session commands apply to the main conversation while viewing a child.');\r\n }\r\n // Coarse slash-command dispatch trace (one event per submit).\r\n const parsedSlash = parseSlashInput(value);\r\n if (parsedSlash && attachments.length > 0) {\r\n addLocalMessage('✕ Image attachments cannot be combined with slash commands.');\r\n return;\r\n }\r\n if (parsedSlash?.name === 'queue') {\r\n const operation = parsedSlash.rawArguments.trim().toLowerCase();\r\n if (operation === 'clear') {\r\n replaceQueuedInputs([]);\r\n replaceEditingQueuedInput(undefined);\r\n queueDrainPausedRef.current = false;\r\n setQueueNotice('Queued follow-up inputs cleared.');\r\n } else {\r\n const count = queuedInputsRef.current.length;\r\n setQueueNotice(\r\n count === 0\r\n ? 'The follow-up queue is empty.'\r\n : `${count} follow-up input${count === 1 ? '' : 's'} queued. Up edits the newest.`,\r\n );\r\n }\r\n return;\r\n }\r\n if (parsedSlash) {\r\n uiLog.event('slash:dispatch', {\r\n command: parsedSlash.name,\r\n hasArg: parsedSlash.rawArguments.length > 0,\r\n disabled: isThinking,\r\n });\r\n } else {\r\n uiLog.event('submit:text', { len: value.length, disabled: isThinking });\r\n }\r\n // Built-ins resolve through the shared exact-name registry before custom commands.\r\n const commandName = parsedSlash?.name ?? '';\r\n const commandArg = parsedSlash?.rawArguments ?? '';\r\n if (parsedSlash) {\r\n const commandContext: BuiltinCommandContext = {\r\n workspace: config.workspace,\r\n sessionId,\r\n model: liveConfig.model,\r\n provider: liveConfig.provider,\r\n currentTurn,\r\n messages,\r\n lastError: error,\r\n effortUnavailableError: getEffortUnavailableError(liveConfig),\r\n runtimeConfig: liveConfig,\r\n mode,\r\n usage,\r\n turnDurationMs,\r\n contextHistory,\r\n compactBoundaries,\r\n commandCount: commands.length,\r\n skillCount: skills.length,\r\n skillSnapshot: runtime?.inspectSkills(currentTurn),\r\n mcpSnapshot,\r\n toolCallStats: runtime?.toolCallStats,\r\n resolveAmbientContext: () => ({\r\n subagentCount: discoverAgents(config.workspace).length,\r\n hasMemoryIndex: Boolean(\r\n liveConfig.memoryContext?.indexLoaded ?? getMemoryIndex(config.workspace).indexFile,\r\n ),\r\n hasClaudeMdLoader: discoverClaudeMd(config.workspace).length > 0,\r\n }),\r\n };\r\n let effect: BuiltinCommandEffect | undefined;\r\n try {\r\n effect = builtinCommandRegistry.execute(\r\n parsedSlash.name,\r\n parsedSlash.rawArguments,\r\n commandContext,\r\n );\r\n } catch (commandError) {\r\n addLocalMessage(\r\n `✕ ${commandError instanceof Error ? commandError.message : String(commandError)}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'send-prompt') {\r\n void dispatchAgentSend(effect.prompt, effect.context);\r\n return;\r\n }\r\n if (effect?.type === 'local-message') {\r\n if (effect.display) addLocalMessage(effect.content, effect.display);\r\n else addLocalMessage(effect.content);\r\n if (effect.refreshMemory) refreshMemoryContext();\r\n return;\r\n }\r\n if (effect?.type === 'start-new-conversation') {\r\n clearTasks();\r\n setReferencePanel(null);\r\n setShowSessionPicker(false);\r\n setShowRewindPicker(false);\r\n void startNewConversation(effect.previousName).catch((err) => {\r\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\r\n });\r\n stdout?.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n return;\r\n }\r\n if (effect?.type === 'resume-conversation') {\r\n if (!effect.session) {\r\n setShowSessionPicker(true);\r\n } else {\r\n clearTasks();\r\n void resumeConversation(effect.session).catch((err) => {\r\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\r\n });\r\n }\r\n return;\r\n }\r\n if (effect?.type === 'compact') {\r\n void compact(effect.focus);\r\n return;\r\n }\r\n if (effect?.type === 'exit') {\r\n void endCurrentSession('exit').finally(exitApp);\r\n return;\r\n }\r\n if (effect?.type === 'show-modal') {\r\n // Opened by its own command, so Esc belongs to the composer rather\r\n // than to a `/config` menu the user may have visited earlier.\r\n forgetConfigOrigin();\r\n if (effect.modal === 'config') {\r\n setConfigInitialRow(0);\r\n setShowConfigPicker(true);\r\n } else if (effect.modal === 'model') {\r\n setSelectingCompactModel(false);\r\n setShowModelPicker(true);\r\n } else if (effect.modal === 'rewind') setShowRewindPicker(true);\r\n else if (effect.modal === 'skills') setShowSkills(true);\r\n else if (effect.modal === 'theme') {\r\n setCustomThemes(listCustomThemes(config.workspace));\r\n setShowThemePicker(true);\r\n } else setShowEffortPicker(true);\r\n return;\r\n }\r\n if (effect?.type === 'set-theme') {\r\n const result = applyThemePreference(effect.preference);\r\n addLocalMessage(result.ok ? themeAppliedMessage(result.theme) : `✕ ${result.error}`);\r\n return;\r\n }\r\n if (effect?.type === 'set-model') {\r\n const result = setModel(effect.selection);\r\n addLocalMessage(\r\n result.ok ? `Switched to ${effect.selection} (saved as default).` : `✕ ${result.error}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-effort') {\r\n const result = setEffort(effect.level);\r\n addLocalMessage(\r\n result.ok\r\n ? `Set effort level to ${effect.level} (saved as default).`\r\n : `✕ ${result.error}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-compact-model') {\r\n const result = setCompactModel(effect.model);\r\n addLocalMessage(\r\n result.ok\r\n ? `Set compact model to ${effect.model} (saved as default).`\r\n : `✕ ${result.error}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-default-permission-mode') {\r\n const result = setDefaultPermissionMode(effect.mode);\r\n addLocalMessage(\r\n result.ok\r\n ? `Default permission mode is now ${effect.mode} (saved as default).`\r\n : `✕ ${result.error}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-show-thinking') {\r\n const result = toggleShowThinking(effect.enabled);\r\n addLocalMessage(\r\n result.ok\r\n ? `Show thinking is now ${effect.enabled ? 'on' : 'off'} (saved as default).`\r\n : `✕ ${result.error ?? 'Could not save thinking setting.'}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-startup-animation') {\r\n const result = toggleStartupAnimation(effect.enabled);\r\n addLocalMessage(\r\n result.ok\r\n ? `Startup fire is now ${effect.enabled ? 'on' : 'off'} (saved as default).`\r\n : `✕ ${result.error ?? 'Could not save the startup animation setting.'}`,\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'set-memory-auto-save') {\r\n setMemoryAutoSave(effect.enabled);\r\n addLocalMessage(\r\n effect.enabled\r\n ? 'Memory auto-capture enabled. New candidates will still require approval.'\r\n : 'Memory auto-capture disabled. Existing approved memory can still load.',\r\n );\r\n return;\r\n }\r\n if (effect?.type === 'toggle-panel') {\r\n const panel = effect.panel;\r\n setReferencePanel((current) => (current === panel ? null : panel));\r\n return;\r\n }\r\n if (effect?.type === 'add-task') {\r\n addTask({ subject: effect.subject, status: 'pending' });\r\n return;\r\n }\r\n if (effect?.type === 'show-diff') {\r\n void runGit(['diff'], {\r\n workspaceRoot: config.workspace,\r\n env: process.env as Record<string, string>,\r\n }).then((result) => {\r\n addLocalMessage(\r\n result.error ? `✕ ${result.error}` : result.output.trim() || '(no changes)',\r\n );\r\n });\r\n return;\r\n }\r\n if (effect?.type === 'reload-assets') {\r\n setCommands(discoverCommands(config.workspace));\r\n const refreshedSkills = runtime?.reloadSkills(\r\n config.workspace,\r\n liveConfig.settings.skills,\r\n 'command',\r\n );\r\n setSkills(\r\n refreshedSkills?.list() ??\r\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\r\n executionOverrides: liveConfig.settings.skills.execution,\r\n enabled: liveConfig.settings.skills.enabled,\r\n }),\r\n );\r\n setSkillWatcherError(runtime?.skillWatcherError);\r\n setCustomThemes(listCustomThemes(config.workspace));\r\n setAgentProfiles(withBuiltInAgents(discoverAgents(config.workspace)));\r\n addLocalMessage('Commands and skills have been reloaded.');\r\n return;\r\n }\r\n if (effect?.type === 'review') {\r\n startReview(effect.scope);\r\n return;\r\n }\r\n if (effect?.type === 'managed-agent') {\r\n const manager = managedAgentManager;\r\n const reportError = (managedError: unknown) =>\r\n addLocalMessage(\r\n `✕ ${managedError instanceof Error ? managedError.message : String(managedError)}`,\r\n );\r\n if (effect.operation === 'list') {\r\n managedAgents.setSurface('tasks');\r\n void managedAgents.refresh().catch(reportError);\r\n backgroundShells.refresh();\r\n } else if (effect.operation === 'import') {\r\n try {\r\n const previews = previewAgentImport(effect.importPath!);\r\n if (previews.length === 0) throw new Error('No Markdown agent definitions found.');\r\n const report = previews\r\n .map((preview) =>\r\n [\r\n `${preview.name}: ${preview.description}`,\r\n `tools: ${preview.tools.join(', ') || '(none)'}`,\r\n `model: ${preview.model ?? 'inherit'}`,\r\n ...preview.warnings.map((warning) => `warning: ${warning}`),\r\n ].join('\\n'),\r\n )\r\n .join('\\n\\n');\r\n if (!effect.confirmed) {\r\n addLocalMessage(\r\n `${report}\\n\\nRun /agents import --confirm ${effect.importPath} to install.`,\r\n );\r\n } else {\r\n const installed = installAgentImports(\r\n previews,\r\n join(config.workspace, '.book', 'agents'),\r\n );\r\n addLocalMessage(`${report}\\n\\nInstalled:\\n${installed.join('\\n')}`);\r\n setAgentProfiles(withBuiltInAgents(discoverAgents(config.workspace)));\r\n void managedAgents.refresh();\r\n }\r\n } catch (importError) {\r\n reportError(importError);\r\n }\r\n } else if (effect.operation === 'send') {\r\n void manager\r\n .send(effect.agentId!, effect.message ?? '')\r\n .then((record) => {\r\n managedAgents.selectAgent(record.id);\r\n managedAgents.setSurface('detail');\r\n })\r\n .catch(reportError);\r\n } else if (effect.operation === 'stop') {\r\n void manager\r\n .stop(effect.agentId!)\r\n .then((record) => addLocalMessage(`Stopped ${record.displayName ?? record.name}.`))\r\n .catch(reportError);\r\n } else if (effect.operation === 'apply') {\r\n void manager\r\n .apply(effect.agentId!, effect.evidenceId)\r\n .then((result) =>\r\n addLocalMessage(\r\n result.status === 'applied'\r\n ? `Applied validated candidate${result.commit ? ` (${result.commit})` : ''}.`\r\n : `Application ${result.status}${result.error ? `: ${result.error}` : '.'}`,\r\n ),\r\n )\r\n .catch(reportError);\r\n } else {\r\n void manager\r\n .get(effect.agentId!)\r\n .then((record) => {\r\n if (!record) throw new Error(`Agent ${effect.agentId} was not found.`);\r\n managedAgents.selectAgent(record.id);\r\n managedAgents.setSurface('detail');\r\n })\r\n .catch(reportError);\r\n }\r\n return;\r\n }\r\n }\r\n if (value.startsWith('/')) {\r\n // Custom slash command: /name [args]\r\n const cmd = commands.find((c) => c.name === commandName);\r\n if (cmd) {\r\n const controller = new AbortController();\r\n commandResolutionRef.current?.abort();\r\n commandResolutionRef.current = controller;\r\n setIsResolvingCommand(true);\r\n let resolved: string;\r\n try {\r\n ({ resolved } = await resolveCommandBody(\r\n cmd,\r\n commandArg,\r\n {\r\n sessionId,\r\n workspace: config.workspace,\r\n model: liveConfig.model,\r\n projectCommands: liveConfig.settings.commands.projectCommands,\r\n },\r\n controller.signal,\r\n ));\r\n } catch (resolveError) {\r\n if (!controller.signal.aborted) {\r\n addLocalMessage(\r\n `✕ ${resolveError instanceof Error ? resolveError.message : String(resolveError)}`,\r\n );\r\n }\r\n return;\r\n } finally {\r\n if (commandResolutionRef.current === controller) {\r\n commandResolutionRef.current = null;\r\n setIsResolvingCommand(false);\r\n }\r\n }\r\n // Escape/Ctrl+C may abort after resolution succeeds; never dispatch stale input.\r\n if (controller.signal.aborted) return;\r\n // Pass command context for allowed-tools and model enforcement.\r\n // Shared with print/headless so both hosts enforce it identically.\r\n void dispatchAgentSend(resolved, commandEnforcementContext(cmd, resolved));\r\n } else {\r\n // Unknown command — send as-is (the model might handle it).\r\n void dispatchAgentSend(value);\r\n }\r\n } else {\r\n replaceEditingQueuedInput(undefined);\r\n void dispatchAgentSend(value, undefined, attachments);\r\n }\r\n },\r\n [\r\n dispatchAgentSend,\r\n commandResolutionRef,\r\n clear,\r\n startNewConversation,\r\n resumeConversation,\r\n clearTasks,\r\n compact,\r\n addTask,\r\n commands,\r\n exitApp,\r\n endCurrentSession,\r\n usage,\r\n liveConfig,\r\n addLocalMessage,\r\n setModel,\r\n setEffort,\r\n messages,\r\n currentTurn,\r\n turnDurationMs,\r\n error,\r\n skills,\r\n mcpSnapshot,\r\n sessionId,\r\n stdout,\r\n isThinking,\r\n redrawViewport,\r\n applyThemePreference,\r\n builtinCommandRegistry,\r\n managedAgentManager,\r\n managedAgents,\r\n replaceEditingQueuedInput,\r\n replaceQueuedInputs,\r\n ],\r\n );\r\n\r\n const canSubmitWhileParentBusy = useCallback((value: string) => {\r\n const name = parseSlashInput(value)?.name;\r\n return name === 'tasks' || name === 'jobs' || name === 'queue';\r\n }, []);\r\n const canQueueWhileParentBusy = useCallback(\r\n (value: string) => !value.trimStart().startsWith('/'),\r\n [],\r\n );\r\n\r\n const handleGlobalShortcut = useCallback(\r\n (\r\n input: string,\r\n key: {\r\n ctrl?: boolean;\r\n meta?: boolean;\r\n shift?: boolean;\r\n tab?: boolean;\r\n home?: boolean;\r\n end?: boolean;\r\n },\r\n ): boolean => {\r\n // Ctrl+/ and Ctrl+E must be handled here (not only in the parent useInput)\r\n // because ink-text-input consumes some Ctrl key events before they reach\r\n // the parent handler.\r\n if (\r\n showModelPicker ||\r\n showEffortPicker ||\r\n showPermissionModePicker ||\r\n showThemePicker ||\r\n showRewindPicker ||\r\n showConfigPicker ||\r\n showAgentProfilePicker ||\r\n showSkills\r\n )\r\n return true;\r\n if (key.ctrl && input === 'c') {\r\n if (pendingUserQuestion || pendingElicitation) {\r\n uiLog.event('input:Ctrl+C', { action: 'cancel-question-turn' });\r\n interrupt();\r\n return true;\r\n }\r\n if (pendingPermission || pendingPlanApproval) {\r\n uiLog.event('input:Ctrl+C', { action: 'noop-approval-active' });\r\n return true;\r\n }\r\n if (isThinking || sendInFlight || isResolvingCommand) {\r\n uiLog.event('input:Ctrl+C', { action: 'cancel-stream' });\r\n interrupt();\r\n return true;\r\n }\r\n uiLog.event('input:Ctrl+C', { action: 'exit' });\r\n void endCurrentSession('exit').finally(exitApp);\r\n return true;\r\n }\r\n if (key.ctrl && input === 'l') {\r\n uiLog.event('input:Ctrl+L', { action: 'redraw' });\r\n redrawViewport?.();\r\n return true;\r\n }\r\n if (\r\n key.ctrl &&\r\n (input.toLowerCase() === 'u' || input.toLowerCase() === 'd' || key.home || key.end)\r\n ) {\r\n return true;\r\n }\r\n if (isShortcutsToggleKey(input, key)) {\r\n uiLog.event('input:Ctrl+/', { action: 'toggle-shortcuts' });\r\n setReferencePanel((current) => (current === 'shortcuts' ? null : 'shortcuts'));\r\n return true; // consumed\r\n }\r\n const transcriptAction = getTranscriptShortcutAction(transcriptMode, input, key);\r\n if (transcriptAction === 'enter-detailed') {\r\n uiLog.event('input:Ctrl+O', { action: 'enter-detailed-transcript' });\r\n setTranscriptMode('detailed');\r\n setShowAllDetailedOutput(false);\r\n return true;\r\n }\r\n if (transcriptAction === 'expand-output') {\r\n const targetToolId =\r\n activeExpandedToolId ?? focusedToolId ?? selectLatestToolId(activeTranscriptMessages);\r\n uiLog.event('input:Ctrl+E', { action: 'expand-current-tool', toolId: targetToolId });\r\n if (targetToolId) {\r\n updateToolExpansionOverrides((current) => new Map(current).set(targetToolId, true));\r\n showAllToolOutput(targetToolId);\r\n }\r\n return true; // consumed\r\n }\r\n return false; // not consumed — let text input handle it\r\n },\r\n [\r\n interrupt,\r\n endCurrentSession,\r\n exitApp,\r\n isThinking,\r\n sendInFlight,\r\n isResolvingCommand,\r\n pendingPermission,\r\n pendingPlanApproval,\r\n pendingUserQuestion,\r\n pendingElicitation,\r\n redrawViewport,\r\n showEffortPicker,\r\n showPermissionModePicker,\r\n showModelPicker,\r\n showThemePicker,\r\n showRewindPicker,\r\n showConfigPicker,\r\n showAgentProfilePicker,\r\n showSkills,\r\n activeExpandedToolId,\r\n activeTranscriptMessages,\r\n focusedToolId,\r\n showAllToolOutput,\r\n updateToolExpansionOverrides,\r\n ],\r\n );\r\n\r\n // Track input changes for command menu filtering — now handled inside InputBar.\r\n // handleGlobalShortcut remains for Ctrl+/ keyboard shortcut reference.\r\n\r\n // Hoisted so the composer and the interactive /permissions sheet agree on who\r\n // holds the keyboard, instead of restating the same fifteen flags twice.\r\n const modalOwnsInput = ownsModalInput(\r\n pendingPermission ?? childPermission ?? childQuestion,\r\n pendingPlanApproval,\r\n showModelPicker,\r\n showSessionPicker,\r\n pendingUserQuestion,\r\n showEffortPicker,\r\n showThemePicker,\r\n showRewindPicker,\r\n showConfigPicker,\r\n showAgentProfilePicker,\r\n showPermissionModePicker,\r\n showSkills,\r\n showMcpApproval,\r\n pendingElicitation,\r\n );\r\n\r\n // The subset of `modalOwnsInput` that is genuinely a question. Everything else\r\n // it covers is a sheet holding the keyboard while it is open, and telling\r\n // someone to answer `/config` describes a prompt that is not there.\r\n const awaitingAnswer =\r\n Boolean(\r\n pendingPermission ??\r\n childPermission ??\r\n childQuestion ??\r\n pendingPlanApproval ??\r\n pendingUserQuestion ??\r\n pendingElicitation,\r\n ) || showMcpApproval;\r\n\r\n const pickerOwnsTranscript =\r\n showModelPicker ||\r\n showEffortPicker ||\r\n showPermissionModePicker ||\r\n showThemePicker ||\r\n showSessionPicker ||\r\n showRewindPicker ||\r\n showConfigPicker ||\r\n showAgentProfilePicker ||\r\n showSkills;\r\n\r\n // A render crash replaces the whole UI, so the error box is the only thing\r\n // left to say whether the conversation survived. It did — the session file is\r\n // appended synchronously — but only when there is a store to have written it,\r\n // and only worth reopening once it holds more than its own header. A crash\r\n // during startup would otherwise promise a conversation and hand back an\r\n // empty one.\r\n const resumeCommand =\r\n session.store && messages.length > 0 ? `book --resume ${sessionId}` : undefined;\r\n // The boundary cannot lean on the global handler below: that handler is still\r\n // mounted with whatever state it held when the render blew up, so it swallows\r\n // Ctrl+C behind `ownsModalInput` if a picker was open and spends it on\r\n // `interrupt()` if a turn was streaming. It gets the same exit path either\r\n // way, so the session still ends cleanly.\r\n const exitFromCrash = () => {\r\n void endCurrentSession('exit').finally(exitApp);\r\n };\r\n\r\n if (startupFireActive) {\r\n return (\r\n <AppProviders theme={currentTheme.tokens} density={density}>\r\n <ErrorBoundary resumeCommand={resumeCommand} onExit={exitFromCrash}>\r\n <StartupFire\r\n width={termWidth}\r\n height={Math.max(1, termHeight - 1)}\r\n onComplete={() => setStartupFireActive(false)}\r\n />\r\n </ErrorBoundary>\r\n </AppProviders>\r\n );\r\n }\r\n\r\n const contextWindow = resolveContextWindow(liveConfig);\r\n\r\n return (\r\n <AppProviders theme={currentTheme.tokens} density={density}>\r\n <ErrorBoundary resumeCommand={resumeCommand} onExit={exitFromCrash}>\r\n <Box\r\n flexDirection=\"column\"\r\n width={termWidth}\r\n height={Math.max(1, termHeight - 1)}\r\n overflow=\"hidden\"\r\n >\r\n <TranscriptView\r\n key={sessionId}\r\n width={termWidth}\r\n isActive={!pickerOwnsTranscript && managedAgents.surface !== 'tasks'}\r\n followRequestKey={followRequestKey}\r\n layoutRevision={transcriptLayoutRevision}\r\n onToggleTool={toggleToolExpansion}\r\n onNotify={handleCopiedNotice}\r\n onRedrawViewport={redrawViewport}\r\n >\r\n <Box flexDirection=\"column\" width={termWidth}>\r\n {error && (\r\n <Box paddingX={1} marginBottom={1}>\r\n <Text color={theme.error}>✕ {error}</Text>\r\n </Box>\r\n )}\r\n {managedAgents.surface === 'detail' && selectedShellId ? (\r\n backgroundShells.shells.find((shell) => shell.id === selectedShellId) ? (\r\n <BackgroundShellDetail\r\n shell={backgroundShells.shells.find((shell) => shell.id === selectedShellId)!}\r\n readTail={readSelectedShellTail}\r\n width={termWidth}\r\n />\r\n ) : (\r\n <Box paddingX={1}>\r\n <Text color={theme.subtle}>Loading background shell…</Text>\r\n </Box>\r\n )\r\n ) : managedAgents.surface === 'detail' && managedAgents.selectedAgentId ? (\r\n // Viewing a child: never fall back to the main conversation.\r\n // The record can briefly lag its summary (a status event lists\r\n // an agent before its record is stored), so show a loading\r\n // placeholder until it arrives rather than the parent transcript.\r\n managedAgents.records.get(managedAgents.selectedAgentId) ? (\r\n <SubagentDetail\r\n record={managedAgents.records.get(managedAgents.selectedAgentId)!}\r\n liveText={managedAgents.liveText.get(managedAgents.selectedAgentId)}\r\n width={termWidth}\r\n height={termHeight}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={activeExpandedToolId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n showAllToolOutput={showAllDetailedOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n showThinking={liveConfig.settings.ui.showThinking}\r\n />\r\n ) : (\r\n <Box paddingX={1}>\r\n <Text color={theme.subtle}>Loading subagent…</Text>\r\n </Box>\r\n )\r\n ) : (\r\n <ChatPanel\r\n messages={messages}\r\n managedAgentTraces={managedAgentTraces}\r\n compactBoundaries={compactBoundaries}\r\n streamingMessageId={streamingMessageId}\r\n pendingPermission={pendingPermission}\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={expandedToolId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n terminalWidth={termWidth}\r\n showThinking={liveConfig.settings.ui.showThinking}\r\n terminalHeight={termHeight}\r\n workspace={config.workspace}\r\n model={liveConfig.modelSelection ?? liveConfig.model}\r\n mode={mode}\r\n commandCount={commands.length}\r\n skillCount={skills.length}\r\n retryPhase={retryPhase}\r\n showAllToolOutput={showAllDetailedOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n retryAttempt={retryAttempt}\r\n retryMax={retryMax}\r\n retryCountdownMs={retryCountdownMs}\r\n />\r\n )}\r\n {showAgentPlan && <AgentTodoList todos={agentTodos} terminalWidth={termWidth} />}\r\n {showTasks && (\r\n <TaskList tasks={tasks} onUpdateStatus={updateTaskStatus} onRemove={removeTask} />\r\n )}\r\n {showHelp && (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n width={panelGrid(termWidth).width}\r\n >\r\n <PanelHeading title=\"Slash Commands\" theme={theme} />\r\n <Box flexDirection=\"column\">\r\n <HelpRow label=\"/help\" description=\"Toggle this help\" theme={theme} />\r\n <HelpRow label=\"/exit\" description=\"Exit book\" theme={theme} />\r\n <HelpRow\r\n label=\"/clear [name]\"\r\n description=\"Start new; save previous (/new, /reset)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/resume [id|name]\"\r\n description=\"Resume a saved conversation\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/compact [focus]\"\r\n description=\"Summarize conversation (optional focus)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/rewind\"\r\n description=\"Restore conversation, code, or both\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"/task <subject>\" description=\"Add a task\" theme={theme} />\r\n <HelpRow\r\n label=\"/tasks\"\r\n description=\"Manage background subagents\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/agents\"\r\n description=\"Show subagent configuration guidance\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/theme [apple|dark|light|auto|name]\"\r\n description=\"Choose and save a color theme\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/model [name]\"\r\n description=\"Switch models and manage BYOK providers\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/providers\"\r\n description=\"Add providers; Alt+D removes selected local BYOK\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/effort [low|medium|high|xhigh|max]\"\r\n description=\"Set thinking effort\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"/config\" description=\"Show configuration\" theme={theme} />\r\n <HelpRow label=\"/diff\" description=\"Show git diff\" theme={theme} />\r\n <HelpRow label=\"/status\" description=\"Session status\" theme={theme} />\r\n <HelpRow label=\"/memory\" description=\"Manage memory\" theme={theme} />\r\n <HelpRow label=\"/permissions\" description=\"Permission rules\" theme={theme} />\r\n <HelpRow label=\"/cost\" description=\"Token usage/cost\" theme={theme} />\r\n <HelpRow label=\"/skills\" description=\"Manage skills\" theme={theme} />\r\n <HelpRow label=\"/init\" description=\"Initialize CLAUDE.md\" theme={theme} />\r\n <HelpRow\r\n label=\"/reload-skills\"\r\n description=\"Reload commands and skills\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/export [file]\"\r\n description=\"Export conversation\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/usage\"\r\n description=\"Session cost & tokens (/stats)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/context\"\r\n description=\"What fills the context window\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/review [scope]\"\r\n description=\"Review current git diff\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/security-review [scope]\"\r\n description=\"Security audit of the diff\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/release-notes\"\r\n description=\"Version + changelog\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/feedback [note]\"\r\n description=\"Save a bug-report snapshot\"\r\n theme={theme}\r\n />\r\n {commands.length > 0 && (\r\n <>\r\n <Text color={theme.subtle} dimColor>\r\n ─── Custom (.book/commands/) ───\r\n </Text>\r\n {commands.map((cmd) => (\r\n <HelpRow\r\n key={cmd.name}\r\n label={`/${cmd.name}${cmd.argumentHint ? ` ${cmd.argumentHint}` : ''}`}\r\n description={cmd.description}\r\n theme={theme}\r\n />\r\n ))}\r\n </>\r\n )}\r\n </Box>\r\n </Box>\r\n )}\r\n {showStatus && (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n width={panelGrid(termWidth).width}\r\n >\r\n <PanelHeading title=\"Session Status\" theme={theme} />\r\n <Box flexDirection=\"column\">\r\n <HelpRow\r\n label=\"Model\"\r\n description={liveConfig.modelSelection ?? liveConfig.model}\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Auth\"\r\n description={liveConfig.apiKey ? 'API key' : 'none'}\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Session\"\r\n description={displaySessionName(sessionName)}\r\n theme={theme}\r\n />\r\n <HelpRow label=\"Workspace\" description={config.workspace} theme={theme} />\r\n <HelpRow\r\n label=\"Max Tokens\"\r\n description={String(config.maxTokens)}\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Max Turns\"\r\n description={\r\n config.maxTurns == null || config.maxTurns <= 0\r\n ? 'unlimited'\r\n : String(config.maxTurns)\r\n }\r\n theme={theme}\r\n />\r\n <HelpRow label=\"Mode\" description={mode} theme={theme} />\r\n <HelpRow label=\"Tokens Used\" description={`${tokenCount}`} theme={theme} />\r\n <HelpRow label=\"Turn\" description={`${currentTurn}`} theme={theme} />\r\n <HelpRow\r\n label=\"Tasks\"\r\n description={`${tasks.length} (${tasks.filter((t) => t.status === 'in_progress').length} active)`}\r\n theme={theme}\r\n />\r\n </Box>\r\n </Box>\r\n )}\r\n {showPermissions && (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n width={panelGrid(termWidth).width}\r\n >\r\n <PanelHeading title=\"Permission Mode\" theme={theme} />\r\n <PermissionsPanel\r\n mode={mode}\r\n permissions={liveConfig.settings.permissions}\r\n onRemove={removePermissionRule}\r\n active={!modalOwnsInput}\r\n terminalWidth={termWidth}\r\n screenReader={screenReader}\r\n />\r\n </Box>\r\n )}\r\n {pendingPlanApproval ? (\r\n <PlanApprovalDetails\r\n plan={pendingPlanApproval.plan}\r\n screenReader={screenReader}\r\n terminalWidth={termWidth}\r\n />\r\n ) : null}\r\n {showShortcuts && (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n width={panelGrid(termWidth).width}\r\n >\r\n <PanelHeading title=\"Keyboard Shortcuts\" theme={theme} />\r\n <Box flexDirection=\"column\">\r\n <HelpRow\r\n label=\"Esc\"\r\n description=\"Deny a prompt, cancel the turn, or close this panel\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"Ctrl+C\" description=\"Cancel current turn\" theme={theme} />\r\n <HelpRow\r\n label=\"Ctrl+T\"\r\n description=\"Toggle the main agent checklist (not background tasks)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"/tasks\"\r\n description=\"Focus background tasks; ↑↓ select, Enter open, x stop\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+O\"\r\n description=\"Toggle detailed transcript\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+E\"\r\n description=\"Expand current tool output (empty prompt)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Click\"\r\n description=\"Expand or collapse a tool summary\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"Ctrl+L\" description=\"Redraw screen\" theme={theme} />\r\n <HelpRow label=\"Alt+M\" description=\"Cycle permission mode\" theme={theme} />\r\n <HelpRow label=\"Alt+P\" description=\"Open model picker\" theme={theme} />\r\n <HelpRow label=\"Alt+V\" description=\"Attach clipboard image\" theme={theme} />\r\n <HelpRow label=\"Up/Down\" description=\"Navigate input history\" theme={theme} />\r\n <HelpRow label=\"Wheel\" description=\"Scroll transcript\" theme={theme} />\r\n <HelpRow\r\n label=\"Drag\"\r\n description=\"Select visible text and copy on release\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Shift+drag\"\r\n description=\"Use terminal-native text selection\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"PgUp/PgDn\" description=\"Scroll transcript\" theme={theme} />\r\n <HelpRow\r\n label=\"Ctrl+U/Ctrl+D\"\r\n description=\"Scroll transcript half a page (empty prompt)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+Home/End\"\r\n description=\"Jump to transcript start/latest\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+J / Shift+Enter\"\r\n description=\"Insert newline (multiline)\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+A / Ctrl+E\"\r\n description=\"Move to start / end of the prompt\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+W / Alt+Bksp\"\r\n description=\"Delete the previous word\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+U / Ctrl+K\"\r\n description=\"Delete to start / end of the prompt\"\r\n theme={theme}\r\n />\r\n <HelpRow\r\n label=\"Ctrl+Y\"\r\n description=\"Put back the last deletion\"\r\n theme={theme}\r\n />\r\n <HelpRow label=\"Ctrl+/\" description=\"Toggle this reference\" theme={theme} />\r\n <HelpRow label=\"@path\" description=\"Expand file contents\" theme={theme} />\r\n <HelpRow label=\"!cmd\" description=\"Run shell command\" theme={theme} />\r\n </Box>\r\n </Box>\r\n )}\r\n </Box>\r\n </TranscriptView>\r\n\r\n <Box flexDirection=\"column\" flexShrink={0} width={termWidth}>\r\n {pendingPermission ? (\r\n <PermissionButtons\r\n key={pendingPermission.toolCall.id}\r\n toolCall={pendingPermission.toolCall}\r\n onResolve={resolvePermission}\r\n screenReader={screenReader}\r\n terminalWidth={termWidth}\r\n terminalRows={termHeight}\r\n workspaceRoot={config.workspace}\r\n />\r\n ) : childPermission?.type === 'agent_permission' ? (\r\n <Box flexDirection=\"column\">\r\n <Text color={theme.warning}>\r\n ? {childPermission.request.displayName} (\r\n {managedAgents.records.get(childPermission.agentId)?.profile ?? 'agent'}) requests{' '}\r\n {childPermission.request.toolName}\r\n </Text>\r\n <PermissionButtons\r\n key={childPermission.request.id}\r\n toolCall={childPermission.request.toolCall}\r\n onResolve={(decision) =>\r\n void managedAgents.resolvePermission(\r\n childPermission.request.id,\r\n // A managed agent persists rules through its own manager,\r\n // which has no scope ladder, so only the result travels.\r\n permissionResultOf(decision),\r\n )\r\n }\r\n screenReader={screenReader}\r\n terminalWidth={termWidth}\r\n terminalRows={termHeight}\r\n // A worktree-isolated agent mutates its own checkout, so the\r\n // preview must read the file the call will actually touch.\r\n workspaceRoot={\r\n managedAgents.records.get(childPermission.agentId)?.worktree ?? config.workspace\r\n }\r\n />\r\n </Box>\r\n ) : null}\r\n {pendingPlanApproval ? (\r\n <PlanApprovalActions\r\n plan={pendingPlanApproval.plan}\r\n onResolve={resolvePlanApproval}\r\n screenReader={screenReader}\r\n terminalWidth={termWidth}\r\n />\r\n ) : null}\r\n {pendingElicitation ? (\r\n <McpElicitationForm\r\n key={pendingElicitation.request.id}\r\n request={pendingElicitation.request}\r\n queueLength={pendingElicitationCount}\r\n terminalWidth={termWidth}\r\n onResolve={resolveElicitation}\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n {pendingUserQuestion ? (\r\n <AskUserQuestionWizard\r\n key={pendingUserQuestion.request.id}\r\n request={pendingUserQuestion.request}\r\n queueLength={pendingUserQuestionCount}\r\n terminalWidth={termWidth}\r\n onResolve={resolveUserQuestion}\r\n screenReader={screenReader}\r\n />\r\n ) : childQuestion ? (\r\n <AskUserQuestionWizard\r\n key={childQuestion.request.id}\r\n request={childQuestion.request}\r\n queueLength={managedAgents.pendingQuestions.length}\r\n terminalWidth={termWidth}\r\n onResolve={(response) =>\r\n void managedAgents.resolveQuestion(childQuestion.agentId, response)\r\n }\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n {showSessionPicker ? (\r\n <SessionPicker\r\n sessions={listSessions()}\r\n currentSessionId={sessionId}\r\n onPick={(selected) => {\r\n setShowSessionPicker(false);\r\n clearTasks();\r\n void resumeConversation(selected.id).catch((err) => {\r\n addLocalMessage(`✕ ${err instanceof Error ? err.message : String(err)}`);\r\n });\r\n }}\r\n onCancel={() => setShowSessionPicker(false)}\r\n />\r\n ) : null}\r\n {showRewindPicker ? (\r\n <RewindPicker\r\n targets={getRewindTargets()}\r\n isRewinding={isRewinding}\r\n onAction={async (target, action) => {\r\n const result = await rewind(target.id, action);\r\n if (!result.ok) return result;\r\n if (action === 'conversation' || action === 'both') clearTasks();\r\n if (result.restoredPrompt !== undefined) {\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: result.restoredPrompt!,\r\n attachments: result.restoredAttachments,\r\n }));\r\n }\r\n setShowRewindPicker(false);\r\n setFollowRequestKey((key) => key + 1);\r\n return { ok: true };\r\n }}\r\n onCancel={() => setShowRewindPicker(false)}\r\n />\r\n ) : null}\r\n {showSkills ? (\r\n <SkillManager\r\n skills={skills}\r\n enabled={liveConfig.settings.skills.enabled}\r\n watcherError={skillWatcherError}\r\n lifecycleEvents={runtime?.inspectSkills(currentTurn)?.events}\r\n activeSkillNames={runtime\r\n ?.inspectSkills(currentTurn)\r\n ?.active.map((frame) => frame.skillName)}\r\n terminalWidth={termWidth}\r\n maxVisible={Math.max(3, Math.min(10, termHeight - 10))}\r\n onChangeActivation={(skillName, activation) => {\r\n const result = setSkillActivation(skillName, activation);\r\n if (!result.ok) return result;\r\n setSkills((current) =>\r\n current.map((skill) =>\r\n skill.name === skillName ? { ...skill, activation } : skill,\r\n ),\r\n );\r\n return result;\r\n }}\r\n onChangeExecution={(skillName, execution) => {\r\n const result = setSkillExecution(skillName, execution);\r\n if (!result.ok) return result;\r\n setSkills((current) =>\r\n current.map((skill) =>\r\n skill.name === skillName ? { ...skill, execution } : skill,\r\n ),\r\n );\r\n return result;\r\n }}\r\n onChangeEnabled={(enabled) => {\r\n const result = setSkillsEnabled(enabled);\r\n if (result.ok) {\r\n setSkills(\r\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\r\n executionOverrides: liveConfig.settings.skills.execution,\r\n enabled,\r\n }),\r\n );\r\n }\r\n return result;\r\n }}\r\n onUse={(skill: Skill) => {\r\n setDraftRestore((current) => ({\r\n key: (current?.key ?? 0) + 1,\r\n value: `$${skill.name} `,\r\n }));\r\n forgetConfigOrigin();\r\n setShowSkills(false);\r\n }}\r\n onReload={() => {\r\n const refreshed = runtime?.reloadSkills(\r\n config.workspace,\r\n liveConfig.settings.skills,\r\n );\r\n setSkills(\r\n refreshed?.list() ??\r\n discoverSkills(config.workspace, liveConfig.settings.skills.overrides, {\r\n executionOverrides: liveConfig.settings.skills.execution,\r\n enabled: liveConfig.settings.skills.enabled,\r\n }),\r\n );\r\n setSkillWatcherError(runtime?.skillWatcherError);\r\n }}\r\n onCancel={() => {\r\n setShowSkills(false);\r\n returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showConfigPicker ? (\r\n <ConfigMenu\r\n model={liveConfig.modelSelection ?? liveConfig.model}\r\n compactModel={liveConfig.compactModel ?? liveConfig.settings.compactModel}\r\n effort={liveConfig.effort}\r\n themeName={currentTheme.preference}\r\n memoryAutoSave={liveConfig.settings.memory.autoSave}\r\n showThinking={liveConfig.settings.ui.showThinking}\r\n startupAnimation={liveConfig.settings.ui.startupAnimation}\r\n agentCount={agentProfiles.length}\r\n skillCount={skills.length}\r\n defaultPermissionMode={resolvePermissionMode(liveConfig.settings)}\r\n terminalWidth={termWidth}\r\n initialSelection={configInitialRow}\r\n onOpen={(section: ConfigSection, rowIndex: number) => {\r\n if (section === 'effort') {\r\n const unavailable = getEffortUnavailableError(liveConfig);\r\n if (unavailable) {\r\n addLocalMessage(`✕ ${unavailable}`);\r\n return;\r\n }\r\n }\r\n configReturnRow.current = rowIndex;\r\n setShowConfigPicker(false);\r\n if (section === 'model') {\r\n setSelectingCompactModel(false);\r\n setAgentProfileForModel(undefined);\r\n setShowModelPicker(true);\r\n } else if (section === 'compact-model') {\r\n setSelectingCompactModel(true);\r\n setAgentProfileForModel(undefined);\r\n setShowModelPicker(true);\r\n } else if (section === 'effort') {\r\n setShowEffortPicker(true);\r\n } else if (section === 'theme') {\r\n setCustomThemes(listCustomThemes(config.workspace));\r\n setShowThemePicker(true);\r\n } else if (section === 'permission-mode') {\r\n setShowPermissionModePicker(true);\r\n } else if (section === 'skills') {\r\n setShowSkills(true);\r\n } else {\r\n setShowAgentProfilePicker(true);\r\n }\r\n }}\r\n onToggleMemory={() => toggleMemoryAutoSave()}\r\n onToggleThinking={() => {\r\n const result = toggleShowThinking();\r\n if (!result.ok)\r\n addLocalMessage(`✕ ${result.error ?? 'Could not save thinking setting.'}`);\r\n }}\r\n onToggleStartupAnimation={() => {\r\n const result = toggleStartupAnimation();\r\n if (!result.ok) {\r\n addLocalMessage(\r\n `✕ ${result.error ?? 'Could not save startup animation setting.'}`,\r\n );\r\n }\r\n }}\r\n onCancel={() => {\r\n forgetConfigOrigin();\r\n setShowConfigPicker(false);\r\n }}\r\n />\r\n ) : null}\r\n {showAgentProfilePicker ? (\r\n <AgentProfilePicker\r\n profiles={agentProfiles}\r\n parentModel={liveConfig.modelSelection ?? liveConfig.model}\r\n configuredModels={configuredAgentModels}\r\n terminalWidth={termWidth}\r\n onSelect={(profile) => {\r\n setSelectingCompactModel(false);\r\n setAgentProfileForModel(profile);\r\n setShowAgentProfilePicker(false);\r\n setShowModelPicker(true);\r\n }}\r\n onReset={(profile) => {\r\n const result = setAgentProfileModel(profile);\r\n addLocalMessage(\r\n result.ok\r\n ? `${profile} now inherits the parent model.`\r\n : `✕ ${result.error ?? `Could not reset ${profile}.`}`,\r\n );\r\n }}\r\n onCancel={() => {\r\n setShowAgentProfilePicker(false);\r\n returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showModelPicker ? (\r\n <ModelPicker\r\n title={selectingCompactModel ? 'Choose compact model' : undefined}\r\n options={modelOptions}\r\n currentModel={modelPickerSelection}\r\n currentEffort={selectingCompactModel ? undefined : liveConfig.effort}\r\n effortLevels={\r\n selectingCompactModel || agentProfileForModel ? [] : (effortLevels ?? [])\r\n }\r\n hasPriorOutput={\r\n !selectingCompactModel && !agentProfileForModel && messages.length > 0\r\n }\r\n providers={liveConfig.settings.provider}\r\n workspace={config.workspace}\r\n retry={liveConfig.retry}\r\n compact={isNarrow || isTiny}\r\n maxVisibleModels={Math.max(3, Math.min(10, termHeight - 10))}\r\n warnings={[\r\n process.env.BOOK_MODEL\r\n ? `BOOK_MODEL is set to \"${process.env.BOOK_MODEL}\" — it overrides settings.model on next startup.`\r\n : '',\r\n liveConfig.model.startsWith('claude-') &&\r\n config.model &&\r\n !config.model.startsWith('claude-')\r\n ? 'Switching to an Anthropic model may need a separate API key.'\r\n : '',\r\n ].filter(Boolean)}\r\n onPick={(model, saveDefault) => {\r\n if (selectingCompactModel) {\r\n const result = setCompactModel(model);\r\n if (!result.ok) return result;\r\n addLocalMessage(`Set compact model to ${model}.`);\r\n setSelectingCompactModel(false);\r\n setShowModelPicker(false);\r\n returnToConfig();\r\n return result;\r\n }\r\n if (agentProfileForModel) {\r\n const result = setAgentProfileModel(agentProfileForModel, model);\r\n if (!result.ok) return result;\r\n addLocalMessage(`Set ${agentProfileForModel} subagent model to ${model}.`);\r\n setAgentProfileForModel(undefined);\r\n setShowModelPicker(false);\r\n setShowAgentProfilePicker(true);\r\n return result;\r\n }\r\n const result = setModel(model, { persist: saveDefault });\r\n if (!result.ok) return result;\r\n addLocalMessage(\r\n saveDefault\r\n ? `Switched to ${model} (saved as default).`\r\n : `Switched to ${model} for this session only.`,\r\n );\r\n setShowModelPicker(false);\r\n returnToConfig();\r\n return result;\r\n }}\r\n onPickEffort={(level) => setEffort(level)}\r\n allowProviderManagement={!selectingCompactModel && !agentProfileForModel}\r\n onSaveProvider={upsertProviderAndSelect}\r\n removableProviderIds={removableProviderIds}\r\n removableProviderModelCounts={removableProviderModelCounts}\r\n onRemoveProvider={(providerId) => {\r\n const result = removeProvider(providerId);\r\n if (!result.ok) return result;\r\n addLocalMessage(providerRemovalMessage(result));\r\n setShowModelPicker(false);\r\n returnToConfig();\r\n return result;\r\n }}\r\n onProviderSaved={(request) => {\r\n addLocalMessage(\r\n `Added ${request.providerId} with ${request.models.length} model${request.models.length === 1 ? '' : 's'}; using ${request.providerId}/${request.activeModelId}.`,\r\n );\r\n setShowModelPicker(false);\r\n returnToConfig();\r\n }}\r\n onCancel={() => {\r\n // A model chosen *for a profile* was reached through the\r\n // profile picker, which is one step deeper than the menu; its\r\n // own cancel carries the user the rest of the way back, so the\r\n // recorded `/config` row must survive this close.\r\n const returnToAgents = Boolean(agentProfileForModel);\r\n setSelectingCompactModel(false);\r\n setAgentProfileForModel(undefined);\r\n setShowModelPicker(false);\r\n if (returnToAgents) setShowAgentProfilePicker(true);\r\n else returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showEffortPicker && effortLevels ? (\r\n <EffortPicker\r\n current={liveConfig.effort}\r\n availableLevels={effortLevels}\r\n onSelect={(level) => {\r\n const result = setEffort(level);\r\n if (!result.ok) return result;\r\n addLocalMessage(`Set effort level to ${level} (saved as default).`);\r\n setShowEffortPicker(false);\r\n returnToConfig();\r\n return result;\r\n }}\r\n onCancel={() => {\r\n setShowEffortPicker(false);\r\n returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showPermissionModePicker ? (\r\n <PermissionModePicker\r\n current={resolvePermissionMode(liveConfig.settings)}\r\n availableModes={\r\n [\r\n 'default',\r\n 'auto',\r\n 'plan',\r\n 'accept-edits',\r\n 'dontAsk',\r\n ...(liveConfig.settings.disableBypassPermissionsMode\r\n ? []\r\n : ['bypassPermissions']),\r\n ] as PermissionMode[]\r\n }\r\n onSelect={(nextMode) => {\r\n const result = setDefaultPermissionMode(nextMode);\r\n if (!result.ok) return result;\r\n addLocalMessage(`Default permission mode set to ${nextMode} globally.`);\r\n setShowPermissionModePicker(false);\r\n returnToConfig();\r\n return result;\r\n }}\r\n onCancel={() => {\r\n setShowPermissionModePicker(false);\r\n returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showThemePicker ? (\r\n <ThemePicker\r\n current={currentTheme.preference}\r\n customThemes={customThemes}\r\n onSelect={(name) => {\r\n const result = applyThemePreference(name);\r\n if (!result.ok) return result;\r\n addLocalMessage(themeAppliedMessage(result.theme));\r\n setShowThemePicker(false);\r\n returnToConfig();\r\n return { ok: true };\r\n }}\r\n onCancel={() => {\r\n setShowThemePicker(false);\r\n returnToConfig();\r\n }}\r\n />\r\n ) : null}\r\n {showMcpApproval && pendingMcpApproval && mcp ? (\r\n <McpServerApprovalPrompt\r\n key={pendingMcpApproval.name}\r\n server={pendingMcpApproval}\r\n remainingCount={mcpSnapshot.pendingApprovals.length - 1}\r\n onApprove={() => mcp.approve(pendingMcpApproval.name)}\r\n onReject={() => mcp.reject(pendingMcpApproval.name)}\r\n onDefer={() => mcp.defer(pendingMcpApproval.name)}\r\n />\r\n ) : null}\r\n </Box>\r\n\r\n {compactUi && (compactUi.phase === 'error' || compactUi.phase === 'skipped') ? (\r\n <CompactDiffCard\r\n state={compactUi}\r\n terminalWidth={termWidth}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n\r\n {isResolvingCommand ? <Text dimColor>Resolving command shell expansions...</Text> : null}\r\n\r\n {reviewStatus ? <Text dimColor>{reviewStatus}... (Esc to cancel)</Text> : null}\r\n\r\n {managedAgents.persistenceEvent ? (\r\n <Text\r\n color={\r\n managedAgents.persistenceEvent.state === 'degraded' ? theme.warning : theme.success\r\n }\r\n >\r\n {managedAgents.persistenceEvent.state === 'degraded' ? '! ' : '✓ '}\r\n {managedAgents.persistenceEvent.message}\r\n </Text>\r\n ) : null}\r\n\r\n <WorkingIndicator\r\n isThinking={isThinking}\r\n isCompacting={isCompacting}\r\n compactTrigger={compactUi?.trigger}\r\n messages={messages}\r\n streamingMessageId={streamingMessageId}\r\n pendingPermission={pendingPermission}\r\n pendingPlanApproval={pendingPlanApproval}\r\n pendingUserQuestion={pendingUserQuestion}\r\n pendingElicitation={pendingElicitation}\r\n retryPhase={retryPhase}\r\n retryAttempt={retryAttempt}\r\n retryMax={retryMax}\r\n retryCountdownMs={retryCountdownMs}\r\n terminalWidth={termWidth}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n />\r\n\r\n {/* Input bar — above the status line. Command menu is built into InputBar. */}\r\n <Box\r\n flexDirection=\"column\"\r\n flexShrink={0}\r\n width={termWidth}\r\n marginTop={messages.length > 0 ? 1 : 0}\r\n >\r\n <QueuedInputPreview\r\n items={queuedInputs}\r\n terminalWidth={termWidth}\r\n notice={queueNotice ?? copyNotice}\r\n />\r\n <InputBar\r\n key={sessionId}\r\n onSubmit={handleSubmit}\r\n onPasteImage={pasteClipboardImage}\r\n submissionMode={\r\n managedAgents.surface === 'detail'\r\n ? 'submit'\r\n : isThinking || sendInFlight\r\n ? 'queue'\r\n : isCompacting || isRewinding || isResolvingCommand\r\n ? 'blocked'\r\n : 'submit'\r\n }\r\n mode={mode}\r\n onCycleMode={cycleMode}\r\n canSubmitWhileBusy={canSubmitWhileParentBusy}\r\n canQueueWhileBusy={canQueueWhileParentBusy}\r\n onQueue={enqueueFollowUp}\r\n onRecallQueued={managedAgents.surface === 'main' ? recallQueuedInput : undefined}\r\n onCancelQueuedEdit={cancelQueuedEdit}\r\n editingQueuedInput={Boolean(editingQueuedInput)}\r\n onDraftChange={(value, attachments) => {\r\n draftRef.current = value;\r\n draftAttachmentsRef.current = attachments ?? [];\r\n }}\r\n onCycleAgentFocus={cycleAgentFocus}\r\n onFocusBackgroundTask={() => {\r\n if (managedAgents.surface === 'detail') {\r\n if (!managedAgentUiEnabled) return false;\r\n setDetailTaskPickerAgentId(undefined);\r\n setDetailTaskPickerOpen(true);\r\n return true;\r\n }\r\n const firstJobId =\r\n managedAgents.summaries[0]?.agentId ?? backgroundShells.shells[0]?.id;\r\n if (!managedAgentUiEnabled || !firstJobId) return false;\r\n selectBackgroundJob(firstJobId);\r\n managedAgents.setSurface('tasks');\r\n return true;\r\n }}\r\n inputSuppressed={\r\n modalOwnsInput ||\r\n // The rules sheet is a list, not a page of text: while it is up\r\n // it takes the arrows, so the composer must not also read them\r\n // as history navigation. Esc closes it, as it does every panel.\r\n showPermissions ||\r\n transcriptMode === 'detailed' ||\r\n managedAgents.surface === 'tasks' ||\r\n detailTaskPickerOpen\r\n }\r\n awaitingAnswer={awaitingAnswer}\r\n onGlobalShortcut={handleGlobalShortcut}\r\n commands={commands}\r\n skills={skills}\r\n terminalWidth={termWidth}\r\n maxMenuRows={maxCommandMenuRows}\r\n compact={isNarrow || isTiny}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n draftRestore={draftRestore}\r\n />\r\n </Box>\r\n\r\n {managedAgentUiEnabled &&\r\n (managedAgents.surface === 'main' ||\r\n managedAgents.surface === 'tasks' ||\r\n (managedAgents.surface === 'detail' && !detailTaskPickerOpen)) ? (\r\n <SubagentPanel\r\n agents={managedAgents.summaries}\r\n shells={backgroundShells.shells}\r\n selectedJobId={selectedShellId ?? managedAgents.selectedAgentId}\r\n isActive={managedAgents.surface === 'tasks'}\r\n onSelect={selectBackgroundJob}\r\n onOpen={(jobId) => {\r\n selectBackgroundJob(jobId);\r\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\r\n backgroundShells.acknowledge(jobId);\r\n }\r\n managedAgents.setSurface('detail');\r\n }}\r\n onClose={() => managedAgents.setSurface('main')}\r\n onCancel={() => managedAgents.setSurface('main')}\r\n onStopOrDismiss={(jobId) => {\r\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\r\n void backgroundShells.stopOrDismiss(jobId);\r\n } else {\r\n void managedAgents.stopOrDismiss(jobId);\r\n }\r\n }}\r\n width={termWidth}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n\r\n {managedAgentUiEnabled && managedAgents.surface === 'detail' && detailTaskPickerOpen ? (\r\n <SubagentPanel\r\n agents={managedAgents.summaries}\r\n shells={backgroundShells.shells}\r\n selectedJobId={detailTaskPickerAgentId}\r\n isActive\r\n onSelect={setDetailTaskPickerAgentId}\r\n onOpen={(jobId) => {\r\n setDetailTaskPickerOpen(false);\r\n setDetailTaskPickerAgentId(undefined);\r\n selectBackgroundJob(jobId);\r\n }}\r\n onClose={returnToMain}\r\n onCancel={() => {\r\n setDetailTaskPickerOpen(false);\r\n setDetailTaskPickerAgentId(undefined);\r\n }}\r\n onStopOrDismiss={(jobId) => {\r\n if (backgroundShells.shells.some((shell) => shell.id === jobId)) {\r\n void backgroundShells.stopOrDismiss(jobId);\r\n } else {\r\n void managedAgents.stopOrDismiss(jobId);\r\n }\r\n }}\r\n width={termWidth}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n\r\n {/* Status line — stable footer */}\r\n <Box flexShrink={0} width={termWidth}>\r\n <StatusLine\r\n gitBranch={gitStatus.branch}\r\n gitStatus={gitStatus.status}\r\n model={liveConfig.modelSelection ?? liveConfig.model}\r\n tokenCount={tokenCount}\r\n maxTokens={contextWindow.window}\r\n maxTokensSource={contextWindow.source}\r\n mode={mode}\r\n taskCount={tasks.length}\r\n activeTaskCount={tasks.filter((t) => t.status === 'in_progress').length}\r\n agentCount={managedAgentUiEnabled ? managedAgents.summaries.length : 0}\r\n activeAgentCount={\r\n managedAgentUiEnabled\r\n ? managedAgents.summaries.filter(\r\n (agent) =>\r\n !['completed', 'failed', 'stopped', 'interrupted'].includes(agent.status),\r\n ).length\r\n : 0\r\n }\r\n needsInputAgentCount={\r\n managedAgentUiEnabled\r\n ? managedAgents.summaries.filter(\r\n (agent) =>\r\n agent.status === 'waiting_input' || agent.status === 'waiting_permission',\r\n ).length\r\n : 0\r\n }\r\n terminalWidth={termWidth}\r\n compact={compactStatus}\r\n reducedMotion={motionDisabled}\r\n screenReader={screenReader}\r\n />\r\n </Box>\r\n </Box>\r\n </ErrorBoundary>\r\n </AppProviders>\r\n );\r\n}\r\n\r\nfunction AppProviders({\r\n theme,\r\n density,\r\n children,\r\n}: {\r\n theme: ThemeTokens;\r\n density: ReturnType<typeof resolveTuiDensity>;\r\n children: ReactNode;\r\n}) {\r\n return (\r\n <ThemeContext.Provider value={theme}>\r\n <DensityContext.Provider value={density}>{children}</DensityContext.Provider>\r\n </ThemeContext.Provider>\r\n );\r\n}\r\n\r\n/**\r\n * Title row for a reference sheet, carrying the way out.\r\n *\r\n * These panels are pinned above the composer until something dismisses them, so\r\n * the exit has to be written on the panel itself — a reader who does not\r\n * already know the toggle command has nothing else to go on. It rides the title\r\n * rather than a footer line because `/help` already runs taller than a short\r\n * terminal, and a panel that has to scroll to reveal how to close it is no\r\n * better than one that never says.\r\n */\r\nfunction PanelHeading({\r\n title,\r\n theme,\r\n}: {\r\n title: string;\r\n theme: { brand: string; subtle: string };\r\n}) {\r\n return (\r\n <Box>\r\n <Text bold color={theme.brand}>\r\n {title}\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n {' Esc to close'}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction HelpRow({\r\n label,\r\n description,\r\n theme,\r\n}: {\r\n label: string;\r\n description: string;\r\n theme: { brand: string; text: string; subtle: string };\r\n}) {\r\n return (\r\n <Box>\r\n <Text color={theme.brand}>{label}</Text>\r\n <Text color={theme.subtle}> — {description}</Text>\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * The transcript grid.\r\n *\r\n * Every row the TUI draws — an agent paragraph, a tool row, a turn rule, the\r\n * composer, the status line — resolves its horizontal position through this\r\n * module. Before it existed each component picked its own `marginLeft` and its\r\n * own `width - N` budget, so content landed on columns 1, 2, 4 and 5 with\r\n * nothing to scan down.\r\n *\r\n * The rule: a row is `[gutter][content]`. The gutter is exactly\r\n * {@link GUTTER_WIDTH} columns wide and carries status (a glyph, a rail, a\r\n * spinner); content always begins at {@link CONTENT_COLUMN}. Bordered surfaces\r\n * sit flush at column 0 so their one column of padding lands their text on the\r\n * same content column.\r\n *\r\n * Tool rows are the one deliberate step off that column. They carry their own\r\n * gutter one level in ({@link indentedGrid}) so the work a turn did reads as\r\n * nested under the prose that ordered it, instead of hanging a column of status\r\n * glyphs to the left of every sentence.\r\n */\r\n\r\n/** Status glyph plus its trailing space: `\"✓ \"`, `\"│ \"`, `\" \"`. */\r\nexport const GUTTER_WIDTH = 2;\r\n\r\n/**\r\n * Widest measure a floating surface uses, however wide the terminal is.\r\n *\r\n * Content and chrome want opposite things from a wide terminal. The transcript\r\n * holds the conversation — prose, diffs, code — and every column it is given is\r\n * a column it can use. A popover holds a list: slash commands, files, skills,\r\n * permission rules, none of them much past forty columns. Stretching that\r\n * border to two hundred draws an enormous empty box around a short list, which\r\n * is the same defect as a half-empty window wearing the opposite mask. So\r\n * content takes the terminal and chrome stops here.\r\n */\r\nexport const MAX_PANEL_MEASURE = 120;\r\n\r\n/**\r\n * Widest measure an aligned row lays its columns out in.\r\n *\r\n * A tool row puts its metadata flush against the right edge so the eye can scan\r\n * that column straight down a turn. This only reads as alignment while the edge\r\n * stays near the target: `67ms` sitting a hundred and seventy columns from the\r\n * command it timed is not aligned with that command, it is merely far away from\r\n * it. The prose around these rows takes the full terminal; the aligned columns\r\n * stop here, which also bounds the padding {@link composeToolRow} builds.\r\n */\r\nexport const MAX_ROW_MEASURE = 120;\r\n\r\n/** Columns a bordered surface spends on its own border plus one of padding. */\r\nexport const PANEL_CHROME = 4;\r\n\r\n/** Column where content begins on every row, nested or not. */\r\nexport const CONTENT_COLUMN = GUTTER_WIDTH;\r\n\r\n/** Below this width the label column collapses and rows render inline. */\r\nconst LABEL_COLUMN_MIN_WIDTH = 76;\r\n\r\n/** Widest label the aligned tool column holds without truncating. */\r\nexport const LABEL_COLUMN_WIDTH = 10;\r\n\r\n/** A target column narrower than this is not worth aligning around. */\r\nexport const MIN_TARGET_WIDTH = 12;\r\n\r\nexport interface TranscriptGrid {\r\n /** Full terminal width in columns. */\r\n width: number;\r\n /** Columns available to content, measured from {@link CONTENT_COLUMN}. */\r\n content: number;\r\n /**\r\n * Columns an aligned row lays its columns out in: {@link content}, bounded by\r\n * {@link MAX_ROW_MEASURE}. Shrinks with nesting exactly as `content` does, so\r\n * a nested row's right edge still lands on its parent's.\r\n */\r\n row: number;\r\n /** Width of the fixed label column; `0` when labels render inline. */\r\n label: number;\r\n /** Columns the middle (target) column may occupy. */\r\n target: number;\r\n /** Columns reserved for right-aligned metadata. */\r\n meta: number;\r\n}\r\n\r\n/**\r\n * Resolve the transcript grid for a terminal width.\r\n *\r\n * The grid takes the whole terminal. An earlier version capped the measure at\r\n * 120 columns to keep prose from running long, but a capped transcript on a\r\n * 200-column terminal does not read as a considered measure — it reads as a\r\n * broken window. Two thirds of the screen sits blank, the composer border stops\r\n * in mid-air, and diffs and code, which are most of what this UI exists to\r\n * show, get wrapped for no reason while the space to hold them goes unused.\r\n * The user picked the width of their terminal; do not reintroduce a cap here.\r\n */\r\nexport function transcriptGrid(terminalWidth: number): TranscriptGrid {\r\n // One trailing column stays empty: writing the last cell makes some\r\n // terminals emit a spurious wrap, which shears the row below.\r\n const width = Math.max(20, Math.floor(terminalWidth));\r\n const content = Math.max(8, width - CONTENT_COLUMN - 1);\r\n const label = width >= LABEL_COLUMN_MIN_WIDTH ? LABEL_COLUMN_WIDTH : 0;\r\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\r\n const target = Math.max(MIN_TARGET_WIDTH, content - label - meta - 1);\r\n return { width, content, row: Math.min(content, MAX_ROW_MEASURE), label, target, meta };\r\n}\r\n\r\n/**\r\n * A grid indented `depth` gutters, keeping its label column.\r\n *\r\n * The model says something, then shows its work; the work should sit under the\r\n * sentence that ordered it. Hanging the status glyph in a column to the *left*\r\n * of the prose made a turn read as a list of tool calls with text wedged\r\n * between them, the sentences pushed in from the margin rather than owning it.\r\n *\r\n * Indenting spends two columns, so the grid narrows as it shifts and the row's\r\n * right edge stays where the prose's is — right-aligned metadata still lines up\r\n * all the way down the transcript. Unlike {@link nestedGrid} the label column\r\n * survives: a top-level tool row is still the row that names its verb.\r\n */\r\nexport function indentedGrid(grid: TranscriptGrid, depth = 1): TranscriptGrid {\r\n const content = railContentWidth(grid, depth);\r\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\r\n const label = Math.min(grid.label, Math.max(0, content - meta - MIN_TARGET_WIDTH - 1));\r\n return {\r\n ...grid,\r\n content,\r\n row: railRowWidth(grid, depth),\r\n label,\r\n target: Math.max(MIN_TARGET_WIDTH, content - label - meta - 1),\r\n meta,\r\n };\r\n}\r\n\r\n/** Content width inside a rail nested `depth` levels under a transcript row. */\r\nexport function railContentWidth(grid: TranscriptGrid, depth = 1): number {\r\n return Math.max(8, grid.content - GUTTER_WIDTH * depth);\r\n}\r\n\r\n/**\r\n * Aligned-row width inside a rail nested `depth` levels under a transcript row.\r\n *\r\n * The bound has to travel down the nesting the same way the content width does.\r\n * Clamping every depth to a flat {@link MAX_ROW_MEASURE} would let a child row,\r\n * which starts two columns further in, end two columns further right than the\r\n * parent it hangs under — undoing the one thing {@link indentedGrid} exists for.\r\n */\r\nexport function railRowWidth(grid: TranscriptGrid, depth = 1): number {\r\n return Math.max(8, grid.row - GUTTER_WIDTH * depth);\r\n}\r\n\r\n/**\r\n * A grid for rows nested under a transcript row (a rail, a mutation child).\r\n *\r\n * Nested rows drop the label column: the parent row already named the verb, and\r\n * at this depth the columns left over are better spent on the target.\r\n */\r\nexport function nestedGrid(grid: TranscriptGrid, depth = 1): TranscriptGrid {\r\n const content = railContentWidth(grid, depth);\r\n const meta = Math.max(0, Math.min(20, Math.floor(content * 0.3)));\r\n return {\r\n ...grid,\r\n content,\r\n row: railRowWidth(grid, depth),\r\n label: 0,\r\n target: Math.max(MIN_TARGET_WIDTH, content - meta - 1),\r\n meta,\r\n };\r\n}\r\n\r\n/**\r\n * Narrow the label column to what a specific run of rows actually needs.\r\n *\r\n * The column is sized per message, not globally: a turn of `Bash` / `Read` /\r\n * `Grep` rows needs four columns, and padding those to fit a hypothetical\r\n * `Git status` opens a visible gulf between every verb and its target. A label\r\n * too wide for the measured column is not truncated — {@link composeToolRow}\r\n * runs it inline instead, so an under-measured column costs alignment on that\r\n * one row and never legibility.\r\n */\r\nexport function withLabelColumn(grid: TranscriptGrid, labelWidth: number): TranscriptGrid {\r\n if (grid.label === 0) return grid;\r\n const label = Math.max(1, Math.min(LABEL_COLUMN_WIDTH, Math.floor(labelWidth)));\r\n if (label === grid.label) return grid;\r\n return {\r\n ...grid,\r\n label,\r\n target: Math.max(MIN_TARGET_WIDTH, grid.content - label - grid.meta - 1),\r\n };\r\n}\r\n\r\nexport interface FrameGrid {\r\n /** Outer width of the bordered box. */\r\n width: number;\r\n /** Horizontal margin outside the border. Always 0: boxes sit flush left. */\r\n marginX: number;\r\n}\r\n\r\n/**\r\n * Metrics for a bordered surface that spans the transcript — the composer.\r\n *\r\n * The box is flush at column 0 so that its border plus one column of padding\r\n * places its text on {@link CONTENT_COLUMN}, matching every transcript row. It\r\n * takes the full terminal for the same reason the transcript does: it is as\r\n * wide as the thing the user is typing into, and a composer that stops halfway\r\n * is the most visible way a window can look broken. A surface that merely\r\n * floats over the transcript wants {@link panelGrid} instead.\r\n */\r\nexport function frameGrid(terminalWidth: number): FrameGrid {\r\n const outer = Math.max(20, Math.floor(terminalWidth));\r\n if (outer < 32) return { width: outer, marginX: 0 };\r\n return { width: outer - 1, marginX: 0 };\r\n}\r\n\r\n/**\r\n * Metrics for a floating surface (menu, picker, card, rules panel).\r\n *\r\n * Same geometry as {@link frameGrid}, bounded by {@link MAX_PANEL_MEASURE}.\r\n */\r\nexport function panelGrid(terminalWidth: number): FrameGrid {\r\n const outer = Math.min(MAX_PANEL_MEASURE, Math.max(20, Math.floor(terminalWidth)));\r\n if (outer < 32) return { width: outer, marginX: 0 };\r\n return { width: outer - 1, marginX: 0 };\r\n}\r\n\r\n/** Interior width of a bordered surface sized by {@link panelGrid}. */\r\nexport function panelContentWidth(terminalWidth: number, minimum = 24): number {\r\n return Math.max(minimum, panelGrid(terminalWidth).width - PANEL_CHROME);\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\r\nimport { useTheme } from '../theme.js';\r\nimport { transcriptGrid } from '../layout.js';\r\nimport type { CompactBoundary } from '../../types/sessions.js';\r\nimport type { Message } from '../../types/messages.js';\r\nimport type { PermissionResult, PlanApprovalResult } from '../../types/tools.js';\r\nimport type { RetryPhase } from '../../types/runtime.js';\r\nimport type {\r\n PendingPermissionRequest,\r\n PendingPlanApprovalRequest,\r\n} from '../../session/agent-interactions.js';\r\nimport { AgentMessage, managedAgentTracesEqualForMessage } from './AgentMessage.js';\r\nimport { UserMessage } from './UserMessage.js';\r\nimport { WelcomeScreen } from './WelcomeScreen.js';\r\nimport { createRenderDebugLogger, createUiDebugLogger } from '../../debug-log.js';\r\nimport { useDebugMount, useDebugRender } from '../debug.js';\r\nimport { useDensity } from '../density.js';\r\nimport { mergeAssistantMessages } from './transcript-messages.js';\r\nimport { selectExpandedToolId } from '../tool-traces.js';\r\nimport type { TranscriptMode } from '../tool-presentation.js';\r\nimport type { ManagedAgentTrace } from '../managed-agent-transcript.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\nimport { useTranscriptHistoryLoader, useTranscriptLayoutChange } from '../transcript-layout.js';\r\nimport { useVirtualTranscript, VirtualTranscriptRow } from './virtual-transcript.js';\r\n\r\nconst renderLog = createRenderDebugLogger('tui:chatpanel');\r\nconst uiLog = createUiDebugLogger('tui:chatpanel');\r\nconst EMPTY_BOUNDARIES: CompactBoundary[] = [];\r\nconst STREAMING_TIMELINE_MIN_WINDOW = 16;\r\nconst STREAMING_TIMELINE_MAX_WINDOW = 64;\r\nconst COMPLETED_TIMELINE_MIN_WINDOW = 80;\r\nconst COMPLETED_TIMELINE_MAX_WINDOW = 192;\r\n\r\nexport function getStreamingTimelineWindow(terminalHeight?: number): number {\r\n const height = Math.max(8, Math.floor(terminalHeight ?? 40));\r\n // Keep a small amount of context above the viewport without rendering an\r\n // entire long transcript on every streamed token.\r\n return Math.min(\r\n STREAMING_TIMELINE_MAX_WINDOW,\r\n Math.max(STREAMING_TIMELINE_MIN_WINDOW, Math.ceil(height * 1.25)),\r\n );\r\n}\r\n\r\nexport function getCompletedTimelineWindow(terminalHeight?: number): number {\r\n const height = Math.max(8, Math.floor(terminalHeight ?? 40));\r\n return Math.min(\r\n COMPLETED_TIMELINE_MAX_WINDOW,\r\n Math.max(COMPLETED_TIMELINE_MIN_WINDOW, Math.ceil(height * 3)),\r\n );\r\n}\r\n\r\nfunction estimateWrappedRows(content: string, width: number): number {\r\n // Wrap against the measure the row is actually rendered at, not the raw\r\n // terminal width: the virtual transcript sizes its spacers from this count,\r\n // so estimating against the wrong measure undercounts the wrapped rows.\r\n const contentWidth = transcriptGrid(width).content;\r\n if (!content) return 1;\r\n return (\r\n content\r\n .split('\\n')\r\n // Ink wraps on display width, so a CJK or emoji line occupies more columns\r\n // than it has code units and `.length` would report half its true height.\r\n .reduce((rows, line) => rows + Math.max(1, Math.ceil(displayWidth(line) / contentWidth)), 0)\r\n );\r\n}\r\n\r\nfunction estimateTimelineRows(entry: Message | CompactBoundary, terminalWidth: number): number {\r\n if ('transcriptOrdinal' in entry) return 1;\r\n\r\n const textRows = estimateWrappedRows(entry.content, terminalWidth);\r\n const attachmentRows = entry.attachments?.length ? 1 : 0;\r\n const toolRows = (entry.toolCalls?.length ?? 0) * 2 + (entry.toolResults?.length ?? 0);\r\n // A user turn opens with its rule, which is a row of its own.\r\n const turnRuleRows = entry.role === 'user' ? 1 : 0;\r\n return Math.max(1, textRows + attachmentRows + toolRows + turnRuleRows);\r\n}\r\n\r\nfunction messageOwnsTool(message: Message, toolId: string | null | undefined): boolean {\r\n if (!toolId) return false;\r\n if (message.toolCalls?.some((call) => call.id === toolId)) return true;\r\n return Boolean(\r\n message.nestedToolInvocations?.some(\r\n (invocation) => invocation.traceId === toolId || invocation.call.id === toolId,\r\n ),\r\n );\r\n}\r\n\r\nfunction formatTurnTime(timestamp: number): string {\r\n if (!timestamp) return '';\r\n return new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\r\n}\r\n\r\nfunction ScreenReaderRoleLabel({\r\n role,\r\n timestamp,\r\n}: {\r\n role: 'user' | 'assistant';\r\n timestamp: number;\r\n}) {\r\n const label = formatTurnTime(timestamp);\r\n return (\r\n <Box>\r\n <Text>\r\n {role === 'user' ? 'User' : 'Assistant'}\r\n {label ? ` at ${label}` : ''}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\ninterface ChatPanelProps {\r\n messages: Message[];\r\n managedAgentTraces?: ReadonlyMap<string, ManagedAgentTrace>;\r\n compactBoundaries?: CompactBoundary[];\r\n streamingMessageId?: string | null;\r\n pendingPermission?: PendingPermissionRequest | null;\r\n /** @deprecated Approval actions now render in App's fixed interaction area. */\r\n onResolvePermission?: (result: PermissionResult) => void;\r\n /** @deprecated Plan details/actions now render outside ChatPanel. */\r\n pendingPlanApproval?: PendingPlanApprovalRequest | null;\r\n /** @deprecated Plan details/actions now render outside ChatPanel. */\r\n onResolvePlanApproval?: (result: PlanApprovalResult) => void;\r\n /** @deprecated Dynamic transcript rendering no longer needs Static replay epochs. */\r\n staticEpoch?: number;\r\n expandedToolCallId?: string | null;\r\n transcriptMode?: TranscriptMode;\r\n automaticToolCallId?: string | null;\r\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n terminalWidth?: number;\r\n terminalHeight?: number;\r\n workspace?: string;\r\n model?: string;\r\n mode?: string;\r\n commandCount?: number;\r\n skillCount?: number;\r\n retryPhase?: RetryPhase;\r\n showAllToolOutput?: boolean;\r\n showAllToolOutputIds?: ReadonlySet<string>;\r\n showThinking?: boolean;\r\n retryAttempt?: number;\r\n retryMax?: number;\r\n retryCountdownMs?: number;\r\n}\r\n\r\n/** Dynamically renders transcript content. TranscriptView owns clipping and navigation. */\r\nexport function ChatPanelInner({\r\n messages,\r\n managedAgentTraces,\r\n compactBoundaries = EMPTY_BOUNDARIES,\r\n streamingMessageId,\r\n pendingPermission,\r\n expandedToolCallId,\r\n transcriptMode = 'compact',\r\n automaticToolCallId,\r\n toolExpansionOverrides,\r\n reducedMotion = false,\r\n screenReader = false,\r\n terminalWidth,\r\n terminalHeight,\r\n workspace,\r\n model,\r\n mode,\r\n commandCount = 0,\r\n skillCount = 0,\r\n retryPhase = 'none',\r\n showAllToolOutput = false,\r\n showAllToolOutputIds,\r\n showThinking = true,\r\n retryAttempt = 0,\r\n retryMax = 0,\r\n retryCountdownMs = 0,\r\n}: ChatPanelProps) {\r\n const density = useDensity();\r\n useDebugMount(uiLog, { model, mode, commandCount, skillCount });\r\n const timeline = useIncrementalTimeline(messages, compactBoundaries, streamingMessageId);\r\n const completedWindow = getCompletedTimelineWindow(terminalHeight);\r\n const [historyWindowSize, setHistoryWindowSize] = useState(completedWindow);\r\n const previousTimelineLengthRef = useRef(timeline.length);\r\n const notifyLayoutChange = useTranscriptLayoutChange();\r\n\r\n useEffect(() => {\r\n if (timeline.length < previousTimelineLengthRef.current) {\r\n setHistoryWindowSize(completedWindow);\r\n }\r\n previousTimelineLengthRef.current = timeline.length;\r\n }, [completedWindow, timeline.length]);\r\n\r\n useLayoutEffect(() => {\r\n notifyLayoutChange?.();\r\n }, [historyWindowSize, notifyLayoutChange]);\r\n\r\n const activeWindowSize = streamingMessageId\r\n ? getStreamingTimelineWindow(terminalHeight)\r\n : historyWindowSize;\r\n const hiddenTimelineEntries = Math.max(0, timeline.length - activeWindowSize);\r\n const visibleTimeline = useMemo(\r\n () => (hiddenTimelineEntries > 0 ? timeline.slice(hiddenTimelineEntries) : timeline),\r\n [hiddenTimelineEntries, timeline],\r\n );\r\n const getTimelineKey = useCallback(\r\n (entry: Message | CompactBoundary) =>\r\n 'transcriptOrdinal' in entry ? `boundary-${entry.id}` : entry.id,\r\n [],\r\n );\r\n const estimateRows = useCallback(\r\n (entry: Message | CompactBoundary) => estimateTimelineRows(entry, terminalWidth ?? 80),\r\n [terminalWidth],\r\n );\r\n const hiddenHistoryRows = hiddenTimelineEntries > 0 ? (density === 'tight' ? 1 : 2) : 0;\r\n const virtualTimeline = useVirtualTranscript({\r\n items: visibleTimeline,\r\n // Keep completed history virtualized while a live response streams. The\r\n // active message remains in the virtual range and follows the bottom when\r\n // the user is not browsing history.\r\n enabled: !screenReader && visibleTimeline.length > 24,\r\n terminalWidth: terminalWidth ?? 80,\r\n leadingRows: hiddenHistoryRows,\r\n getKey: getTimelineKey,\r\n estimateRows,\r\n });\r\n const estimatedLayoutRows = virtualTimeline.estimatedTotalRows;\r\n useEffect(() => {\r\n // Re-measure only when the estimated row count changes. MarkdownBlock and\r\n // virtual rows also notify for content whose measured height differs from\r\n // this inexpensive estimate.\r\n notifyLayoutChange?.();\r\n }, [estimatedLayoutRows, notifyLayoutChange]);\r\n const loadOlderHistory = useCallback(\r\n (request: 'page' | 'all') => {\r\n if (streamingMessageId || hiddenTimelineEntries === 0) return false;\r\n setHistoryWindowSize((current) =>\r\n request === 'all' ? timeline.length : Math.min(timeline.length, current + completedWindow),\r\n );\r\n return true;\r\n },\r\n [completedWindow, hiddenTimelineEntries, streamingMessageId, timeline.length],\r\n );\r\n useTranscriptHistoryLoader(loadOlderHistory);\r\n const selectedToolCallId =\r\n expandedToolCallId === undefined ? selectExpandedToolId(messages) : expandedToolCallId;\r\n\r\n useDebugRender(renderLog, {\r\n total: timeline.length,\r\n active: streamingMessageId?.slice(-8) ?? null,\r\n isEmpty: timeline.length === 0,\r\n });\r\n\r\n if (timeline.length === 0) {\r\n // A managed child transcript must never fall back to the main welcome\r\n // banner; callers render their own empty/waiting state around this panel.\r\n if (mode === 'managed') return null;\r\n return (\r\n <WelcomeScreen\r\n terminalWidth={terminalWidth ?? 80}\r\n terminalHeight={terminalHeight ?? 24}\r\n workspace={workspace}\r\n model={model}\r\n mode={mode}\r\n commandCount={commandCount}\r\n skillCount={skillCount}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n animate={false}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n {hiddenTimelineEntries > 0 ? (\r\n <Box marginLeft={2} marginBottom={density === 'tight' ? 0 : 1}>\r\n <Text dimColor>\r\n {hiddenTimelineEntries} older transcript entries hidden\r\n {streamingMessageId ? ' while streaming' : ' · scroll to the top to load more'}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {virtualTimeline.topSpacerRows > 0 ? (\r\n <Box height={virtualTimeline.topSpacerRows} flexShrink={0} />\r\n ) : null}\r\n {virtualTimeline.entries.map(({ item: entry, index, key, measurementKey }) => {\r\n let row: React.ReactNode;\r\n if ('transcriptOrdinal' in entry) {\r\n row = <CompactBoundaryRow terminalWidth={terminalWidth} />;\r\n } else {\r\n const message = entry;\r\n const previous = visibleTimeline[index - 1];\r\n if (message.role === 'user') {\r\n row = (\r\n <Box flexDirection=\"column\" marginTop={index > 0 && density !== 'tight' ? 1 : 0}>\r\n {screenReader ? (\r\n <ScreenReaderRoleLabel role=\"user\" timestamp={message.timestamp} />\r\n ) : null}\r\n <UserMessage\r\n content={message.content}\r\n attachments={message.attachments}\r\n terminalWidth={terminalWidth}\r\n timestamp={message.timestamp}\r\n screenReader={screenReader}\r\n />\r\n </Box>\r\n );\r\n } else {\r\n const isStreaming = message.id === streamingMessageId;\r\n const rowExpandedToolCallId = messageOwnsTool(message, selectedToolCallId)\r\n ? selectedToolCallId\r\n : undefined;\r\n const rowAutomaticToolCallId = messageOwnsTool(message, automaticToolCallId)\r\n ? automaticToolCallId\r\n : undefined;\r\n const rowPendingPermission =\r\n pendingPermission && messageOwnsTool(message, pendingPermission.toolCall.id)\r\n ? pendingPermission\r\n : undefined;\r\n const next = visibleTimeline[index + 1];\r\n const nextEntryIsUser = Boolean(next && 'role' in next && next.role === 'user');\r\n const followsToolCall = Boolean(\r\n previous &&\r\n 'role' in previous &&\r\n previous.role === 'assistant' &&\r\n previous.toolCalls?.length,\r\n );\r\n row = (\r\n <Box\r\n flexDirection=\"column\"\r\n marginTop={\r\n followsToolCall ||\r\n (density !== 'tight' &&\r\n previous &&\r\n 'role' in previous &&\r\n previous.role === 'user')\r\n ? 1\r\n : 0\r\n }\r\n >\r\n {screenReader ? (\r\n <ScreenReaderRoleLabel role=\"assistant\" timestamp={message.timestamp} />\r\n ) : null}\r\n <AgentMessage\r\n message={message}\r\n managedAgentTraces={managedAgentTraces}\r\n isStreaming={isStreaming}\r\n pendingPermission={rowPendingPermission}\r\n expandedToolCallId={rowExpandedToolCallId}\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={rowAutomaticToolCallId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n terminalWidth={terminalWidth}\r\n retryPhase={isStreaming ? retryPhase : 'none'}\r\n retryAttempt={isStreaming ? retryAttempt : 0}\r\n retryMax={isStreaming ? retryMax : 0}\r\n retryCountdownMs={isStreaming ? retryCountdownMs : 0}\r\n hideStreamingSpinner={isStreaming}\r\n showAllToolOutput={showAllToolOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n showThinking={showThinking}\r\n trimTrailingSpacing={nextEntryIsUser}\r\n />\r\n </Box>\r\n );\r\n }\r\n }\r\n\r\n if (!virtualTimeline.virtualized) {\r\n return <React.Fragment key={key}>{row}</React.Fragment>;\r\n }\r\n return (\r\n <VirtualTranscriptRow\r\n key={key}\r\n measurementKey={measurementKey}\r\n onMeasure={virtualTimeline.measure}\r\n >\r\n {row}\r\n </VirtualTranscriptRow>\r\n );\r\n })}\r\n {virtualTimeline.bottomSpacerRows > 0 ? (\r\n <Box height={virtualTimeline.bottomSpacerRows} flexShrink={0} />\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n\r\nexport const ChatPanel = React.memo(ChatPanelInner, (previous, next) => {\r\n if (\r\n previous.messages !== next.messages ||\r\n previous.compactBoundaries !== next.compactBoundaries ||\r\n previous.streamingMessageId !== next.streamingMessageId ||\r\n previous.pendingPermission !== next.pendingPermission ||\r\n previous.expandedToolCallId !== next.expandedToolCallId ||\r\n previous.transcriptMode !== next.transcriptMode ||\r\n previous.automaticToolCallId !== next.automaticToolCallId ||\r\n previous.toolExpansionOverrides !== next.toolExpansionOverrides ||\r\n previous.reducedMotion !== next.reducedMotion ||\r\n previous.screenReader !== next.screenReader ||\r\n previous.terminalWidth !== next.terminalWidth ||\r\n previous.terminalHeight !== next.terminalHeight ||\r\n previous.workspace !== next.workspace ||\r\n previous.model !== next.model ||\r\n previous.mode !== next.mode ||\r\n previous.commandCount !== next.commandCount ||\r\n previous.skillCount !== next.skillCount ||\r\n previous.retryPhase !== next.retryPhase ||\r\n previous.showAllToolOutput !== next.showAllToolOutput ||\r\n previous.showAllToolOutputIds !== next.showAllToolOutputIds ||\r\n previous.showThinking !== next.showThinking ||\r\n previous.retryAttempt !== next.retryAttempt ||\r\n previous.retryMax !== next.retryMax ||\r\n previous.retryCountdownMs !== next.retryCountdownMs\r\n ) {\r\n return false;\r\n }\r\n\r\n if (previous.managedAgentTraces === next.managedAgentTraces) return true;\r\n if (!previous.managedAgentTraces?.size && !next.managedAgentTraces?.size) return true;\r\n return previous.messages.every((message) =>\r\n managedAgentTracesEqualForMessage(\r\n message,\r\n previous.managedAgentTraces,\r\n next.managedAgentTraces,\r\n ),\r\n );\r\n});\r\n\r\ninterface TimelineCache {\r\n messages?: Message[];\r\n streamingMessageId?: string | null;\r\n prefixLength: number;\r\n prefixLast?: Message;\r\n boundaries?: CompactBoundary[];\r\n prefix: Array<Message | CompactBoundary>;\r\n composed?: Array<Message | CompactBoundary>;\r\n composedActive?: Message;\r\n}\r\n\r\nfunction useIncrementalTimeline(\r\n messages: Message[],\r\n boundaries: CompactBoundary[],\r\n streamingMessageId?: string | null,\r\n): Array<Message | CompactBoundary> {\r\n const cache = useRef<TimelineCache>({ prefixLength: -1, prefix: [] });\r\n if (!streamingMessageId) {\r\n if (cache.current.messages !== messages || cache.current.boundaries !== boundaries) {\r\n cache.current = {\r\n messages,\r\n streamingMessageId,\r\n prefixLength: messages.length,\r\n prefixLast: messages.at(-1),\r\n boundaries,\r\n prefix: buildTimeline(messages, boundaries, streamingMessageId),\r\n };\r\n }\r\n return cache.current.prefix;\r\n }\r\n const streamingIndex = messages.findIndex((message) => message.id === streamingMessageId);\r\n if (streamingIndex < 0 || streamingIndex !== messages.length - 1) {\r\n return buildTimeline(messages, boundaries, streamingMessageId);\r\n }\r\n\r\n const prefixLast = streamingIndex > 0 ? messages[streamingIndex - 1] : undefined;\r\n if (\r\n cache.current.streamingMessageId !== streamingMessageId ||\r\n cache.current.prefixLength !== streamingIndex ||\r\n cache.current.prefixLast !== prefixLast ||\r\n cache.current.boundaries !== boundaries\r\n ) {\r\n cache.current = {\r\n streamingMessageId,\r\n prefixLength: streamingIndex,\r\n prefixLast,\r\n boundaries,\r\n prefix: buildTimeline(messages.slice(0, streamingIndex), boundaries, streamingMessageId),\r\n };\r\n }\r\n const active = messages[streamingIndex];\r\n if (active.kind === 'agent-notification') return cache.current.prefix;\r\n // Reuse the composed array while the active message object is unchanged so\r\n // re-renders without new deltas keep a stable timeline identity downstream.\r\n if (cache.current.composedActive !== active) {\r\n cache.current.composed = [...cache.current.prefix, active];\r\n cache.current.composedActive = active;\r\n }\r\n return cache.current.composed!;\r\n}\r\n\r\nfunction buildTimeline(\r\n messages: Message[],\r\n boundaries: CompactBoundary[],\r\n streamingMessageId?: string | null,\r\n): Array<Message | CompactBoundary> {\r\n const byOrdinal = new Map<number, CompactBoundary[]>();\r\n for (const boundary of boundaries) {\r\n const group = byOrdinal.get(boundary.transcriptOrdinal) ?? [];\r\n group.push(boundary);\r\n byOrdinal.set(boundary.transcriptOrdinal, group);\r\n }\r\n const timeline: Array<Message | CompactBoundary> = [];\r\n let segment: Message[] = [];\r\n const flush = () => {\r\n if (!segment.length) return;\r\n timeline.push(...mergeAssistantMessages(segment, streamingMessageId));\r\n segment = [];\r\n };\r\n for (let index = 0; index <= messages.length; index++) {\r\n const markers = byOrdinal.get(index);\r\n if (markers?.length) {\r\n flush();\r\n timeline.push(...markers.sort((a, b) => a.timestamp - b.timestamp));\r\n }\r\n if (index < messages.length && messages[index].kind !== 'agent-notification') {\r\n segment.push(messages[index]);\r\n }\r\n }\r\n flush();\r\n return timeline;\r\n}\r\n\r\nfunction CompactBoundaryRow({ terminalWidth = 80 }: { terminalWidth?: number }) {\r\n const theme = useTheme();\r\n return (\r\n <Box width={transcriptGrid(terminalWidth).width}>\r\n <Text color={theme.success}>✓ </Text>\r\n <Text color={theme.text}>\r\n {truncateDisplay('Compact conversation', transcriptGrid(terminalWidth).content)}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n","import { Text, Box } from 'ink';\r\nimport React, { useMemo } from 'react';\r\nimport { Spinner } from './Spinner.js';\r\nimport { MetaText, TargetText, ToolCallBlock } from './ToolCallBlock.js';\r\nimport { DiffBlock, isUnifiedDiffLike } from './Diff.js';\r\nimport { MarkdownBlock, useThrottledValue } from './MarkdownBlock.js';\r\nimport { CommandPanel } from './CommandPanel.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport {\r\n CONTENT_COLUMN,\r\n GUTTER_WIDTH,\r\n indentedGrid,\r\n transcriptGrid,\r\n withLabelColumn,\r\n} from '../layout.js';\r\nimport { composeToolRow, toolLabelColumnWidth, toolRowLabel } from '../tool-presentation.js';\r\nimport type { Message } from '../../types/messages.js';\r\nimport type { RetryPhase } from '../../types/runtime.js';\r\nimport type { PendingPermissionRequest } from '../../session/agent-interactions.js';\r\nimport { createRenderDebugLogger } from '../../debug-log.js';\r\nimport { splitReasoningParts } from '../../reasoning-tags.js';\r\nimport {\r\n countNestedToolInvocations,\r\n indexNestedToolInvocations,\r\n type NestedToolChildren,\r\n} from '../tool-traces.js';\r\nimport {\r\n getFileMutationDisplaySummary,\r\n type FileMutationDisplaySummary,\r\n} from '../file-mutation-display.js';\r\nimport {\r\n shouldDefaultExpandTool,\r\n shouldExpandTool,\r\n type TranscriptMode,\r\n} from '../tool-presentation.js';\r\nimport type { ManagedAgentTrace } from '../managed-agent-transcript.js';\r\nimport { ManagedAgentActivityBlock } from './ManagedAgentActivityBlock.js';\r\nimport { useDebugRender } from '../debug.js';\r\n\r\nconst renderLog = createRenderDebugLogger('tui:agentmsg');\r\n\r\ninterface AgentMessageProps {\r\n message: Message;\r\n managedAgentTraces?: ReadonlyMap<string, ManagedAgentTrace>;\r\n isStreaming: boolean;\r\n pendingPermission?: PendingPermissionRequest | null;\r\n expandedToolCallId?: string | null;\r\n transcriptMode?: TranscriptMode;\r\n automaticToolCallId?: string | null;\r\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n /** Terminal width in columns — passed down to MarkdownBlock for word-wrap. */\r\n terminalWidth?: number;\r\n /** Retry state — shown in the spinner line when active. */\r\n retryPhase?: RetryPhase;\r\n retryAttempt?: number;\r\n retryMax?: number;\r\n retryCountdownMs?: number;\r\n /** Hide the inline streaming spinner when an external working indicator owns activity state. */\r\n hideStreamingSpinner?: boolean;\r\n /** When true, expanded tool results show the larger output cap instead of a short preview. */\r\n showAllToolOutput?: boolean;\r\n /** Tool-specific full-output expansion used by compact transcript mode. */\r\n showAllToolOutputIds?: ReadonlySet<string>;\r\n /** Whether provider-native and embedded model thinking should be shown. */\r\n showThinking?: boolean;\r\n /** Remove the final markdown block's margin before the next user turn. */\r\n trimTrailingSpacing?: boolean;\r\n}\r\n\r\nconst NO_EXPANSION_OVERRIDES = new Map<string, boolean>();\r\nconst NO_SHOW_ALL_TOOL_OUTPUT_IDS: ReadonlySet<string> = new Set<string>();\r\nfunction NestedToolRows({\r\n childrenByParent,\r\n parentTraceId,\r\n depth,\r\n transcriptMode,\r\n automaticToolCallId,\r\n toolExpansionOverrides,\r\n reducedMotion,\r\n screenReader,\r\n showAllToolOutput,\r\n showAllToolOutputIds,\r\n terminalWidth,\r\n toolRowGap,\r\n}: {\r\n childrenByParent: NestedToolChildren;\r\n parentTraceId: string;\r\n depth: number;\r\n transcriptMode: TranscriptMode;\r\n automaticToolCallId?: string | null;\r\n toolExpansionOverrides: ReadonlyMap<string, boolean>;\r\n reducedMotion: boolean;\r\n screenReader: boolean;\r\n showAllToolOutput: boolean;\r\n showAllToolOutputIds: ReadonlySet<string>;\r\n terminalWidth?: number;\r\n toolRowGap: 0 | 1;\r\n}) {\r\n const children = childrenByParent.get(parentTraceId) ?? [];\r\n return children.map((invocation) => {\r\n return (\r\n <Box\r\n key={invocation.traceId}\r\n flexDirection=\"column\"\r\n marginLeft={screenReader ? 2 : depth * 2}\r\n marginTop={toolRowGap}\r\n >\r\n <ToolCallBlock\r\n toolId={invocation.traceId}\r\n name={invocation.call.name}\r\n args={invocation.call.arguments}\r\n result={invocation.result}\r\n isExpanded={shouldExpandTool({\r\n mode: transcriptMode,\r\n toolId: invocation.traceId,\r\n automaticToolId: automaticToolCallId,\r\n defaultExpanded: shouldDefaultExpandTool(invocation.call.name, invocation.result),\r\n expansionOverrides: toolExpansionOverrides,\r\n screenReader,\r\n })}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n showAllToolOutput={showAllToolOutput || showAllToolOutputIds.has(invocation.traceId)}\r\n terminalWidth={terminalWidth ? Math.max(12, terminalWidth - depth * 2) : undefined}\r\n />\r\n <NestedToolRows\r\n childrenByParent={childrenByParent}\r\n parentTraceId={invocation.traceId}\r\n depth={depth + 1}\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={automaticToolCallId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n showAllToolOutput={showAllToolOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n terminalWidth={terminalWidth}\r\n toolRowGap={toolRowGap}\r\n />\r\n </Box>\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * Strip trailing partial markdown code-fence closings from streaming text.\r\n *\r\n * While streaming, the LLM may emit incomplete closing fences (e.g. `` after a\r\n * ```rust block). These partial markers cause rendered code blocks to visually\r\n * jitter as the fence opens/closes. This function detects when the last line is\r\n * a non-empty prefix of a closing fence marker and strips it.\r\n */\r\nexport function trimPartialClosingFences(text: string): string {\r\n const lines = text.split('\\n');\r\n let lastOpenIdx = -1;\r\n for (let i = lines.length - 2; i >= 0; i--) {\r\n if (/^```/.test(lines[i])) {\r\n lastOpenIdx = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastOpenIdx === -1) return text;\r\n\r\n let hasClose = false;\r\n for (let i = lastOpenIdx + 1; i < lines.length; i++) {\r\n if (/^```\\s*$/.test(lines[i])) {\r\n hasClose = true;\r\n break;\r\n }\r\n }\r\n\r\n if (hasClose) return text;\r\n\r\n const lastLine = lines[lines.length - 1];\r\n if (lastLine === '') return text;\r\n\r\n const closeMarker = '```';\r\n if (lastLine !== closeMarker && closeMarker.startsWith(lastLine)) {\r\n return lines.slice(0, -1).join('\\n') + (lines.length > 1 ? '\\n' : '');\r\n }\r\n\r\n return text;\r\n}\r\n\r\n/** Build the spinner label based on retry state. Exported for testing. */\r\nexport function getRetryLabel(\r\n retryPhase: RetryPhase,\r\n retryAttempt: number,\r\n retryMax: number,\r\n retryCountdownMs: number,\r\n): string | undefined {\r\n if (retryPhase === 'transport') {\r\n const countdown = Math.max(0, Math.ceil(retryCountdownMs / 1000));\r\n const attemptStr =\r\n retryMax > 0 ? `attempt ${retryAttempt}/${retryMax}` : `attempt ${retryAttempt}`;\r\n return `Retrying in ${countdown}s · ${attemptStr}`;\r\n }\r\n if (retryPhase === 'stalled') {\r\n const countdown = Math.max(0, Math.ceil(retryCountdownMs / 1000));\r\n return `Waiting for API response · will retry in ${countdown}s · check your network`;\r\n }\r\n if (retryPhase === 'watchdog') {\r\n return `Retrying (watchdog) · attempt ${retryAttempt}`;\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Reasoning-tag splitting lives in `src/reasoning-tags.ts` so the agent loop can\r\n * apply the same rule when deciding whether a turn produced an answer. It is\r\n * re-exported under the renderer's own name because that is what the transcript\r\n * calls these blocks.\r\n */\r\nexport const splitThinkBlocks = splitReasoningParts;\r\n\r\nfunction reasoningLines(text: string): string[] {\r\n return text\r\n .split(/\\r?\\n/)\r\n .map((line) => line.trim())\r\n .filter(Boolean);\r\n}\r\n\r\nexport function countReasoningLines(text: string): number {\r\n return reasoningLines(text).length;\r\n}\r\n\r\n/**\r\n * Rows a completed thought would occupy if it were expanded.\r\n *\r\n * The collapsed row advertises what expanding costs, so it has to count\r\n * *rendered* rows. Counting source lines put `Thought - 2 lines` above four\r\n * wrapped rows, which read as a bug in the count rather than a wrap.\r\n */\r\nexport function countReasoningRows(text: string, width?: number): number {\r\n const lines = reasoningLines(text);\r\n if (!width || width <= 0) return lines.length;\r\n const measure = Math.max(8, Math.floor(width));\r\n return lines.reduce((rows, line) => rows + Math.max(1, Math.ceil(line.length / measure)), 0);\r\n}\r\n\r\nfunction ThinkBlock({\r\n text,\r\n terminalWidth,\r\n reducedMotion,\r\n active = true,\r\n expanded = false,\r\n screenReader = false,\r\n}: {\r\n text: string;\r\n terminalWidth?: number;\r\n reducedMotion?: boolean;\r\n active?: boolean;\r\n /** Detailed transcript mode keeps a finished thought open. */\r\n expanded?: boolean;\r\n screenReader?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n // Keep the complete thought readable while avoiding a terminal redraw for every delta.\r\n const streamedText = useThrottledValue(text, 80);\r\n // The body sits two gutters in from the block's own width: the rail plus its\r\n // padding, then the indent under the header.\r\n const bodyWidth =\r\n terminalWidth === undefined || screenReader\r\n ? terminalWidth\r\n : Math.max(12, Math.floor(terminalWidth) - GUTTER_WIDTH * 2);\r\n const rowCount = countReasoningRows(text, bodyWidth);\r\n const rowLabel = `${rowCount} ${rowCount === 1 ? 'line' : 'lines'}`;\r\n\r\n // A finished thought collapses to one row.\r\n //\r\n // Watching reasoning arrive is the point of showing it; re-reading it in\r\n // scrollback is not. Expanded by default it put the least important content\r\n // of a turn in the most prominent position — several rows of it above the\r\n // first sentence of the answer. Detailed mode (Ctrl+O) reopens it, so\r\n // nothing becomes unreachable.\r\n if (!active && !expanded && !screenReader) {\r\n return (\r\n <Box>\r\n <Text color={theme.mdThinkText} dimColor>\r\n {`▸ thought · ${rowLabel}`}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"single\"\r\n borderLeft={!screenReader}\r\n borderTop={false}\r\n borderRight={false}\r\n borderBottom={false}\r\n borderLeftColor={theme.mdThinkBorder}\r\n paddingLeft={screenReader ? 0 : 1}\r\n >\r\n <Box>\r\n {active && !screenReader ? (\r\n <Spinner active color={theme.mdThinkText} reducedMotion={reducedMotion} />\r\n ) : null}\r\n <Text color={theme.mdThinkText} bold={active} dimColor={!active}>\r\n {active ? 'Thinking' : 'Thought'}\r\n </Text>\r\n {!active ? <Text color={theme.subtle} dimColor>{` - ${rowLabel}`}</Text> : null}\r\n </Box>\r\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN}>\r\n {active ? (\r\n <Text color={theme.mdThinkText} dimColor>\r\n {streamedText}\r\n </Text>\r\n ) : (\r\n <MarkdownBlock content={text} terminalWidth={bodyWidth} />\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Heading for a run of consecutive file mutations, laid out like a tool row so\r\n * its verb, target and churn land on the same columns as everything else.\r\n */\r\nfunction MutationGroupRow({\r\n createdOnly,\r\n fileCount,\r\n addedLines,\r\n removedLines,\r\n grid,\r\n screenReader,\r\n}: {\r\n createdOnly: boolean;\r\n fileCount: number;\r\n addedLines: number;\r\n removedLines: number;\r\n grid: ReturnType<typeof transcriptGrid>;\r\n screenReader: boolean;\r\n}) {\r\n const theme = useTheme();\r\n const row = composeToolRow(\r\n {\r\n title: createdOnly ? 'Create' : 'Edit',\r\n target: `${fileCount} ${fileCount === 1 ? 'file' : 'files'}`,\r\n metadata: [`+${addedLines}`, `-${removedLines}`],\r\n },\r\n grid,\r\n );\r\n if (screenReader) {\r\n return (\r\n <Box>\r\n <Text>\r\n {createdOnly ? 'Created' : 'Edited'} {fileCount} {fileCount === 1 ? 'file' : 'files'} (+\r\n {addedLines} -{removedLines})\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n return (\r\n <Box height={1} marginLeft={CONTENT_COLUMN}>\r\n <Text color={theme.success}>{'• '}</Text>\r\n {row.label ? (\r\n <Text color={theme.inactive} dimColor>\r\n {row.label}{' '}\r\n </Text>\r\n ) : null}\r\n <TargetText target={row.target} failed={false} />\r\n <Text>{row.gap}</Text>\r\n <MetaText meta={row.meta} failed={false} />\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Marks where reasoning ends and the answer begins.\r\n *\r\n * Visually this is a blank row: a finished thought already collapses to a\r\n * single line, so a labelled rule on top of it was chrome announcing chrome.\r\n * Screen readers still get the spoken boundary, which they cannot infer from\r\n * spacing.\r\n */\r\nfunction AnswerDivider({ screenReader }: { screenReader: boolean }) {\r\n if (!screenReader) return <Box marginTop={1} />;\r\n return (\r\n <Box>\r\n <Text>Answer:</Text>\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Claude Code-style agent message block.\r\n *\r\n * Each assistant turn renders as:\r\n * 1. Spinner line — shows thinking tips, or retry countdown during retries\r\n * 2. Streaming text content\r\n * 3. One tool row per invocation, with Task subagent tools nested below their parent\r\n *\r\n * During retries, the spinner line shows Claude Code-style messages:\r\n * - Transport retry: \"Retrying in 4s · attempt 3/10\"\r\n * - Stream stall: \"Waiting for API response · will retry in 8s · check your network\"\r\n * - Watchdog: \"Retrying (watchdog) · attempt 47\"\r\n *\r\n * When screenReader mode is enabled, all decorations (spinners,\r\n * box borders, expand/collapse toggles) are stripped for flat,\r\n * accessible rendering.\r\n */\r\nexport function AgentMessageInner({\r\n message,\r\n managedAgentTraces,\r\n isStreaming,\r\n pendingPermission,\r\n expandedToolCallId,\r\n transcriptMode = 'compact',\r\n automaticToolCallId,\r\n toolExpansionOverrides = NO_EXPANSION_OVERRIDES,\r\n reducedMotion = false,\r\n screenReader = false,\r\n terminalWidth,\r\n retryPhase = 'none',\r\n retryAttempt = 0,\r\n retryMax = 0,\r\n retryCountdownMs = 0,\r\n hideStreamingSpinner = false,\r\n showAllToolOutput = false,\r\n showAllToolOutputIds = NO_SHOW_ALL_TOOL_OUTPUT_IDS,\r\n showThinking = true,\r\n trimTrailingSpacing = false,\r\n}: AgentMessageProps) {\r\n const theme = useTheme();\r\n const { toolRowGap, toolBlockGap } = useDensityMetrics();\r\n const toolCalls = message.toolCalls ?? [];\r\n const suppressDelegationNarration = toolCalls.some((call) => {\r\n if (call.name !== 'AgentSpawn') return false;\r\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\r\n return !result || result.status === 'success';\r\n });\r\n // AgentSpawn has its own activity row. Keep the model text in history/context,\r\n // but avoid showing duplicated delegation narration in the user transcript.\r\n const rawDisplayContent = useMemo(\r\n () => (isStreaming ? trimPartialClosingFences(message.content) : message.content),\r\n [isStreaming, message.content],\r\n );\r\n const displayContent = suppressDelegationNarration ? '' : rawDisplayContent;\r\n const reasoningContent = message.reasoningContent;\r\n\r\n useDebugRender(renderLog, {\r\n id: message.id.slice(-8),\r\n streaming: isStreaming,\r\n contentLen: displayContent.length,\r\n toolCalls: (message.toolCalls ?? []).length,\r\n toolResults: (message.toolResults ?? []).length,\r\n retry: retryPhase,\r\n });\r\n\r\n const childrenByParent = useMemo(\r\n () => indexNestedToolInvocations(message.nestedToolInvocations ?? []),\r\n [message.nestedToolInvocations],\r\n );\r\n\r\n const spinnerLabel = useMemo(\r\n () => getRetryLabel(retryPhase, retryAttempt, retryMax, retryCountdownMs),\r\n [retryPhase, retryAttempt, retryMax, retryCountdownMs],\r\n );\r\n\r\n const isRetrying = retryPhase !== 'none';\r\n\r\n // Prose sits on the transcript content column, the same one tool rows and the\r\n // status line use. Activity labels render on their own row so they never\r\n // steal horizontal space from markdown or diffs.\r\n const grid = useMemo(() => transcriptGrid(terminalWidth ?? 80), [terminalWidth]);\r\n const contentWidth = terminalWidth ? grid.content : undefined;\r\n const mdWidth = contentWidth;\r\n // Once a turn has spoken its last — settled, and holding no tool call to\r\n // continue through — a reasoning tag the provider never closed must not be\r\n // allowed to swallow the answer into a collapsed thought. A turn that did call\r\n // a tool keeps the strict reading; see `splitReasoningParts`.\r\n //\r\n // An empty reasoning block is dropped outright. Routers that inline thinking\r\n // as `<think></think>` emit one on every tool-call turn, and each rendered as\r\n // a `thought · 0 lines` row: a toggle that expands to nothing.\r\n const contentParts = useMemo(\r\n () =>\r\n splitThinkBlocks(displayContent, {\r\n concluded: !isStreaming && toolCalls.length === 0,\r\n }).filter((part) => part.kind !== 'think' || part.text.length > 0),\r\n [displayContent, isStreaming, toolCalls.length],\r\n );\r\n const renderAsUnifiedDiff = useMemo(\r\n () => displayContent.length > 0 && isUnifiedDiffLike(displayContent),\r\n [displayContent],\r\n );\r\n const embeddedThinking = useMemo(\r\n () => contentParts.some((part) => part.kind === 'think'),\r\n [contentParts],\r\n );\r\n const topLevelInvocations = useMemo(\r\n () =>\r\n toolCalls.map((call) => {\r\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\r\n return {\r\n id: call.id,\r\n name: call.name,\r\n call,\r\n result,\r\n mutation: getFileMutationDisplaySummary(call.name, call.arguments, result),\r\n };\r\n }),\r\n [message.toolResults, toolCalls],\r\n );\r\n // Size the label column to this turn's own rows. A turn of `Bash` / `Read`\r\n // rows padded to fit a hypothetical `Git status` puts seven dead columns\r\n // between every verb and its target.\r\n const labelWidth = useMemo(\r\n () =>\r\n toolLabelColumnWidth(\r\n topLevelInvocations.map((invocation) => toolRowLabel(invocation.name, invocation.result)),\r\n ),\r\n [topLevelInvocations],\r\n );\r\n // The heading sits on the same indented grid as the tool rows it heads.\r\n const mutationGrid = useMemo(\r\n () => indentedGrid(withLabelColumn(grid, labelWidth)),\r\n [grid, labelWidth],\r\n );\r\n const selectedAutomaticToolId = automaticToolCallId ?? expandedToolCallId;\r\n\r\n if (message.localCommand) {\r\n return (\r\n <CommandPanel\r\n display={message.localCommand}\r\n fallback={displayContent}\r\n terminalWidth={terminalWidth}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n {/* Spinner line: shows thinking tips, or retry countdown during retries */}\r\n {isStreaming &&\r\n !hideStreamingSpinner &&\r\n !displayContent &&\r\n !(showThinking && reasoningContent) &&\r\n !message.toolCalls?.length ? (\r\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN}>\r\n {isRetrying && spinnerLabel ? (\r\n <Box>\r\n <Text color={theme.error}>Retrying: </Text>\r\n <Text color={theme.error}>{spinnerLabel}</Text>\r\n </Box>\r\n ) : (\r\n <Spinner active reducedMotion={reducedMotion} showTips={true} />\r\n )}\r\n </Box>\r\n ) : null}\r\n\r\n {showThinking && reasoningContent ? (\r\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN} flexDirection=\"column\">\r\n <ThinkBlock\r\n text={reasoningContent}\r\n terminalWidth={mdWidth}\r\n reducedMotion={reducedMotion}\r\n active={isStreaming && !displayContent}\r\n expanded={transcriptMode === 'detailed'}\r\n screenReader={screenReader}\r\n />\r\n </Box>\r\n ) : null}\r\n\r\n {/* Activity and content use separate rows so markdown keeps its full budget. */}\r\n {displayContent ? (\r\n <Box marginLeft={screenReader ? 0 : CONTENT_COLUMN} flexDirection=\"column\">\r\n {showThinking && reasoningContent && !embeddedThinking ? (\r\n <AnswerDivider screenReader={screenReader} />\r\n ) : null}\r\n {isStreaming && !hideStreamingSpinner && !isRetrying ? (\r\n <Box>\r\n <Spinner active reducedMotion={reducedMotion} />\r\n </Box>\r\n ) : null}\r\n {isRetrying && !hideStreamingSpinner && spinnerLabel ? (\r\n <Box>\r\n <Text color={theme.error}>Retrying: </Text>\r\n <Text color={theme.error}>{spinnerLabel}</Text>\r\n </Box>\r\n ) : null}\r\n {renderAsUnifiedDiff ? (\r\n <DiffBlock output={displayContent} terminalWidth={contentWidth} />\r\n ) : (\r\n <Box flexDirection=\"column\">\r\n {contentParts.map((part, i) => {\r\n if (part.kind === 'think') {\r\n if (!showThinking) return null;\r\n const answerHasStarted = contentParts\r\n .slice(i + 1)\r\n .some((candidate) => candidate.kind === 'markdown' && candidate.text.trim());\r\n return (\r\n <ThinkBlock\r\n key={`think-${i}`}\r\n text={part.text}\r\n terminalWidth={mdWidth}\r\n reducedMotion={reducedMotion}\r\n active={isStreaming && !answerHasStarted}\r\n expanded={transcriptMode === 'detailed'}\r\n screenReader={screenReader}\r\n />\r\n );\r\n }\r\n const hasEarlierThinking = contentParts\r\n .slice(0, i)\r\n .some((candidate) => candidate.kind === 'think');\r\n return (\r\n <React.Fragment key={`md-${i}`}>\r\n {showThinking && hasEarlierThinking ? (\r\n <AnswerDivider screenReader={screenReader} />\r\n ) : null}\r\n <MarkdownBlock\r\n content={part.text}\r\n terminalWidth={mdWidth}\r\n isStreaming={isStreaming}\r\n trimTrailingMargin={trimTrailingSpacing && i === contentParts.length - 1}\r\n />\r\n </React.Fragment>\r\n );\r\n })}\r\n </Box>\r\n )}\r\n </Box>\r\n ) : null}\r\n\r\n {/* Every invocation gets its own row. Task subagent tools stay display-only and nest below it. */}\r\n {topLevelInvocations.map((invocation, index) => {\r\n const marginTop =\r\n index === 0\r\n ? displayContent || (showThinking && reasoningContent)\r\n ? toolBlockGap\r\n : 0\r\n : toolRowGap;\r\n const tc = invocation.call;\r\n const result = invocation.result;\r\n const mutation = invocation.mutation;\r\n const previousMutation = topLevelInvocations[index - 1]?.mutation;\r\n let mutationGroup:\r\n | {\r\n summaries: FileMutationDisplaySummary[];\r\n fileCount: number;\r\n addedLines: number;\r\n removedLines: number;\r\n createdOnly: boolean;\r\n }\r\n | undefined;\r\n if (mutation && !previousMutation) {\r\n const summaries: FileMutationDisplaySummary[] = [];\r\n for (let groupIndex = index; groupIndex < topLevelInvocations.length; groupIndex++) {\r\n const summary = topLevelInvocations[groupIndex].mutation;\r\n if (!summary) break;\r\n summaries.push(summary);\r\n }\r\n mutationGroup = {\r\n summaries,\r\n fileCount: summaries.some((summary) => (summary.fileCount ?? 1) > 1)\r\n ? summaries.reduce((total, summary) => total + (summary.fileCount ?? 1), 0)\r\n : new Set(summaries.map((summary) => summary.filePath)).size,\r\n addedLines: summaries.reduce((total, summary) => total + summary.addedLines, 0),\r\n removedLines: summaries.reduce((total, summary) => total + summary.removedLines, 0),\r\n createdOnly: summaries.every((summary) => summary.kind === 'create'),\r\n };\r\n }\r\n const isPending = pendingPermission?.toolCall.id === tc.id;\r\n const managedAgentTrace = managedAgentTraces?.get(tc.id);\r\n return (\r\n <Box\r\n key={tc.id || `tool-${index}`}\r\n flexDirection=\"column\"\r\n marginTop={mutation && previousMutation ? 0 : marginTop}\r\n >\r\n {mutationGroup ? (\r\n <MutationGroupRow\r\n createdOnly={mutationGroup.createdOnly}\r\n fileCount={mutationGroup.fileCount}\r\n addedLines={mutationGroup.addedLines}\r\n removedLines={mutationGroup.removedLines}\r\n grid={mutationGrid}\r\n screenReader={screenReader}\r\n />\r\n ) : null}\r\n {managedAgentTrace ? (\r\n <ManagedAgentActivityBlock\r\n trace={managedAgentTrace}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n terminalWidth={terminalWidth}\r\n />\r\n ) : (\r\n <ToolCallBlock\r\n toolId={tc.id}\r\n name={tc.name}\r\n args={tc.arguments}\r\n result={result}\r\n isExpanded={shouldExpandTool({\r\n mode: transcriptMode,\r\n toolId: tc.id,\r\n automaticToolId: selectedAutomaticToolId,\r\n defaultExpanded: shouldDefaultExpandTool(tc.name, result),\r\n expansionOverrides: toolExpansionOverrides,\r\n screenReader,\r\n })}\r\n isPending={isPending}\r\n nestedActivityCount={countNestedToolInvocations(childrenByParent, tc.id)}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n showAllToolOutput={showAllToolOutput || showAllToolOutputIds.has(tc.id)}\r\n summaryVariant={mutation ? 'file-child' : 'default'}\r\n terminalWidth={terminalWidth}\r\n labelWidth={labelWidth}\r\n />\r\n )}\r\n {!managedAgentTrace && childrenByParent.has(tc.id) ? (\r\n <NestedToolRows\r\n childrenByParent={childrenByParent}\r\n parentTraceId={tc.id}\r\n depth={1}\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={selectedAutomaticToolId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n showAllToolOutput={showAllToolOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n terminalWidth={terminalWidth}\r\n toolRowGap={toolRowGap}\r\n />\r\n ) : null}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n );\r\n}\r\n\r\nfunction managedAgentTraceEqual(\r\n left: ManagedAgentTrace | undefined,\r\n right: ManagedAgentTrace | undefined,\r\n): boolean {\r\n if (left === right) return true;\r\n if (!left || !right) return false;\r\n if (\r\n left.agentId !== right.agentId ||\r\n left.parentToolCallId !== right.parentToolCallId ||\r\n left.profile !== right.profile ||\r\n left.purpose !== right.purpose ||\r\n left.status !== right.status ||\r\n left.startedAt !== right.startedAt ||\r\n left.finishedAt !== right.finishedAt ||\r\n left.toolUses.length !== right.toolUses.length\r\n ) {\r\n return false;\r\n }\r\n return left.toolUses.every((tool, index) => {\r\n const candidate = right.toolUses[index];\r\n return (\r\n candidate !== undefined &&\r\n tool.id === candidate.id &&\r\n tool.call === candidate.call &&\r\n tool.result === candidate.result &&\r\n tool.status === candidate.status &&\r\n tool.startedAt === candidate.startedAt &&\r\n tool.finishedAt === candidate.finishedAt\r\n );\r\n });\r\n}\r\n\r\nexport function managedAgentTracesEqualForMessage(\r\n message: Message,\r\n left: ReadonlyMap<string, ManagedAgentTrace> | undefined,\r\n right: ReadonlyMap<string, ManagedAgentTrace> | undefined,\r\n): boolean {\r\n if (left === right) return true;\r\n for (const call of message.toolCalls ?? []) {\r\n if (call.name !== 'AgentSpawn') continue;\r\n if (!managedAgentTraceEqual(left?.get(call.id), right?.get(call.id))) return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * Memoized agent message with a custom comparator.\r\n *\r\n * Scalar props are compared first (fast path). Message arrays use reference\r\n * equality because every streaming append/result update replaces its array.\r\n *\r\n */\r\nexport const AgentMessage = React.memo(AgentMessageInner, (prev, next) => {\r\n // Fast path: same references for the most common props.\r\n if (\r\n prev.isStreaming === next.isStreaming &&\r\n prev.expandedToolCallId === next.expandedToolCallId &&\r\n prev.transcriptMode === next.transcriptMode &&\r\n prev.automaticToolCallId === next.automaticToolCallId &&\r\n prev.toolExpansionOverrides === next.toolExpansionOverrides &&\r\n prev.pendingPermission?.toolCall?.id === next.pendingPermission?.toolCall?.id &&\r\n prev.retryPhase === next.retryPhase &&\r\n prev.retryAttempt === next.retryAttempt &&\r\n prev.retryMax === next.retryMax &&\r\n prev.retryCountdownMs === next.retryCountdownMs &&\r\n prev.hideStreamingSpinner === next.hideStreamingSpinner &&\r\n prev.showAllToolOutput === next.showAllToolOutput &&\r\n prev.showAllToolOutputIds === next.showAllToolOutputIds &&\r\n prev.showThinking === next.showThinking &&\r\n prev.trimTrailingSpacing === next.trimTrailingSpacing &&\r\n prev.reducedMotion === next.reducedMotion &&\r\n prev.screenReader === next.screenReader &&\r\n prev.terminalWidth === next.terminalWidth\r\n ) {\r\n // Check message identity.\r\n const pm = prev.message;\r\n const nm = next.message;\r\n if (\r\n pm.id === nm.id &&\r\n pm.content === nm.content &&\r\n pm.reasoningContent === nm.reasoningContent &&\r\n pm.localCommand === nm.localCommand &&\r\n pm.toolCalls === nm.toolCalls &&\r\n pm.toolResults === nm.toolResults &&\r\n pm.nestedToolInvocations === nm.nestedToolInvocations &&\r\n managedAgentTracesEqualForMessage(nm, prev.managedAgentTraces, next.managedAgentTraces)\r\n ) {\r\n return true; // skip re-render\r\n }\r\n }\r\n return false;\r\n});\r\n","import { Text, Box } from 'ink';\r\nimport { useState, useEffect, useMemo, useRef } from 'react';\r\nimport { useGradientSpinner } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\nexport const SPINNER_TIPS = [\r\n 'Press Ctrl+/ for keyboard shortcuts',\r\n 'Use @filename to include file contents',\r\n 'Start with ! to run a shell command',\r\n 'Press Esc or Ctrl+C to cancel the current operation',\r\n 'Type /help for available commands',\r\n 'Alt+M to cycle permission modes',\r\n 'Alt+P to open the model picker',\r\n 'Alt+V to attach a clipboard image',\r\n 'Use /compact when context is getting long',\r\n 'Use /theme to choose and save a color theme',\r\n 'Ctrl+T to toggle the task list',\r\n 'Sessions auto-save — use -c to resume',\r\n 'Ctrl+J or Shift+Enter for multiline input',\r\n 'Type /task <subject> to add a task',\r\n 'The model can use multiple tools per turn',\r\n 'Use /new to start fresh; /resume returns to saved conversations',\r\n 'Use PageUp/PageDown to review earlier messages',\r\n 'Tab to accept suggestions in the input bar',\r\n 'Up/Down arrows for input history',\r\n 'Ctrl+L to redraw the screen',\r\n];\r\n\r\ninterface SpinnerProps {\r\n active?: boolean;\r\n style?: 'braille' | 'dots';\r\n color?: string;\r\n reducedMotion?: boolean;\r\n showTips?: boolean;\r\n /** Custom tip strings to override the defaults. */\r\n tips?: string[];\r\n /** If true, only show custom tips (no defaults mixed in). */\r\n excludeDefaultTips?: boolean;\r\n}\r\n\r\n/**\r\n * Claude Code-style spinner with rotating tips.\r\n *\r\n * During long operations, the spinner cycles through a list of tips every 4\r\n * seconds, shown inline next to the spinner frame. The tip list is\r\n * configurable via the `tips` and `excludeDefaultTips` props.\r\n */\r\nexport function Spinner({\r\n active = true,\r\n style = 'dots',\r\n color,\r\n reducedMotion = false,\r\n showTips = false,\r\n tips,\r\n excludeDefaultTips = false,\r\n}: SpinnerProps) {\r\n const theme = useTheme();\r\n const { frame, color: gradientColor } = useGradientSpinner(active, style, reducedMotion);\r\n const spinnerColor = color || gradientColor;\r\n const [tipIndex, setTipIndex] = useState(0);\r\n const tipTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n\r\n const effectiveTips = useMemo(() => {\r\n if (tips && excludeDefaultTips) return tips;\r\n if (tips) return [...SPINNER_TIPS, ...tips];\r\n return SPINNER_TIPS;\r\n }, [tips, excludeDefaultTips]);\r\n\r\n useEffect(() => {\r\n if (!active || !showTips) {\r\n if (tipTimerRef.current) {\r\n clearInterval(tipTimerRef.current);\r\n tipTimerRef.current = null;\r\n }\r\n return;\r\n }\r\n // Reset tip index when starting.\r\n setTipIndex(0);\r\n tipTimerRef.current = setInterval(() => {\r\n setTipIndex((i) => (i + 1) % effectiveTips.length);\r\n }, 4000);\r\n return () => {\r\n if (tipTimerRef.current) {\r\n clearInterval(tipTimerRef.current);\r\n tipTimerRef.current = null;\r\n }\r\n };\r\n }, [active, showTips, effectiveTips.length]);\r\n\r\n const tip = effectiveTips[tipIndex];\r\n\r\n return (\r\n <Box>\r\n <Text color={spinnerColor}>{frame} </Text>\r\n {showTips && active && tip ? (\r\n <Text color={theme.subtle} dimColor>\r\n {tip}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { useState, useEffect, useRef } from 'react';\r\nimport { createRenderDebugLogger } from '../../debug-log.js';\r\nimport { isTranscriptScrollActive } from '../scroll-activity.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport { shimmerColor } from '../shimmer.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\nconst animLog = createRenderDebugLogger('tui:animation');\r\n\r\nconst BRAILLE_FRAMES = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];\r\n\r\n/**\r\n * Ten frames at the 100ms clock: one revolution per second, and one shimmer\r\n * breath per revolution.\r\n */\r\nconst DOT_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\r\n\r\n/**\r\n * The spinner.\r\n *\r\n * Colour comes from the active theme's `shimmerPair` and eases across it over\r\n * a full revolution. It used to be a hardcoded `cyan`/`#5cf` pair swapped every\r\n * frame, which put an off-palette 5Hz strobe in front of the user on every turn\r\n * regardless of theme.\r\n *\r\n * When reducedMotion is true, returns a static frame in a static colour.\r\n */\r\nexport function useGradientSpinner(\r\n active: boolean,\r\n style: 'braille' | 'dots' = 'dots',\r\n reducedMotion = false,\r\n): { frame: string; color: string } {\r\n const theme = useTheme();\r\n const frames = style === 'braille' ? BRAILLE_FRAMES : DOT_FRAMES;\r\n const tick = useUiClock('fast', active && !reducedMotion);\r\n const animating = active && !reducedMotion;\r\n\r\n return {\r\n frame: frames[animating ? tick % frames.length : 0],\r\n color: animating ? shimmerColor(theme.shimmerPair, tick) : theme.shimmerPair[0],\r\n };\r\n}\r\n\r\nexport function useStaggeredReveal(\r\n count: number,\r\n active: boolean,\r\n intervalMs = 120,\r\n reducedMotion = false,\r\n): number {\r\n const [visibleCount, setVisibleCount] = useState(reducedMotion ? count : 0);\r\n\r\n useEffect(() => {\r\n if (!active || reducedMotion) {\r\n setVisibleCount(count);\r\n return;\r\n }\r\n setVisibleCount(0);\r\n let current = 0;\r\n const interval = setInterval(() => {\r\n if (isTranscriptScrollActive()) return;\r\n current++;\r\n setVisibleCount(Math.min(count, current));\r\n if (current >= count) {\r\n clearInterval(interval);\r\n }\r\n }, intervalMs);\r\n return () => clearInterval(interval);\r\n }, [active, count, intervalMs, reducedMotion]);\r\n\r\n return visibleCount;\r\n}\r\n\r\nexport function useTimedFlash(triggerValue: unknown, durationMs = 220, disabled = false): boolean {\r\n const [on, setOn] = useState(false);\r\n const firstRun = useRef(true);\r\n\r\n useEffect(() => {\r\n if (disabled) {\r\n setOn(false);\r\n firstRun.current = false;\r\n return;\r\n }\r\n if (firstRun.current) {\r\n firstRun.current = false;\r\n return;\r\n }\r\n setOn(true);\r\n const timer = setTimeout(() => setOn(false), durationMs);\r\n return () => clearTimeout(timer);\r\n }, [triggerValue, durationMs, disabled]);\r\n\r\n return on;\r\n}\r\n\r\nexport function usePulse(active: boolean, interval = 500): boolean {\r\n const [on, setOn] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!active) {\r\n setOn(false);\r\n return;\r\n }\r\n animLog.event('pulse:start', { interval });\r\n const timer = setInterval(() => {\r\n if (isTranscriptScrollActive()) return;\r\n setOn((o) => !o);\r\n }, interval);\r\n return () => {\r\n clearInterval(timer);\r\n animLog.event('pulse:stop', { interval });\r\n };\r\n }, [active, interval]);\r\n\r\n return on;\r\n}\r\n\r\n/** Time-based pending progress; callers must render 100% from a real completion signal. */\r\nexport function useAnimatedProgress(\r\n active: boolean,\r\n durationMs = 2_400,\r\n reducedMotion = false,\r\n maximum = 95,\r\n): number {\r\n const [progress, setProgress] = useState(0);\r\n const safeMaximum = Math.max(0, Math.min(99, maximum));\r\n const startedAtRef = useRef(Date.now());\r\n const tick = useUiClock('fast', active && !reducedMotion && progress < safeMaximum);\r\n\r\n useEffect(() => {\r\n startedAtRef.current = Date.now();\r\n setProgress(0);\r\n }, [active, durationMs, reducedMotion, safeMaximum]);\r\n\r\n useEffect(() => {\r\n if (!active || reducedMotion) return;\r\n const safeDuration = Math.max(1, durationMs);\r\n setProgress(\r\n Math.min(safeMaximum, Math.floor(((Date.now() - startedAtRef.current) / safeDuration) * 100)),\r\n );\r\n }, [active, durationMs, reducedMotion, safeMaximum, tick]);\r\n\r\n return progress;\r\n}\r\n","export const TRANSCRIPT_SCROLL_IDLE_MS = 150;\r\n\r\nlet activeUntil = 0;\r\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\nexport function markTranscriptScrollActivity(now = Date.now()): void {\r\n activeUntil = Math.max(activeUntil, now + TRANSCRIPT_SCROLL_IDLE_MS);\r\n if (idleTimer !== null) clearTimeout(idleTimer);\r\n idleTimer = setTimeout(() => {\r\n idleTimer = null;\r\n if (Date.now() >= activeUntil) activeUntil = 0;\r\n }, TRANSCRIPT_SCROLL_IDLE_MS);\r\n}\r\n\r\nexport function isTranscriptScrollActive(now = Date.now()): boolean {\r\n return activeUntil > now;\r\n}\r\n","import { useCallback, useSyncExternalStore } from 'react';\r\nimport { isTranscriptScrollActive } from './scroll-activity.js';\r\n\r\nexport type UiClockRate = 'cinematic' | 'fast' | 'slow';\r\n\r\ninterface ClockState {\r\n revision: number;\r\n timer: ReturnType<typeof setInterval> | null;\r\n listeners: Set<() => void>;\r\n}\r\n\r\nconst CLOCK_INTERVAL_MS: Record<UiClockRate, number> = {\r\n cinematic: 50,\r\n fast: 100,\r\n slow: 1000,\r\n};\r\n\r\nconst clocks: Record<UiClockRate, ClockState> = {\r\n cinematic: { revision: 0, timer: null, listeners: new Set() },\r\n fast: { revision: 0, timer: null, listeners: new Set() },\r\n slow: { revision: 0, timer: null, listeners: new Set() },\r\n};\r\n\r\nfunction startClock(rate: UiClockRate): void {\r\n const clock = clocks[rate];\r\n if (clock.timer !== null) return;\r\n clock.timer = setInterval(() => {\r\n if (rate !== 'slow' && isTranscriptScrollActive()) return;\r\n clock.revision++;\r\n for (const listener of clock.listeners) listener();\r\n }, CLOCK_INTERVAL_MS[rate]);\r\n}\r\n\r\nexport function subscribeUiClock(rate: UiClockRate, listener: () => void): () => void {\r\n const clock = clocks[rate];\r\n clock.listeners.add(listener);\r\n startClock(rate);\r\n return () => {\r\n clock.listeners.delete(listener);\r\n if (clock.listeners.size === 0 && clock.timer !== null) {\r\n clearInterval(clock.timer);\r\n clock.timer = null;\r\n }\r\n };\r\n}\r\n\r\nfunction subscribeNoop(): () => void {\r\n return () => {};\r\n}\r\n\r\nexport function useUiClock(rate: UiClockRate, enabled = true): number {\r\n const subscribe = useCallback(\r\n (listener: () => void) => (enabled ? subscribeUiClock(rate, listener) : subscribeNoop()),\r\n [enabled, rate],\r\n );\r\n const getSnapshot = useCallback(() => clocks[rate].revision, [rate]);\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","/**\r\n * Spinner shimmer.\r\n *\r\n * The spinner is the most-watched pixel in the TUI, so it gets the most care.\r\n * Two rules:\r\n *\r\n * - It uses the theme's `shimmerPair`, never a literal colour. The gradient\r\n * used to be hardcoded `['cyan', '#5cf']`, which put a bright blue strobe on\r\n * a warm editorial palette in every theme.\r\n * - It eases between the pair over a full revolution instead of swapping on\r\n * every frame. Alternating two colours at the frame rate is a 5Hz strobe;\r\n * easing across {@link SHIMMER_STEPS} frames reads as a breath.\r\n */\r\n\r\n/** Frames in one shimmer cycle. Matches the spinner's revolution. */\r\nexport const SHIMMER_STEPS = 10;\r\n\r\ninterface Rgb {\r\n r: number;\r\n g: number;\r\n b: number;\r\n}\r\n\r\n/** Last-resort colour when a theme supplies no usable shimmer pair. */\r\nconst FALLBACK_SHIMMER = '#AFC19D';\r\n\r\n/**\r\n * Parse a hex colour, tolerating anything a custom theme might supply.\r\n *\r\n * The parameter is `unknown` on purpose: theme tokens are merged from\r\n * unvalidated JSON, so the declared `string` was a claim rather than a fact.\r\n */\r\nfunction parseHex(color: unknown): Rgb | null {\r\n if (typeof color !== 'string') return null;\r\n const match = /^#?([0-9a-f]{6})$/i.exec(color.trim());\r\n if (!match) return null;\r\n const value = Number.parseInt(match[1], 16);\r\n return { r: (value >> 16) & 0xff, g: (value >> 8) & 0xff, b: value & 0xff };\r\n}\r\n\r\nfunction toHex({ r, g, b }: Rgb): string {\r\n const channel = (value: number) =>\r\n Math.max(0, Math.min(255, Math.round(value)))\r\n .toString(16)\r\n .padStart(2, '0');\r\n return `#${channel(r)}${channel(g)}${channel(b)}`;\r\n}\r\n\r\n/**\r\n * Position within the breath for a frame index: 0 at the start, 1 at the\r\n * midpoint, back to 0 — a raised cosine, so the turn at each end is gradual\r\n * rather than a hard bounce.\r\n */\r\nexport function shimmerPhase(tick: number, steps = SHIMMER_STEPS): number {\r\n const period = Math.max(1, Math.floor(steps));\r\n const position = ((Math.floor(tick) % period) + period) % period;\r\n return (1 - Math.cos((2 * Math.PI * position) / period)) / 2;\r\n}\r\n\r\n/**\r\n * Blend a theme's shimmer pair at `tick`.\r\n *\r\n * Falls back to the first colour when either end is not a plain hex value —\r\n * custom themes may use Ink's named or `ansi256` colours, which cannot be\r\n * interpolated.\r\n */\r\nexport function shimmerColor(pair: readonly [string, string], tick: number): string {\r\n // `loadCustomTheme` merges arbitrary `.book/themes/*.json` into the token set\r\n // without validating it, so this pair can be short, empty, or not an array at\r\n // all. It reaches here on the spinner's first frame, where throwing takes the\r\n // whole TUI down.\r\n const [from, to] = Array.isArray(pair) ? (pair as readonly unknown[]) : [];\r\n const start = parseHex(from);\r\n const end = parseHex(to);\r\n if (!start) return typeof from === 'string' && from ? from : FALLBACK_SHIMMER;\r\n if (!end) return from as string;\r\n const t = shimmerPhase(tick);\r\n return toHex({\r\n r: start.r + (end.r - start.r) * t,\r\n g: start.g + (end.g - start.g) * t,\r\n b: start.b + (end.b - start.b) * t,\r\n });\r\n}\r\n","import { Text, Box, type DOMElement } from 'ink';\r\nimport React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\r\nimport { Spinner } from './Spinner.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { DiffBlock } from './Diff.js';\r\nimport { MarkdownBlock } from './MarkdownBlock.js';\r\nimport { highlightCode } from './syntax-highlight.js';\r\nimport { prepareToolOutputDisplay } from './tool-output.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport {\r\n getFileMutationDisplaySummary,\r\n isRenderableFileMutationDiff,\r\n} from '../file-mutation-display.js';\r\nimport {\r\n composeToolRow,\r\n deriveToolPresentation,\r\n type ToolPresentationStatus,\r\n} from '../tool-presentation.js';\r\nimport {\r\n CONTENT_COLUMN,\r\n GUTTER_WIDTH,\r\n indentedGrid,\r\n nestedGrid,\r\n transcriptGrid,\r\n withLabelColumn,\r\n} from '../layout.js';\r\nimport { formatElapsedDuration } from './SubagentRow.js';\r\nimport { useToolRowInteractionRegistry } from './tool-row-interactions.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport type { ToolResult } from '../../types/tools.js';\r\n\r\ninterface ToolCallBlockProps {\r\n toolId?: string;\r\n name: string;\r\n args: Record<string, unknown>;\r\n result?: ToolResult;\r\n isExpanded: boolean;\r\n isPending?: boolean;\r\n nestedActivityCount?: number;\r\n agentColor?: string;\r\n reducedMotion?: boolean;\r\n /** When true, renders flat, complete text without decorations. */\r\n screenReader?: boolean;\r\n /** When true, expanded tool results show the large rendering ceiling. */\r\n showAllToolOutput?: boolean;\r\n /** Render a file path as a child row under an aggregate mutation heading. */\r\n summaryVariant?: 'default' | 'file-child';\r\n /** Available terminal width, including this block's outer indentation. */\r\n terminalWidth?: number;\r\n /**\r\n * Width of the label column, measured across the sibling rows of this turn.\r\n * Omitted, the row uses the grid's default column.\r\n */\r\n labelWidth?: number;\r\n}\r\n\r\n/** Compatibility export used by existing consumers and tests. */\r\nfunction getResultLabel(result?: ToolResult): { label: string; color: string } {\r\n if (!result) return { label: '', color: 'gray' };\r\n if (result.status === 'blocked') return { label: '[SKIPPED]', color: 'yellow' };\r\n if (result.status !== 'success') return { label: '[ERR]', color: 'red' };\r\n return { label: '[OK]', color: 'green' };\r\n}\r\n\r\nfunction isDiffOutput(toolName: string, result: ToolResult | undefined): boolean {\r\n return isRenderableFileMutationDiff(toolName, result);\r\n}\r\n\r\nfunction toolLabel(name: string): string {\r\n const labels: Record<string, string> = {\r\n Read: 'Read file',\r\n ApplyPatch: 'Apply patch',\r\n Write: 'Write file',\r\n Edit: 'Edit file',\r\n MultiEdit: 'Edit file',\r\n NotebookEdit: 'Edit notebook',\r\n Bash: 'Run command',\r\n BashOutput: 'Read shell output',\r\n KillShell: 'Kill shell',\r\n Glob: 'Find files',\r\n Grep: 'Search files',\r\n WebFetch: 'Fetch URL',\r\n WebSearch: 'Search web',\r\n Task: 'Run subagent',\r\n InvokeSkill: 'Use skill',\r\n };\r\n return labels[name] ?? name;\r\n}\r\n\r\nfunction statusColor(status: ToolPresentationStatus, theme: ReturnType<typeof useTheme>): string {\r\n if (status === 'success') return theme.success;\r\n if (status === 'failure') return theme.error;\r\n if (status === 'skipped' || status === 'pending') return theme.warning;\r\n return theme.brand;\r\n}\r\n\r\nfunction statusSymbol(status: ToolPresentationStatus): string {\r\n if (status === 'success') return '✓';\r\n if (status === 'failure') return '×';\r\n if (status === 'skipped') return '–';\r\n if (status === 'pending') return '?';\r\n return '◌';\r\n}\r\n\r\nfunction useRunningElapsed(isRunning: boolean): number {\r\n const startedAtRef = useRef(Date.now());\r\n // The 1s clock keeps a running row to one re-render per second; the fast\r\n // clock forced 10 renders + full Yoga layouts per second for every running\r\n // tool. Second granularity in the label (formatElapsedDuration) matches.\r\n const tick = useUiClock('slow', isRunning);\r\n\r\n useEffect(() => {\r\n startedAtRef.current = Date.now();\r\n }, [isRunning]);\r\n\r\n void tick;\r\n return isRunning ? Date.now() - startedAtRef.current : 0;\r\n}\r\n\r\nfunction ScreenReaderTool({\r\n presentation,\r\n result,\r\n}: {\r\n presentation: ReturnType<typeof deriveToolPresentation>;\r\n result?: ToolResult;\r\n}) {\r\n const status =\r\n presentation.status === 'running'\r\n ? '[Running]'\r\n : presentation.status === 'pending'\r\n ? '[needs approval]'\r\n : presentation.status === 'success'\r\n ? '[OK]'\r\n : presentation.status === 'skipped'\r\n ? '[SKIPPED]'\r\n : '[ERR]';\r\n const accessibleSummary =\r\n presentation.previewType === 'diff' || presentation.canonicalName.startsWith('mcp__')\r\n ? presentation.summary\r\n : `${toolLabel(presentation.canonicalName)}${presentation.target ? ` ${presentation.target}` : ''}${\r\n presentation.metadata.length > 0 ? ` · ${presentation.metadata.join(' ')}` : ''\r\n }`;\r\n return (\r\n <Box flexDirection=\"column\">\r\n <Text>\r\n {status} {accessibleSummary}\r\n </Text>\r\n {result?.content ? <Text>{result.content}</Text> : null}\r\n {result?.structuredError && result.status !== 'blocked' ? (\r\n <Text>Error: {result.structuredError.message}</Text>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Render a target so the part that identifies it carries the weight.\r\n *\r\n * Two ramps at once. Across the row: a path's directory is context and its\r\n * basename is the thing being acted on, and in a column of twenty rows the\r\n * directories are largely identical. Against the rest of the turn: a tool row\r\n * is machinery, and it sits a step below prose so the answer is the brightest\r\n * thing on screen rather than one more row of the same weight.\r\n */\r\nexport function TargetText({\r\n target,\r\n failed,\r\n path = false,\r\n}: {\r\n target: string;\r\n failed: boolean;\r\n /** Split the directory prefix off. Only meaningful for filesystem paths. */\r\n path?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n if (failed) return <Text color={theme.error}>{target}</Text>;\r\n const split = path ? target.lastIndexOf('/') : -1;\r\n // A trailing slash leaves no basename, which would paint the whole target in\r\n // the dim prefix colour and make the row's only content the faintest thing\r\n // on screen.\r\n if (split < 0 || split === target.length - 1) {\r\n return <Text color={theme.subtle}>{target}</Text>;\r\n }\r\n return (\r\n <Text>\r\n <Text color={theme.inactive} dimColor>\r\n {target.slice(0, split + 1)}\r\n </Text>\r\n <Text color={theme.subtle}>{target.slice(split + 1)}</Text>\r\n </Text>\r\n );\r\n}\r\n\r\n/** `+12` / `-3`: churn counts, which read faster in the diff colours. */\r\nconst CHURN_TOKEN = /^([+-])(\\d+)$/;\r\n\r\n/**\r\n * Render right-aligned metadata, colouring churn counts.\r\n *\r\n * Everything else stays recessive — the figures a reader scans for are the\r\n * lines added and removed, and an error.\r\n */\r\nexport function MetaText({ meta, failed }: { meta: string; failed: boolean }) {\r\n const theme = useTheme();\r\n if (failed) return <Text color={theme.error}>{meta}</Text>;\r\n if (!CHURN_TOKEN.test(meta.split(' ')[0] ?? '')) {\r\n return (\r\n <Text color={theme.subtle} dimColor>\r\n {meta}\r\n </Text>\r\n );\r\n }\r\n return (\r\n <Text>\r\n {meta.split(' ').map((token, index) => {\r\n const churn = CHURN_TOKEN.exec(token);\r\n const color = !churn ? theme.subtle : churn[1] === '+' ? theme.success : theme.error;\r\n return (\r\n <Text key={index} color={color} dimColor={!churn}>\r\n {index > 0 ? ' ' : ''}\r\n {token}\r\n </Text>\r\n );\r\n })}\r\n </Text>\r\n );\r\n}\r\n\r\nfunction ToolCallBlockInner({\r\n toolId,\r\n name,\r\n args,\r\n result,\r\n isExpanded,\r\n isPending = false,\r\n nestedActivityCount = 0,\r\n agentColor,\r\n reducedMotion = false,\r\n screenReader = false,\r\n showAllToolOutput = false,\r\n summaryVariant = 'default',\r\n terminalWidth = 80,\r\n labelWidth,\r\n}: ToolCallBlockProps) {\r\n const theme = useTheme();\r\n const registry = useToolRowInteractionRegistry();\r\n const summaryRef = useRef<DOMElement>(null);\r\n const grid = useMemo(() => {\r\n const base = transcriptGrid(terminalWidth);\r\n return labelWidth === undefined ? base : withLabelColumn(base, labelWidth);\r\n }, [labelWidth, terminalWidth]);\r\n // The row nests one gutter under the prose it belongs to, so its own grid is\r\n // the indented one; `grid` stays the message-level measure the label column\r\n // was negotiated against.\r\n const rowGrid = useMemo(() => indentedGrid(grid), [grid]);\r\n const blockWidth = rowGrid.content;\r\n const presentation = useMemo(\r\n () => deriveToolPresentation(name, args, result, { isPending, nestedActivityCount }),\r\n [args, isPending, name, nestedActivityCount, result],\r\n );\r\n const isRunning = presentation.status === 'running';\r\n // Under reducedMotion the row must not tick at all: the spinner is frozen,\r\n // so a changing elapsed label would be the only remaining animation.\r\n const runningElapsedMs = useRunningElapsed(isRunning && !reducedMotion);\r\n const elapsed =\r\n isRunning && !reducedMotion\r\n ? formatElapsedDuration(Math.floor(runningElapsedMs / 1000))\r\n : undefined;\r\n const inlineError = result?.status !== 'blocked' ? result?.structuredError?.message : undefined;\r\n const mutationSummary = useMemo(\r\n () => getFileMutationDisplaySummary(name, args, result),\r\n [args, name, result],\r\n );\r\n const isFileChild = summaryVariant === 'file-child';\r\n // A child row sits under an aggregate heading that already named the verb, so\r\n // it drops the label column and renders on the nested grid.\r\n const row = useMemo(() => {\r\n if (isFileChild && mutationSummary) {\r\n return composeToolRow(\r\n {\r\n title: '',\r\n target: mutationSummary.filePath,\r\n metadata: [`+${mutationSummary.addedLines}`, `-${mutationSummary.removedLines}`],\r\n },\r\n nestedGrid(rowGrid),\r\n { error: inlineError },\r\n );\r\n }\r\n return composeToolRow(presentation, isFileChild ? nestedGrid(rowGrid) : rowGrid, {\r\n elapsed,\r\n error: inlineError,\r\n });\r\n }, [elapsed, rowGrid, inlineError, isFileChild, mutationSummary, presentation]);\r\n\r\n useLayoutEffect(() => {\r\n if (!registry || !toolId) return;\r\n return registry.register({\r\n id: toolId,\r\n element: summaryRef,\r\n expandable: presentation.hasHiddenContent,\r\n expanded: isExpanded,\r\n });\r\n }, [isExpanded, presentation.hasHiddenContent, registry, toolId]);\r\n\r\n if (screenReader) {\r\n return (\r\n <Box flexDirection=\"column\" marginLeft={CONTENT_COLUMN} width={blockWidth}>\r\n <ScreenReaderTool presentation={presentation} result={result} />\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n marginLeft={isFileChild ? CONTENT_COLUMN + GUTTER_WIDTH : CONTENT_COLUMN}\r\n >\r\n <Box ref={summaryRef} height={1}>\r\n {/* The gutter carries status; content always begins on the next column. */}\r\n {isFileChild ? (\r\n <Text color={theme.toolRail}>└ </Text>\r\n ) : isRunning ? (\r\n <>\r\n {/* Spinner emits its own trailing space, so the gutter stays two\r\n columns wide and the verb does not shift when the tool ends. */}\r\n <Spinner\r\n active\r\n style=\"dots\"\r\n color={agentColor ?? theme.assistantAccent}\r\n reducedMotion={reducedMotion}\r\n />\r\n </>\r\n ) : (\r\n <Text color={statusColor(presentation.status, theme)}>\r\n {statusSymbol(presentation.status)}{' '}\r\n </Text>\r\n )}\r\n {row.label ? (\r\n <Text color={theme.inactive} dimColor>\r\n {row.label}{' '}\r\n </Text>\r\n ) : null}\r\n <TargetText\r\n target={row.target}\r\n failed={presentation.status === 'failure'}\r\n path={Boolean(presentation.filePath) || isFileChild}\r\n />\r\n <Text>{row.gap}</Text>\r\n <MetaText meta={row.meta} failed={Boolean(inlineError)} />\r\n </Box>\r\n {isExpanded && result && isDiffOutput(name, result) ? (\r\n <DiffBlock\r\n output={result.content}\r\n filePath={presentation.filePath}\r\n terminalWidth={blockWidth}\r\n />\r\n ) : isExpanded && result?.content ? (\r\n <OutputBlock\r\n output={result.content}\r\n success={result.status === 'success'}\r\n theme={theme}\r\n showAllToolOutput={showAllToolOutput}\r\n toolName={presentation.canonicalName}\r\n terminalWidth={blockWidth}\r\n />\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n\r\nexport const ToolCallBlock = React.memo(ToolCallBlockInner);\r\n\r\nfunction looksLikeMarkdown(output: string, toolName: string): boolean {\r\n if (toolName === 'WebFetch' || toolName === 'WebSearch') return true;\r\n return /(^|\\n)\\s{0,3}(#{1,6}\\s|[-*+]\\s|\\d+\\.\\s|>\\s|```|\\|.+\\|)/.test(output);\r\n}\r\n\r\nfunction inferLanguage(output: string, toolName: string): string | undefined {\r\n if (toolName !== 'Read') return undefined;\r\n const firstLine = output.split('\\n', 1)[0] ?? '';\r\n const match = firstLine.match(/\\.(ts|tsx|js|jsx|json|py|rs|go|sh|bash|yml|yaml|css|html|sql)\\b/i);\r\n return match?.[1]?.toLowerCase();\r\n}\r\n\r\nfunction OutputBlock({\r\n output,\r\n success,\r\n theme,\r\n showAllToolOutput,\r\n toolName,\r\n terminalWidth,\r\n}: {\r\n output: string;\r\n success: boolean;\r\n theme: ReturnType<typeof useTheme>;\r\n showAllToolOutput: boolean;\r\n toolName: string;\r\n terminalWidth: number;\r\n}) {\r\n // The rail's border plus its padding occupy the nested gutter.\r\n const contentWidth = Math.max(8, Math.floor(terminalWidth) - CONTENT_COLUMN - 2);\r\n const footerWidth = contentWidth;\r\n const display = useMemo(\r\n () =>\r\n prepareToolOutputDisplay(output, {\r\n maxLines: showAllToolOutput ? 2000 : success ? 6 : 10,\r\n maxLineWidth: contentWidth,\r\n hint: showAllToolOutput ? undefined : 'Ctrl+E shows all',\r\n strategy: showAllToolOutput ? 'head' : success ? 'head-tail' : 'tail',\r\n }),\r\n [contentWidth, output, showAllToolOutput, success],\r\n );\r\n const language = inferLanguage(output, toolName);\r\n const displayText = display.lines.join('\\n');\r\n const highlighted = useMemo(\r\n () => (language ? highlightCode(displayText, language, theme) : undefined),\r\n [displayText, language, theme],\r\n );\r\n // The markdown sniff regex scans the whole output string; memoize it so an\r\n // expanded multi-MB result pays that once per output, not once per render.\r\n const renderAsMarkdown = useMemo(\r\n () => !language && looksLikeMarkdown(output, toolName),\r\n [language, output, toolName],\r\n );\r\n\r\n if (renderAsMarkdown) {\r\n return (\r\n <Box\r\n marginLeft={CONTENT_COLUMN}\r\n flexDirection=\"column\"\r\n borderStyle=\"single\"\r\n borderLeft\r\n borderTop={false}\r\n borderRight={false}\r\n borderBottom={false}\r\n borderLeftColor={theme.toolRail}\r\n paddingLeft={1}\r\n paddingRight={1}\r\n >\r\n <MarkdownBlock content={display.lines.join('\\n')} terminalWidth={contentWidth} />\r\n {display.footer ? (\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(display.footer, footerWidth)}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n marginLeft={CONTENT_COLUMN}\r\n flexDirection=\"column\"\r\n borderStyle=\"single\"\r\n borderLeft\r\n borderTop={false}\r\n borderRight={false}\r\n borderBottom={false}\r\n borderLeftColor={theme.toolRail}\r\n paddingLeft={1}\r\n paddingRight={1}\r\n >\r\n {display.lines.map((line, index) => (\r\n <Box key={index}>\r\n {highlighted ? (\r\n <Text>\r\n {highlighted[index]?.map((segment, segmentIndex) => (\r\n <Text\r\n key={segmentIndex}\r\n color={segment.color}\r\n bold={segment.bold}\r\n italic={segment.italic}\r\n dimColor\r\n >\r\n {segment.text}\r\n </Text>\r\n ))}\r\n </Text>\r\n ) : (\r\n <Text color={theme.text} dimColor>\r\n {line}\r\n </Text>\r\n )}\r\n </Box>\r\n ))}\r\n {display.footer ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(display.footer, footerWidth)}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n\r\nexport { isDiffOutput, getResultLabel, toolLabel };\r\n","import { Text, Box } from 'ink';\r\nimport { Fragment, useMemo } from 'react';\r\nimport { useTheme } from '../theme.js';\r\nimport { displayWidth, hardWrapLine, padDisplay, truncateDisplay } from './word-wrap.js';\r\nimport { highlightCode, type StyledSegment } from './syntax-highlight.js';\r\n\r\ninterface DiffProps {\r\n output: string;\r\n filePath?: string;\r\n /** When true, render a change-focused preview across all hunks. */\r\n collapsed?: boolean;\r\n /** Row budget for the collapsed preview; defaults to the transcript's. */\r\n maxRows?: number;\r\n /** Key hint appended to the omission footer while collapsed. */\r\n expandHint?: string;\r\n terminalWidth?: number;\r\n}\r\n\r\nconst COLLAPSED_ROWS = 80;\r\nconst COLLAPSED_CONTEXT_ROWS = 2;\r\nconst MAX_WORD_TOKENS = 200;\r\nconst MAX_WORD_LINE_LENGTH = 2000;\r\n\r\nexport function isUnifiedDiffLike(output: string): boolean {\r\n const hasHunk = /^@@\\s+-\\d+(?:,\\d+)?\\s+\\+\\d+(?:,\\d+)?\\s+@@/m.test(output);\r\n const hasChangedLine = /^(?:\\+(?!\\+\\+)|-(?!--))/m.test(output);\r\n return hasHunk && hasChangedLine;\r\n}\r\n\r\nexport type DiffLineKind = 'add' | 'del' | 'hunk' | 'ctx' | 'meta';\r\nexport type DiffSpanKind = 'plain' | 'addedWord' | 'removedWord';\r\n\r\nexport interface DiffSpan {\r\n text: string;\r\n kind: DiffSpanKind;\r\n}\r\n\r\nexport interface ParsedDiffLine {\r\n /** Original source row, retained for exact byte accounting and compatibility. */\r\n text: string;\r\n content: string;\r\n marker: '+' | '-' | ' ' | '@' | '\\\\';\r\n kind: DiffLineKind;\r\n oldLineNumber?: number;\r\n newLineNumber?: number;\r\n spans?: DiffSpan[];\r\n}\r\n\r\ninterface HunkPosition {\r\n oldLine: number;\r\n newLine: number;\r\n}\r\n\r\nfunction parseHunkPosition(line: string): HunkPosition | undefined {\r\n const match = /^@@\\s+-(\\d+)(?:,\\d+)?\\s+\\+(\\d+)(?:,\\d+)?\\s+@@/.exec(line);\r\n if (!match) return undefined;\r\n return { oldLine: Number(match[1]), newLine: Number(match[2]) };\r\n}\r\n\r\n/** Parse Claude-style embedded word markers such as `{+new+}` when present. */\r\nfunction parseEmbeddedWordMarkers(content: string): DiffSpan[] | undefined {\r\n const spans: DiffSpan[] = [];\r\n const combined = /\\{(\\+|\\-)(.+?)\\1\\}/gs;\r\n let lastIndex = 0;\r\n let match: RegExpExecArray | null;\r\n\r\n while ((match = combined.exec(content)) !== null) {\r\n const before = content.slice(lastIndex, match.index);\r\n if (before) spans.push({ text: before, kind: 'plain' });\r\n spans.push({\r\n text: match[2],\r\n kind: match[1] === '+' ? 'addedWord' : 'removedWord',\r\n });\r\n lastIndex = combined.lastIndex;\r\n }\r\n\r\n if (spans.length === 0) return undefined;\r\n const after = content.slice(lastIndex);\r\n if (after) spans.push({ text: after, kind: 'plain' });\r\n return spans;\r\n}\r\n\r\nfunction tokenizeForDiff(value: string): string[] {\r\n return value.match(/\\s+|[\\p{L}\\p{N}_]+|[^\\s\\p{L}\\p{N}_]/gu) ?? [];\r\n}\r\n\r\nfunction mergeSpans(spans: DiffSpan[]): DiffSpan[] {\r\n const merged: DiffSpan[] = [];\r\n for (const span of spans) {\r\n const previous = merged[merged.length - 1];\r\n if (previous?.kind === span.kind) previous.text += span.text;\r\n else if (span.text) merged.push({ ...span });\r\n }\r\n return merged;\r\n}\r\n\r\n/** Bounded token LCS for adjacent one-line replacements. */\r\nfunction calculateReplacementSpans(\r\n removed: string,\r\n added: string,\r\n): { removed: DiffSpan[]; added: DiffSpan[] } | undefined {\r\n if (removed.length > MAX_WORD_LINE_LENGTH || added.length > MAX_WORD_LINE_LENGTH)\r\n return undefined;\r\n const oldTokens = tokenizeForDiff(removed);\r\n const newTokens = tokenizeForDiff(added);\r\n if (\r\n oldTokens.length === 0 ||\r\n newTokens.length === 0 ||\r\n oldTokens.length > MAX_WORD_TOKENS ||\r\n newTokens.length > MAX_WORD_TOKENS\r\n ) {\r\n return undefined;\r\n }\r\n\r\n const table = Array.from(\r\n { length: oldTokens.length + 1 },\r\n () => new Uint16Array(newTokens.length + 1),\r\n );\r\n for (let oldIndex = oldTokens.length - 1; oldIndex >= 0; oldIndex--) {\r\n for (let newIndex = newTokens.length - 1; newIndex >= 0; newIndex--) {\r\n table[oldIndex][newIndex] =\r\n oldTokens[oldIndex] === newTokens[newIndex]\r\n ? table[oldIndex + 1][newIndex + 1] + 1\r\n : Math.max(table[oldIndex + 1][newIndex], table[oldIndex][newIndex + 1]);\r\n }\r\n }\r\n\r\n const removedSpans: DiffSpan[] = [];\r\n const addedSpans: DiffSpan[] = [];\r\n let oldIndex = 0;\r\n let newIndex = 0;\r\n let commonTokens = 0;\r\n while (oldIndex < oldTokens.length || newIndex < newTokens.length) {\r\n if (\r\n oldIndex < oldTokens.length &&\r\n newIndex < newTokens.length &&\r\n oldTokens[oldIndex] === newTokens[newIndex]\r\n ) {\r\n removedSpans.push({ text: oldTokens[oldIndex], kind: 'plain' });\r\n addedSpans.push({ text: newTokens[newIndex], kind: 'plain' });\r\n oldIndex++;\r\n newIndex++;\r\n commonTokens++;\r\n } else if (\r\n newIndex < newTokens.length &&\r\n (oldIndex >= oldTokens.length ||\r\n table[oldIndex][newIndex + 1] >= table[oldIndex + 1][newIndex])\r\n ) {\r\n addedSpans.push({ text: newTokens[newIndex], kind: 'addedWord' });\r\n newIndex++;\r\n } else {\r\n removedSpans.push({ text: oldTokens[oldIndex], kind: 'removedWord' });\r\n oldIndex++;\r\n }\r\n }\r\n\r\n // Unrelated long lines are clearer with whole-line highlighting.\r\n if (commonTokens === 0 && Math.max(oldTokens.length, newTokens.length) > 8) return undefined;\r\n return { removed: mergeSpans(removedSpans), added: mergeSpans(addedSpans) };\r\n}\r\n\r\nexport function parseDiffLines(output: string): ParsedDiffLine[] {\r\n if (output.length === 0) return [];\r\n\r\n let oldLine: number | undefined;\r\n let newLine: number | undefined;\r\n let inHunk = false;\r\n const rows = output.split('\\n').map((text): ParsedDiffLine => {\r\n const hunk = parseHunkPosition(text);\r\n if (hunk) {\r\n inHunk = true;\r\n oldLine = hunk.oldLine;\r\n newLine = hunk.newLine;\r\n return { text, content: text, marker: '@', kind: 'hunk' };\r\n }\r\n if (text.startsWith('diff ')) {\r\n inHunk = false;\r\n oldLine = undefined;\r\n newLine = undefined;\r\n return { text, content: text, marker: ' ', kind: 'meta' };\r\n }\r\n if (!inHunk && (text.startsWith('---') || text.startsWith('+++'))) {\r\n return { text, content: text, marker: ' ', kind: 'meta' };\r\n }\r\n if (text.startsWith('\\\')) {\r\n return { text, content: text.slice(2), marker: '\\\\', kind: 'meta' };\r\n }\r\n if (text.startsWith('-')) {\r\n const row = {\r\n text,\r\n content: text.slice(1),\r\n marker: '-' as const,\r\n kind: 'del' as const,\r\n oldLineNumber: oldLine,\r\n spans: parseEmbeddedWordMarkers(text.slice(1)),\r\n };\r\n if (oldLine !== undefined) oldLine++;\r\n return row;\r\n }\r\n if (text.startsWith('+')) {\r\n const row = {\r\n text,\r\n content: text.slice(1),\r\n marker: '+' as const,\r\n kind: 'add' as const,\r\n newLineNumber: newLine,\r\n spans: parseEmbeddedWordMarkers(text.slice(1)),\r\n };\r\n if (newLine !== undefined) newLine++;\r\n return row;\r\n }\r\n\r\n const content = text.startsWith(' ') ? text.slice(1) : text;\r\n const row = {\r\n text,\r\n content,\r\n marker: ' ' as const,\r\n kind: 'ctx' as const,\r\n oldLineNumber: oldLine,\r\n newLineNumber: newLine,\r\n };\r\n if (oldLine !== undefined) oldLine++;\r\n if (newLine !== undefined) newLine++;\r\n return row;\r\n });\r\n\r\n for (let index = 0; index < rows.length;) {\r\n if (rows[index].kind !== 'del') {\r\n index++;\r\n continue;\r\n }\r\n const deletedStart = index;\r\n while (index < rows.length && rows[index].kind === 'del') index++;\r\n const addedStart = index;\r\n while (index < rows.length && rows[index].kind === 'add') index++;\r\n const pairCount = Math.min(addedStart - deletedStart, index - addedStart);\r\n for (let pairIndex = 0; pairIndex < pairCount; pairIndex++) {\r\n const removed = rows[deletedStart + pairIndex];\r\n const added = rows[addedStart + pairIndex];\r\n if (removed.spans || added.spans) continue;\r\n const replacement = calculateReplacementSpans(removed.content, added.content);\r\n if (!replacement) continue;\r\n removed.spans = replacement.removed;\r\n added.spans = replacement.added;\r\n }\r\n }\r\n return rows;\r\n}\r\n\r\nexport function inferDiffLanguage(filePath: string | undefined): string | undefined {\r\n const extension = filePath?.split('.').pop()?.toLowerCase();\r\n const languages: Record<string, string> = {\r\n ts: 'typescript',\r\n tsx: 'typescript',\r\n js: 'javascript',\r\n jsx: 'javascript',\r\n py: 'python',\r\n rs: 'rust',\r\n go: 'go',\r\n sh: 'bash',\r\n bash: 'bash',\r\n json: 'json',\r\n yml: 'yaml',\r\n yaml: 'yaml',\r\n css: 'css',\r\n html: 'html',\r\n sql: 'sql',\r\n };\r\n return extension ? languages[extension] : undefined;\r\n}\r\n\r\nexport function expandTabs(value: string, tabSize = 4): string {\r\n let column = 0;\r\n let result = '';\r\n for (const character of value) {\r\n if (character === '\\t') {\r\n const spaces = tabSize - (column % tabSize);\r\n result += ' '.repeat(spaces);\r\n column += spaces;\r\n } else {\r\n result += character;\r\n column += displayWidth(character);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nfunction expandSpanTabs(spans: readonly DiffSpan[], tabSize = 4): DiffSpan[] {\r\n const output: DiffSpan[] = [];\r\n let column = 0;\r\n for (const span of spans) {\r\n let text = '';\r\n for (const character of span.text) {\r\n if (character === '\\t') {\r\n const spaces = tabSize - (column % tabSize);\r\n text += ' '.repeat(spaces);\r\n column += spaces;\r\n } else {\r\n text += character;\r\n column += displayWidth(character);\r\n }\r\n }\r\n if (text) output.push({ ...span, text });\r\n }\r\n return output;\r\n}\r\n\r\nfunction wrapSpans(spans: readonly DiffSpan[], width: number): DiffSpan[][] {\r\n const lines: DiffSpan[][] = [[]];\r\n let lineWidth = 0;\r\n\r\n for (const span of expandSpanTabs(spans)) {\r\n for (const character of span.text) {\r\n const characterWidth = displayWidth(character);\r\n if (lines[lines.length - 1].length > 0 && lineWidth + characterWidth > width) {\r\n lines.push([]);\r\n lineWidth = 0;\r\n }\r\n\r\n const line = lines[lines.length - 1];\r\n const previous = line[line.length - 1];\r\n if (previous?.kind === span.kind) previous.text += character;\r\n else line.push({ text: character, kind: span.kind });\r\n lineWidth += characterWidth;\r\n }\r\n }\r\n\r\n return lines;\r\n}\r\n\r\nfunction rowByteSize(row: ParsedDiffLine, index: number, total: number): number {\r\n return Buffer.byteLength(`${row.text}${index < total - 1 ? '\\n' : ''}`, 'utf8');\r\n}\r\n\r\nfunction selectPreviewIndices(rows: readonly ParsedDiffLine[], limit: number): number[] {\r\n if (rows.length <= limit) return rows.map((_, index) => index);\r\n const changedIndices = rows\r\n .map((row, index) => (row.kind === 'add' || row.kind === 'del' ? index : -1))\r\n .filter((index) => index >= 0);\r\n if (changedIndices.length === 0) return Array.from({ length: limit }, (_, index) => index);\r\n\r\n const hunkHeaders = rows\r\n .map((row, index) => (row.kind === 'hunk' ? index : -1))\r\n .filter((index) => index >= 0);\r\n const priority = new Set([...hunkHeaders, ...changedIndices]);\r\n\r\n // Context is useful, but changed rows and hunk boundaries always win the budget.\r\n const contextCandidates = new Map<number, number>();\r\n for (const changedIndex of changedIndices) {\r\n for (let distance = 1; distance <= COLLAPSED_CONTEXT_ROWS; distance++) {\r\n for (const candidate of [changedIndex - distance, changedIndex + distance]) {\r\n if (candidate < 0 || candidate >= rows.length || priority.has(candidate)) continue;\r\n if (rows[candidate].kind !== 'ctx') continue;\r\n const previousDistance = contextCandidates.get(candidate);\r\n if (previousDistance === undefined || distance < previousDistance) {\r\n contextCandidates.set(candidate, distance);\r\n }\r\n }\r\n }\r\n }\r\n\r\n const priorityIndices = [...priority].sort((a, b) => a - b);\r\n if (priorityIndices.length >= limit) {\r\n const headCount = Math.ceil(limit / 2);\r\n return [...priorityIndices.slice(0, headCount), ...priorityIndices.slice(-(limit - headCount))];\r\n }\r\n\r\n const contextIndices = [...contextCandidates.entries()]\r\n .sort(([leftIndex, leftDistance], [rightIndex, rightDistance]) =>\r\n leftDistance === rightDistance ? leftIndex - rightIndex : leftDistance - rightDistance,\r\n )\r\n .slice(0, limit - priorityIndices.length)\r\n .map(([index]) => index);\r\n\r\n return [...priorityIndices, ...contextIndices].sort((a, b) => a - b);\r\n}\r\n\r\ninterface SelectedDiffRow {\r\n row: ParsedDiffLine;\r\n sourceIndex: number;\r\n}\r\n\r\nfunction selectRenderedRows(\r\n rows: readonly ParsedDiffLine[],\r\n collapsed: boolean,\r\n limit: number,\r\n): { rows: SelectedDiffRow[]; hiddenRows: number; hiddenBytes: number } {\r\n const rowBytes = rows.map((row, index) => rowByteSize(row, index, rows.length));\r\n const indices = collapsed\r\n ? selectPreviewIndices(rows, Math.max(1, Math.floor(limit)))\r\n : rows.map((_, index) => index);\r\n const selected = new Set(indices);\r\n const hiddenBytes = rowBytes.reduce(\r\n (total, bytes, index) => total + (selected.has(index) ? 0 : bytes),\r\n 0,\r\n );\r\n return {\r\n rows: indices.map((sourceIndex) => ({ row: rows[sourceIndex], sourceIndex })),\r\n hiddenRows: rows.length - indices.length,\r\n hiddenBytes,\r\n };\r\n}\r\n\r\nfunction lineNumber(value: number | undefined, width: number): string {\r\n if (value === undefined) return ' '.repeat(width);\r\n const text = String(value);\r\n return text.length <= width ? padDisplay(text, width, 'right') : text.slice(-width);\r\n}\r\n\r\nfunction syntaxSegments(\r\n content: string,\r\n language: string | undefined,\r\n theme: ReturnType<typeof useTheme>,\r\n): StyledSegment[] | undefined {\r\n if (!language || !content) return undefined;\r\n return highlightCode(content, language, theme)[0];\r\n}\r\n\r\nexport function DiffBlock({\r\n output,\r\n filePath,\r\n collapsed = false,\r\n maxRows = COLLAPSED_ROWS,\r\n expandHint = 'Ctrl+E shows all',\r\n terminalWidth = 80,\r\n}: DiffProps) {\r\n const theme = useTheme();\r\n const parsed = useMemo(() => parseDiffLines(output), [output]);\r\n const selected = useMemo(\r\n () => selectRenderedRows(parsed, collapsed, maxRows),\r\n [collapsed, maxRows, parsed],\r\n );\r\n const language = inferDiffLanguage(filePath);\r\n const maxOld = Math.max(1, ...parsed.map((row) => row.oldLineNumber ?? 0));\r\n const maxNew = Math.max(1, ...parsed.map((row) => row.newLineNumber ?? 0));\r\n const narrow = terminalWidth < 36;\r\n const oldWidth = Math.max(1, Math.min(String(maxOld).length, narrow ? 3 : 6));\r\n const newWidth = Math.max(1, Math.min(String(maxNew).length, narrow ? 3 : 6));\r\n // marginLeft(2) + `│` + gutters + marker remain visible before wrapped content.\r\n const fixedWidth = 2 + 1 + oldWidth + 1 + newWidth + 1 + 2;\r\n const contentWidth = Math.max(1, Math.floor(terminalWidth) - fixedWidth);\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n {selected.rows.map(({ row, sourceIndex }, index) => {\r\n const previousSourceIndex = selected.rows[index - 1]?.sourceIndex;\r\n const gapRows =\r\n previousSourceIndex === undefined ? sourceIndex : sourceIndex - previousSourceIndex - 1;\r\n const backgroundColor =\r\n row.kind === 'add' ? theme.diffAdded : row.kind === 'del' ? theme.diffRemoved : undefined;\r\n const foregroundColor = row.kind === 'hunk' ? theme.brand : theme.text;\r\n const rawContent = expandTabs(row.content);\r\n const wrappedSpans = row.spans ? wrapSpans(row.spans, contentWidth) : undefined;\r\n const wrappedContent = wrappedSpans\r\n ? wrappedSpans.map((spans) => spans.map((span) => span.text).join(''))\r\n : hardWrapLine(rawContent, contentWidth);\r\n\r\n return (\r\n <Fragment key={`${sourceIndex}-${row.text}`}>\r\n {gapRows > 0 ? (\r\n <Box marginLeft={2}>\r\n <Text color={theme.subtle} dimColor>\r\n │{' '}\r\n {truncateDisplay(\r\n `⋮ ${gapRows} ${gapRows === 1 ? 'row' : 'rows'} omitted`,\r\n Math.max(4, terminalWidth - 4),\r\n )}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {wrappedContent.map((content, visualIndex) => {\r\n const spans = wrappedSpans?.[visualIndex];\r\n const highlighted =\r\n !spans && (row.kind === 'add' || row.kind === 'del' || row.kind === 'ctx')\r\n ? syntaxSegments(content, language, theme)\r\n : undefined;\r\n const visibleWidth = spans\r\n ? spans.reduce((total, span) => total + displayWidth(span.text), 0)\r\n : displayWidth(content);\r\n const padding = backgroundColor\r\n ? ' '.repeat(Math.max(0, contentWidth - visibleWidth))\r\n : '';\r\n const continuation = visualIndex > 0;\r\n\r\n return (\r\n <Box key={visualIndex} marginLeft={2}>\r\n <Text color={theme.subtle}>│</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {lineNumber(continuation ? undefined : row.oldLineNumber, oldWidth)}{' '}\r\n {lineNumber(continuation ? undefined : row.newLineNumber, newWidth)}{' '}\r\n </Text>\r\n <Text\r\n color={\r\n row.kind === 'add'\r\n ? theme.success\r\n : row.kind === 'del'\r\n ? theme.error\r\n : foregroundColor\r\n }\r\n backgroundColor={backgroundColor}\r\n >\r\n {continuation ? ' ' : row.marker}{' '}\r\n </Text>\r\n <Text color={foregroundColor} backgroundColor={backgroundColor}>\r\n {spans\r\n ? spans.map((span, spanIndex) => (\r\n <Text\r\n key={spanIndex}\r\n backgroundColor={\r\n span.kind === 'addedWord'\r\n ? theme.diffAddedWord\r\n : span.kind === 'removedWord'\r\n ? theme.diffRemovedWord\r\n : backgroundColor\r\n }\r\n bold={span.kind !== 'plain'}\r\n >\r\n {span.text}\r\n </Text>\r\n ))\r\n : highlighted\r\n ? highlighted.map((segment, segmentIndex) => (\r\n <Text\r\n key={segmentIndex}\r\n color={segment.color}\r\n bold={segment.bold}\r\n italic={segment.italic}\r\n dimColor={segment.dimColor}\r\n >\r\n {segment.text}\r\n </Text>\r\n ))\r\n : content}\r\n {padding}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Fragment>\r\n );\r\n })}\r\n {selected.hiddenRows > 0 || selected.hiddenBytes > 0 ? (\r\n <Box marginLeft={2}>\r\n <Text color={theme.subtle} dimColor>\r\n │{' '}\r\n {truncateDisplay(\r\n `… ${selected.hiddenRows} ${selected.hiddenRows === 1 ? 'row' : 'rows'} and ${selected.hiddenBytes} B omitted${collapsed && expandHint ? `; ${expandHint}` : ''}`,\r\n Math.max(4, terminalWidth - 4),\r\n )}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * Soft word-boundary text wrapping utility.\r\n *\r\n * Unlike Ink's built-in wrap-ansi (which uses `hard: true` and breaks at any\r\n * character position), this wraps only at word boundaries (spaces). Words\r\n * longer than maxWidth are kept intact — Ink's hard wrap handles those as\r\n * a safety net.\r\n *\r\n * ANSI escape sequences are stripped before measuring width so that colored\r\n * text is not mismeasured.\r\n */\r\n\r\n/**\r\n * Strip ANSI escape sequences from a string for accurate width measurement.\r\n */\r\nexport function stripAnsi(text: string): string {\r\n return text.replace(/\\x1B\\[[0-?]*[ -/]*[@-~]/g, '');\r\n}\r\n\r\n/**\r\n * Unicode zero-width character ranges.\r\n * Characters in these ranges contribute 0 to terminal display width.\r\n */\r\nconst ZERO_WIDTH_RANGES: [number, number][] = [\r\n [0x0300, 0x036f], // Combining Diacritical Marks\r\n [0x0483, 0x0489], // Cyrillic combining marks\r\n [0x0591, 0x05bd], // Hebrew combining marks\r\n [0x05bf, 0x05bf],\r\n [0x05c1, 0x05c2],\r\n [0x05c4, 0x05c5],\r\n [0x05c7, 0x05c7],\r\n [0x0610, 0x061a], // Arabic combining marks\r\n [0x064b, 0x065f],\r\n [0x0670, 0x0670],\r\n [0x06d6, 0x06dc],\r\n [0x06df, 0x06e4],\r\n [0x06e7, 0x06e8],\r\n [0x06ea, 0x06ed],\r\n [0x0711, 0x0711],\r\n [0x0730, 0x074a],\r\n [0x07a6, 0x07b0],\r\n [0x0900, 0x0902], // Devanagari combining\r\n [0x093a, 0x093c],\r\n [0x0941, 0x0948],\r\n [0x094d, 0x094d],\r\n [0x0951, 0x0957],\r\n [0x0962, 0x0963],\r\n [0x0981, 0x0981],\r\n [0x09bc, 0x09bc],\r\n [0x09c1, 0x09c4],\r\n [0x09cd, 0x09cd],\r\n [0x09e2, 0x09e3],\r\n [0x0a01, 0x0a02],\r\n [0x0a3c, 0x0a3c],\r\n [0x0a41, 0x0a42],\r\n [0x0a47, 0x0a48],\r\n [0x0a4b, 0x0a4d],\r\n [0x0a70, 0x0a71],\r\n [0x0a81, 0x0a82],\r\n [0x0abc, 0x0abc],\r\n [0x0ac1, 0x0ac5],\r\n [0x0ac7, 0x0ac8],\r\n [0x0acd, 0x0acd],\r\n [0x0ae2, 0x0ae3],\r\n [0x0b01, 0x0b01],\r\n [0x0b3c, 0x0b3c],\r\n [0x0b3f, 0x0b3f],\r\n [0x0b41, 0x0b44],\r\n [0x0b4d, 0x0b4d],\r\n [0x0b56, 0x0b56],\r\n [0x0b62, 0x0b63],\r\n [0x0b82, 0x0b82],\r\n [0x0bc0, 0x0bc0],\r\n [0x0bcd, 0x0bcd],\r\n [0x0c00, 0x0c00],\r\n [0x0c3e, 0x0c40],\r\n [0x0c46, 0x0c48],\r\n [0x0c4a, 0x0c4d],\r\n [0x0c55, 0x0c56],\r\n [0x0c62, 0x0c63],\r\n [0x0c81, 0x0c81],\r\n [0x0cbc, 0x0cbc],\r\n [0x0ccc, 0x0ccd],\r\n [0x0ce2, 0x0ce3],\r\n [0x0d01, 0x0d01],\r\n [0x0d41, 0x0d44],\r\n [0x0d4d, 0x0d4d],\r\n [0x0d62, 0x0d63],\r\n [0x0dca, 0x0dca],\r\n [0x0dd2, 0x0dd4],\r\n [0x0dd6, 0x0dd6],\r\n [0x0e31, 0x0e31], // Thai\r\n [0x0e34, 0x0e3a],\r\n [0x0e47, 0x0e4e],\r\n [0x0eb1, 0x0eb1], // Lao\r\n [0x0eb4, 0x0eb9],\r\n [0x0ebb, 0x0ebc],\r\n [0x0ec8, 0x0ecd],\r\n [0x0f18, 0x0f19], // Tibetan\r\n [0x0f35, 0x0f35],\r\n [0x0f37, 0x0f37],\r\n [0x0f39, 0x0f39],\r\n [0x0f71, 0x0f7e],\r\n [0x0f80, 0x0f84],\r\n [0x0f86, 0x0f87],\r\n [0x0f90, 0x0f97],\r\n [0x0f99, 0x0fbc],\r\n [0x0fc6, 0x0fc6],\r\n [0x1031, 0x1031], // Myanmar\r\n [0x103b, 0x103c],\r\n [0x103d, 0x103e],\r\n [0x1056, 0x1057],\r\n [0x1058, 0x1059],\r\n [0x105e, 0x1060],\r\n [0x1062, 0x1064],\r\n [0x1067, 0x106d],\r\n [0x1071, 0x1074],\r\n [0x1082, 0x1082],\r\n [0x1085, 0x1086],\r\n [0x108d, 0x108d],\r\n [0x109d, 0x109d],\r\n [0x135d, 0x135f], // Ethiopic\r\n [0x1712, 0x1714], // Tagalog\r\n [0x1732, 0x1734], // Hanunoo\r\n [0x1752, 0x1753], // Buhid\r\n [0x1772, 0x1773], // Tagbanwa\r\n [0x17b4, 0x17b5], // Khmer\r\n [0x17b7, 0x17bd],\r\n [0x17c6, 0x17c6],\r\n [0x17c9, 0x17d3],\r\n [0x17dd, 0x17dd],\r\n [0x180b, 0x180d], // Mongolian\r\n [0x18a9, 0x18a9],\r\n [0x1920, 0x1922], // Limbu\r\n [0x1927, 0x1928],\r\n [0x1932, 0x1932],\r\n [0x1939, 0x193b],\r\n [0x1a17, 0x1a18], // Buginese\r\n [0x1a56, 0x1a56], // Tai Tham\r\n [0x1a58, 0x1a5e],\r\n [0x1a60, 0x1a60],\r\n [0x1a62, 0x1a62],\r\n [0x1a65, 0x1a6c],\r\n [0x1a73, 0x1a7c],\r\n [0x1a7f, 0x1a7f],\r\n [0x1ab0, 0x1abe], // Combining Diacritical Marks Extended\r\n [0x1b00, 0x1b03], // Balinese\r\n [0x1b34, 0x1b34],\r\n [0x1b36, 0x1b3a],\r\n [0x1b3c, 0x1b3c],\r\n [0x1b42, 0x1b42],\r\n [0x1b6b, 0x1b73],\r\n [0x1b80, 0x1b81], // Sundanese\r\n [0x1ba2, 0x1ba5],\r\n [0x1ba8, 0x1ba9],\r\n [0x1bab, 0x1bad],\r\n [0x1be6, 0x1be6],\r\n [0x1be8, 0x1be9],\r\n [0x1bed, 0x1bed],\r\n [0x1bef, 0x1bf1],\r\n [0x1c2c, 0x1c33], // Lepcha\r\n [0x1c36, 0x1c37],\r\n [0x1cd0, 0x1cd2], // Vedic Extensions\r\n [0x1cd4, 0x1ce0],\r\n [0x1ce2, 0x1ce8],\r\n [0x1ced, 0x1ced],\r\n [0x1cf4, 0x1cf4],\r\n [0x1cf8, 0x1cf9],\r\n [0x1dc0, 0x1df5], // Combining Diacritical Marks Supplement\r\n [0x1dfc, 0x1dff],\r\n [0x200b, 0x200f], // ZWSP, ZWNJ, ZWJ, LRM, RLM\r\n [0x2028, 0x2029], // Line/Paragraph separator\r\n [0x202a, 0x202e], // Bidi control chars\r\n [0x2060, 0x2064], // Word joiner, invisible operators\r\n [0x2066, 0x206f], // Bidi override chars\r\n [0x20d0, 0x20f0], // Combining Diacritical Marks for Symbols\r\n [0x2cef, 0x2cf1], // Coptic combining\r\n [0x2d7f, 0x2d7f], // Tifinagh combining\r\n [0x2de0, 0x2dff], // Cyrillic Extended-A combining\r\n [0xa66f, 0xa672],\r\n [0xa674, 0xa67d],\r\n [0xa69e, 0xa69f],\r\n [0xa6f0, 0xa6f1], // Bamum\r\n [0xa802, 0xa802], // Syloti Nagri\r\n [0xa806, 0xa806],\r\n [0xa80b, 0xa80b],\r\n [0xa825, 0xa826],\r\n [0xa8c4, 0xa8c4], // Saurashtra\r\n [0xa8e0, 0xa8f1], // Devanagari Extended combining\r\n [0xa926, 0xa92d], // Kayah Li\r\n [0xa947, 0xa951], // Rejang\r\n [0xa980, 0xa982], // Javanese\r\n [0xa9b3, 0xa9b3],\r\n [0xa9b6, 0xa9b9],\r\n [0xa9bc, 0xa9bc],\r\n [0xa9e5, 0xa9e5],\r\n [0xaa29, 0xaa2e], // Cham\r\n [0xaa31, 0xaa32],\r\n [0xaa35, 0xaa36],\r\n [0xaa43, 0xaa43],\r\n [0xaa4c, 0xaa4c],\r\n [0xaa7c, 0xaa7c],\r\n [0xaab0, 0xaab0], // Tai Viet\r\n [0xaab2, 0xaab4],\r\n [0xaab7, 0xaab8],\r\n [0xaabe, 0xaabf],\r\n [0xaac1, 0xaac1],\r\n [0xaaec, 0xaaed], // Meetei Mayek\r\n [0xaaf6, 0xaaf6],\r\n [0xabe5, 0xabe5], // Meetei Mayek Ext\r\n [0xabe8, 0xabe8],\r\n [0xabed, 0xabed],\r\n [0xfb1e, 0xfb1e], // Hebrew presentation forms\r\n [0xfe00, 0xfe0f], // Variation selectors\r\n [0xfe20, 0xfe2f], // Combining Half Marks\r\n [0xfeff, 0xfeff], // BOM / ZWNBSP\r\n [0xfff9, 0xfffb], // Interlinear annotation anchors\r\n [0x101fd, 0x101fd], // Phaistos Disc\r\n [0x102e0, 0x102e0], // Coptic Epact Numbers\r\n [0x10376, 0x1037a], // Combining Old Permic\r\n [0x10a01, 0x10a03], // Kharoshthi\r\n [0x10a05, 0x10a06],\r\n [0x10a0c, 0x10a0f],\r\n [0x10a38, 0x10a3a],\r\n [0x10a3f, 0x10a3f],\r\n [0x10ae5, 0x10ae6], // Manichaean\r\n [0x11001, 0x11001], // Brahmi\r\n [0x11038, 0x11046],\r\n [0x1107f, 0x11081],\r\n [0x110b3, 0x110b6],\r\n [0x110b9, 0x110ba],\r\n [0x11100, 0x11102], // Chakma\r\n [0x11127, 0x1112b],\r\n [0x1112d, 0x11134],\r\n [0x11173, 0x11173],\r\n [0x11180, 0x11181], // Sharada\r\n [0x111b6, 0x111be],\r\n [0x111c9, 0x111cc],\r\n [0x1122f, 0x11231], // Khojki\r\n [0x11234, 0x11234],\r\n [0x11236, 0x11237],\r\n [0x112df, 0x112df], // Khudawadi\r\n [0x112e3, 0x112ea],\r\n [0x11300, 0x11301], // Grantha\r\n [0x1133c, 0x1133c],\r\n [0x11340, 0x11340],\r\n [0x11366, 0x1136c],\r\n [0x11370, 0x11374],\r\n [0x114b3, 0x114b8], // Tirhuta\r\n [0x114ba, 0x114ba],\r\n [0x114bf, 0x114c0],\r\n [0x114c2, 0x114c3],\r\n [0x115b2, 0x115b5], // Siddham\r\n [0x115bc, 0x115bd],\r\n [0x115bf, 0x115c0],\r\n [0x115dc, 0x115dd],\r\n [0x11633, 0x1163a], // Modi\r\n [0x1163d, 0x1163d],\r\n [0x1163f, 0x11640],\r\n [0x116ab, 0x116ab], // Takri\r\n [0x116ad, 0x116ad],\r\n [0x116b0, 0x116b5],\r\n [0x116b7, 0x116b7],\r\n [0x1171d, 0x1171f], // Ahom\r\n [0x11722, 0x11725],\r\n [0x11727, 0x1172b],\r\n [0x11a01, 0x11a06], // Zanabazar Square\r\n [0x11a09, 0x11a0a],\r\n [0x11a33, 0x11a38],\r\n [0x11a3b, 0x11a3e],\r\n [0x11a47, 0x11a47],\r\n [0x11a51, 0x11a56],\r\n [0x11a59, 0x11a5b],\r\n [0x11a8a, 0x11a96],\r\n [0x11a98, 0x11a99],\r\n [0x11c30, 0x11c36], // Bhaiksuki\r\n [0x11c38, 0x11c3d],\r\n [0x11c3f, 0x11c3f],\r\n [0x11c92, 0x11ca7], // Marchen\r\n [0x11caa, 0x11cb0],\r\n [0x11cb2, 0x11cb3],\r\n [0x11cb5, 0x11cb6],\r\n [0x11d31, 0x11d36], // Masaram Gondi\r\n [0x11d3a, 0x11d3a],\r\n [0x11d3c, 0x11d3d],\r\n [0x11d3f, 0x11d45],\r\n [0x11d47, 0x11d47],\r\n [0x16af0, 0x16af4], // Bassa Vah\r\n [0x16b30, 0x16b36], // Pahawh Hmong\r\n [0x16f8f, 0x16f92], // Miao\r\n [0x1bc9d, 0x1bc9e], // Duployan\r\n [0x1bca0, 0x1bca3],\r\n [0x1d167, 0x1d169], // Musical symbols combining\r\n [0x1d173, 0x1d182],\r\n [0x1d185, 0x1d18b],\r\n [0x1d1aa, 0x1d1ad],\r\n [0x1d242, 0x1d244], // Combining music symbols\r\n [0x1da00, 0x1da36], // SignWriting\r\n [0x1da3b, 0x1da6c],\r\n [0x1da75, 0x1da75],\r\n [0x1da84, 0x1da84],\r\n [0x1da9b, 0x1da9f],\r\n [0x1daa1, 0x1daaf],\r\n [0x1e000, 0x1e006], // Glagolitic supplement combining\r\n [0x1e008, 0x1e018],\r\n [0x1e01b, 0x1e021],\r\n [0x1e023, 0x1e024],\r\n [0x1e026, 0x1e02a],\r\n [0x1e8d0, 0x1e8d6], // Mende Kikakui\r\n [0x1e944, 0x1e94a], // Adlam\r\n [0xe0001, 0xe0001], // Language tags\r\n [0xe0020, 0xe007f], // Tag characters\r\n [0xe0100, 0xe01ef], // Variation Selectors Supplement\r\n];\r\n\r\n/**\r\n * Unicode wide-character ranges (2 columns in terminal).\r\n * Covers CJK, Hangul, fullwidth forms, and emoji/pictographs.\r\n */\r\nconst WIDE_RANGES: [number, number][] = [\r\n // CJK / Hangul / fullwidth forms\r\n [0x1100, 0x115f], // Hangul Jamo\r\n [0x2e80, 0xa4cf], // CJK Radicals, Yi, Kangxi, etc.\r\n [0xac00, 0xd7a3], // Hangul Syllables\r\n [0xf900, 0xfaff], // CJK Compatibility Ideographs\r\n [0xfe30, 0xfe6f], // CJK Compatibility Forms\r\n [0xff01, 0xff60], // Fullwidth Forms\r\n [0xffe0, 0xffe6], // Fullwidth Signs\r\n [0x20000, 0x2fffd], // CJK Extension B+\r\n [0x30000, 0x3fffd], // CJK Extension G+\r\n // Emoji and pictographs (many terminals render these as 2-wide)\r\n [0x1f300, 0x1f5ff], // Misc Symbols and Pictographs\r\n [0x1f600, 0x1f64f], // Emoticons\r\n [0x1f680, 0x1f6ff], // Transport and Map Symbols\r\n [0x1f700, 0x1f77f], // Alchemical Symbols\r\n [0x1f780, 0x1f7ff], // Geometric Shapes Extended\r\n [0x1f800, 0x1f8ff], // Supplemental Arrows-C\r\n [0x1f900, 0x1f9ff], // Supplemental Symbols and Pictographs\r\n [0x1fa00, 0x1fa6f], // Chess Symbols\r\n [0x1fa70, 0x1faff], // Symbols and Pictographs Extended-A\r\n [0x2600, 0x26ff], // Misc symbols\r\n // Dingbats, emoji-presentation subset only. The block also holds\r\n // East-Asian *ambiguous* marks — U+2713 ✓, U+2717 ✗ and friends — which\r\n // terminals and Ink's own layout render one column wide. Measuring the whole\r\n // block as wide put our width math one column out from the renderer for the\r\n // check mark used on every successful tool row.\r\n [0x2705, 0x2705], // White heavy check mark\r\n [0x270a, 0x270b], // Raised fist, raised hand\r\n [0x2728, 0x2728], // Sparkles\r\n [0x274c, 0x274c], // Cross mark\r\n [0x274e, 0x274e], // Negative squared cross mark\r\n [0x2753, 0x2755], // Question and exclamation ornaments\r\n [0x2757, 0x2757], // Heavy exclamation mark\r\n [0x2795, 0x2797], // Heavy plus, minus, division\r\n [0x27b0, 0x27b0], // Curly loop\r\n [0x27bf, 0x27bf], // Double curly loop\r\n [0x2300, 0x23ff], // Misc Technical (many 2-wide symbols)\r\n [0x2b50, 0x2b55], // Star, circle\r\n [0x2b05, 0x2b07], // Direction arrows\r\n [0x2b1b, 0x2b1c], // Large squares\r\n [0x2934, 0x2935], // Curved arrows\r\n [0x25aa, 0x25ab], // Small squares\r\n [0x25fb, 0x25fe], // Medium squares\r\n [0x231a, 0x231b], // Watch, hourglass\r\n [0x2328, 0x2328], // Keyboard\r\n [0x23e9, 0x23f3], // Double triangles, hourglass\r\n [0x23f8, 0x23fa], // Power symbols\r\n [0x24c2, 0x24c2], // Circled M\r\n [0x25b6, 0x25b6], // Play\r\n [0x25c0, 0x25c0], // Reverse\r\n [0x3030, 0x3030], // Wavy dash\r\n [0x303d, 0x303d], // Part alternation mark\r\n [0x3297, 0x3297], // Circled ideograph\r\n [0x3299, 0x3299], // Circled ideograph secret\r\n];\r\n\r\nfunction mergeRanges(ranges: [number, number][]): [number, number][] {\r\n const sorted = [...ranges].sort((left, right) => left[0] - right[0]);\r\n const merged: [number, number][] = [];\r\n for (const [low, high] of sorted) {\r\n const previous = merged[merged.length - 1];\r\n if (!previous || low > previous[1] + 1) {\r\n merged.push([low, high]);\r\n } else {\r\n previous[1] = Math.max(previous[1], high);\r\n }\r\n }\r\n return merged;\r\n}\r\n\r\nconst SORTED_ZERO_WIDTH_RANGES = mergeRanges(ZERO_WIDTH_RANGES);\r\nconst SORTED_WIDE_RANGES = mergeRanges(WIDE_RANGES);\r\nconst ASCII_PRINTABLE = /^[\\x20-\\x7e]*$/;\r\n\r\n/**\r\n * Check if a code point falls within any range in the given list.\r\n */\r\nfunction inRanges(cp: number, ranges: [number, number][]): boolean {\r\n let low = 0;\r\n let high = ranges.length - 1;\r\n while (low <= high) {\r\n const middle = (low + high) >>> 1;\r\n const [rangeLow, rangeHigh] = ranges[middle]!;\r\n if (cp < rangeLow) {\r\n high = middle - 1;\r\n } else if (cp > rangeHigh) {\r\n low = middle + 1;\r\n } else {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Get the display width of a string (accounting for wide chars).\r\n *\r\n * - CJK, Hangul, fullwidth, and emoji characters → 2 columns\r\n * - Combining marks, zero-width chars, control chars → 0 columns\r\n * - Everything else → 1 column\r\n *\r\n * ANSI escape sequences are stripped before measurement.\r\n */\r\nexport function displayWidth(text: string): number {\r\n if (text.length === 0) return 0;\r\n // Fast path for the per-character calls from wrap/truncate loops.\r\n if (text.length === 1) {\r\n const code = text.charCodeAt(0);\r\n if (code >= 0x20 && code < 0x7f) return 1;\r\n }\r\n // Skip the regex replace when no ANSI escape can be present.\r\n const plain = text.indexOf('\\u001B') === -1 ? text : stripAnsi(text);\r\n if (ASCII_PRINTABLE.test(plain)) return plain.length;\r\n\r\n let width = 0;\r\n for (const ch of plain) {\r\n const cp = ch.codePointAt(0) ?? 0;\r\n if (inRanges(cp, SORTED_ZERO_WIDTH_RANGES)) {\r\n // width += 0\r\n } else if (inRanges(cp, SORTED_WIDE_RANGES)) {\r\n width += 2;\r\n } else {\r\n width += 1;\r\n }\r\n }\r\n return width;\r\n}\r\n\r\n/** Build a terminal divider that never underflows on tiny widths. */\r\nexport function makeDivider(width: number, padding = 0, char = '─'): string {\r\n return char.repeat(Math.max(5, Math.floor(width) - padding));\r\n}\r\n\r\n/** True when `text` fits within `maxWidth` terminal display columns. */\r\nexport function fitsDisplayWidth(text: string, maxWidth: number): boolean {\r\n return displayWidth(text) <= Math.max(0, maxWidth);\r\n}\r\n\r\n/**\r\n * Truncate a string by terminal display columns.\r\n *\r\n * ANSI SGR sequences are preserved without counting toward width. Wide and\r\n * zero-width Unicode characters use the same width model as `displayWidth`.\r\n */\r\nexport function truncateDisplay(text: string, maxWidth: number, suffix = '…'): string {\r\n const limit = Math.max(0, Math.floor(maxWidth));\r\n if (limit === 0) return '';\r\n if (fitsDisplayWidth(text, limit)) return text;\r\n\r\n const suffixWidth = displayWidth(suffix);\r\n const contentLimit = Math.max(0, limit - suffixWidth);\r\n if (contentLimit === 0) return suffixWidth <= limit ? suffix : '';\r\n\r\n let width = 0;\r\n let out = '';\r\n for (let i = 0; i < text.length;) {\r\n if (text.charCodeAt(i) === 0x1b) {\r\n const match = text.slice(i).match(/^\\x1B\\[[0-?]*[ -/]*[@-~]/);\r\n if (match) {\r\n out += match[0];\r\n i += match[0].length;\r\n continue;\r\n }\r\n }\r\n\r\n const cp = text.codePointAt(i);\r\n if (cp === undefined) break;\r\n const ch = String.fromCodePoint(cp);\r\n const chWidth = displayWidth(ch);\r\n if (width + chWidth > contentLimit) break;\r\n out += ch;\r\n width += chWidth;\r\n i += ch.length;\r\n }\r\n\r\n return out + suffix;\r\n}\r\n\r\n/** Clip ANSI-stripped text to a display-column budget without adding an ellipsis. */\r\nexport function sliceDisplayWidth(text: string, maxWidth: number): string {\r\n const limit = Math.max(0, Math.floor(maxWidth));\r\n const plain = stripAnsi(text);\r\n if (limit === 0) return '';\r\n if (displayWidth(plain) <= limit) return plain;\r\n\r\n let width = 0;\r\n let out = '';\r\n for (const ch of plain) {\r\n const chWidth = displayWidth(ch);\r\n if (width + chWidth > limit) break;\r\n out += ch;\r\n width += chWidth;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Split text into chunks that each fit within `maxWidth` display columns.\r\n *\r\n * Breaks mid-word when needed. Wide characters (CJK/emoji) never split a\r\n * grapheme cluster produced by `for...of` (code-point safe). A single\r\n * character wider than `maxWidth` is still emitted alone so content is never\r\n * dropped. Combining marks stay attached to the preceding base when they are\r\n * zero-width and fit in the same iteration budget.\r\n */\r\nexport function hardWrap(text: string, maxWidth: number): string {\r\n if (maxWidth <= 0 || !text) return text;\r\n return text\r\n .split('\\n')\r\n .map((line) => hardWrapLine(line, maxWidth).join('\\n'))\r\n .join('\\n');\r\n}\r\n\r\n/** Display-width-aware hard wrap for a single line (no embedded newlines). */\r\nexport function hardWrapLine(text: string, maxWidth: number): string[] {\r\n if (maxWidth <= 0 || !text) return text ? [text] : [''];\r\n if (fitsDisplayWidth(text, maxWidth)) return [text];\r\n\r\n const lines: string[] = [];\r\n let current = '';\r\n let currentWidth = 0;\r\n\r\n for (const ch of text) {\r\n const chWidth = displayWidth(ch);\r\n if (current && currentWidth + chWidth > maxWidth) {\r\n lines.push(current);\r\n current = ch;\r\n currentWidth = chWidth;\r\n continue;\r\n }\r\n current += ch;\r\n currentWidth += chWidth;\r\n }\r\n\r\n if (current) lines.push(current);\r\n return lines.length > 0 ? lines : [''];\r\n}\r\n\r\n/**\r\n * Soft-wrap text at word boundaries to fit within `maxWidth` columns.\r\n *\r\n * Words longer than maxWidth are hard-wrapped by display width (CJK/emoji\r\n * safe). Multiple consecutive spaces are collapsed when wrapping. Paragraph\r\n * breaks (blank lines / double-newline) are preserved.\r\n *\r\n * @param text The text to wrap\r\n * @param maxWidth Maximum columns per line\r\n * @returns Wrapped text with newlines inserted at word boundaries\r\n */\r\nexport function wordWrap(text: string, maxWidth: number): string {\r\n if (maxWidth <= 0 || !text) return text;\r\n\r\n const paragraphs = text.split('\\n');\r\n const wrapped: string[] = [];\r\n\r\n for (const paragraph of paragraphs) {\r\n // Preserve blank lines (paragraph separators).\r\n if (paragraph.trim().length === 0) {\r\n wrapped.push('');\r\n continue;\r\n }\r\n\r\n const words = paragraph.split(' ');\r\n const lines: string[] = [];\r\n let current = '';\r\n let currentWidth = 0;\r\n\r\n const pushWordChunks = (word: string) => {\r\n const chunks = hardWrapLine(word, maxWidth);\r\n for (let i = 0; i < chunks.length; i++) {\r\n const chunk = chunks[i]!;\r\n const chunkWidth = displayWidth(chunk);\r\n if (!current) {\r\n current = chunk;\r\n currentWidth = chunkWidth;\r\n } else if (currentWidth + 1 + chunkWidth <= maxWidth && i === 0) {\r\n // Only the first chunk of a hard-broken word can share a line with\r\n // previous content; continuation chunks always start a new line.\r\n current = `${current} ${chunk}`;\r\n currentWidth = currentWidth + 1 + chunkWidth;\r\n } else {\r\n lines.push(current);\r\n current = chunk;\r\n currentWidth = chunkWidth;\r\n }\r\n }\r\n };\r\n\r\n for (const word of words) {\r\n if (word === '') {\r\n // Consecutive spaces — add one space to current line if not empty.\r\n if (current) {\r\n current += ' ';\r\n currentWidth += 1;\r\n }\r\n continue;\r\n }\r\n\r\n const wordWidth = displayWidth(word);\r\n const candidateWidth = current ? currentWidth + 1 + wordWidth : wordWidth;\r\n\r\n if (wordWidth > maxWidth) {\r\n // Long token: flush current line, then hard-wrap the word.\r\n if (current) {\r\n lines.push(current);\r\n current = '';\r\n currentWidth = 0;\r\n }\r\n pushWordChunks(word);\r\n } else if (candidateWidth > maxWidth) {\r\n // This word would overflow — start a new line.\r\n if (current) {\r\n lines.push(current);\r\n current = word;\r\n currentWidth = wordWidth;\r\n } else {\r\n pushWordChunks(word);\r\n }\r\n } else {\r\n current = current ? `${current} ${word}` : word;\r\n currentWidth = candidateWidth;\r\n }\r\n }\r\n\r\n if (current) lines.push(current);\r\n wrapped.push(lines.join('\\n'));\r\n }\r\n\r\n return wrapped.join('\\n');\r\n}\r\n\r\n/**\r\n * Pad `text` to `width` display columns (not string length).\r\n * Truncates with ellipsis when text is wider than `width`.\r\n */\r\nexport function padDisplay(\r\n text: string,\r\n width: number,\r\n align: 'left' | 'right' | 'center' = 'left',\r\n): string {\r\n const limit = Math.max(0, Math.floor(width));\r\n if (limit === 0) return '';\r\n const clipped = fitsDisplayWidth(text, limit) ? text : truncateDisplay(text, limit);\r\n const pad = Math.max(0, limit - displayWidth(clipped));\r\n if (pad === 0) return clipped;\r\n if (align === 'right') return `${' '.repeat(pad)}${clipped}`;\r\n if (align === 'center') {\r\n const left = Math.floor(pad / 2);\r\n return `${' '.repeat(left)}${clipped}${' '.repeat(pad - left)}`;\r\n }\r\n return `${clipped}${' '.repeat(pad)}`;\r\n}\r\n","import type { ThemeTokens } from '../../types/theme.js';\r\n\r\nexport interface StyledSegment {\r\n text: string;\r\n color?: string;\r\n bold?: boolean;\r\n italic?: boolean;\r\n dimColor?: boolean;\r\n}\r\n\r\nexport type StyledLine = StyledSegment[];\r\n\r\nconst cache = new Map<string, StyledLine[]>();\r\nconst MAX_CACHE_ENTRIES = 80;\r\n\r\nfunction normalizeLang(lang?: string): string {\r\n const normalized = (lang ?? '').toLowerCase().trim();\r\n if (normalized === 'js') return 'javascript';\r\n if (normalized === 'jsx') return 'javascript';\r\n if (normalized === 'ts') return 'typescript';\r\n if (normalized === 'tsx') return 'typescript';\r\n if (normalized === 'py') return 'python';\r\n if (normalized === 'sh' || normalized === 'shell') return 'bash';\r\n if (normalized === 'yml') return 'yaml';\r\n return normalized;\r\n}\r\n\r\nfunction pushSegment(line: StyledLine, text: string, segment: Omit<StyledSegment, 'text'> = {}) {\r\n if (!text) return;\r\n const previous = line[line.length - 1];\r\n if (\r\n previous &&\r\n previous.color === segment.color &&\r\n previous.bold === segment.bold &&\r\n previous.italic === segment.italic &&\r\n previous.dimColor === segment.dimColor\r\n ) {\r\n previous.text += text;\r\n return;\r\n }\r\n line.push({ text, ...segment });\r\n}\r\n\r\nfunction keywordPattern(lang: string): RegExp | null {\r\n if (['javascript', 'typescript'].includes(lang)) {\r\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;\r\n }\r\n if (lang === 'python') {\r\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;\r\n }\r\n if (lang === 'rust') {\r\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;\r\n }\r\n if (lang === 'go') {\r\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;\r\n }\r\n if (lang === 'bash') {\r\n return /\\b(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)\\b/y;\r\n }\r\n if (lang === 'sql') {\r\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;\r\n }\r\n if (lang === 'css') {\r\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;\r\n }\r\n return null;\r\n}\r\n\r\nfunction highlightLine(raw: string, lang: string, theme: ThemeTokens): StyledLine {\r\n const line: StyledLine = [];\r\n const keyword = keywordPattern(lang);\r\n let i = 0;\r\n\r\n while (i < raw.length) {\r\n const rest = raw.slice(i);\r\n\r\n const commentStart = lang === 'python' || lang === 'bash' || lang === 'yaml' ? '#' : '//';\r\n if (rest.startsWith(commentStart)) {\r\n pushSegment(line, rest, { color: theme.mdCodeComment, italic: true, dimColor: true });\r\n break;\r\n }\r\n if (rest.startsWith('/*')) {\r\n const end = raw.indexOf('*/', i + 2);\r\n const text = end === -1 ? rest : raw.slice(i, end + 2);\r\n pushSegment(line, text, { color: theme.mdCodeComment, italic: true, dimColor: true });\r\n i += text.length;\r\n continue;\r\n }\r\n\r\n const stringMatch = rest.match(/^(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`)/);\r\n if (stringMatch) {\r\n pushSegment(line, stringMatch[0], { color: theme.mdCodeString });\r\n i += stringMatch[0].length;\r\n continue;\r\n }\r\n\r\n const numberMatch = rest.match(/^\\b\\d+(?:\\.\\d+)?\\b/);\r\n if (numberMatch) {\r\n pushSegment(line, numberMatch[0], { color: theme.mdCodeNumber });\r\n i += numberMatch[0].length;\r\n continue;\r\n }\r\n\r\n const functionMatch = rest.match(/^([A-Za-z_$][\\w$-]*)(?=\\s*\\()/);\r\n if (functionMatch) {\r\n pushSegment(line, functionMatch[1], { color: theme.mdCodeFunction });\r\n i += functionMatch[1].length;\r\n continue;\r\n }\r\n\r\n if (keyword) {\r\n keyword.lastIndex = i;\r\n const match = keyword.exec(raw);\r\n if (match && match.index === i) {\r\n pushSegment(line, match[0], { color: theme.mdCodeKeyword, bold: true });\r\n i += match[0].length;\r\n continue;\r\n }\r\n }\r\n\r\n pushSegment(line, raw[i], { color: theme.mdCodeText });\r\n i += 1;\r\n }\r\n\r\n return line.length > 0 ? line : [{ text: '', color: theme.mdCodeText }];\r\n}\r\n\r\nexport function highlightCode(\r\n code: string,\r\n lang: string | undefined,\r\n theme: ThemeTokens,\r\n): StyledLine[] {\r\n const normalized = normalizeLang(lang);\r\n const key = `${normalized}\\0${code}\\0${JSON.stringify({\r\n keyword: theme.mdCodeKeyword,\r\n string: theme.mdCodeString,\r\n comment: theme.mdCodeComment,\r\n number: theme.mdCodeNumber,\r\n function: theme.mdCodeFunction,\r\n text: theme.mdCodeText,\r\n })}`;\r\n const cached = cache.get(key);\r\n if (cached) return cached;\r\n\r\n const lines = code.split('\\n').map((line) => highlightLine(line, normalized, theme));\r\n cache.set(key, lines);\r\n if (cache.size > MAX_CACHE_ENTRIES) {\r\n const oldest = cache.keys().next().value;\r\n if (oldest) cache.delete(oldest);\r\n }\r\n return lines;\r\n}\r\n","import { Text, Box } from 'ink';\r\nimport React, { useLayoutEffect, useMemo, useRef, useState, useEffect } from 'react';\r\nimport { marked, Tokens, Token } from 'marked';\r\nimport { useTheme } from '../theme.js';\r\nimport { useDensity } from '../density.js';\r\nimport { useTranscriptLayoutChange } from '../transcript-layout.js';\r\nimport { displayWidth, wordWrap } from './word-wrap.js';\r\nimport { highlightCode, type StyledLine } from './syntax-highlight.js';\r\nimport {\r\n layoutCodeBlock,\r\n layoutHeadingChrome,\r\n layoutHorizontalRule,\r\n layoutTable,\r\n markdownBlockGap,\r\n nestedContentWidth,\r\n sliceStyledLine,\r\n} from './markdown-layout.js';\r\n\r\n/** Columns a list is indented from the surrounding prose. */\r\nconst LIST_INDENT = 2;\r\n\r\ninterface MarkdownBlockProps {\r\n /** Raw markdown string to render. */\r\n content: string;\r\n /** Terminal width in columns for word-boundary wrapping. */\r\n terminalWidth?: number;\r\n /** While streaming, keep expensive final-pass decoration such as syntax highlighting disabled. */\r\n isStreaming?: boolean;\r\n /** Remove the final block's bottom margin when another transcript turn follows immediately. */\r\n trimTrailingMargin?: boolean;\r\n}\r\n\r\ntype InlineStyle = {\r\n color?: string;\r\n bold?: boolean;\r\n italic?: boolean;\r\n strikethrough?: boolean;\r\n underline?: boolean;\r\n dimColor?: boolean;\r\n};\r\n\r\ntype InlineRun = InlineStyle & { text: string };\r\n\r\ninterface RenderContext {\r\n textColor?: string;\r\n depth: number;\r\n isStreaming: boolean;\r\n /** Nested blockquote depth for width budgeting. */\r\n blockquoteDepth: number;\r\n}\r\n\r\nexport function wrapParagraphLines(rawText: string, terminalWidth: number): string[] {\r\n if (terminalWidth <= 0) return rawText.split('\\n');\r\n // wordWrap already hard-wraps overlong tokens with displayWidth semantics;\r\n // scanning every completed line a second time doubles paragraph render cost.\r\n return wordWrap(rawText, terminalWidth).split('\\n');\r\n}\r\n\r\n/**\r\n * Throttle a rapidly-changing value onto a fixed cadence, with an immediate\r\n * first render and a guaranteed trailing emit.\r\n *\r\n * Why: during streaming, `content` grows ~every 16ms (the accumulator flush).\r\n * `marked.lexer(content)` on every flush re-parses the whole string ~60×/sec\r\n * — the main CPU sink while a large assistant reply streams in. Throttling the\r\n * value React actually parses caps re-lex work to ~17×/sec regardless of how\r\n * fast `content` changes, and the trailing emit guarantees the final, complete\r\n * markdown always renders.\r\n *\r\n * Semantics:\r\n * - First value passed is emitted synchronously (no delayed first frame).\r\n * - A change while within `interval` of the last emit is held; it is flushed\r\n * on a trailing timer so the newest value always wins.\r\n * - A change after `interval` emits immediately.\r\n *\r\n * `ponytail:` no leading-edge coalesce on the very first call. If a future\r\n * caller streams a value that changes mid-first-frame and needs the leading\r\n * edge deferred too, pass an explicit `startPending` flag. Ceiling: none —\r\n * this is the standard throttle shape.\r\n */\r\nexport function useThrottledValue<T>(next: T, intervalMs: number, onEmit?: () => void): T {\r\n const [value, setValue] = useState<T>(next);\r\n const lastEmitRef = useRef<number | null>(null);\r\n const mountedRef = useRef(false);\r\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const nextRef = useRef<T>(next);\r\n const onEmitRef = useRef(onEmit);\r\n const notifiedValueRef = useRef(value);\r\n onEmitRef.current = onEmit;\r\n\r\n useEffect(() => {\r\n nextRef.current = next;\r\n if (!mountedRef.current) {\r\n mountedRef.current = true;\r\n lastEmitRef.current = Date.now();\r\n return;\r\n }\r\n if (next === value) return;\r\n const now = Date.now();\r\n const elapsed = now - (lastEmitRef.current ?? now);\r\n if (elapsed >= intervalMs) {\r\n lastEmitRef.current = now;\r\n setValue(next);\r\n return;\r\n }\r\n if (timerRef.current === null) {\r\n const remaining = intervalMs - elapsed;\r\n timerRef.current = setTimeout(() => {\r\n timerRef.current = null;\r\n lastEmitRef.current = Date.now();\r\n setValue(nextRef.current);\r\n }, remaining);\r\n }\r\n }, [next, intervalMs]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (timerRef.current !== null) {\r\n clearTimeout(timerRef.current);\r\n timerRef.current = null;\r\n }\r\n };\r\n }, []);\r\n\r\n useLayoutEffect(() => {\r\n if (value === notifiedValueRef.current) return;\r\n notifiedValueRef.current = value;\r\n onEmitRef.current?.();\r\n }, [value]);\r\n\r\n return value;\r\n}\r\n\r\nfunction mergeStyle(base: InlineStyle, next: InlineStyle): InlineStyle {\r\n return { ...base, ...next };\r\n}\r\n\r\nfunction appendRun(runs: InlineRun[], text: string, style: InlineStyle) {\r\n if (!text) return;\r\n const previous = runs[runs.length - 1];\r\n if (\r\n previous &&\r\n previous.color === style.color &&\r\n previous.bold === style.bold &&\r\n previous.italic === style.italic &&\r\n previous.strikethrough === style.strikethrough &&\r\n previous.underline === style.underline &&\r\n previous.dimColor === style.dimColor\r\n ) {\r\n previous.text += text;\r\n return;\r\n }\r\n // Style first, then text — callers may pass an InlineRun as `style`, and the\r\n // sliced `text` argument must win over any previous `style.text`.\r\n runs.push({ ...style, text });\r\n}\r\n\r\nfunction plainTextFromTokens(tokens: Token[]): string {\r\n const runs = inlineRunsFromTokens(tokens, { color: undefined }, undefined);\r\n return runs.map((run) => run.text).join('');\r\n}\r\n\r\nfunction inlineRunsFromTokens(\r\n tokens: Token[],\r\n style: InlineStyle,\r\n theme: ReturnType<typeof useTheme> | undefined,\r\n): InlineRun[] {\r\n const runs: InlineRun[] = [];\r\n for (const token of tokens) {\r\n switch (token.type) {\r\n case 'text': {\r\n const t = token as Tokens.Text & { tokens?: Token[] };\r\n if (t.tokens?.length) {\r\n runs.push(...inlineRunsFromTokens(t.tokens, style, theme));\r\n } else {\r\n appendRun(runs, t.text, style);\r\n }\r\n break;\r\n }\r\n case 'strong': {\r\n const t = token as Tokens.Strong;\r\n runs.push(...inlineRunsFromTokens(t.tokens, mergeStyle(style, { bold: true }), theme));\r\n break;\r\n }\r\n case 'em': {\r\n const t = token as Tokens.Em;\r\n runs.push(...inlineRunsFromTokens(t.tokens, mergeStyle(style, { italic: true }), theme));\r\n break;\r\n }\r\n case 'del': {\r\n const t = token as Tokens.Del;\r\n runs.push(\r\n ...inlineRunsFromTokens(\r\n t.tokens,\r\n mergeStyle(style, {\r\n strikethrough: true,\r\n color: theme?.subtle ?? style.color,\r\n }),\r\n theme,\r\n ),\r\n );\r\n break;\r\n }\r\n case 'codespan': {\r\n // Colour alone marks inline code. A background pill on every span\r\n // turned an ordinary paragraph into a row of highlighted badges, which\r\n // is exactly the noise the quiet palette removes everywhere else.\r\n const t = token as Tokens.Codespan;\r\n appendRun(\r\n runs,\r\n t.text,\r\n mergeStyle(style, { color: theme?.mdInlineCodeText ?? style.color }),\r\n );\r\n break;\r\n }\r\n case 'link': {\r\n const t = token as Tokens.Link;\r\n const linkRuns = inlineRunsFromTokens(\r\n t.tokens,\r\n mergeStyle(style, { color: theme?.mdLink ?? style.color, underline: true }),\r\n theme,\r\n );\r\n runs.push(...linkRuns);\r\n const label = linkRuns.map((run) => run.text).join('');\r\n if (t.href && t.href !== label) {\r\n appendRun(\r\n runs,\r\n ` (${t.href})`,\r\n mergeStyle(style, { color: theme?.mdLink ?? style.color }),\r\n );\r\n }\r\n break;\r\n }\r\n case 'image': {\r\n const t = token as Tokens.Image;\r\n appendRun(\r\n runs,\r\n `[Image: ${t.text || t.href}]`,\r\n mergeStyle(style, { color: theme?.mdLink ?? style.color, dimColor: true }),\r\n );\r\n break;\r\n }\r\n case 'br':\r\n appendRun(runs, '\\n', style);\r\n break;\r\n case 'escape': {\r\n const t = token as Tokens.Escape;\r\n appendRun(runs, t.text, style);\r\n break;\r\n }\r\n case 'html': {\r\n const t = token as Tokens.HTML;\r\n if (t.text && !t.block) appendRun(runs, t.text, mergeStyle(style, { dimColor: true }));\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n return runs;\r\n}\r\n\r\nfunction wrappedInlineRuns(runs: InlineRun[], terminalWidth: number): InlineRun[][] {\r\n const rawText = runs.map((run) => run.text).join('');\r\n const lines = wrapParagraphLines(rawText, terminalWidth);\r\n let searchOffset = 0;\r\n let runIndex = 0;\r\n let runOffset = 0;\r\n return lines.map((line) => {\r\n // wordWrap may collapse spaces or replace an original newline with a visual\r\n // line break. Locate each rendered slice in the source instead of assuming\r\n // every break consumed exactly one space; otherwise style offsets drift and\r\n // later lines can lose their final character.\r\n const locatedOffset = rawText.indexOf(line, searchOffset);\r\n const lineOffset = locatedOffset === -1 ? searchOffset : locatedOffset;\r\n const lineRuns: InlineRun[] = [];\r\n while (runIndex < runs.length && runOffset + runs[runIndex]!.text.length <= lineOffset) {\r\n runOffset += runs[runIndex]!.text.length;\r\n runIndex++;\r\n }\r\n\r\n let localIndex = runIndex;\r\n let localOffset = runOffset;\r\n const lineEnd = lineOffset + line.length;\r\n while (localIndex < runs.length && localOffset < lineEnd) {\r\n const run = runs[localIndex]!;\r\n const overlapStart = Math.max(localOffset, lineOffset);\r\n const overlapEnd = Math.min(localOffset + run.text.length, lineEnd);\r\n if (overlapStart < overlapEnd) {\r\n appendRun(\r\n lineRuns,\r\n run.text.slice(overlapStart - localOffset, overlapEnd - localOffset),\r\n run,\r\n );\r\n }\r\n localOffset += run.text.length;\r\n localIndex++;\r\n }\r\n searchOffset = lineOffset + line.length;\r\n return lineRuns;\r\n });\r\n}\r\n\r\ninterface FenceContext {\r\n marker: string;\r\n info: string;\r\n}\r\n\r\nfunction fenceOpening(context: FenceContext): string {\r\n return `${context.marker}${context.info}`;\r\n}\r\n\r\nfunction fenceContextAt(content: string, offset: number): FenceContext | undefined {\r\n let open: FenceContext | undefined;\r\n let lineStart = 0;\r\n\r\n while (lineStart < offset) {\r\n const lineEnd = content.indexOf('\\n', lineStart);\r\n if (lineEnd === -1 || lineEnd > offset) break;\r\n\r\n const line = content.slice(lineStart, lineEnd).replace(/\\r$/, '');\r\n const match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(line);\r\n if (match) {\r\n const marker = match[2]!;\r\n const rest = match[3]!;\r\n // Backtick fences cannot contain backticks in their info string.\r\n if (!(marker[0] === '`' && rest.includes('`'))) {\r\n if (open) {\r\n if (\r\n marker[0] === open.marker[0] &&\r\n marker.length >= open.marker.length &&\r\n rest.trim() === ''\r\n ) {\r\n open = undefined;\r\n }\r\n } else {\r\n open = { marker, info: rest.trim() };\r\n }\r\n }\r\n }\r\n\r\n lineStart = lineEnd + 1;\r\n }\r\n\r\n return open;\r\n}\r\n\r\nfunction standaloneBlockStart(content: string, offset: number): number | undefined {\r\n let lineStart = content.indexOf('\\n', offset);\r\n if (lineStart === -1) return undefined;\r\n lineStart++;\r\n\r\n while (lineStart < content.length) {\r\n const lineEnd = content.indexOf('\\n', lineStart);\r\n const line = content.slice(lineStart, lineEnd === -1 ? content.length : lineEnd);\r\n if (\r\n /^( {0,3})(?:#{1,6}(?:\\s|$)|>|(?:[-+*]|\\d+[.)])\\s|`{3,}|~{3,}|(?:[-*_]\\s*){3,}$)/.test(line)\r\n ) {\r\n return lineStart;\r\n }\r\n if (lineEnd === -1) return undefined;\r\n lineStart = lineEnd + 1;\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nfunction contextualStreamingTail(content: string, maxCharacters: number): string {\r\n const desiredStart = content.length - maxCharacters;\r\n if (desiredStart <= 0) return content;\r\n\r\n const context = fenceContextAt(content, desiredStart);\r\n if (context) {\r\n return `${fenceOpening(context)}\\n${content.slice(desiredStart)}`;\r\n }\r\n\r\n // Start complete Markdown blocks whenever possible. This avoids turning a\r\n // truncated table/list/paragraph prefix into a misleading partial block.\r\n const blankLine = content.indexOf('\\n\\n', desiredStart);\r\n const standaloneStart =\r\n blankLine === -1 ? standaloneBlockStart(content, desiredStart) : undefined;\r\n const start = blankLine >= 0 ? blankLine + 2 : standaloneStart;\r\n if (start === undefined) {\r\n const tail = content.slice(desiredStart);\r\n return /[*_`~[\\]<>|\\\\]/.test(tail) ? '' : tail;\r\n }\r\n const startContext = fenceContextAt(content, start);\r\n if (startContext) {\r\n return `${fenceOpening(startContext)}\\n${content.slice(start)}`;\r\n }\r\n return content.slice(start);\r\n}\r\n\r\nexport function streamingMarkdownWindow(content: string, terminalWidth?: number): string {\r\n const width = Math.max(20, Math.floor(terminalWidth ?? 80));\r\n // Keep enough history for the live tail to feel continuous without making\r\n // every throttled Markdown parse scale with the full assistant response.\r\n const maxCharacters = width * 24;\r\n if (content.length <= maxCharacters) return content;\r\n return `… earlier response hidden while streaming\\n\\n${contextualStreamingTail(content, maxCharacters)}`;\r\n}\r\n\r\nfunction InlineRuns({ runs }: { runs: InlineRun[] }) {\r\n // Parent already soft/hard-wrapped to terminal width — disable Ink re-wrap.\r\n return (\r\n <Text wrap=\"truncate\">\r\n {runs.map((run, i) => (\r\n <Text\r\n key={i}\r\n color={run.color}\r\n bold={run.bold}\r\n italic={run.italic}\r\n strikethrough={run.strikethrough}\r\n underline={run.underline}\r\n dimColor={run.dimColor}\r\n >\r\n {run.text}\r\n </Text>\r\n ))}\r\n </Text>\r\n );\r\n}\r\n\r\nfunction renderStyledLine(line: StyledLine, keyPrefix: string) {\r\n return (\r\n <Text>\r\n {line.map((segment, i) => (\r\n <Text\r\n key={`${keyPrefix}-${i}`}\r\n color={segment.color}\r\n bold={segment.bold}\r\n italic={segment.italic}\r\n dimColor={segment.dimColor}\r\n >\r\n {segment.text}\r\n </Text>\r\n ))}\r\n </Text>\r\n );\r\n}\r\n\r\nfunction renderTableCells(\r\n cells: string[],\r\n key: string,\r\n theme: ReturnType<typeof useTheme>,\r\n bold = false,\r\n) {\r\n return (\r\n <Box key={key} flexDirection=\"row\">\r\n <Text color={theme.mdTableBorder}>│ </Text>\r\n {cells.map((cell, ci) => (\r\n <React.Fragment key={`${key}-${ci}`}>\r\n <Text bold={bold} color={theme.text}>\r\n {cell}\r\n </Text>\r\n <Text color={theme.mdTableBorder}>{ci === cells.length - 1 ? ' │' : ' │ '}</Text>\r\n </React.Fragment>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Render a block-level token into an Ink Box/Text component tree.\r\n */\r\nfunction renderBlockToken(\r\n token: Token,\r\n theme: ReturnType<typeof useTheme>,\r\n index: number,\r\n terminalWidth: number | undefined,\r\n context: RenderContext,\r\n): React.ReactNode {\r\n switch (token.type) {\r\n case 'heading': {\r\n const t = token as Tokens.Heading;\r\n const text = plainTextFromTokens(t.tokens);\r\n const chrome = layoutHeadingChrome(text, t.depth, terminalWidth);\r\n if (t.depth === 1) {\r\n return (\r\n <Box key={`h-${index}`} flexDirection=\"column\">\r\n <Text bold color={theme.mdHeadingH1}>\r\n {chrome.prefix}\r\n {chrome.text}\r\n {chrome.suffix}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n if (t.depth === 2) {\r\n return (\r\n <Box key={`h-${index}`} flexDirection=\"column\">\r\n <Text bold color={theme.mdHeadingH2}>\r\n {chrome.prefix}\r\n {chrome.text}\r\n {chrome.suffix}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n return (\r\n <Box key={`h-${index}`} flexDirection=\"column\">\r\n <Text bold={t.depth <= 4} color={theme.mdHeading} dimColor={t.depth >= 5}>\r\n {chrome.prefix}\r\n {chrome.text}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n case 'paragraph': {\r\n const t = token as Tokens.Paragraph;\r\n const runs = inlineRunsFromTokens(\r\n t.tokens,\r\n { color: context.textColor ?? theme.text },\r\n theme,\r\n );\r\n if (terminalWidth) {\r\n const wrappedLines = wrappedInlineRuns(runs, terminalWidth);\r\n return (\r\n <Box key={`p-${index}`} flexDirection=\"column\" flexGrow={1}>\r\n {wrappedLines.map((lineRuns, li) => (\r\n <Box key={`pw-${index}-${li}`} flexDirection=\"row\">\r\n <InlineRuns runs={lineRuns} />\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n }\r\n return (\r\n <Box key={`p-${index}`} flexDirection=\"row\" flexGrow={1}>\r\n <InlineRuns runs={runs} />\r\n </Box>\r\n );\r\n }\r\n\r\n case 'code': {\r\n const t = token as Tokens.Code;\r\n const lines = t.text.split('\\n');\r\n const displayLines =\r\n lines.length > 0 && lines[lines.length - 1] === '' ? lines.slice(0, -1) : lines;\r\n const layout = layoutCodeBlock(displayLines, terminalWidth, {\r\n lang: t.lang,\r\n preferLineNumbers: displayLines.length > 5,\r\n });\r\n const highlighted = context.isStreaming\r\n ? undefined\r\n : highlightCode(displayLines.join('\\n'), t.lang, theme);\r\n\r\n const widthProp =\r\n terminalWidth && terminalWidth > 0 ? { width: Math.max(1, Math.floor(terminalWidth)) } : {};\r\n\r\n // A left rail plus the code tint, never a four-sided box: the border used\r\n // to be the heaviest element in an answer, wrapped around its smallest.\r\n const boxProps = layout.showRail\r\n ? {\r\n ...widthProp,\r\n paddingLeft: 1 as const,\r\n borderLeft: true,\r\n borderTop: false,\r\n borderRight: false,\r\n borderBottom: false,\r\n borderStyle: 'single' as const,\r\n borderColor: theme.mdCodeBorder,\r\n backgroundColor: theme.mdCodeBackground,\r\n }\r\n : {\r\n ...widthProp,\r\n backgroundColor: theme.mdCodeBackground,\r\n };\r\n\r\n return (\r\n <Box key={`code-${index}`} flexDirection=\"column\">\r\n {layout.langLabel ? (\r\n // On the rail, not floating above it. A bare dim word at the prose\r\n // indent with nothing joining it to the block below reads as a\r\n // one-word paragraph — `js` sitting in the answer as if the model\r\n // had said it. Sharing the rail makes it a caption on the block.\r\n <Box {...(layout.showRail ? railCaptionProps(theme) : {})}>\r\n <Text color={theme.mdCodeBorder} dimColor>\r\n {layout.langLabel}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n <Box flexDirection=\"column\" {...boxProps}>\r\n {layout.lines.map((visual, vi) => {\r\n const highlightedLine = highlighted?.[visual.sourceLineIndex];\r\n const segments: StyledLine = highlightedLine\r\n ? sliceStyledLine(highlightedLine, visual.sourceStart, visual.sourceEnd)\r\n : [{ text: visual.text, color: theme.mdCodeText }];\r\n const safeSegments: StyledLine =\r\n segments.length > 0 ? segments : [{ text: visual.text, color: theme.mdCodeText }];\r\n\r\n return (\r\n <Box key={`code-${index}-v${vi}`}>\r\n {layout.showLineNumbers ? (\r\n <Text color={theme.mdCodeLineNumber} dimColor>\r\n {visual.gutter}\r\n </Text>\r\n ) : null}\r\n {highlighted ? (\r\n renderStyledLine(safeSegments, `code-${index}-${vi}`)\r\n ) : (\r\n <Text color={theme.mdCodeText}>{visual.text}</Text>\r\n )}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n case 'blockquote': {\r\n const t = token as Tokens.Blockquote;\r\n // Incremental budget: border + paddingLeft ≈ 2 columns per quote level.\r\n const childWidth =\r\n terminalWidth !== undefined ? Math.max(1, Math.floor(terminalWidth) - 2) : undefined;\r\n return (\r\n <Box\r\n key={`bq-${index}`}\r\n flexDirection=\"column\"\r\n borderStyle=\"single\"\r\n borderLeft\r\n borderTop={false}\r\n borderRight={false}\r\n borderBottom={false}\r\n borderLeftColor={theme.mdBlockquoteBorder}\r\n paddingLeft={1}\r\n >\r\n {t.tokens.map((childToken, ci) =>\r\n renderBlockToken(childToken, theme, index * 1000 + ci, childWidth, {\r\n ...context,\r\n textColor: theme.mdBlockquoteText,\r\n blockquoteDepth: context.blockquoteDepth + 1,\r\n }),\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n case 'list': {\r\n const t = token as Tokens.List;\r\n const markerFor = (item: Tokens.ListItem, ii: number): string =>\r\n item.task\r\n ? item.checked\r\n ? '[x]'\r\n : '[ ]'\r\n : t.ordered\r\n ? `${(typeof t.start === 'number' ? t.start : 1) + ii}.`\r\n : '•';\r\n // One marker column for the whole list, sized to its widest marker: a\r\n // per-item width shears the text column between items 9 and 10, and a\r\n // fixed width leaves a dead column after every bullet.\r\n const markerWidth =\r\n Math.max(...t.items.map((item, ii) => displayWidth(markerFor(item, ii))), 1) + 1;\r\n return (\r\n <Box key={`list-${index}`} flexDirection=\"column\" marginLeft={context.depth > 0 ? 2 : 0}>\r\n {t.items.map((item, ii) => {\r\n const marker = markerFor(item, ii);\r\n const markerColor = item.task\r\n ? item.checked\r\n ? theme.mdCheckboxChecked\r\n : theme.mdCheckboxUnchecked\r\n : theme.mdListMarker;\r\n // Incremental: marker column + margins. Nested lists receive an already-reduced width.\r\n const itemWidth = nestedContentWidth(terminalWidth, {\r\n depth: 0,\r\n listGutter: LIST_INDENT + markerWidth,\r\n blockquoteDepth: 0,\r\n });\r\n return (\r\n <Box key={`li-${index}-${ii}`} flexDirection=\"row\" marginLeft={LIST_INDENT}>\r\n <Box width={markerWidth} flexShrink={0}>\r\n <Text color={markerColor}>{marker}</Text>\r\n </Box>\r\n <Box flexDirection=\"column\" flexGrow={1}>\r\n {item.tokens.map((childToken, ci) => {\r\n if (childToken.type === 'text') {\r\n const textToken = childToken as Tokens.Text & { tokens?: Token[] };\r\n const childRuns = textToken.tokens?.length\r\n ? inlineRunsFromTokens(\r\n textToken.tokens,\r\n { color: context.textColor ?? theme.text },\r\n theme,\r\n )\r\n : [{ text: textToken.text, color: context.textColor ?? theme.text }];\r\n if (itemWidth) {\r\n const wrapped = wrappedInlineRuns(childRuns, itemWidth);\r\n return (\r\n <Box key={`lit-${index}-${ii}-${ci}`} flexDirection=\"column\">\r\n {wrapped.map((lineRuns, li) => (\r\n <Box key={`lit-${index}-${ii}-${ci}-l${li}`}>\r\n <InlineRuns runs={lineRuns} />\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n }\r\n return (\r\n <Box key={`lit-${index}-${ii}-${ci}`}>\r\n <InlineRuns runs={childRuns} />\r\n </Box>\r\n );\r\n }\r\n return renderBlockToken(\r\n childToken,\r\n theme,\r\n index * 1000 + ii * 100 + ci,\r\n itemWidth,\r\n { ...context, depth: context.depth + 1 },\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n );\r\n }\r\n\r\n case 'hr': {\r\n const rule = layoutHorizontalRule(terminalWidth);\r\n return (\r\n <Box key={`hr-${index}`}>\r\n <Text color={theme.mdHr} dimColor>\r\n {rule}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n case 'table': {\r\n const t = token as Tokens.Table;\r\n if (t.header.length === 0 && t.rows.length === 0) return null;\r\n\r\n const layout = layoutTable({\r\n header: t.header.map((cell) => ({ text: plainTextFromTokens(cell.tokens) })),\r\n rows: t.rows.map((row) => row.map((cell) => ({ text: plainTextFromTokens(cell.tokens) }))),\r\n align: t.align ?? [],\r\n terminalWidth: terminalWidth ?? 80,\r\n });\r\n\r\n if (layout.mode === 'stacked') {\r\n return (\r\n <Box key={`table-${index}`} flexDirection=\"column\">\r\n {layout.lines.map((line, li) => (\r\n <Text key={`table-${index}-s${li}`} color={theme.text}>\r\n {line}\r\n </Text>\r\n ))}\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box key={`table-${index}`} flexDirection=\"column\">\r\n <Text color={theme.mdTableBorder}>{layout.top}</Text>\r\n {layout.headerRows.map((row, ri) =>\r\n renderTableCells(row, `tr-${index}-h${ri}`, theme, true),\r\n )}\r\n <Text color={theme.mdTableBorder}>{layout.middle}</Text>\r\n {layout.bodyRows.map((row, ri) => renderTableCells(row, `tr-${index}-${ri}`, theme))}\r\n <Text color={theme.mdTableBorder}>{layout.bottom}</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n case 'space':\r\n return null;\r\n\r\n case 'html': {\r\n const t = token as Tokens.HTML;\r\n if (t.block && t.text) {\r\n return (\r\n <Box key={`html-${index}`}>\r\n <Text color={theme.subtle} dimColor>\r\n {t.text}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n return null;\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Renders markdown content into Ink components.\r\n *\r\n * Uses marked.lexer() to tokenize the markdown string, then maps each\r\n * block-level token to Ink Box/Text components with appropriate styling\r\n * from the current theme (mdCodeBackground, mdHeading, mdLink, etc.).\r\n */\r\ninterface MarkdownRendererProps {\r\n content: string;\r\n terminalWidth?: number;\r\n isStreaming: boolean;\r\n theme: ReturnType<typeof useTheme>;\r\n density: ReturnType<typeof useDensity>;\r\n}\r\n\r\nconst MarkdownRenderer = React.memo(function MarkdownRenderer({\r\n content,\r\n terminalWidth,\r\n isStreaming,\r\n theme,\r\n density,\r\n}: MarkdownRendererProps) {\r\n const tokens = useMemo(\r\n () => marked.lexer(content).filter((token) => token.type !== 'space'),\r\n [content],\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n {tokens.map((token, i) => {\r\n const gap = markdownBlockGap(tokens[i - 1]?.type, token.type, density);\r\n return (\r\n <React.Fragment key={`block-${i}`}>\r\n {gap > 0 ? <Box height={gap} /> : null}\r\n {renderBlockToken(token, theme, i, terminalWidth, {\r\n depth: 0,\r\n isStreaming,\r\n blockquoteDepth: 0,\r\n })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </Box>\r\n );\r\n});\r\n\r\n/** The rail a code block draws down its left edge, for its caption to share. */\r\nfunction railCaptionProps(theme: ReturnType<typeof useTheme>) {\r\n return {\r\n paddingLeft: 1 as const,\r\n borderLeft: true,\r\n borderTop: false,\r\n borderRight: false,\r\n borderBottom: false,\r\n borderStyle: 'single' as const,\r\n borderColor: theme.mdCodeBorder,\r\n };\r\n}\r\n\r\nexport function MarkdownBlock({ content, terminalWidth, isStreaming = false }: MarkdownBlockProps) {\r\n const theme = useTheme();\r\n const density = useDensity();\r\n const notifyLayoutChange = useTranscriptLayoutChange();\r\n\r\n const parsedContent = useThrottledValue(content, 60, notifyLayoutChange ?? undefined);\r\n // Completed content should never wait for the streaming throttle. This also\r\n // ensures the final render highlights the complete response immediately.\r\n const effectiveContent = isStreaming ? parsedContent || content : content;\r\n // Keep the live view bounded, but use the same Markdown tree as the final\r\n // view. This avoids a visible raw-text-to-Markdown layout swap when a large\r\n // response completes; streaming only disables expensive code highlighting.\r\n const displayContent = useMemo(\r\n () =>\r\n isStreaming ? streamingMarkdownWindow(effectiveContent, terminalWidth) : effectiveContent,\r\n [effectiveContent, isStreaming, terminalWidth],\r\n );\r\n\r\n if (!displayContent) return null;\r\n\r\n return (\r\n <MarkdownRenderer\r\n content={displayContent}\r\n terminalWidth={terminalWidth}\r\n isStreaming={isStreaming}\r\n theme={theme}\r\n density={density}\r\n />\r\n );\r\n}\r\n","/* Hallmark pre-emit critique: P5 H5 E5 S5 R5 V4 */\r\n\r\nimport { createContext, useContext } from 'react';\r\n\r\nexport type TuiDensity = 'compact' | 'tight';\r\n\r\nexport interface DensityMetrics {\r\n panelMarginY: 0;\r\n turnMarginY: 0;\r\n userPaddingX: 1;\r\n userPaddingY: 0;\r\n headingGapBefore: 0 | 1;\r\n majorBlockGap: 0 | 1;\r\n /** Blank rows between consecutive tool rows. Zero: they read as one column. */\r\n toolRowGap: 0 | 1;\r\n /** Blank rows between prose and the tool block that follows it. */\r\n toolBlockGap: 0 | 1;\r\n paragraphGap: 1;\r\n showOptionalHelp: boolean;\r\n}\r\n\r\nconst COMPACT_METRICS: DensityMetrics = {\r\n panelMarginY: 0,\r\n turnMarginY: 0,\r\n userPaddingX: 1,\r\n userPaddingY: 0,\r\n headingGapBefore: 1,\r\n majorBlockGap: 1,\r\n toolRowGap: 0,\r\n toolBlockGap: 1,\r\n paragraphGap: 1,\r\n showOptionalHelp: true,\r\n};\r\n\r\nconst TIGHT_METRICS: DensityMetrics = {\r\n ...COMPACT_METRICS,\r\n headingGapBefore: 0,\r\n majorBlockGap: 0,\r\n toolRowGap: 0,\r\n toolBlockGap: 0,\r\n showOptionalHelp: false,\r\n};\r\n\r\nexport const DensityContext = createContext<TuiDensity>('compact');\r\n\r\nexport function resolveTuiDensity(rows: number): TuiDensity {\r\n return Math.floor(rows) < 18 ? 'tight' : 'compact';\r\n}\r\n\r\nexport function densityMetrics(density: TuiDensity): DensityMetrics {\r\n return density === 'tight' ? TIGHT_METRICS : COMPACT_METRICS;\r\n}\r\n\r\nexport function useDensity(): TuiDensity {\r\n return useContext(DensityContext);\r\n}\r\n\r\nexport function useDensityMetrics(): DensityMetrics {\r\n return densityMetrics(useDensity());\r\n}\r\n","import { createContext, useContext, useEffect, useSyncExternalStore } from 'react';\r\n\r\nexport type TranscriptLayoutChange = () => void;\r\nexport type TranscriptHistoryRequest = 'page' | 'all';\r\nexport type TranscriptHistoryLoader = (request: TranscriptHistoryRequest) => boolean;\r\n\r\ninterface TranscriptHistoryRegistry {\r\n register: (loader: TranscriptHistoryLoader) => () => void;\r\n}\r\n\r\nexport interface TranscriptViewportSnapshot {\r\n scrollTop: number;\r\n viewportRows: number;\r\n followBottom: boolean;\r\n}\r\n\r\nexport interface TranscriptViewportStore {\r\n subscribe: (listener: () => void) => () => void;\r\n getRevision: () => number;\r\n getSnapshot: () => TranscriptViewportSnapshot;\r\n}\r\n\r\nexport const TranscriptLayoutContext = createContext<TranscriptLayoutChange | null>(null);\r\nexport const TranscriptHistoryContext = createContext<TranscriptHistoryRegistry | null>(null);\r\nexport const TranscriptViewportContext = createContext<TranscriptViewportStore | null>(null);\r\n\r\nexport function useTranscriptLayoutChange(): TranscriptLayoutChange | null {\r\n return useContext(TranscriptLayoutContext);\r\n}\r\n\r\nexport function useTranscriptHistoryLoader(loader: TranscriptHistoryLoader): void {\r\n const registry = useContext(TranscriptHistoryContext);\r\n useEffect(() => registry?.register(loader), [loader, registry]);\r\n}\r\n\r\nexport function useTranscriptViewport(): TranscriptViewportSnapshot | null {\r\n const store = useContext(TranscriptViewportContext);\r\n useSyncExternalStore(\r\n store?.subscribe ?? subscribeNoop,\r\n store?.getRevision ?? getZeroRevision,\r\n getZeroRevision,\r\n );\r\n return store?.getSnapshot() ?? null;\r\n}\r\n\r\nfunction subscribeNoop(): () => void {\r\n return () => {};\r\n}\r\n\r\nfunction getZeroRevision(): number {\r\n return 0;\r\n}\r\n","/**\r\n * Pure layout helpers for MarkdownBlock: tables, fenced code chrome, and\r\n * nested block width budgets. All measurements use displayWidth (CJK/emoji\r\n * safe). No React imports — unit-testable without Ink.\r\n */\r\n\r\nimport {\r\n displayWidth,\r\n hardWrapLine,\r\n makeDivider,\r\n padDisplay,\r\n truncateDisplay,\r\n wordWrap,\r\n} from './word-wrap.js';\r\nimport type { TuiDensity } from '../density.js';\r\n\r\nexport function markdownBlockGap(\r\n previous: string | undefined,\r\n next: string,\r\n density: TuiDensity,\r\n): 0 | 1 {\r\n if (!previous) return 0;\r\n if (previous === 'heading') return 0;\r\n if (next === 'heading') return density === 'compact' ? 1 : 0;\r\n if (previous === 'paragraph' && next === 'paragraph') return 1;\r\n\r\n const major = new Set(['code', 'table', 'blockquote', 'hr']);\r\n if (major.has(previous) || major.has(next)) return density === 'compact' ? 1 : 0;\r\n\r\n return 0;\r\n}\r\n\r\nexport type TableAlign = 'left' | 'right' | 'center' | null | undefined;\r\n\r\nexport interface TableCellInput {\r\n text: string;\r\n}\r\n\r\nexport interface TableLayoutInput {\r\n header: TableCellInput[];\r\n rows: TableCellInput[][];\r\n align?: TableAlign[];\r\n /** Available terminal columns for the whole table (including borders). */\r\n terminalWidth: number;\r\n}\r\n\r\nexport interface TableGridLayout {\r\n mode: 'grid';\r\n /** Display widths of cell content (excluding padding/borders). */\r\n colWidths: number[];\r\n /** Full border/body line width (display columns). */\r\n totalWidth: number;\r\n top: string;\r\n middle: string;\r\n bottom: string;\r\n /** First visual header row (padded cells). */\r\n headerCells: string[];\r\n /** Full multi-line header rows (padded cells). */\r\n headerRows: string[][];\r\n bodyRows: string[][];\r\n}\r\n\r\nexport interface TableStackedLayout {\r\n mode: 'stacked';\r\n /** Lines like \"Header: value\", already hard-wrapped to terminalWidth. */\r\n lines: string[];\r\n}\r\n\r\nexport type TableLayout = TableGridLayout | TableStackedLayout;\r\n\r\nexport interface CodeLineLayout {\r\n /** Gutter prefix for this visual line (line number + separator, or continuation spaces). */\r\n gutter: string;\r\n /** Hard-wrapped content segment for this visual line. */\r\n text: string;\r\n /** 0-based source line index in the original fenced block. */\r\n sourceLineIndex: number;\r\n /** Character offset into the original source line where `text` starts. */\r\n sourceStart: number;\r\n /** Character offset into the original source line where `text` ends (exclusive). */\r\n sourceEnd: number;\r\n /** True when this is a continuation of a previous hard-wrap for the same source line. */\r\n isContinuation: boolean;\r\n}\r\n\r\nexport interface CodeBlockLayout {\r\n /** Render the left rail (a border column plus one column of padding). */\r\n showRail: boolean;\r\n showLineNumbers: boolean;\r\n /** Content columns available after border/padding/gutter. */\r\n contentWidth: number;\r\n /** Full outer width budget used for border lines. */\r\n outerWidth: number;\r\n /** Language label, truncated to contentWidth when present. */\r\n langLabel: string | null;\r\n /** Flattened visual lines ready to render. */\r\n lines: CodeLineLayout[];\r\n}\r\n\r\nconst MIN_CELL = 1;\r\n// Row format: │ + \" \" + cell + \" \" + │ ... → per column: 3 chrome chars + width,\r\n// plus one final │. Equivalently: 1 + sum(width_i + 3) for n columns?\r\n// Actual: \"│ \" + cell + \" │ \" + cell + \" │\"\r\n// Between cells: \" │ \" (3), left edge \"│ \" (2), right edge \"│\" (1).\r\n// total = 1 (left │) + n * (1 space + width + 1 space) + (n-1) * 1 (│ between) + 1?\r\n// Looking at current MarkdownBlock: `│ ` + cell + ` │ ` between + final via same pattern.\r\n// renderTableRow: <Text>│ </Text> then for each cell: cell + ` │ `\r\n// So: \"│ \" + cell0 + \" │ \" + cell1 + \" │ \" ... = 2 + sum(width_i + 3) for each cell\r\n// = 2 + n*width + 3n = n*width + 3n + 2\r\n// Border: ┌ + ─.repeat(w+2) joined by ┬ + ┐\r\n// = 1 + sum(w+2) + (n-1) + 1 = n*w + 2n + n + 1? join('┬') adds n-1 seps of 1\r\n// = 1 + sum(w_i+2) + (n-1) + 1 = sum(w_i) + 2n + n - 1 + 2 = sum(w) + 3n + 1\r\n// Row body: \"│ \" (2) + for each: cell + \" │ \" (width+3) = 2 + sum(w)+3n = sum(w)+3n+2\r\n// Off-by-one: border is sum(w)+3n+1, body is sum(w)+3n+2\r\n// Looking at existing code:\r\n// const separator = colWidths.map((width) => '─'.repeat(width + 2));\r\n// const top = `┌${separator.join('┬')}┐`;\r\n// For widths [3,3]: sep = ['─────','─────'] join ┬ → ┌─────┬─────┐ length = 1+5+1+5+1=13\r\n// Body: │ + space + 3 + space + │ + space + 3 + space + │ = 2+3+3+2+3+3?\r\n// \"│ \" + \"aaa\" + \" │ \" + \"bbb\" + \" │\" = 2+3+3+3+3+2 wait\r\n// \"│ \" = 2, cell=3, \" │ \" = 3, cell=3, \" │\" = 2 → 2+3+3+3+2 = 13. Yes!\r\n// So totalWidth = sum(w_i + 2) + (n - 1) + 2 = sum(w) + 2n + n - 1 + 2 = sum(w) + 3n + 1\r\n// With the trailing \" │\" being 2 chars (space+│) not 3.\r\n// Formula: 1 + sum(width_i + 2) + (n-1) = sum(width) + 3n\r\n\r\nfunction tableChromeWidth(colWidths: number[]): number {\r\n if (colWidths.length === 0) return 0;\r\n // ┌ + ─×(w+2) joined by ┬ + ┐ == sum(w) + 3n\r\n // Body: \"│ \" + cells with \" │ \" separators ending in \" │\" matches same width.\r\n return colWidths.reduce((sum, w) => sum + w + 2, 0) + (colWidths.length - 1) + 2;\r\n}\r\n\r\nfunction normalizeAlign(align: TableAlign): 'left' | 'right' | 'center' {\r\n if (align === 'right' || align === 'center') return align;\r\n return 'left';\r\n}\r\n\r\n/**\r\n * Allocate column content widths that fit inside `terminalWidth`.\r\n * Prefers natural content widths; shrinks proportionally when needed.\r\n * Returns null when even minimum columns cannot fit (caller should stack).\r\n */\r\nexport function allocateTableColumns(\r\n naturalWidths: number[],\r\n terminalWidth: number,\r\n): number[] | null {\r\n const n = naturalWidths.length;\r\n if (n === 0) return [];\r\n\r\n const minTotal = tableChromeWidth(Array<number>(n).fill(MIN_CELL));\r\n if (terminalWidth < minTotal) return null;\r\n\r\n const natural = naturalWidths.map((w) => Math.max(MIN_CELL, Math.ceil(w)));\r\n const naturalTotal = tableChromeWidth(natural);\r\n if (naturalTotal <= terminalWidth) return natural;\r\n\r\n // tableChromeWidth(zeros) = 0*n + 3n = 3n ... wait:\r\n // sum(0+2) + (n-1) + 2 = 2n + n - 1 + 2 = 3n + 1. Yes.\r\n // contentBudget = terminalWidth - (3n + 1), and sum(widths) must equal contentBudget?\r\n // total = sum(w) + 3n + 1 => sum(w) = terminalWidth - 3n - 1\r\n const sumTarget = terminalWidth - 3 * n - 1;\r\n if (sumTarget < n * MIN_CELL) return null;\r\n\r\n // Start from natural, shrink largest columns first until sum fits.\r\n const widths = [...natural];\r\n let sum = widths.reduce((a, b) => a + b, 0);\r\n while (sum > sumTarget) {\r\n let maxIdx = 0;\r\n for (let i = 1; i < n; i++) {\r\n if (widths[i]! > widths[maxIdx]!) maxIdx = i;\r\n }\r\n if (widths[maxIdx]! <= MIN_CELL) break;\r\n widths[maxIdx]! -= 1;\r\n sum -= 1;\r\n }\r\n\r\n if (sum > sumTarget) return null;\r\n // Distribute any leftover to the widest natural columns for readability.\r\n let leftover = sumTarget - sum;\r\n while (leftover > 0) {\r\n let maxIdx = 0;\r\n for (let i = 1; i < n; i++) {\r\n if (natural[i]! > natural[maxIdx]!) maxIdx = i;\r\n }\r\n // Prefer columns that are still below natural width.\r\n let growIdx = -1;\r\n for (let i = 0; i < n; i++) {\r\n if (widths[i]! < natural[i]!) {\r\n if (growIdx < 0 || natural[i]! > natural[growIdx]!) growIdx = i;\r\n }\r\n }\r\n if (growIdx < 0) growIdx = maxIdx;\r\n widths[growIdx]! += 1;\r\n leftover -= 1;\r\n }\r\n\r\n return widths;\r\n}\r\n\r\nfunction wrapCellLines(text: string, width: number): string[] {\r\n if (width <= 0) return [''];\r\n const soft = wordWrap(text, width);\r\n const out: string[] = [];\r\n for (const line of soft.split('\\n')) {\r\n out.push(...hardWrapLine(line, width));\r\n }\r\n return out.length > 0 ? out : [''];\r\n}\r\n\r\nfunction buildBorder(colWidths: number[], left: string, join: string, right: string): string {\r\n return `${left}${colWidths.map((w) => '─'.repeat(w + 2)).join(join)}${right}`;\r\n}\r\n\r\n/**\r\n * Layout a markdown table for the given terminal width.\r\n * Falls back to stacked \"Header: value\" lines when the grid cannot fit.\r\n */\r\nexport function layoutTable(input: TableLayoutInput): TableLayout {\r\n const { header, rows, align = [], terminalWidth } = input;\r\n const colCount = Math.max(header.length, ...rows.map((r) => r.length), 0);\r\n if (colCount === 0) {\r\n return { mode: 'stacked', lines: [] };\r\n }\r\n\r\n const normalizedHeader = Array.from({ length: colCount }, (_, i) => header[i]?.text ?? '');\r\n const normalizedRows = rows.map((row) =>\r\n Array.from({ length: colCount }, (_, i) => row[i]?.text ?? ''),\r\n );\r\n\r\n const naturalWidths: number[] = Array.from({ length: colCount }, () => MIN_CELL);\r\n for (let ci = 0; ci < colCount; ci++) {\r\n naturalWidths[ci] = Math.max(naturalWidths[ci]!, displayWidth(normalizedHeader[ci]!));\r\n for (const row of normalizedRows) {\r\n naturalWidths[ci] = Math.max(naturalWidths[ci]!, displayWidth(row[ci]!));\r\n }\r\n }\r\n\r\n const widthBudget = Math.max(0, Math.floor(terminalWidth));\r\n const colWidths = allocateTableColumns(naturalWidths, widthBudget);\r\n\r\n // Prefer stacked layout when columns are extremely narrow relative to content\r\n // or allocation failed (too many columns / tiny terminal).\r\n const tooNarrow =\r\n colWidths === null ||\r\n colWidths.some((w, i) => w < 3 && naturalWidths[i]! > w * 2) ||\r\n (colCount >= 4 && widthBudget < colCount * 8);\r\n\r\n if (tooNarrow || colWidths === null) {\r\n return {\r\n mode: 'stacked',\r\n lines: layoutStackedTable(normalizedHeader, normalizedRows, widthBudget),\r\n };\r\n }\r\n\r\n // Wrap header + body cells; expand multi-line cells into stacked visual rows.\r\n const headerLineGroups = normalizedHeader.map((text, ci) => wrapCellLines(text, colWidths[ci]!));\r\n const headerHeight = Math.max(1, ...headerLineGroups.map((lines) => lines.length));\r\n const headerRows: string[][] = [];\r\n for (let li = 0; li < headerHeight; li++) {\r\n headerRows.push(\r\n headerLineGroups.map((lines, ci) =>\r\n padDisplay(lines[li] ?? '', colWidths[ci]!, normalizeAlign(align[ci])),\r\n ),\r\n );\r\n }\r\n\r\n const bodyRows: string[][] = [];\r\n for (const row of normalizedRows) {\r\n const cellLines = row.map((text, ci) => wrapCellLines(text, colWidths[ci]!));\r\n const height = Math.max(1, ...cellLines.map((lines) => lines.length));\r\n for (let li = 0; li < height; li++) {\r\n bodyRows.push(\r\n cellLines.map((lines, ci) =>\r\n padDisplay(lines[li] ?? '', colWidths[ci]!, normalizeAlign(align[ci])),\r\n ),\r\n );\r\n }\r\n }\r\n\r\n const totalWidth = tableChromeWidth(colWidths);\r\n return {\r\n mode: 'grid',\r\n colWidths,\r\n totalWidth,\r\n top: buildBorder(colWidths, '┌', '┬', '┐'),\r\n middle: buildBorder(colWidths, '├', '┼', '┤'),\r\n bottom: buildBorder(colWidths, '└', '┴', '┘'),\r\n // First visual header row kept as headerCells for simple consumers;\r\n // full multi-line header is in headerRows.\r\n headerCells: headerRows[0] ?? Array(colCount).fill(''.padEnd(0)),\r\n headerRows,\r\n bodyRows,\r\n };\r\n}\r\n\r\nfunction layoutStackedTable(header: string[], rows: string[][], terminalWidth: number): string[] {\r\n const width = Math.max(1, terminalWidth);\r\n const lines: string[] = [];\r\n for (const row of rows) {\r\n if (lines.length > 0) lines.push(''); // blank separator between records\r\n for (let ci = 0; ci < header.length; ci++) {\r\n const label = header[ci]?.trim() || `Col ${ci + 1}`;\r\n const value = row[ci] ?? '';\r\n const combined = `${label}: ${value}`;\r\n const wrapped = wordWrap(combined, width).split('\\n');\r\n for (const line of wrapped) {\r\n lines.push(...hardWrapLine(line, width));\r\n }\r\n }\r\n }\r\n // If there are headers but no body rows, still show headers.\r\n if (rows.length === 0 && header.some((h) => h.length > 0)) {\r\n for (const h of header) {\r\n lines.push(...hardWrapLine(h, width));\r\n }\r\n }\r\n return lines;\r\n}\r\n\r\n/** Nested content budget after list markers / blockquote bars. */\r\nexport function nestedContentWidth(\r\n terminalWidth: number | undefined,\r\n options: { depth?: number; listGutter?: number; blockquoteDepth?: number } = {},\r\n): number | undefined {\r\n if (terminalWidth === undefined) return undefined;\r\n const depth = options.depth ?? 0;\r\n const listGutter = options.listGutter ?? 5; // marker column + margins\r\n const bq = options.blockquoteDepth ?? 0;\r\n // Each list depth: +2 marginLeft on list + 2 on item ≈ 4, plus marker width ~3.\r\n // Keep a conservative clamp matching previous Math.max(10, terminalWidth - 5 - depth*2).\r\n const listDeduction = listGutter + depth * 2;\r\n const bqDeduction = bq * 2; // border + paddingLeft\r\n return Math.max(1, Math.floor(terminalWidth) - listDeduction - bqDeduction);\r\n}\r\n\r\n/** Clamp decorative heading chrome so it fits `terminalWidth`. */\r\nexport function layoutHeadingChrome(\r\n text: string,\r\n depth: number,\r\n terminalWidth: number | undefined,\r\n): { prefix: string; text: string; suffix: string } {\r\n // Headings are bold and brightness-ranked by depth (see MarkdownBlock). They\r\n // carry no `=== TEXT ===` side chrome: that competed with the turn rule for\r\n // the eye and made an in-answer heading look like a transcript boundary.\r\n const budget = terminalWidth && terminalWidth > 0 ? Math.max(1, Math.floor(terminalWidth)) : null;\r\n return {\r\n prefix: '',\r\n text: budget === null || fitsIn(text, budget) ? text : truncateDisplay(text, budget),\r\n suffix: '',\r\n };\r\n}\r\n\r\nfunction fitsIn(text: string, width: number): boolean {\r\n return displayWidth(text) <= width;\r\n}\r\n\r\n/** Horizontal rule that respects terminal width (min 5, max 60). */\r\nexport function layoutHorizontalRule(terminalWidth: number | undefined): string {\r\n const width = terminalWidth && terminalWidth > 0 ? Math.floor(terminalWidth) : 40;\r\n return makeDivider(Math.min(width, 60), 0, '─');\r\n}\r\n\r\n/**\r\n * Layout a fenced code block.\r\n *\r\n * Accounts for the left rail (1) + its padding (1) + an optional line-number\r\n * gutter. Hard-wraps unbroken source lines; continuation lines use a blank\r\n * gutter so the numbering stays readable.\r\n */\r\nexport function layoutCodeBlock(\r\n sourceLines: string[],\r\n terminalWidth: number | undefined,\r\n options: { lang?: string; preferLineNumbers?: boolean } = {},\r\n): CodeBlockLayout {\r\n const preferLineNumbers = options.preferLineNumbers ?? sourceLines.length > 5;\r\n const lang = options.lang?.trim() || null;\r\n\r\n // Without a known width, keep full chrome and do not wrap (Ink may hard-wrap).\r\n if (!terminalWidth || terminalWidth <= 0) {\r\n const gutterWidth = String(Math.max(sourceLines.length, 1)).length;\r\n const showLineNumbers = preferLineNumbers;\r\n const lines: CodeLineLayout[] = sourceLines.map((text, i) => {\r\n const gutter = showLineNumbers ? `${String(i + 1).padStart(gutterWidth, ' ')} │ ` : '';\r\n return {\r\n gutter,\r\n text,\r\n sourceLineIndex: i,\r\n sourceStart: 0,\r\n sourceEnd: text.length,\r\n isContinuation: false,\r\n };\r\n });\r\n return {\r\n showRail: true,\r\n showLineNumbers,\r\n contentWidth: Number.POSITIVE_INFINITY,\r\n outerWidth: terminalWidth ?? 0,\r\n langLabel: lang,\r\n lines,\r\n };\r\n }\r\n\r\n const outerWidth = Math.max(1, Math.floor(terminalWidth));\r\n\r\n // Rail cost: one border column on the left, plus one column of padding\r\n // inside it. A code block is content, not a panel, so it never pays for a\r\n // four-sided box — that chrome outweighed the code it wrapped.\r\n const BORDER = 1;\r\n const PADDING_X = 1;\r\n\r\n type Chrome = { border: boolean; lineNumbers: boolean };\r\n const candidates: Chrome[] = [\r\n { border: true, lineNumbers: preferLineNumbers },\r\n { border: true, lineNumbers: false },\r\n { border: false, lineNumbers: preferLineNumbers },\r\n { border: false, lineNumbers: false },\r\n ];\r\n\r\n const gutterWidth = String(Math.max(sourceLines.length, 1)).length;\r\n // \"N │ \" → gutterWidth + 3\r\n const lineNumberGutterCols = gutterWidth + 3;\r\n\r\n let chosen: Chrome = { border: false, lineNumbers: false };\r\n let contentWidth = Math.max(1, outerWidth);\r\n\r\n for (const candidate of candidates) {\r\n const chrome =\r\n (candidate.border ? BORDER + PADDING_X : 0) +\r\n (candidate.lineNumbers ? lineNumberGutterCols : 0);\r\n const available = outerWidth - chrome;\r\n if (available >= 1) {\r\n chosen = candidate;\r\n contentWidth = available;\r\n break;\r\n }\r\n }\r\n\r\n // Final clamp: always leave at least 1 content column.\r\n contentWidth = Math.max(1, contentWidth);\r\n\r\n const langLabel =\r\n lang === null ? null : fitsIn(lang, contentWidth) ? lang : truncateDisplay(lang, contentWidth);\r\n\r\n const lines: CodeLineLayout[] = [];\r\n for (let i = 0; i < sourceLines.length; i++) {\r\n const source = sourceLines[i] ?? '';\r\n const chunks = hardWrapLine(source, contentWidth);\r\n let charOffset = 0;\r\n for (let ci = 0; ci < chunks.length; ci++) {\r\n const chunk = chunks[ci]!;\r\n // hardWrapLine splits by code points; concatenation of chunks equals source.\r\n const start = charOffset;\r\n const end = start + chunk.length;\r\n charOffset = end;\r\n\r\n const isContinuation = ci > 0;\r\n let gutter = '';\r\n if (chosen.lineNumbers) {\r\n gutter = isContinuation\r\n ? `${' '.repeat(gutterWidth)} │ `\r\n : `${String(i + 1).padStart(gutterWidth, ' ')} │ `;\r\n }\r\n\r\n lines.push({\r\n gutter,\r\n text: chunk,\r\n sourceLineIndex: i,\r\n sourceStart: start,\r\n sourceEnd: end,\r\n isContinuation,\r\n });\r\n }\r\n }\r\n\r\n return {\r\n showRail: chosen.border,\r\n showLineNumbers: chosen.lineNumbers,\r\n contentWidth,\r\n outerWidth,\r\n langLabel,\r\n lines,\r\n };\r\n}\r\n\r\n/**\r\n * Slice a styled segment line by character offsets (not display width).\r\n * Preserves segment styles for hard-wrapped code visual lines.\r\n */\r\nexport function sliceStyledLine<T extends { text: string }>(\r\n segments: T[],\r\n start: number,\r\n end: number,\r\n): T[] {\r\n if (end <= start) return [];\r\n const out: T[] = [];\r\n let cursor = 0;\r\n for (const seg of segments) {\r\n const segStart = cursor;\r\n const segEnd = cursor + seg.text.length;\r\n const overlapStart = Math.max(segStart, start);\r\n const overlapEnd = Math.min(segEnd, end);\r\n if (overlapStart < overlapEnd) {\r\n const text = seg.text.slice(overlapStart - segStart, overlapEnd - segStart);\r\n if (text) out.push({ ...seg, text });\r\n }\r\n cursor = segEnd;\r\n if (cursor >= end) break;\r\n }\r\n return out;\r\n}\r\n","import { displayWidth, truncateDisplay } from './word-wrap.js';\r\n\r\nexport interface ToolOutputDisplayOptions {\r\n maxLines: number;\r\n maxLineWidth: number;\r\n /** Optional hint appended to the footer when output is hidden. */\r\n hint?: string;\r\n /** Select initial lines, final lines, or a balanced initial/final preview. */\r\n strategy?: 'head' | 'tail' | 'head-tail';\r\n}\r\n\r\nexport interface ToolOutputDisplay {\r\n lines: string[];\r\n totalLines: number;\r\n totalChars: number;\r\n totalBytes: number;\r\n hiddenLines: number;\r\n hiddenBytes: number;\r\n truncatedLines: number;\r\n truncated: boolean;\r\n footer?: string;\r\n}\r\n\r\nexport function formatByteSize(bytes: number): string {\r\n if (bytes < 1024) return `${bytes} B`;\r\n const kib = bytes / 1024;\r\n if (kib < 1024) return `${kib.toFixed(kib >= 10 ? 0 : 1)} KB`;\r\n const mib = kib / 1024;\r\n return `${mib.toFixed(mib >= 10 ? 0 : 1)} MB`;\r\n}\r\n\r\n/**\r\n * Prepare tool output for terminal display without mutating the underlying result.\r\n * Counts the original output, then returns a bounded, display-width-aware preview.\r\n */\r\nexport function prepareToolOutputDisplay(\r\n output: string,\r\n { maxLines, maxLineWidth, hint, strategy = 'head' }: ToolOutputDisplayOptions,\r\n): ToolOutputDisplay {\r\n const rawLines = output.length === 0 ? [] : output.split('\\n');\r\n const lineLimit = Math.max(0, Math.floor(maxLines));\r\n const widthLimit = Math.max(0, Math.floor(maxLineWidth));\r\n const visibleIndices = selectVisibleLineIndices(rawLines.length, lineLimit, strategy);\r\n const visibleRawLines = visibleIndices.map((index) => rawLines[index] ?? '');\r\n // Measure the whole output in one call and only the visible lines\r\n // individually — a per-line map allocates a string and a Buffer measurement\r\n // for every line of a potentially huge output just to fill in the footer.\r\n const totalBytes = Buffer.byteLength(output, 'utf8');\r\n let visibleBytes = 0;\r\n for (const index of visibleIndices) {\r\n visibleBytes +=\r\n Buffer.byteLength(rawLines[index] ?? '', 'utf8') + (index < rawLines.length - 1 ? 1 : 0);\r\n }\r\n let truncatedLines = 0;\r\n const lines = visibleRawLines.map((line) => {\r\n const next = truncateDisplay(line, widthLimit);\r\n if (displayWidth(next) < displayWidth(line) || next !== line) truncatedLines++;\r\n return next;\r\n });\r\n const hiddenLines = Math.max(0, rawLines.length - visibleRawLines.length);\r\n const hiddenBytes = Math.max(0, totalBytes - visibleBytes);\r\n const truncated = hiddenLines > 0 || truncatedLines > 0;\r\n const footer = truncated\r\n ? formatToolOutputFooter({\r\n totalLines: rawLines.length,\r\n totalBytes,\r\n hiddenLines,\r\n hiddenBytes,\r\n truncatedLines,\r\n hint,\r\n })\r\n : undefined;\r\n\r\n return {\r\n lines,\r\n totalLines: rawLines.length,\r\n totalChars: output.length,\r\n totalBytes,\r\n hiddenLines,\r\n hiddenBytes,\r\n truncatedLines,\r\n truncated,\r\n footer,\r\n };\r\n}\r\n\r\nfunction selectVisibleLineIndices(\r\n totalLines: number,\r\n maxLines: number,\r\n strategy: NonNullable<ToolOutputDisplayOptions['strategy']>,\r\n): number[] {\r\n if (maxLines <= 0 || totalLines <= 0) return [];\r\n if (totalLines <= maxLines) return Array.from({ length: totalLines }, (_, index) => index);\r\n if (strategy === 'tail') {\r\n return Array.from({ length: maxLines }, (_, index) => totalLines - maxLines + index);\r\n }\r\n if (strategy === 'head-tail' && maxLines > 1) {\r\n const headLines = Math.ceil(maxLines / 2);\r\n const tailLines = maxLines - headLines;\r\n return [\r\n ...Array.from({ length: headLines }, (_, index) => index),\r\n ...Array.from({ length: tailLines }, (_, index) => totalLines - tailLines + index),\r\n ];\r\n }\r\n return Array.from({ length: maxLines }, (_, index) => index);\r\n}\r\n\r\nfunction formatToolOutputFooter({\r\n totalLines,\r\n totalBytes,\r\n hiddenLines,\r\n hiddenBytes,\r\n truncatedLines,\r\n hint,\r\n}: {\r\n totalLines: number;\r\n totalBytes: number;\r\n hiddenLines: number;\r\n hiddenBytes: number;\r\n truncatedLines: number;\r\n hint?: string;\r\n}): string {\r\n const parts: string[] = [];\r\n if (hiddenLines > 0)\r\n parts.push(\r\n `${hiddenLines} more ${hiddenLines === 1 ? 'line' : 'lines'} hidden, ${hiddenBytes} B`,\r\n );\r\n if (truncatedLines > 0)\r\n parts.push(`${truncatedLines} long ${truncatedLines === 1 ? 'line' : 'lines'} shortened`);\r\n const summary = `${totalLines} ${totalLines === 1 ? 'line' : 'lines'}, ${formatByteSize(totalBytes)} total`;\r\n return `… ${parts.join(', ')} (${summary}${hint ? `; ${hint}` : ''})`;\r\n}\r\n","import type { ToolResult } from '../types/tools.js';\r\nimport { canonicalToolName } from '../tools/aliases.js';\r\nimport { getPrimaryArg } from '../tools/primary-arg.js';\r\nimport { isFileMutatingTool } from '../tools/tool-capabilities.js';\r\nimport { isUnifiedDiffLike } from './components/Diff.js';\r\n\r\nexport interface FileMutationDisplaySummary {\r\n filePath: string;\r\n kind: 'create' | 'update' | 'delete';\r\n addedLines: number;\r\n removedLines: number;\r\n fileCount?: number;\r\n}\r\n\r\nexport function isRenderableFileMutationDiff(\r\n toolName: string,\r\n result: ToolResult | undefined,\r\n): boolean {\r\n if (result?.status !== 'success' || !result.content) return false;\r\n return isFileMutatingTool(canonicalToolName(toolName)) && isUnifiedDiffLike(result.content);\r\n}\r\n\r\nexport function getFileMutationDisplaySummary(\r\n toolName: string,\r\n args: Record<string, unknown>,\r\n result: ToolResult | undefined,\r\n): FileMutationDisplaySummary | undefined {\r\n if (!isRenderableFileMutationDiff(toolName, result)) return undefined;\r\n\r\n const mutations = result?.artifacts?.fileMutations ?? [];\r\n if (mutations.length > 1) {\r\n const kinds = new Set(mutations.map((mutation) => mutation.kind));\r\n return {\r\n filePath: `${mutations.length} files`,\r\n kind: kinds.size === 1 ? mutations[0].kind : 'update',\r\n addedLines: mutations.reduce((total, mutation) => total + mutation.addedLines, 0),\r\n removedLines: mutations.reduce((total, mutation) => total + mutation.removedLines, 0),\r\n fileCount: new Set(mutations.map((mutation) => mutation.filePath)).size,\r\n };\r\n }\r\n const mutation = result?.artifacts?.fileMutation;\r\n const filePath =\r\n mutation?.filePath ??\r\n ['filePath', 'file_path', 'notebook_path', 'path']\r\n .map((key) => args[key])\r\n .find((value): value is string => typeof value === 'string' && value.length > 0) ??\r\n getPrimaryArg(args) ??\r\n '(unknown file)';\r\n const lines = result?.content.split('\\n') ?? [];\r\n const addedLines =\r\n mutation?.addedLines ??\r\n lines.filter((line) => line.startsWith('+') && !line.startsWith('+++')).length;\r\n const removedLines =\r\n mutation?.removedLines ??\r\n lines.filter((line) => line.startsWith('-') && !line.startsWith('---')).length;\r\n\r\n return {\r\n filePath,\r\n kind: mutation?.kind ?? 'update',\r\n addedLines,\r\n removedLines,\r\n fileCount: 1,\r\n };\r\n}\r\n","import type { ToolResult } from '../types/tools.js';\r\nimport { canonicalToolName } from '../tools/aliases.js';\r\nimport { getPrimaryArg } from '../tools/primary-arg.js';\r\nimport { isFileMutatingTool } from '../tools/tool-capabilities.js';\r\nimport { displayWidth, truncateDisplay } from './components/word-wrap.js';\r\nimport { LABEL_COLUMN_WIDTH, MIN_TARGET_WIDTH, type TranscriptGrid } from './layout.js';\r\nimport { isRenderableFileMutationDiff } from './file-mutation-display.js';\r\n\r\nexport type TranscriptMode = 'compact' | 'detailed';\r\nexport type TranscriptShortcutAction = 'enter-detailed' | 'exit-detailed' | 'expand-output';\r\nexport type ToolPresentationStatus = 'running' | 'pending' | 'success' | 'failure' | 'skipped';\r\nexport type ToolPreviewType = 'none' | 'text' | 'markdown' | 'diff';\r\n\r\nexport interface ToolPresentation {\r\n canonicalName: string;\r\n status: ToolPresentationStatus;\r\n title: string;\r\n target?: string;\r\n metadata: string[];\r\n summary: string;\r\n previewType: ToolPreviewType;\r\n hasDetails: boolean;\r\n hasHiddenContent: boolean;\r\n filePath?: string;\r\n}\r\n\r\nexport interface ToolPresentationOptions {\r\n isPending?: boolean;\r\n nestedActivityCount?: number;\r\n}\r\n\r\nexport function getTranscriptShortcutAction(\r\n mode: TranscriptMode,\r\n input: string,\r\n key: { ctrl?: boolean; meta?: boolean; escape?: boolean },\r\n): TranscriptShortcutAction | null {\r\n if (\r\n mode === 'detailed' &&\r\n (key.escape || (!key.ctrl && !key.meta && input.toLowerCase() === 'q'))\r\n ) {\r\n return 'exit-detailed';\r\n }\r\n if (key.ctrl && (input === 'o' || input.charCodeAt(0) === 15)) {\r\n return mode === 'detailed' ? 'exit-detailed' : 'enter-detailed';\r\n }\r\n if (key.ctrl && (input === 'e' || input.charCodeAt(0) === 5)) return 'expand-output';\r\n return null;\r\n}\r\n\r\n/**\r\n * True for the keypress that toggles the keyboard-shortcut reference.\r\n *\r\n * A terminal sends US (`0x1f`) for Ctrl+/, and Ink's `parseKeypress` reports\r\n * that byte as `{ name: '', ctrl: false }` — the sequence reaches `useInput` as\r\n * `input`, with no `ctrl` flag to gate on. Testing only `key.ctrl && input ===\r\n * '/'` therefore never matched, so the one shortcut advertised on the welcome\r\n * screen could not be pressed, while a unit test synthesizing `{ ctrl: true }`\r\n * passed. Match the raw byte first and keep the flag form for terminals that do\r\n * report it.\r\n */\r\nexport function isShortcutsToggleKey(\r\n input: string,\r\n key: { ctrl?: boolean; meta?: boolean },\r\n): boolean {\r\n if (input.charCodeAt(0) === 31) return true;\r\n return Boolean(key.ctrl) && !key.meta && (input === '/' || input === '_');\r\n}\r\n\r\nexport interface PresentableToolInvocation<TCall = unknown> {\r\n id: string;\r\n name: string;\r\n call: TCall;\r\n result?: ToolResult;\r\n}\r\n\r\nexport type CompactToolGroup<TCall = unknown> =\r\n | { kind: 'tool'; invocation: PresentableToolInvocation<TCall> }\r\n | {\r\n kind: 'mcp-group';\r\n id: string;\r\n server: string;\r\n invocations: PresentableToolInvocation<TCall>[];\r\n };\r\n\r\n/** Group adjacent successful, completed MCP calls from the same server. */\r\nexport function groupConsecutiveMcpCalls<TCall>(\r\n invocations: readonly PresentableToolInvocation<TCall>[],\r\n): CompactToolGroup<TCall>[] {\r\n const groups: CompactToolGroup<TCall>[] = [];\r\n for (let index = 0; index < invocations.length;) {\r\n const current = invocations[index];\r\n const mcp = parseMcpToolName(current.name);\r\n if (!mcp || current.result?.status !== 'success') {\r\n groups.push({ kind: 'tool', invocation: current });\r\n index++;\r\n continue;\r\n }\r\n\r\n const consecutive: PresentableToolInvocation<TCall>[] = [current];\r\n let nextIndex = index + 1;\r\n while (nextIndex < invocations.length) {\r\n const next = invocations[nextIndex];\r\n const nextMcp = parseMcpToolName(next.name);\r\n if (!nextMcp || nextMcp.server !== mcp.server || next.result?.status !== 'success') break;\r\n consecutive.push(next);\r\n nextIndex++;\r\n }\r\n\r\n if (consecutive.length === 1) groups.push({ kind: 'tool', invocation: current });\r\n else {\r\n groups.push({\r\n kind: 'mcp-group',\r\n id: `mcp-group:${consecutive.map((item) => item.id).join(',')}`,\r\n server: mcp.server,\r\n invocations: consecutive,\r\n });\r\n }\r\n index = nextIndex;\r\n }\r\n return groups;\r\n}\r\nconst LABELS: Record<string, string> = {\r\n Read: 'Read',\r\n ApplyPatch: 'Apply patch',\r\n Write: 'Write',\r\n Edit: 'Edit',\r\n MultiEdit: 'Edit',\r\n NotebookEdit: 'Edit notebook',\r\n Bash: 'Bash',\r\n BashOutput: 'Shell output',\r\n KillShell: 'Kill shell',\r\n Glob: 'Glob',\r\n Grep: 'Grep',\r\n WebFetch: 'Fetch',\r\n WebSearch: 'Search web',\r\n GitStatus: 'Git status',\r\n GitDiff: 'Git diff',\r\n GitLog: 'Git log',\r\n GitCommit: 'Git commit',\r\n GitBranch: 'Git branch',\r\n TodoWrite: 'Update todos',\r\n Task: 'Task',\r\n InvokeSkill: 'Skill',\r\n};\r\n\r\nexport function formatDuration(durationMs: number | undefined): string | undefined {\r\n if (durationMs === undefined || durationMs < 0) return undefined;\r\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`;\r\n if (durationMs < 60_000) return `${(durationMs / 1000).toFixed(1)}s`;\r\n const minutes = Math.floor(durationMs / 60_000);\r\n const seconds = Math.floor((durationMs % 60_000) / 1000);\r\n return `${minutes}m ${seconds}s`;\r\n}\r\n\r\nexport function parseMcpToolName(name: string): { server: string; tool: string } | undefined {\r\n const match = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(name);\r\n if (!match) return undefined;\r\n return { server: match[1], tool: match[2].replace(/_/g, ' ') };\r\n}\r\n\r\nfunction stringArg(args: Record<string, unknown>, ...names: string[]): string | undefined {\r\n for (const name of names) {\r\n const value = args[name];\r\n if (typeof value === 'string' && value.length > 0) return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction countOutputLines(output: string | undefined): number {\r\n if (!output) return 0;\r\n return output.split('\\n').length;\r\n}\r\n\r\nfunction countNonEmptyOutputLines(output: string | undefined): number {\r\n if (!output) return 0;\r\n return output.split('\\n').filter((line) => line.trim().length > 0).length;\r\n}\r\n\r\nfunction outputSizeMetadata(result: ToolResult | undefined): string | undefined {\r\n if (!result?.content) return undefined;\r\n // Line count only. The byte size rode along on every row that produced any\r\n // output and told the reader nothing they would act on.\r\n const lines = countOutputLines(result.content);\r\n return `${lines} ${lines === 1 ? 'line' : 'lines'}`;\r\n}\r\n\r\nfunction statusFor(result: ToolResult | undefined, isPending: boolean): ToolPresentationStatus {\r\n if (isPending) return 'pending';\r\n if (!result) return 'running';\r\n if (result.status === 'blocked') return 'skipped';\r\n return result.status === 'success' ? 'success' : 'failure';\r\n}\r\n\r\nfunction resultStatusMetadata(status: ToolPresentationStatus): string | undefined {\r\n if (status === 'failure') return 'failed';\r\n if (status === 'skipped') return 'skipped';\r\n if (status === 'pending') return 'needs approval';\r\n return undefined;\r\n}\r\n\r\nfunction fileMutationPresentation(\r\n canonicalName: string,\r\n args: Record<string, unknown>,\r\n result: ToolResult | undefined,\r\n status: ToolPresentationStatus,\r\n): Pick<ToolPresentation, 'title' | 'target' | 'metadata' | 'previewType' | 'filePath'> {\r\n const filePath =\r\n result?.artifacts?.fileMutation?.filePath ??\r\n stringArg(args, 'filePath', 'file_path', 'notebook_path', 'path') ??\r\n getPrimaryArg(args);\r\n const action =\r\n result?.artifacts?.fileMutation?.kind === 'create'\r\n ? 'Create'\r\n : result?.artifacts?.fileMutation?.kind === 'delete'\r\n ? 'Delete'\r\n : 'Edit';\r\n const metadata: string[] = [];\r\n const mutation =\r\n result?.artifacts?.fileMutation ??\r\n (result?.status === 'success' && /^@@/m.test(result.content)\r\n ? {\r\n kind: 'update' as const,\r\n filePath,\r\n addedLines: result.content\r\n .split('\\n')\r\n .filter((line) => line.startsWith('+') && !line.startsWith('+++')).length,\r\n removedLines: result.content\r\n .split('\\n')\r\n .filter((line) => line.startsWith('-') && !line.startsWith('---')).length,\r\n }\r\n : undefined);\r\n if (result?.status === 'success' && mutation) {\r\n if (mutation.addedLines > 0) metadata.push(`+${mutation.addedLines}`);\r\n if (mutation.removedLines > 0) metadata.push(`-${mutation.removedLines}`);\r\n if (mutation.addedLines === 0 && mutation.removedLines === 0) metadata.push('no changes');\r\n } else {\r\n const statusLabel = resultStatusMetadata(status);\r\n if (statusLabel) metadata.push(statusLabel);\r\n }\r\n const previewType = result?.status === 'success' && /^@@/m.test(result.content) ? 'diff' : 'none';\r\n return {\r\n title: action,\r\n target: filePath,\r\n metadata,\r\n previewType,\r\n filePath,\r\n };\r\n}\r\n\r\nfunction readMetadata(args: Record<string, unknown>, result: ToolResult | undefined): string[] {\r\n if (result?.status !== 'success') return [];\r\n const lineCount = countOutputLines(result.content);\r\n const offset = Number(args.offset ?? 0);\r\n const start = Number.isFinite(offset) && offset > 0 ? Math.floor(offset) : 1;\r\n const end = Math.max(start, start + Math.max(0, lineCount - 1));\r\n if (lineCount === 0) return ['empty'];\r\n const size = lineCount === 1 ? '1 line' : `${lineCount} lines`;\r\n // `121 lines · 1-121` says the same thing twice. The range earns its place\r\n // only when the read started partway into the file.\r\n return start > 1 ? [size, `${start}-${end}`] : [size];\r\n}\r\n\r\nfunction domainFor(value: string | undefined): string | undefined {\r\n if (!value) return undefined;\r\n try {\r\n return new URL(value).hostname || value;\r\n } catch {\r\n return value;\r\n }\r\n}\r\n\r\n/** Derive all concise tool-row text without depending on Ink rendering. */\r\nexport function deriveToolPresentation(\r\n name: string,\r\n args: Record<string, unknown>,\r\n result?: ToolResult,\r\n options: ToolPresentationOptions = {},\r\n): ToolPresentation {\r\n const canonicalName = canonicalToolName(name);\r\n const status = statusFor(result, Boolean(options.isPending));\r\n const primary = getPrimaryArg(args);\r\n const mcp = parseMcpToolName(name);\r\n let title = LABELS[canonicalName] ?? canonicalName;\r\n let target = primary || undefined;\r\n let metadata: string[] = [];\r\n let previewType: ToolPreviewType = result?.content ? 'text' : 'none';\r\n let filePath: string | undefined;\r\n\r\n if (result?.version === 2 && result.presentation) {\r\n const structured = result.presentation;\r\n target = structured.target ?? target;\r\n metadata = [...(structured.metadata ?? [])];\r\n previewType =\r\n structured.kind === 'diff'\r\n ? 'diff'\r\n : structured.kind === 'markdown' || structured.kind === 'search'\r\n ? 'markdown'\r\n : structured.details\r\n ? 'text'\r\n : 'none';\r\n const mutation = result.artifacts?.fileMutation;\r\n if (mutation) {\r\n title =\r\n mutation.kind === 'create' ? 'Create' : mutation.kind === 'delete' ? 'Delete' : 'Edit';\r\n filePath = mutation.filePath;\r\n target = mutation.filePath;\r\n }\r\n const statusMetadata = resultStatusMetadata(status);\r\n if (statusMetadata && !metadata.includes(statusMetadata)) metadata.unshift(statusMetadata);\r\n const duration = formatDuration(result.metrics?.durationMs);\r\n if (duration) metadata.push(duration);\r\n const retryAttempt = result.metrics?.retryAttempt;\r\n if (retryAttempt && retryAttempt > 1) metadata.push(`attempt ${retryAttempt}`);\r\n const hasDetails = Boolean(structured.details);\r\n return {\r\n canonicalName,\r\n status,\r\n title,\r\n target,\r\n metadata,\r\n summary: structured.summary || `${title}${target ? `(${target})` : ''}`,\r\n previewType,\r\n hasDetails,\r\n hasHiddenContent: hasDetails,\r\n filePath,\r\n };\r\n }\r\n\r\n if (isFileMutatingTool(canonicalName)) {\r\n const mutation = fileMutationPresentation(canonicalName, args, result, status);\r\n title = mutation.title;\r\n target = mutation.target;\r\n metadata = mutation.metadata;\r\n previewType = mutation.previewType;\r\n filePath = mutation.filePath;\r\n } else if (canonicalName === 'Read') {\r\n target = stringArg(args, 'filePath', 'file_path', 'path') ?? target;\r\n metadata = readMetadata(args, result);\r\n } else if (canonicalName === 'Glob') {\r\n target = stringArg(args, 'pattern') ?? target;\r\n if (result?.status === 'success') {\r\n const files = /^(?:No files found|No matches found)$/i.test(result.content.trim())\r\n ? 0\r\n : countNonEmptyOutputLines(result.content.replace(/\\n\\.\\.\\. \\(truncated[\\s\\S]*$/, ''));\r\n metadata = [`${files} ${files === 1 ? 'file' : 'files'}`];\r\n }\r\n } else if (canonicalName === 'Grep') {\r\n target = stringArg(args, 'pattern') ?? target;\r\n if (result?.status === 'success') {\r\n const outputMode = stringArg(args, 'output_mode') ?? 'content';\r\n if (/^No matches found$/i.test(result.content.trim())) metadata = ['0 matches'];\r\n else if (outputMode === 'files_with_matches') {\r\n const files = countNonEmptyOutputLines(result.content);\r\n metadata = [`${files} ${files === 1 ? 'file' : 'files'}`];\r\n } else if (outputMode === 'count') {\r\n const matches = result.content.split('\\n').reduce((total, line) => {\r\n const count = /:(\\d+)\\s*$/.exec(line)?.[1];\r\n return total + (count ? Number(count) : 0);\r\n }, 0);\r\n metadata = [`${matches} ${matches === 1 ? 'match' : 'matches'}`];\r\n } else {\r\n const contentLines = result.content.split('\\n');\r\n const structuredMatches = contentLines.filter((line) => /:\\d+:/.test(line)).length;\r\n const matches = structuredMatches || contentLines.filter((line) => line.trim()).length;\r\n metadata = [`${matches} ${matches === 1 ? 'match' : 'matches'}`];\r\n }\r\n }\r\n } else if (canonicalName === 'WebFetch') {\r\n target = domainFor(stringArg(args, 'url'));\r\n previewType = result?.content ? 'markdown' : 'none';\r\n } else if (canonicalName === 'WebSearch') {\r\n target = stringArg(args, 'query') ?? target;\r\n previewType = result?.content ? 'markdown' : 'none';\r\n } else if (canonicalName === 'Task') {\r\n target = stringArg(args, 'agent', 'subject', 'description', 'prompt') ?? target;\r\n if ((options.nestedActivityCount ?? 0) > 0) {\r\n const count = options.nestedActivityCount ?? 0;\r\n metadata.push(`${count} ${count === 1 ? 'activity' : 'activities'}`);\r\n }\r\n } else if (mcp) {\r\n const groupCount = Number(args.__groupCount ?? 0);\r\n title =\r\n Number.isSafeInteger(groupCount) && groupCount > 1\r\n ? `Called ${mcp.server} ${groupCount} times`\r\n : `Called ${mcp.server}`;\r\n target = groupCount > 1 ? undefined : mcp.tool;\r\n previewType = result?.content ? 'markdown' : 'none';\r\n } else if (\r\n canonicalName === 'Bash' ||\r\n canonicalName.startsWith('Git') ||\r\n canonicalName === 'BashOutput'\r\n ) {\r\n const size = outputSizeMetadata(result);\r\n if (size) metadata.push(size);\r\n }\r\n\r\n const statusMetadata = resultStatusMetadata(status);\r\n if (statusMetadata && !metadata.includes(statusMetadata)) metadata.unshift(statusMetadata);\r\n const duration = formatDuration(result?.metrics?.durationMs);\r\n if (duration) metadata.push(duration);\r\n if (result?.metrics?.retryAttempt && result.metrics.retryAttempt > 1)\r\n metadata.push(`attempt ${result.metrics.retryAttempt}`);\r\n\r\n const targetText = target ? `(${target})` : '';\r\n const metadataText = metadata.length > 0 ? ` · ${metadata.join(' ')}` : '';\r\n const summary = `${title}${targetText}${metadataText}`;\r\n const hasDetails = Boolean(result?.content);\r\n\r\n return {\r\n canonicalName,\r\n status,\r\n title,\r\n target,\r\n metadata,\r\n summary,\r\n previewType,\r\n hasDetails,\r\n hasHiddenContent: hasDetails,\r\n filePath,\r\n };\r\n}\r\n\r\nexport interface ToolExpansionPolicyInput {\r\n mode: TranscriptMode;\r\n toolId: string;\r\n automaticToolId?: string | null;\r\n defaultExpanded?: boolean;\r\n expansionOverrides: ReadonlyMap<string, boolean>;\r\n screenReader?: boolean;\r\n}\r\n\r\n/** Successful file mutations stay visible until the user explicitly collapses them. */\r\nexport function shouldDefaultExpandTool(name: string, result?: ToolResult): boolean {\r\n return isRenderableFileMutationDiff(name, result);\r\n}\r\n\r\n/** Centralized expansion policy shared by top-level and nested tool rows. */\r\nexport function shouldExpandTool({\r\n mode,\r\n toolId,\r\n automaticToolId,\r\n defaultExpanded = false,\r\n expansionOverrides,\r\n screenReader = false,\r\n}: ToolExpansionPolicyInput): boolean {\r\n if (screenReader) return true;\r\n const override = expansionOverrides.get(toolId);\r\n if (override !== undefined) return override;\r\n return mode === 'detailed' || automaticToolId === toolId || defaultExpanded;\r\n}\r\n\r\n/**\r\n * Widest a failure message may grow the metadata column.\r\n *\r\n * Long enough for the shell errors that actually occur — `'tail' is not\r\n * recognized as an internal or external command` is 57 — without letting a\r\n * pathological message crowd out the target it failed on.\r\n */\r\nconst ERROR_META_MAX = 64;\r\n\r\n/** MCP rows are titled `Called <server>` by {@link deriveToolPresentation}. */\r\nconst MCP_TITLE_PREFIX = 'Called ';\r\n\r\n/** `+12` / `-3`: churn counts that belong together as one figure. */\r\nconst CHURN = /^[+-]\\d+$/;\r\n\r\n/**\r\n * Join metadata parts with `·`, except adjacent churn counts, which join with a\r\n * space so `+3 -2` reads as one number rather than two facts.\r\n */\r\nfunction joinMetadata(parts: readonly string[]): string {\r\n return parts.reduce((joined, part, index) => {\r\n if (index === 0) return part;\r\n const separator = CHURN.test(part) && CHURN.test(parts[index - 1]!) ? ' ' : ' · ';\r\n return `${joined}${separator}${part}`;\r\n }, '');\r\n}\r\n\r\n/**\r\n * Shorten a presentation title for the aligned label column.\r\n *\r\n * An MCP row's title reads `Called <server>`; inside the column the verb is\r\n * redundant and the server name is what the reader scans for.\r\n */\r\nexport function shortLabel(title: string): string {\r\n const stripped = title.startsWith(MCP_TITLE_PREFIX)\r\n ? title.slice(MCP_TITLE_PREFIX.length)\r\n : title;\r\n return SHORT_LABELS[stripped] ?? stripped;\r\n}\r\n\r\n/**\r\n * The label a row will show, derived without scanning result content.\r\n *\r\n * Callers measuring a column across many rows must not pay for a full\r\n * {@link deriveToolPresentation} per row: that regex-scans result bodies, which\r\n * is real cost on a multi-megabyte tool result. This reads only the cheap\r\n * fields and is allowed to be wrong — an under-measured column costs one row\r\n * its alignment, never its content.\r\n */\r\nexport function toolRowLabel(name: string, result?: ToolResult): string {\r\n const mutation = result?.artifacts?.fileMutation;\r\n if (mutation) {\r\n return mutation.kind === 'create' ? 'Create' : mutation.kind === 'delete' ? 'Delete' : 'Edit';\r\n }\r\n const mcp = parseMcpToolName(name);\r\n if (mcp) return mcp.server;\r\n const canonical = canonicalToolName(name);\r\n return shortLabel(LABELS[canonical] ?? canonical);\r\n}\r\n\r\n/**\r\n * Standard label-column widths.\r\n *\r\n * Nearly every verb is four (`Read`, `Bash`, `Grep`, `Edit`) or six (`Create`,\r\n * `Delete`); snapping to these means two turns in a row almost always land on\r\n * the same column, which exact per-turn sizing did not.\r\n */\r\nconst LABEL_COLUMN_STEPS = [4, 6, LABEL_COLUMN_WIDTH] as const;\r\n\r\n/** Widest standard label column a run of rows needs, in columns. */\r\nexport function toolLabelColumnWidth(labels: readonly string[]): number {\r\n const widest = labels.reduce((max, label) => Math.max(max, displayWidth(label)), 1);\r\n return LABEL_COLUMN_STEPS.find((step) => step >= widest) ?? LABEL_COLUMN_WIDTH;\r\n}\r\n\r\n/** Labels short enough for the aligned row's fixed label column. */\r\nconst SHORT_LABELS: Record<string, string> = {\r\n 'Apply patch': 'Patch',\r\n 'Edit notebook': 'Notebook',\r\n 'Shell output': 'Shell',\r\n 'Update todos': 'Todos',\r\n};\r\n\r\n/** The three aligned columns of a tool row, already padded to the grid. */\r\nexport interface ToolRowColumns {\r\n /** Verb, padded to the grid's label column. Empty when labels are inline. */\r\n label: string;\r\n /** What the tool acted on, truncated to fit. */\r\n target: string;\r\n /** Spaces that push `meta` flush against the right edge. */\r\n gap: string;\r\n /** Right-aligned result metadata, or the error message on a failure. */\r\n meta: string;\r\n}\r\n\r\n/**\r\n * Lay a tool row out as `[label][target] … [meta]`.\r\n *\r\n * The label and meta columns are fixed so the eye can scan straight down a\r\n * column of rows; only the target flexes. Below the grid's label threshold the\r\n * label column collapses and the verb runs inline, because a fixed column would\r\n * leave nothing for the path.\r\n */\r\nexport function composeToolRow(\r\n presentation: Pick<ToolPresentation, 'title' | 'target' | 'metadata'>,\r\n grid: TranscriptGrid,\r\n extra: { elapsed?: string; error?: string } = {},\r\n): ToolRowColumns {\r\n const title = shortLabel(presentation.title);\r\n // Never truncate the verb. A row whose label does not fit the column runs\r\n // inline instead: `Read sr…` is unreadable in a way `Read src/a.ts` is not.\r\n const useLabelColumn = grid.label > 0 && displayWidth(title) <= grid.label;\r\n const metaSource = extra.error\r\n ? [extra.error]\r\n : [...presentation.metadata, ...(extra.elapsed ? [extra.elapsed] : [])];\r\n\r\n const label = useLabelColumn ? title.padEnd(grid.label) : '';\r\n const labelWidth = useLabelColumn ? grid.label + 1 : 0;\r\n const inlinePrefix = useLabelColumn || !title ? '' : `${title} `;\r\n\r\n // Aligned rows lay out inside the grid's bounded row measure even when the\r\n // prose around them takes the whole terminal. Right-aligning `67ms` against\r\n // column 197 does not align it with the command it timed -- it just puts it\r\n // far away, with a gap of pure padding rebuilt on every streamed frame in\r\n // between. The bound lives on the grid so it narrows with nesting.\r\n const measure = grid.row;\r\n\r\n // An error message outranks the target it failed on, so a failing row takes\r\n // as much as the message needs — capped, and never so much that the target\r\n // drops below a width worth reading.\r\n const metaBudget = extra.error\r\n ? Math.max(\r\n grid.meta,\r\n Math.min(\r\n ERROR_META_MAX,\r\n measure - labelWidth - displayWidth(inlinePrefix) - MIN_TARGET_WIDTH - 1,\r\n ),\r\n )\r\n : grid.meta;\r\n const meta = metaBudget > 0 ? truncateDisplay(joinMetadata(metaSource), metaBudget) : '';\r\n\r\n const metaWidth = displayWidth(meta);\r\n // The budget covers the whole truncated string, prefix included — subtracting\r\n // the prefix here as well clipped an inline-label row by exactly the width of\r\n // its own verb, and `gap` then padded those columns back with spaces.\r\n const targetBudget = Math.max(4, measure - labelWidth - metaWidth - (metaWidth > 0 ? 1 : 0));\r\n const target = truncateDisplay(`${inlinePrefix}${presentation.target ?? ''}`, targetBudget);\r\n\r\n const used = labelWidth + displayWidth(target) + metaWidth;\r\n const gap = ' '.repeat(Math.max(metaWidth > 0 ? 1 : 0, measure - used));\r\n return { label, target, gap, meta };\r\n}\r\n","import { Text } from 'ink';\r\nimport type { AgentSummary } from '../../agents/types.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\n\r\nfunction statusGlyph(status: AgentSummary['status'], reducedMotion: boolean): string {\r\n if (status === 'completed') return '✓';\r\n if (status === 'failed') return '✕';\r\n if (status === 'stopped' || status === 'interrupted') return '■';\r\n if (status === 'waiting_input' || status === 'waiting_permission') return '?';\r\n return reducedMotion ? '*' : '●';\r\n}\r\n\r\nfunction terminalActivity(agent: AgentSummary): string {\r\n if (agent.status === 'completed') return agent.summary?.split(/\\r?\\n/, 1)[0] ?? 'Completed';\r\n if (agent.status === 'failed') return agent.error?.split(/\\r?\\n/, 1)[0] ?? 'Failed';\r\n if (agent.status === 'stopped') return 'Stopped';\r\n if (agent.status === 'interrupted') return 'Interrupted';\r\n return agent.currentActivity?.label ?? agent.status.replace('_', ' ');\r\n}\r\n\r\nexport function formatElapsedDuration(totalSeconds: number): string {\r\n const seconds = Math.max(0, Math.floor(totalSeconds));\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n const remainingSeconds = seconds % 60;\r\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\r\n const hours = Math.floor(minutes / 60);\r\n return `${hours}h ${minutes % 60}m ${remainingSeconds}s`;\r\n}\r\n\r\nfunction useCurrentTime(active: boolean, fixedNow?: number): number {\r\n const tick = useUiClock('slow', active && fixedNow === undefined);\r\n void tick;\r\n return fixedNow ?? Date.now();\r\n}\r\n\r\nexport function SubagentRow({\r\n agent,\r\n selected = false,\r\n width = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n now,\r\n}: {\r\n agent: AgentSummary;\r\n selected?: boolean;\r\n width?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n now?: number;\r\n}) {\r\n const theme = useTheme();\r\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(agent.status);\r\n const currentTime = useCurrentTime(!terminal, now);\r\n const activity = terminal\r\n ? terminalActivity(agent)\r\n : (agent.currentActivity?.label ?? agent.status.replace('_', ' '));\r\n const elapsed = Math.max(\r\n 0,\r\n Math.floor(((agent.finishedAt ?? currentTime) - (agent.startedAt ?? agent.createdAt)) / 1000),\r\n );\r\n const color =\r\n agent.status === 'failed'\r\n ? theme.error\r\n : agent.status === 'completed'\r\n ? theme.success\r\n : agent.status === 'waiting_input' || agent.status === 'waiting_permission'\r\n ? theme.warning\r\n : theme.brand;\r\n\r\n if (screenReader) {\r\n return (\r\n <Text>\r\n {agent.displayName}. {agent.profile}. {agent.resolvedModel}. {agent.status}. {activity}.\r\n </Text>\r\n );\r\n }\r\n\r\n const elapsedLabel = formatElapsedDuration(elapsed);\r\n const elapsedSuffix = ` | ${elapsedLabel}`;\r\n const displayNameWidth = Math.max(1, width - 8 - elapsedSuffix.length);\r\n return (\r\n <Text color={selected ? theme.text : color} bold={selected}>\r\n {selected ? '› ' : ' '}\r\n {statusGlyph(agent.status, reducedMotion)}{' '}\r\n {truncateDisplay(agent.displayName, displayNameWidth)}\r\n <Text color={theme.subtle}>{elapsedSuffix}</Text>\r\n </Text>\r\n );\r\n}\r\n","import { createContext, useContext, type RefObject } from 'react';\r\nimport type { DOMElement } from 'ink';\r\n\r\nexport interface ToolSummaryRowRegistration {\r\n id: string;\r\n element: RefObject<DOMElement | null>;\r\n expandable: boolean;\r\n expanded: boolean;\r\n}\r\n\r\nexport interface ToolRowInteractionRegistry {\r\n register: (registration: ToolSummaryRowRegistration) => () => void;\r\n}\r\n\r\nexport const ToolRowInteractionContext = createContext<ToolRowInteractionRegistry | null>(null);\r\n\r\nexport function useToolRowInteractionRegistry(): ToolRowInteractionRegistry | null {\r\n return useContext(ToolRowInteractionContext);\r\n}\r\n","/* Hallmark · component: command instrument panel · genre: modern-minimal · theme: existing TUI\r\n * states: default · narrow · empty · warning · reduced-motion · screen-reader\r\n * contrast: pass (40–41; inherited from ThemeTokens)\r\n * Hallmark · pre-emit critique: P5 H5 E4 S5 R5 V5\r\n */\r\nimport { Box, Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport type {\r\n ConfigCommandDisplay,\r\n ContextCommandDisplay,\r\n LocalCommandDisplay,\r\n UsageCommandDisplay,\r\n} from '../../types/messages.js';\r\nimport { useStaggeredReveal } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { failureTotal, formatFailureCounts } from '../../pricing.js';\r\nimport { sourceLabel } from '../../context-report.js';\r\nimport { padDisplay, truncateDisplay, wordWrap } from './word-wrap.js';\r\n\r\ninterface CommandPanelProps {\r\n display: LocalCommandDisplay;\r\n fallback: string;\r\n terminalWidth?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}\r\n\r\ninterface ConfigEntry {\r\n path: string;\r\n value: string;\r\n}\r\n\r\ninterface Metric {\r\n label: string;\r\n value: string;\r\n color?: string;\r\n}\r\n\r\nconst REVEAL_STEPS = 10;\r\n\r\nfunction clamp(value: number, min: number, max: number): number {\r\n return Math.max(min, Math.min(max, value));\r\n}\r\n\r\nfunction compactNumber(value: number): string {\r\n const absolute = Math.abs(value);\r\n if (absolute >= 1_000_000) {\r\n return `${(value / 1_000_000).toFixed(absolute >= 10_000_000 ? 0 : 1)}m`;\r\n }\r\n if (absolute >= 1_000) {\r\n return `${(value / 1_000).toFixed(absolute >= 100_000 ? 0 : 1)}k`;\r\n }\r\n return value.toLocaleString();\r\n}\r\n\r\nfunction formatDuration(durationMs: number): string {\r\n if (durationMs <= 0) return '—';\r\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`;\r\n return `${(durationMs / 1000).toFixed(durationMs >= 10_000 ? 0 : 1)}s`;\r\n}\r\n\r\nfunction formatConfigValue(value: unknown): string {\r\n if (value === undefined) return '—';\r\n if (value === null) return 'null';\r\n if (typeof value === 'string') return value || '(empty)';\r\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\r\n return JSON.stringify(value);\r\n}\r\n\r\nfunction flattenConfigValue(\r\n value: unknown,\r\n path: string,\r\n entries: ConfigEntry[],\r\n depth: number,\r\n): void {\r\n if (depth > 7) {\r\n entries.push({ path, value: formatConfigValue(value) });\r\n return;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n entries.push({ path, value: '[]' });\r\n return;\r\n }\r\n if (value.every((item) => item === null || typeof item !== 'object')) {\r\n entries.push({ path, value: value.map(formatConfigValue).join(', ') });\r\n return;\r\n }\r\n value.forEach((item, index) => {\r\n flattenConfigValue(item, `${path}[${index}]`, entries, depth + 1);\r\n });\r\n return;\r\n }\r\n\r\n if (value && typeof value === 'object') {\r\n const objectEntries = Object.entries(value as Record<string, unknown>);\r\n if (objectEntries.length === 0) {\r\n entries.push({ path, value: '{}' });\r\n return;\r\n }\r\n for (const [key, nested] of objectEntries) {\r\n flattenConfigValue(nested, path ? `${path}.${key}` : key, entries, depth + 1);\r\n }\r\n return;\r\n }\r\n\r\n entries.push({ path, value: formatConfigValue(value) });\r\n}\r\n\r\nexport function flattenConfigSnapshot(snapshot: Record<string, unknown>): ConfigEntry[] {\r\n const entries: ConfigEntry[] = [];\r\n for (const [key, value] of Object.entries(snapshot)) {\r\n flattenConfigValue(value, key, entries, 0);\r\n }\r\n return entries;\r\n}\r\n\r\nfunction revealProgress(step: number, startAt = 1): number {\r\n return clamp((step - startAt) / Math.max(1, REVEAL_STEPS - startAt), 0, 1);\r\n}\r\n\r\nfunction ScanRail({ width, progress }: { width: number; progress: number }) {\r\n const theme = useTheme();\r\n const safeWidth = Math.max(8, width);\r\n const head = Math.min(safeWidth - 1, Math.floor(progress * (safeWidth - 1)));\r\n\r\n return (\r\n <Box flexWrap=\"nowrap\">\r\n <Text color={theme.brand}>{'─'.repeat(head)}</Text>\r\n <Text color={progress >= 1 ? theme.success : theme.brandShimmer}>•</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {'─'.repeat(Math.max(0, safeWidth - head - 1))}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction PanelHeader({\r\n command,\r\n title,\r\n subtitle,\r\n contentWidth,\r\n step,\r\n}: {\r\n command: string;\r\n title: string;\r\n subtitle: string;\r\n contentWidth: number;\r\n step: number;\r\n}) {\r\n const theme = useTheme();\r\n const ready = step >= REVEAL_STEPS;\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <Box justifyContent=\"space-between\" flexWrap=\"nowrap\">\r\n <Text bold color={theme.brand}>\r\n {command} <Text color={theme.toolRail}>·</Text> <Text color={theme.text}>{title}</Text>\r\n </Text>\r\n <Text color={ready ? theme.success : theme.brandShimmer}>\r\n {ready ? 'ready' : 'reading'}\r\n </Text>\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(subtitle, contentWidth)}\r\n </Text>\r\n <ScanRail width={contentWidth} progress={revealProgress(step, 0)} />\r\n </Box>\r\n );\r\n}\r\n\r\nfunction MetricGrid({\r\n metrics,\r\n contentWidth,\r\n narrow,\r\n illuminated,\r\n}: {\r\n metrics: Metric[];\r\n contentWidth: number;\r\n narrow: boolean;\r\n illuminated: boolean;\r\n}) {\r\n const theme = useTheme();\r\n\r\n if (narrow) {\r\n const labelWidth = Math.min(12, Math.max(8, Math.floor(contentWidth * 0.34)));\r\n const valueWidth = Math.max(8, contentWidth - labelWidth - 1);\r\n return (\r\n <Box flexDirection=\"column\">\r\n {metrics.map((metric) => (\r\n <Box key={metric.label} flexWrap=\"nowrap\">\r\n <Text color={theme.subtle} dimColor>\r\n {padDisplay(metric.label, labelWidth)}\r\n </Text>\r\n <Text color={illuminated ? (metric.color ?? theme.text) : theme.subtle} bold>\r\n {truncateDisplay(metric.value, valueWidth)}\r\n </Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n }\r\n\r\n const columnWidth = Math.max(10, Math.floor(contentWidth / metrics.length));\r\n return (\r\n <Box flexDirection=\"row\" flexWrap=\"nowrap\">\r\n {metrics.map((metric) => (\r\n <Box key={metric.label} width={columnWidth} flexDirection=\"column\">\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(metric.label, columnWidth - 1)}\r\n </Text>\r\n <Text color={illuminated ? (metric.color ?? theme.text) : theme.subtle} bold>\r\n {truncateDisplay(metric.value, columnWidth - 1)}\r\n </Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n\r\nfunction Meter({\r\n fraction,\r\n width,\r\n progress,\r\n color,\r\n}: {\r\n fraction: number;\r\n width: number;\r\n progress: number;\r\n color: string;\r\n}) {\r\n const theme = useTheme();\r\n const safeWidth = Math.max(5, width);\r\n const target = Math.round(clamp(fraction, 0, 1) * safeWidth);\r\n const filled = Math.round(target * clamp(progress, 0, 1));\r\n\r\n return (\r\n <Box flexWrap=\"nowrap\">\r\n <Text color={color}>{'•'.repeat(filled)}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {'·'.repeat(Math.max(0, safeWidth - filled))}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction StackedUsageMeter({\r\n promptTokens,\r\n completionTokens,\r\n totalTokens,\r\n width,\r\n progress,\r\n}: {\r\n promptTokens: number;\r\n completionTokens: number;\r\n totalTokens: number;\r\n width: number;\r\n progress: number;\r\n}) {\r\n const theme = useTheme();\r\n const safeWidth = Math.max(8, width);\r\n const safeTotal = Math.max(1, totalTokens, promptTokens + completionTokens);\r\n const promptTarget = Math.round((promptTokens / safeTotal) * safeWidth);\r\n const completionTarget = Math.min(\r\n safeWidth - promptTarget,\r\n Math.round((completionTokens / safeTotal) * safeWidth),\r\n );\r\n const promptFilled = Math.round(promptTarget * progress);\r\n const completionFilled = Math.round(completionTarget * progress);\r\n const remainder = Math.max(0, safeWidth - promptFilled - completionFilled);\r\n\r\n return (\r\n <Box flexWrap=\"nowrap\">\r\n <Text color={theme.brand}>{'•'.repeat(promptFilled)}</Text>\r\n <Text color={theme.success}>{'•'.repeat(completionFilled)}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {'·'.repeat(remainder)}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction SectionLabel({ children }: { children: string }) {\r\n const theme = useTheme();\r\n return (\r\n <Text color={theme.subtle} dimColor>\r\n {children}\r\n </Text>\r\n );\r\n}\r\n\r\nfunction ConfigPanelBody({\r\n data,\r\n contentWidth,\r\n narrow,\r\n step,\r\n}: {\r\n data: ConfigCommandDisplay;\r\n contentWidth: number;\r\n narrow: boolean;\r\n step: number;\r\n}) {\r\n const theme = useTheme();\r\n const entries = useMemo(() => flattenConfigSnapshot(data.snapshot), [data.snapshot]);\r\n const groups = useMemo(() => {\r\n const counts = new Map<string, number>();\r\n for (const entry of entries) {\r\n const dotIndex = entry.path.indexOf('.');\r\n const bracketIndex = entry.path.indexOf('[');\r\n const boundaries = [dotIndex, bracketIndex].filter((index) => index >= 0);\r\n const boundary = boundaries.length > 0 ? Math.min(...boundaries) : entry.path.length;\r\n const group = entry.path.slice(0, boundary) || 'root';\r\n counts.set(group, (counts.get(group) ?? 0) + 1);\r\n }\r\n return [...counts.entries()]\r\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\r\n .slice(0, narrow ? 3 : 5);\r\n }, [entries, narrow]);\r\n const maxGroup = Math.max(1, ...groups.map(([, count]) => count));\r\n const labelWidth = narrow ? Math.min(16, Math.floor(contentWidth * 0.42)) : 24;\r\n const valueWidth = Math.max(8, contentWidth - labelWidth - 1);\r\n const barWidth = Math.max(8, Math.min(narrow ? 16 : 28, contentWidth - 18));\r\n const progress = revealProgress(step, 2);\r\n const metrics: Metric[] = [\r\n { label: 'Model', value: data.runtime.model, color: theme.brand },\r\n { label: 'Provider', value: data.runtime.provider },\r\n { label: 'Mode', value: data.runtime.mode },\r\n { label: 'Budget', value: compactNumber(data.runtime.maxTokens) },\r\n ];\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <MetricGrid\r\n metrics={metrics}\r\n contentWidth={contentWidth}\r\n narrow={narrow}\r\n illuminated={step >= 3}\r\n />\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>configuration signal map</SectionLabel>\r\n {groups.map(([group, count], index) => (\r\n <Box key={group} flexWrap=\"nowrap\">\r\n <Text color={step >= 4 + index ? theme.text : theme.subtle}>\r\n {padDisplay(group, Math.min(14, Math.max(8, contentWidth - barWidth - 5)))}\r\n </Text>\r\n <Text> </Text>\r\n <Meter\r\n fraction={count / maxGroup}\r\n width={barWidth}\r\n progress={progress}\r\n color={index === 0 ? theme.brand : theme.brandShimmer}\r\n />\r\n <Text color={theme.subtle}> {count}</Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>resolved values</SectionLabel>\r\n {entries.map((entry, index) => {\r\n const active = step >= Math.min(REVEAL_STEPS, 5 + (index % 4));\r\n const wrappedValue = wordWrap(entry.value, valueWidth);\r\n return narrow ? (\r\n <Box key={`${entry.path}-${index}`} flexDirection=\"column\">\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(entry.path, contentWidth)}\r\n </Text>\r\n <Text color={active ? theme.text : theme.subtle}>{wrappedValue}</Text>\r\n </Box>\r\n ) : (\r\n <Box key={`${entry.path}-${index}`} flexDirection=\"row\">\r\n <Text color={theme.subtle} dimColor>\r\n {padDisplay(entry.path, labelWidth)}\r\n </Text>\r\n <Text> </Text>\r\n <Box width={valueWidth}>\r\n <Text color={active ? theme.text : theme.subtle}>{wrappedValue}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n {entries.length} resolved fields · sensitive provider values redacted\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction ContextPanelBody({\r\n data,\r\n contentWidth,\r\n narrow,\r\n step,\r\n}: {\r\n data: ContextCommandDisplay;\r\n contentWidth: number;\r\n narrow: boolean;\r\n step: number;\r\n}) {\r\n const theme = useTheme();\r\n const usageFraction = data.maxTokens > 0 ? data.estimatedTokens / data.maxTokens : 0;\r\n const percent = Math.round(clamp(usageFraction, 0, 1) * 100);\r\n const meterColor = percent >= 95 ? theme.error : percent >= 80 ? theme.warning : theme.brand;\r\n const roleTotal = Math.max(1, data.userTokens + data.assistantTokens);\r\n const meterWidth = Math.max(8, contentWidth - (narrow ? 18 : 24));\r\n const windowSource = sourceLabel(data.windowSource, data.windowDeclared);\r\n const metrics: Metric[] = [\r\n {\r\n label: 'Window',\r\n value:\r\n windowSource && windowSource !== 'declared'\r\n ? `${compactNumber(data.maxTokens)} (${windowSource})`\r\n : compactNumber(data.maxTokens),\r\n color: theme.brand,\r\n },\r\n { label: 'Estimate', value: compactNumber(data.estimatedTokens) },\r\n { label: 'Messages', value: String(data.totalMessages) },\r\n { label: 'Tools', value: `${data.toolCalls}/${data.toolResults}` },\r\n ];\r\n const ambient = [\r\n `commands ${data.ambient.commandCount}`,\r\n data.ambient.skillCount === undefined ? null : `skills ${data.ambient.skillCount}`,\r\n data.ambient.subagentCount === undefined ? null : `agents ${data.ambient.subagentCount}`,\r\n `memory ${data.ambient.hasMemoryIndex ? 'loaded' : 'none'}`,\r\n `rules ${data.ambient.hasClaudeMdLoader ? 'loaded' : 'none'}`,\r\n ].filter((item): item is string => Boolean(item));\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <MetricGrid\r\n metrics={metrics}\r\n contentWidth={contentWidth}\r\n narrow={narrow}\r\n illuminated={step >= 3}\r\n />\r\n <Box flexDirection=\"column\">\r\n <Box justifyContent=\"space-between\">\r\n <SectionLabel>conversation pressure</SectionLabel>\r\n <Text bold color={meterColor}>\r\n {percent}%\r\n </Text>\r\n </Box>\r\n <Meter\r\n fraction={usageFraction}\r\n width={contentWidth}\r\n progress={revealProgress(step, 2)}\r\n color={meterColor}\r\n />\r\n <Text color={theme.subtle} dimColor>\r\n {compactNumber(data.estimatedTokens)} estimated / {compactNumber(data.maxTokens)} tokens\r\n </Text>\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>role split</SectionLabel>\r\n <Box flexWrap=\"nowrap\">\r\n <Text>{padDisplay('user', narrow ? 10 : 12)}</Text>\r\n <Meter\r\n fraction={data.userTokens / roleTotal}\r\n width={meterWidth}\r\n progress={revealProgress(step, 4)}\r\n color={theme.brandShimmer}\r\n />\r\n <Text color={theme.subtle}> {compactNumber(data.userTokens)}</Text>\r\n </Box>\r\n <Box flexWrap=\"nowrap\">\r\n <Text>{padDisplay('assistant', narrow ? 10 : 12)}</Text>\r\n <Meter\r\n fraction={data.assistantTokens / roleTotal}\r\n width={meterWidth}\r\n progress={revealProgress(step, 5)}\r\n color={theme.success}\r\n />\r\n <Text color={theme.subtle}> {compactNumber(data.assistantTokens)}</Text>\r\n </Box>\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>ambient context injected each turn</SectionLabel>\r\n <Text color={step >= 8 ? theme.text : theme.subtle}>{ambient.join(' · ')}</Text>\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n Estimate uses chars/4; provider usage remains authoritative.\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction UsagePanelBody({\r\n data,\r\n contentWidth,\r\n narrow,\r\n step,\r\n}: {\r\n data: UsageCommandDisplay;\r\n contentWidth: number;\r\n narrow: boolean;\r\n step: number;\r\n}) {\r\n const theme = useTheme();\r\n const usage = data.usage;\r\n const metrics: Metric[] = [\r\n { label: 'Turn', value: String(data.currentTurn), color: theme.brand },\r\n { label: 'Messages', value: String(data.messageCount) },\r\n { label: 'Latency', value: formatDuration(data.turnDurationMs) },\r\n {\r\n label: 'Est. cost',\r\n value: data.estimatedCostUsd === undefined ? '—' : `$${data.estimatedCostUsd.toFixed(4)}`,\r\n color: data.estimatedCostUsd === undefined ? theme.subtle : theme.success,\r\n },\r\n ];\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <MetricGrid\r\n metrics={metrics}\r\n contentWidth={contentWidth}\r\n narrow={narrow}\r\n illuminated={step >= 3}\r\n />\r\n {usage ? (\r\n <>\r\n <Box flexDirection=\"column\">\r\n <Box justifyContent=\"space-between\">\r\n <SectionLabel>token traffic</SectionLabel>\r\n <Text bold color={theme.brand}>\r\n {usage.totalTokens.toLocaleString()}\r\n </Text>\r\n </Box>\r\n <StackedUsageMeter\r\n promptTokens={usage.promptTokens}\r\n completionTokens={usage.completionTokens}\r\n totalTokens={usage.totalTokens}\r\n width={contentWidth}\r\n progress={revealProgress(step, 2)}\r\n />\r\n <Box flexDirection={narrow ? 'column' : 'row'} justifyContent=\"space-between\">\r\n <Text color={theme.brand}>• input {usage.promptTokens.toLocaleString()}</Text>\r\n <Text color={theme.success}>• output {usage.completionTokens.toLocaleString()}</Text>\r\n {usage.cacheReadInputTokens ? (\r\n <Text color={theme.subtle}>\r\n cache {usage.cacheReadInputTokens.toLocaleString()}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>active model</SectionLabel>\r\n <Text color={step >= 8 ? theme.text : theme.subtle}>{data.model}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {data.rate\r\n ? `$${data.rate.inputPerMillion}/M input · $${data.rate.outputPerMillion}/M output`\r\n : 'Pricing is not configured for this model.'}\r\n </Text>\r\n </Box>\r\n </>\r\n ) : (\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>token traffic</SectionLabel>\r\n <Meter fraction={0} width={contentWidth} progress={1} color={theme.brand} />\r\n <Text color={theme.subtle}>No model response recorded in this session yet.</Text>\r\n </Box>\r\n )}\r\n {data.toolCallStats && data.toolCallStats.length > 0 ? (\r\n <Box flexDirection=\"column\">\r\n <SectionLabel>tool calls</SectionLabel>\r\n <Text color={theme.subtle}>\r\n {`${data.toolCallStats.reduce((sum, entry) => sum + entry.calls, 0)} total`}\r\n {(() => {\r\n const failed = data.toolCallStats.reduce(\r\n (sum, entry) => sum + failureTotal(entry.failures),\r\n 0,\r\n );\r\n return failed > 0 ? ` · ${failed} failed` : '';\r\n })()}\r\n {data.toolCallStats.length > 8\r\n ? ` · showing 8 of ${data.toolCallStats.length} tools`\r\n : ''}\r\n </Text>\r\n {data.toolCallStats.slice(0, 8).map((entry) => {\r\n const failed = failureTotal(entry.failures);\r\n return (\r\n <Box key={entry.tool} flexWrap=\"nowrap\">\r\n <Text color={step >= 8 ? theme.text : theme.subtle}>\r\n {padDisplay(entry.tool, narrow ? 12 : 16)}\r\n {String(entry.calls)}\r\n </Text>\r\n {failed > 0 ? (\r\n <Text color={theme.error}> · {formatFailureCounts(entry.failures)}</Text>\r\n ) : null}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n ) : null}\r\n <Text color={theme.subtle} dimColor>\r\n Cost is a local estimate for the active model, not a billing statement.\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nexport function CommandPanel({\r\n display,\r\n fallback,\r\n terminalWidth = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: CommandPanelProps) {\r\n const theme = useTheme();\r\n const motionDisabled = reducedMotion || screenReader;\r\n const step = useStaggeredReveal(REVEAL_STEPS, true, 55, motionDisabled);\r\n\r\n if (screenReader) {\r\n return (\r\n <Box marginLeft={0} flexDirection=\"column\">\r\n <Text>{fallback}</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n const panelWidth = clamp(Math.floor(terminalWidth) - 2, 28, 96);\r\n const contentWidth = Math.max(18, panelWidth - 4);\r\n const narrow = panelWidth < 58;\r\n const header =\r\n display.kind === 'config'\r\n ? {\r\n command: '/config',\r\n title: 'Runtime map',\r\n subtitle: `${display.runtime.provider} · ${display.runtime.workspace}`,\r\n }\r\n : display.kind === 'context'\r\n ? {\r\n command: '/context',\r\n title: 'Window map',\r\n subtitle: `${display.model} · estimated conversation load before ambient injection`,\r\n }\r\n : {\r\n command: '/usage',\r\n title: 'Session telemetry',\r\n subtitle: `${display.model} · cumulative provider-reported activity`,\r\n };\r\n\r\n return (\r\n <Box\r\n marginLeft={2}\r\n width={panelWidth}\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n >\r\n <PanelHeader {...header} contentWidth={contentWidth} step={step} />\r\n {display.kind === 'config' ? (\r\n <ConfigPanelBody data={display} contentWidth={contentWidth} narrow={narrow} step={step} />\r\n ) : display.kind === 'context' ? (\r\n <ContextPanelBody data={display} contentWidth={contentWidth} narrow={narrow} step={step} />\r\n ) : (\r\n <UsagePanelBody data={display} contentWidth={contentWidth} narrow={narrow} step={step} />\r\n )}\r\n </Box>\r\n );\r\n}\r\n","import type { Message } from '../types/messages.js';\r\nimport type { NestedToolInvocation } from '../types/tools.js';\r\n\r\nexport type NestedToolChildren = ReadonlyMap<string, readonly NestedToolInvocation[]>;\r\n\r\nexport function indexNestedToolInvocations(\r\n invocations: readonly NestedToolInvocation[],\r\n): Map<string, NestedToolInvocation[]> {\r\n const children = new Map<string, NestedToolInvocation[]>();\r\n for (const invocation of invocations) {\r\n const siblings = children.get(invocation.parentTraceId);\r\n if (siblings) siblings.push(invocation);\r\n else children.set(invocation.parentTraceId, [invocation]);\r\n }\r\n return children;\r\n}\r\n\r\nexport function countNestedToolInvocations(\r\n childrenByParent: NestedToolChildren,\r\n parentTraceId: string,\r\n): number {\r\n let count = 0;\r\n const visited = new Set<string>();\r\n const stack = [...(childrenByParent.get(parentTraceId) ?? [])];\r\n while (stack.length > 0) {\r\n const invocation = stack.pop()!;\r\n if (visited.has(invocation.traceId)) continue;\r\n visited.add(invocation.traceId);\r\n count++;\r\n stack.push(...(childrenByParent.get(invocation.traceId) ?? []));\r\n }\r\n return count;\r\n}\r\n\r\nexport function selectActiveToolId(message: Message | undefined): string | null {\r\n if (!message || message.role !== 'assistant') return null;\r\n\r\n const nested = message.nestedToolInvocations ?? [];\r\n for (let index = nested.length - 1; index >= 0; index--) {\r\n if (!nested[index].result) return nested[index].traceId;\r\n }\r\n\r\n const calls = message.toolCalls ?? [];\r\n const results = new Set((message.toolResults ?? []).map((result) => result.toolCallId));\r\n for (let index = calls.length - 1; index >= 0; index--) {\r\n if (!results.has(calls[index].id)) return calls[index].id;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/** Select the newest action for explicit output expansion when none is active. */\r\nexport function selectLatestToolId(messages: readonly Message[]): string | null {\r\n for (let index = messages.length - 1; index >= 0; index--) {\r\n const message = messages[index];\r\n if (message.role !== 'assistant') continue;\r\n const nested = message.nestedToolInvocations ?? [];\r\n if (nested.length > 0) return nested[nested.length - 1].traceId;\r\n const calls = message.toolCalls ?? [];\r\n if (calls.length > 0) return calls[calls.length - 1].id;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Select the one tool row whose body should be visible in the transcript.\r\n *\r\n * This selects the latest unfinished invocation. Completed file mutations use\r\n * the separate default-expansion policy in tool-presentation.\r\n */\r\nexport function selectExpandedToolId(messages: readonly Message[]): string | null {\r\n for (let index = messages.length - 1; index >= 0; index--) {\r\n const message = messages[index];\r\n if (message.role !== 'assistant') continue;\r\n const hasToolActivity =\r\n (message.toolCalls?.length ?? 0) > 0 || (message.nestedToolInvocations?.length ?? 0) > 0;\r\n if (!hasToolActivity) continue;\r\n const activeToolId = selectActiveToolId(message);\r\n if (activeToolId) return activeToolId;\r\n }\r\n\r\n return null;\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport type { ManagedAgentTrace, ManagedAgentToolUse } from '../managed-agent-transcript.js';\r\nimport { formatDuration, deriveToolPresentation } from '../tool-presentation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { CONTENT_COLUMN, GUTTER_WIDTH, indentedGrid, transcriptGrid } from '../layout.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { Spinner } from './Spinner.js';\r\n\r\nconst MAX_VISIBLE_TOOL_USES = 1;\r\nconst TERMINAL_STATUSES = new Set(['completed', 'failed', 'stopped', 'interrupted']);\r\n\r\nfunction useCurrentTime(active: boolean): number {\r\n const tick = useUiClock('slow', active);\r\n void tick;\r\n return Date.now();\r\n}\r\n\r\nfunction statusGlyph(status: ManagedAgentToolUse['status'] | ManagedAgentTrace['status']): string {\r\n if (status === 'completed') return '✓';\r\n if (status === 'failed') return '✕';\r\n if (status === 'stopped' || status === 'interrupted') return '■';\r\n return '›';\r\n}\r\n\r\nfunction resultPreview(tool: ManagedAgentToolUse): string | undefined {\r\n const content =\r\n tool.result?.structuredError?.message ||\r\n tool.result?.presentation?.details ||\r\n tool.result?.content;\r\n if (!content) return undefined;\r\n const line = content\r\n .split(/\\r?\\n/)\r\n .map((value) => value.trim())\r\n .find(Boolean);\r\n return line ? truncateDisplay(line, 72) : undefined;\r\n}\r\n\r\nfunction durationFor(trace: ManagedAgentTrace, now: number): string | undefined {\r\n const end = trace.finishedAt ?? now;\r\n return formatDuration(Math.max(0, end - trace.startedAt));\r\n}\r\n\r\nfunction toolDuration(tool: ManagedAgentToolUse): string | undefined {\r\n if (!tool.finishedAt) return undefined;\r\n return formatDuration(Math.max(0, tool.finishedAt - tool.startedAt));\r\n}\r\n\r\nexport function ManagedAgentActivityBlock({\r\n trace,\r\n reducedMotion = false,\r\n screenReader = false,\r\n terminalWidth = 80,\r\n}: {\r\n trace: ManagedAgentTrace;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n terminalWidth?: number;\r\n}) {\r\n const theme = useTheme();\r\n const terminal = TERMINAL_STATUSES.has(trace.status);\r\n const now = useCurrentTime(!terminal);\r\n const elapsed = durationFor(trace, now);\r\n const visible = trace.toolUses.slice(-MAX_VISIBLE_TOOL_USES);\r\n const hiddenCount = Math.max(0, trace.toolUses.length - visible.length);\r\n const grid = transcriptGrid(terminalWidth);\r\n // A managed-agent block fills the same transcript slot as a tool row — it is\r\n // the other branch of the same ternary — so it sits on the same indented\r\n // grid. Left on the bare grid it would be the only row still hanging its\r\n // status glyph a gutter to the left of the prose column.\r\n const rowGrid = indentedGrid(grid);\r\n const width = rowGrid.content;\r\n\r\n if (screenReader) {\r\n return (\r\n <Box flexDirection=\"column\" marginLeft={2} width={width}>\r\n <Text>\r\n Subagent {trace.profile}, {trace.purpose}. Status {trace.status}.{' '}\r\n {elapsed ? `Elapsed ${elapsed}.` : ''}\r\n </Text>\r\n {visible.map((tool) => {\r\n const presentation = deriveToolPresentation(\r\n tool.call.name,\r\n tool.call.arguments,\r\n tool.result,\r\n );\r\n return (\r\n <Text key={tool.id}>\r\n {presentation.summary}. {tool.status}. {resultPreview(tool) ?? ''}\r\n </Text>\r\n );\r\n })}\r\n {hiddenCount > 0 ? <Text>{hiddenCount} earlier tool uses hidden.</Text> : null}\r\n <Text>Press Tab to open the complete subagent transcript.</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n const headerColor =\r\n trace.status === 'failed'\r\n ? theme.error\r\n : trace.status === 'completed'\r\n ? theme.success\r\n : trace.status === 'stopped' || trace.status === 'interrupted'\r\n ? theme.warning\r\n : theme.brand;\r\n return (\r\n <Box flexDirection=\"column\" marginLeft={CONTENT_COLUMN} width={width + GUTTER_WIDTH}>\r\n <Box>\r\n {terminal ? (\r\n <Text color={headerColor}>{statusGlyph(trace.status)} </Text>\r\n ) : (\r\n <Spinner active color={theme.assistantAccent} reducedMotion={reducedMotion} />\r\n )}\r\n <Text color={headerColor} bold>\r\n {trace.profile}\r\n </Text>\r\n <Text color={theme.text}>\r\n ({truncateDisplay(trace.purpose, Math.max(12, width - trace.profile.length - 18))})\r\n </Text>\r\n {elapsed ? <Text color={theme.subtle}> · {elapsed}</Text> : null}\r\n </Box>\r\n\r\n {visible.map((tool, index) => {\r\n const presentation = deriveToolPresentation(\r\n tool.call.name,\r\n tool.call.arguments,\r\n tool.result,\r\n );\r\n const running = tool.status === 'running';\r\n const connector = index === visible.length - 1 ? '└' : '├';\r\n const color = tool.status === 'failed' ? theme.error : running ? theme.brand : theme.text;\r\n const duration = toolDuration(tool);\r\n return (\r\n <Box key={tool.id} flexDirection=\"column\" marginLeft={CONTENT_COLUMN}>\r\n <Box>\r\n <Text color={theme.toolRail}>{connector} </Text>\r\n {running ? (\r\n <Spinner active color={theme.assistantAccent} reducedMotion={reducedMotion} />\r\n ) : (\r\n <Text color={color}>{statusGlyph(tool.status)} </Text>\r\n )}\r\n <Text color={color}>\r\n {truncateDisplay(presentation.summary, Math.max(12, width - 8))}\r\n </Text>\r\n {duration ? <Text color={theme.subtle}> · {duration}</Text> : null}\r\n </Box>\r\n {resultPreview(tool) ? (\r\n <Text color={theme.subtle} dimColor>\r\n {' '}└ {resultPreview(tool)}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n })}\r\n\r\n {hiddenCount > 0 ? (\r\n <Text color={theme.subtle}>\r\n {' '}… +{hiddenCount} tool {hiddenCount === 1 ? 'use' : 'uses'}\r\n </Text>\r\n ) : null}\r\n <Text color={theme.subtle} dimColor>\r\n {' '}\r\n {terminal ? 'Transcript retained · Tab to open' : 'Running in background · Tab to open'}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * Shared TUI debug helpers.\r\n *\r\n * Thin hooks and functions that wrap {@link ../debug-log.js} so components\r\n * don't get cluttered with repetitive `isUiDebugEnabled()` guards and manual\r\n * event formatting. They all resolve to no-ops when the corresponding debug\r\n * flag is off.\r\n *\r\n * Usage in a component:\r\n * import { useDebugMount, useDebugRender, debugInput } from '../debug.js';\r\n * const log = createUiDebugLogger('tui:mycomponent');\r\n * useDebugMount(log, { optional: 'info' });\r\n * useDebugRender(log, { count });\r\n * debugInput(log, 'Enter', 'submit-text');\r\n */\r\n\r\nimport { useRef, useEffect } from 'react';\r\nimport type { DebugLogger } from '../debug-log.js';\r\nimport { isUiDebugEnabled, isRenderDebugEnabled, isFlowDebugEnabled } from '../debug-log.js';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Hooks — useDebug* helpers for components to use inside render/effect bodies.\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Log a component mount/unmount event once.\r\n *\r\n * Call unconditionally in the component body (not inside a condition/loop).\r\n * When `BOOK_DEBUG_UI=1` (or `BOOK_DEBUG=1`) this logs `mounted` on first render\r\n * and `unmounted` in the cleanup effect.\r\n */\r\nexport function useDebugMount(log: DebugLogger, info?: Record<string, unknown>): void {\r\n if (!isUiDebugEnabled()) return;\r\n\r\n const isMount = useRef(true);\r\n if (isMount.current) {\r\n log.event('mounted', info);\r\n }\r\n\r\n useEffect(() => {\r\n isMount.current = false;\r\n return () => {\r\n log.event('unmounted');\r\n };\r\n }, [log]);\r\n}\r\n\r\n/**\r\n * Log component render events.\r\n *\r\n * Call unconditionally at the top of the component body. Gated by\r\n * `BOOK_DEBUG_RENDER=1` to keep stderr readable. When enabled, logs\r\n * `render` with the supplied metadata every time the component renders.\r\n *\r\n * Uses a ref-based throttle so high-frequency renders (streaming) don't\r\n * flood stderr.\r\n */\r\nexport function useDebugRender(\r\n log: DebugLogger,\r\n info?: Record<string, unknown>,\r\n throttleMs = 250,\r\n): void {\r\n if (!isRenderDebugEnabled()) return;\r\n\r\n const lastRender = useRef(0);\r\n const now = Date.now();\r\n if (now - lastRender.current < throttleMs) return;\r\n lastRender.current = now;\r\n\r\n log.event('render', info);\r\n}\r\n\r\n/**\r\n * Log when a specific value changes between renders, showing old→new.\r\n *\r\n * Useful for tracking state transitions without adding verbose `useEffect`\r\n * observers for each value.\r\n */\r\nexport function useDebugValueChange(\r\n log: DebugLogger,\r\n label: string,\r\n value: unknown,\r\n toRepr?: (val: unknown) => string,\r\n): void {\r\n if (!isUiDebugEnabled()) return;\r\n\r\n const prevRef = useRef<{ stored: boolean; value: unknown }>({ stored: false, value: undefined });\r\n const { stored, value: prevVal } = prevRef.current;\r\n prevRef.current = { stored: true, value };\r\n\r\n if (!stored) return;\r\n\r\n const format = toRepr ?? String;\r\n if (value !== prevVal) {\r\n log.event(`${label}:change`, { from: format(prevVal), to: format(value) });\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Plain functions — call outside React render cycles (e.g. callbacks).\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Log an input / keyboard event from a TUI component. Gated by UI debug.\r\n */\r\nexport function debugInput(\r\n log: DebugLogger,\r\n key: string,\r\n action: string,\r\n extra?: Record<string, unknown>,\r\n): void {\r\n if (!isUiDebugEnabled()) return;\r\n log.event(`input:${key}`, { action, ...extra });\r\n}\r\n\r\n/**\r\n * Log a layout / sizing decision. Gated by render debug (noisy).\r\n */\r\nexport function debugLayout(log: DebugLogger, info: Record<string, unknown>): void {\r\n if (!isRenderDebugEnabled()) return;\r\n log.event('layout', info);\r\n}\r\n\r\n/**\r\n * Log a flow enter/exit pair with timing.\r\n *\r\n * Call `debugFlowEnter` at the start of an operation and `debugFlowExit`\r\n * at the end. Gated by `BOOK_DEBUG_FLOW=1`.\r\n */\r\nlet flowSeq = 0;\r\nconst flowStack: Array<{ id: number; label: string; start: number }> = [];\r\n\r\nexport function debugFlowEnter(log: DebugLogger, label: string): number {\r\n if (!isFlowDebugEnabled()) return -1;\r\n const id = ++flowSeq;\r\n flowStack.push({ id, label, start: Date.now() });\r\n log.event('enter', { flow: label, id });\r\n return id;\r\n}\r\n\r\nexport function debugFlowExit(log: DebugLogger, label: string, id?: number): void {\r\n if (!isFlowDebugEnabled()) return;\r\n let entry: { id: number; label: string; start: number } | undefined;\r\n if (id !== undefined) {\r\n entry = flowStack.find((f) => f.id === id);\r\n } else {\r\n // Walk backwards to find the latest matching label (findLast replacement).\r\n for (let i = flowStack.length - 1; i >= 0; i--) {\r\n if (flowStack[i].label === label) {\r\n entry = flowStack[i];\r\n break;\r\n }\r\n }\r\n }\r\n if (!entry) {\r\n log.event('exit', { flow: label, durationMs: '?' });\r\n return;\r\n }\r\n const durationMs = Date.now() - entry.start;\r\n // remove from stack\r\n const idx = flowStack.indexOf(entry);\r\n if (idx >= 0) flowStack.splice(idx, 1);\r\n log.event('exit', { flow: label, id: entry.id, durationMs });\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport React from 'react';\r\nimport { useTheme } from '../theme.js';\r\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\r\nimport { TurnRule } from './TurnRule.js';\r\nimport type { ImageAttachment } from '../../types/messages.js';\r\n\r\ninterface UserMessageProps {\r\n content: string;\r\n attachments?: ImageAttachment[];\r\n terminalWidth?: number;\r\n /** Turn start time, shown at the right edge of the turn rule. */\r\n timestamp?: number;\r\n screenReader?: boolean;\r\n}\r\n\r\nfunction formatTurnTime(timestamp?: number): string {\r\n if (!timestamp) return '';\r\n return new Date(timestamp).toLocaleTimeString([], {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: false,\r\n });\r\n}\r\n\r\n/**\r\n * Split content into text segments and @mention tokens.\r\n * Matches the same pattern as input-expansion's findMentionTokens\r\n * but without filesystem dependencies — just identifies @path and @\"path\"\r\n * tokens for color highlighting.\r\n */\r\nfunction parseMentionSegments(content: string): Array<{ text: string; isMention: boolean }> {\r\n const segments: Array<{ text: string; isMention: boolean }> = [];\r\n let i = 0;\r\n let textStart = 0;\r\n\r\n function isBoundary(idx: number): boolean {\r\n if (idx === 0) return true;\r\n return /[\\s([{<\"']/.test(content[idx - 1]);\r\n }\r\n\r\n while (i < content.length) {\r\n if (content[i] !== '@' || !isBoundary(i)) {\r\n i++;\r\n continue;\r\n }\r\n\r\n const afterAt = i + 1;\r\n if (afterAt >= content.length || /\\s/.test(content[afterAt])) {\r\n i++;\r\n continue;\r\n }\r\n\r\n let mentionEnd: number | null = null;\r\n\r\n if (content[afterAt] === '\"') {\r\n const close = content.indexOf('\"', afterAt + 1);\r\n if (close !== -1) {\r\n const filePath = content.slice(afterAt + 1, close);\r\n if (filePath) {\r\n mentionEnd = close + 1;\r\n } else {\r\n i = close + 1;\r\n continue;\r\n }\r\n } else {\r\n i++;\r\n continue;\r\n }\r\n } else {\r\n let end = afterAt;\r\n while (end < content.length && !/\\s/.test(content[end])) end++;\r\n // Strip trailing punctuation\r\n let cleanEnd = end;\r\n while (cleanEnd > afterAt && /[.,;:!?)]/.test(content[cleanEnd - 1])) cleanEnd--;\r\n if (cleanEnd > afterAt) {\r\n mentionEnd = cleanEnd;\r\n } else {\r\n i = end;\r\n continue;\r\n }\r\n }\r\n\r\n if (mentionEnd !== null) {\r\n // Flush preceding plain text\r\n if (textStart < i) {\r\n segments.push({ text: content.slice(textStart, i), isMention: false });\r\n }\r\n segments.push({ text: content.slice(i, mentionEnd), isMention: true });\r\n i = mentionEnd;\r\n textStart = i;\r\n }\r\n }\r\n\r\n // Flush remaining plain text\r\n if (textStart < content.length) {\r\n segments.push({ text: content.slice(textStart), isMention: false });\r\n }\r\n\r\n return segments;\r\n}\r\n\r\n/**\r\n * A user turn: a labelled rule, then the prompt on the content column.\r\n *\r\n * The rule is what makes a long transcript scannable — it is the only element\r\n * that marks where one exchange ended and the next began. The prompt itself\r\n * needs no tint or rail; @mentions stay accented for quick scanning.\r\n */\r\nfunction UserMessageInner({\r\n content,\r\n attachments = [],\r\n terminalWidth = 80,\r\n timestamp,\r\n screenReader = false,\r\n}: UserMessageProps) {\r\n const theme = useTheme();\r\n const grid = transcriptGrid(terminalWidth);\r\n const width = grid.width;\r\n const segments = parseMentionSegments(content);\r\n\r\n if (screenReader) {\r\n return (\r\n <Box width={width}>\r\n <Text wrap=\"wrap\">\r\n {content}\r\n {attachments.length > 0\r\n ? `${content ? '\\n' : ''}${attachments.length} image attachment${attachments.length === 1 ? '' : 's'}`\r\n : ''}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" width={width}>\r\n <TurnRule\r\n label=\"you\"\r\n trailing={formatTurnTime(timestamp)}\r\n width={width - 1}\r\n accent={theme.userAccent}\r\n />\r\n <Box marginLeft={CONTENT_COLUMN} width={grid.content} flexDirection=\"column\">\r\n {content ? (\r\n <Text wrap=\"wrap\">\r\n {segments.map((seg, i) =>\r\n seg.isMention ? (\r\n <Text key={i} color={theme.userAccent}>\r\n {seg.text}\r\n </Text>\r\n ) : (\r\n <Text key={i} color={theme.text}>\r\n {seg.text}\r\n </Text>\r\n ),\r\n )}\r\n </Text>\r\n ) : null}\r\n {attachments.length > 0 ? (\r\n <Text color={theme.userAccent}>\r\n {attachments.map((_, index) => `[image ${index + 1}]`).join(' ')}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n\r\nexport const UserMessage = React.memo(UserMessageInner);\r\n","import { Box, Text } from 'ink';\r\nimport React from 'react';\r\nimport { useTheme } from '../theme.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\n\r\n/**\r\n * Compose a labelled horizontal rule: `── you ─────────────── 10:55 ──`.\r\n *\r\n * Returned as parts so the caller can colour the label independently of the\r\n * rule. The rule always spans exactly `width` columns.\r\n */\r\nexport function composeTurnRule(\r\n label: string,\r\n trailing: string,\r\n width: number,\r\n): { lead: string; label: string; fill: string; trailing: string; tail: string } {\r\n const total = Math.max(8, Math.floor(width));\r\n const lead = '── ';\r\n const tail = ' ──';\r\n const shownTrailing = trailing ? ` ${trailing}` : '';\r\n const labelBudget = Math.max(\r\n 1,\r\n total - displayWidth(lead) - displayWidth(tail) - displayWidth(shownTrailing) - 2,\r\n );\r\n const shownLabel = truncateDisplay(label, labelBudget);\r\n const fillWidth = Math.max(\r\n 0,\r\n total -\r\n displayWidth(lead) -\r\n displayWidth(shownLabel) -\r\n 1 -\r\n displayWidth(shownTrailing) -\r\n displayWidth(tail),\r\n );\r\n return {\r\n lead,\r\n label: shownLabel,\r\n fill: `${' '.repeat(1)}${'─'.repeat(fillWidth)}`,\r\n trailing: shownTrailing,\r\n tail,\r\n };\r\n}\r\n\r\n/**\r\n * The boundary between turns.\r\n *\r\n * A transcript without one is a wall of same-weight rows: this is the single\r\n * element that lets the eye find where a turn began when scrolling back.\r\n */\r\nfunction TurnRuleInner({\r\n label,\r\n trailing = '',\r\n width,\r\n accent,\r\n screenReader = false,\r\n}: {\r\n label: string;\r\n trailing?: string;\r\n width: number;\r\n accent?: string;\r\n screenReader?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n if (screenReader) {\r\n return (\r\n <Box>\r\n <Text>{trailing ? `${label} at ${trailing}` : label}</Text>\r\n </Box>\r\n );\r\n }\r\n const parts = composeTurnRule(label, trailing, width);\r\n return (\r\n <Box>\r\n <Text color={theme.mdTurnSeparator}>{parts.lead}</Text>\r\n <Text color={accent ?? theme.subtle} bold>\r\n {parts.label}\r\n </Text>\r\n <Text color={theme.mdTurnSeparator}>{parts.fill}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {parts.trailing}\r\n </Text>\r\n <Text color={theme.mdTurnSeparator}>{parts.tail}</Text>\r\n </Box>\r\n );\r\n}\r\n\r\nexport const TurnRule = React.memo(TurnRuleInner);\r\n","import { Box, Text } from 'ink';\r\nimport { basename } from 'path';\r\nimport type React from 'react';\r\nimport { useStaggeredReveal } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\r\nimport { Bookplate } from './Bookplate.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\n\r\ninterface WelcomeScreenProps {\r\n terminalWidth: number;\r\n terminalHeight: number;\r\n workspace?: string;\r\n model?: string;\r\n mode?: string;\r\n commandCount?: number;\r\n skillCount?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n /** When false, the welcome bookplate renders directly in its settled state. */\r\n animate?: boolean;\r\n}\r\n\r\nexport interface WelcomeHint {\r\n /** What the user types. */\r\n key: string;\r\n /** What it does. */\r\n label: string;\r\n}\r\n\r\n/** What a first-run user most needs to know, in the order they need it. */\r\nexport const WELCOME_HINTS: readonly WelcomeHint[] = [\r\n { key: '/help', label: 'commands' },\r\n { key: '@file', label: 'context' },\r\n { key: '/skills', label: 'workflows' },\r\n { key: '!cmd', label: 'shell' },\r\n { key: 'Ctrl+/', label: 'shortcuts' },\r\n];\r\n\r\n/** Columns between one hint and the next. */\r\nconst HINT_GAP = 4;\r\n\r\nconst TAGLINE = 'Ask anything, or type / for a command.';\r\n\r\n/**\r\n * A tiny terminal gets the short form. The hint row below already reads\r\n * `/help commands`, so orientation survives losing the long sentence — and a\r\n * truncated tagline reads as breakage, not brevity.\r\n */\r\nconst TAGLINE_TINY = 'Ask anything.';\r\n\r\n/**\r\n * Choose the hints that fit the available width, whole.\r\n *\r\n * A hint is never partially rendered: the previous screen truncated each\r\n * segment against its own budget inside a row that also held fixed separators,\r\n * so a 50-column terminal advertised `/hel commands` — a command that does not\r\n * exist. Dropping the last hint is always better than inventing one.\r\n */\r\nexport function composeWelcomeHints(hints: readonly WelcomeHint[], width: number): WelcomeHint[] {\r\n const budget = Math.max(0, Math.floor(width));\r\n const chosen: WelcomeHint[] = [];\r\n let used = 0;\r\n for (const hint of hints) {\r\n const cost = displayWidth(`${hint.key} ${hint.label}`) + (chosen.length > 0 ? HINT_GAP : 0);\r\n if (used + cost > budget) break;\r\n chosen.push(hint);\r\n used += cost;\r\n }\r\n return chosen;\r\n}\r\n\r\nfunction workspaceName(workspace?: string): string {\r\n if (!workspace) return 'workspace';\r\n return basename(workspace) || workspace;\r\n}\r\n\r\nfunction WelcomeLine({ visible, children }: { visible: boolean; children: React.ReactNode }) {\r\n return <Box>{visible ? children : <Text> </Text>}</Box>;\r\n}\r\n\r\nfunction HintRow({ hints }: { hints: WelcomeHint[] }) {\r\n const theme = useTheme();\r\n return (\r\n <Box>\r\n {hints.map((hint, index) => (\r\n <Text key={hint.key}>\r\n {index > 0 ? ' '.repeat(HINT_GAP) : ''}\r\n <Text color={theme.brand}>{hint.key}</Text>\r\n <Text color={theme.subtle}> {hint.label}</Text>\r\n </Text>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n\r\nexport function WelcomeScreen({\r\n terminalWidth,\r\n terminalHeight,\r\n workspace,\r\n model = 'model',\r\n mode = 'default',\r\n reducedMotion = false,\r\n screenReader = false,\r\n animate = true,\r\n}: WelcomeScreenProps) {\r\n const theme = useTheme();\r\n const grid = transcriptGrid(terminalWidth);\r\n const width = grid.width;\r\n const height = Math.max(8, Math.floor(terminalHeight));\r\n const compact = width < 64 || height < 18;\r\n const tiny = width < 42 || height < 12;\r\n const motionDisabled = reducedMotion || screenReader || !animate;\r\n const reveal = useStaggeredReveal(tiny ? 2 : compact ? 3 : 4, animate, 110, motionDisabled);\r\n const tagline = tiny ? TAGLINE_TINY : TAGLINE;\r\n const contentWidth = grid.content;\r\n const meta = `${workspaceName(workspace)} · ${model} · ${mode}`;\r\n const hints = composeWelcomeHints(WELCOME_HINTS, contentWidth);\r\n\r\n if (screenReader) {\r\n return (\r\n <Box flexDirection=\"column\" paddingLeft={CONTENT_COLUMN} width={width}>\r\n <Text bold>BOOK</Text>\r\n <Text>{truncateDisplay(tagline, contentWidth)}</Text>\r\n {/* Prose, not the `·`-joined chip row: a screen reader reads a\r\n sentence far better than a list of separators. */}\r\n <Text>\r\n {truncateDisplay(\r\n `Workspace ${workspaceName(workspace)}. Model ${model}. Mode ${mode}.`,\r\n contentWidth,\r\n )}\r\n </Text>\r\n <Text>\r\n {truncateDisplay(\r\n 'Type /help for commands, Ctrl+/ for shortcuts, @file for context, !cmd for shell.',\r\n contentWidth,\r\n )}\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n if (tiny) {\r\n return (\r\n <Box flexDirection=\"column\" width={width}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.assistantAccent} bold>\r\n BOOK{' '}\r\n </Text>\r\n <Text color={theme.text}>{truncateDisplay(tagline, contentWidth - 5)}</Text>\r\n </Box>\r\n <WelcomeLine visible={reveal >= 1}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <HintRow hints={composeWelcomeHints(WELCOME_HINTS, contentWidth)} />\r\n </Box>\r\n </WelcomeLine>\r\n </Box>\r\n );\r\n }\r\n\r\n if (compact) {\r\n return (\r\n <Box flexDirection=\"column\" width={width}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.assistantAccent} bold>\r\n BOOK{' '}\r\n </Text>\r\n <Text color={theme.text}>{truncateDisplay(tagline, contentWidth - 5)}</Text>\r\n </Box>\r\n <WelcomeLine visible={reveal >= 1}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(meta, contentWidth)}\r\n </Text>\r\n </Box>\r\n </WelcomeLine>\r\n <WelcomeLine visible={reveal >= 2}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <HintRow hints={hints} />\r\n </Box>\r\n </WelcomeLine>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" width={width}>\r\n {/* The plate's ╭ / ╰ glyphs are the gutter, so the mark and the tagline\r\n already land on the transcript's content column. */}\r\n <Bookplate tagline={tagline} width={contentWidth} />\r\n <WelcomeLine visible={reveal >= 1}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(meta, contentWidth)}\r\n </Text>\r\n </Box>\r\n </WelcomeLine>\r\n <WelcomeLine visible={reveal >= 2}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <HintRow hints={hints} />\r\n </Box>\r\n </WelcomeLine>\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\nexport function Bookplate({ tagline, width }: { tagline: string; width: number }) {\r\n const theme = useTheme();\r\n return (\r\n <Box flexDirection=\"column\">\r\n <Text color={theme.assistantAccent} bold>\r\n {'╭ BOOK'}\r\n </Text>\r\n <Text color={theme.toolRail}>\r\n {'╰ '}\r\n <Text color={theme.text}>{truncateDisplay(tagline, Math.max(1, width - 2))}</Text>\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n","import type { Message } from '../../types/messages.js';\r\n\r\nexport function isBlankAssistantContent(content: string | undefined | null): boolean {\r\n return !content || content.trim().length === 0;\r\n}\r\n\r\n/** Merge completed tool-only assistant messages into the preceding assistant turn for display. */\r\nexport function mergeAssistantMessages(\r\n messages: Message[],\r\n streamingMessageId?: string | null,\r\n): Message[] {\r\n if (messages.length <= 1) return messages;\r\n\r\n const merged: Message[] = [];\r\n let index = 0;\r\n while (index < messages.length) {\r\n const current = messages[index];\r\n if (current.role !== 'assistant') {\r\n merged.push(current);\r\n index++;\r\n continue;\r\n }\r\n\r\n let mergedMessage: Message = { ...current };\r\n let nextIndex = index + 1;\r\n while (nextIndex < messages.length) {\r\n const next = messages[nextIndex];\r\n if (next.role !== 'assistant') break;\r\n if (!isBlankAssistantContent(next.content)) break;\r\n if (next.id === streamingMessageId) break;\r\n mergedMessage = {\r\n ...mergedMessage,\r\n reasoningContent:\r\n [mergedMessage.reasoningContent, next.reasoningContent]\r\n .filter((value): value is string => Boolean(value))\r\n .join('\\n\\n') || undefined,\r\n toolCalls: [...(mergedMessage.toolCalls ?? []), ...(next.toolCalls ?? [])],\r\n toolResults: [...(mergedMessage.toolResults ?? []), ...(next.toolResults ?? [])],\r\n nestedToolInvocations: [\r\n ...(mergedMessage.nestedToolInvocations ?? []),\r\n ...(next.nestedToolInvocations ?? []),\r\n ],\r\n };\r\n nextIndex++;\r\n }\r\n merged.push(mergedMessage);\r\n index = nextIndex;\r\n }\r\n\r\n return merged;\r\n}\r\n","import { Box, measureElement, type DOMElement } from 'ink';\r\nimport React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\r\nimport { useTranscriptLayoutChange, useTranscriptViewport } from '../transcript-layout.js';\r\n\r\nconst DEFAULT_MAX_MOUNTED_ITEMS = 512;\r\n\r\nexport interface VirtualTranscriptRange {\r\n startIndex: number;\r\n endIndex: number;\r\n topSpacerRows: number;\r\n bottomSpacerRows: number;\r\n totalRows: number;\r\n}\r\n\r\ninterface UseVirtualTranscriptOptions<T> {\r\n items: readonly T[];\r\n enabled: boolean;\r\n terminalWidth: number;\r\n leadingRows?: number;\r\n getKey: (item: T) => string;\r\n estimateRows: (item: T) => number;\r\n}\r\n\r\nexport interface VirtualTranscriptWindow<T> extends VirtualTranscriptRange {\r\n entries: Array<{ item: T; index: number; key: string; measurementKey: string }>;\r\n measure: (measurementKey: string, rows: number) => void;\r\n virtualized: boolean;\r\n /** Sum of the pre-measurement row estimates for all items. */\r\n estimatedTotalRows: number;\r\n}\r\n\r\ninterface DerivedItemEntry {\r\n width: number;\r\n key: string;\r\n estimate: number;\r\n measurementKey: string;\r\n}\r\n\r\nfunction lowerBound(values: readonly number[], target: number): number {\r\n let low = 0;\r\n let high = values.length;\r\n while (low < high) {\r\n const middle = Math.floor((low + high) / 2);\r\n if ((values[middle] ?? 0) < target) low = middle + 1;\r\n else high = middle;\r\n }\r\n return low;\r\n}\r\n\r\nexport function getVirtualTranscriptRange(\r\n heights: readonly number[],\r\n scrollTop: number,\r\n viewportRows: number,\r\n overscanRows: number,\r\n followBottom: boolean,\r\n maxMountedItems = DEFAULT_MAX_MOUNTED_ITEMS,\r\n): VirtualTranscriptRange {\r\n const offsets = new Array<number>(heights.length + 1);\r\n offsets[0] = 0;\r\n for (let index = 0; index < heights.length; index++) {\r\n offsets[index + 1] = offsets[index]! + Math.max(1, Math.floor(heights[index] ?? 1));\r\n }\r\n\r\n const totalRows = offsets[heights.length] ?? 0;\r\n if (heights.length === 0) {\r\n return { startIndex: 0, endIndex: 0, topSpacerRows: 0, bottomSpacerRows: 0, totalRows };\r\n }\r\n\r\n const viewport = Math.max(1, Math.floor(viewportRows));\r\n const overscan = Math.max(0, Math.floor(overscanRows));\r\n const maxScrollTop = Math.max(0, totalRows - viewport);\r\n const effectiveScrollTop = followBottom\r\n ? maxScrollTop\r\n : Math.max(0, Math.min(Math.floor(scrollTop), maxScrollTop));\r\n const firstRow = Math.max(0, effectiveScrollTop - overscan);\r\n const lastRow = Math.min(totalRows, effectiveScrollTop + viewport + overscan);\r\n\r\n let startIndex = Math.max(0, lowerBound(offsets, firstRow) - 1);\r\n let endIndex = Math.min(heights.length, Math.max(startIndex + 1, lowerBound(offsets, lastRow)));\r\n const mountedLimit = Math.max(1, Math.floor(maxMountedItems));\r\n if (endIndex - startIndex > mountedLimit) {\r\n if (followBottom) startIndex = endIndex - mountedLimit;\r\n else endIndex = startIndex + mountedLimit;\r\n }\r\n\r\n return {\r\n startIndex,\r\n endIndex,\r\n topSpacerRows: offsets[startIndex] ?? 0,\r\n bottomSpacerRows: totalRows - (offsets[endIndex] ?? totalRows),\r\n totalRows,\r\n };\r\n}\r\n\r\nexport function useVirtualTranscript<T>({\r\n items,\r\n enabled,\r\n terminalWidth,\r\n leadingRows = 0,\r\n getKey,\r\n estimateRows,\r\n}: UseVirtualTranscriptOptions<T>): VirtualTranscriptWindow<T> {\r\n const viewport = useTranscriptViewport();\r\n const notifyLayoutChange = useTranscriptLayoutChange();\r\n const heightCacheRef = useRef(new Map<string, number>());\r\n const [heightVersion, setHeightVersion] = useState(0);\r\n const width = Math.max(1, Math.floor(terminalWidth));\r\n\r\n // Cache per-item derived values by item identity so a streaming update only\r\n // recomputes the one message whose object changed, not the whole window.\r\n const derivedCacheRef = useRef(new WeakMap<object, DerivedItemEntry>());\r\n const derivedFnsRef = useRef({ getKey, estimateRows });\r\n if (\r\n derivedFnsRef.current.getKey !== getKey ||\r\n derivedFnsRef.current.estimateRows !== estimateRows\r\n ) {\r\n derivedCacheRef.current = new WeakMap();\r\n derivedFnsRef.current = { getKey, estimateRows };\r\n }\r\n const derived = useMemo(() => {\r\n const cache = derivedCacheRef.current;\r\n const itemKeys = new Array<string>(items.length);\r\n const estimatedRows = new Array<number>(items.length);\r\n const measurementKeys = new Array<string>(items.length);\r\n let estimatedTotalRows = 0;\r\n for (let index = 0; index < items.length; index++) {\r\n const item = items[index]!;\r\n const cacheable = typeof item === 'object' && item !== null;\r\n let entry = cacheable ? cache.get(item as object) : undefined;\r\n if (!entry || entry.width !== width) {\r\n const key = getKey(item);\r\n const estimate = Math.max(1, Math.ceil(estimateRows(item)));\r\n entry = { width, key, estimate, measurementKey: `${width}:${key}:${estimate}` };\r\n if (cacheable) cache.set(item as object, entry);\r\n }\r\n itemKeys[index] = entry.key;\r\n estimatedRows[index] = entry.estimate;\r\n measurementKeys[index] = entry.measurementKey;\r\n estimatedTotalRows += entry.estimate;\r\n }\r\n return { itemKeys, estimatedRows, measurementKeys, estimatedTotalRows };\r\n }, [estimateRows, getKey, items, width]);\r\n const { itemKeys, estimatedRows, measurementKeys, estimatedTotalRows } = derived;\r\n const heights = useMemo(\r\n () =>\r\n items.map((item, index) =>\r\n Math.max(1, heightCacheRef.current.get(measurementKeys[index]!) ?? estimatedRows[index]!),\r\n ),\r\n [estimatedRows, heightVersion, items, measurementKeys],\r\n );\r\n\r\n useEffect(() => {\r\n const activeKeys = new Set(measurementKeys);\r\n for (const key of heightCacheRef.current.keys()) {\r\n if (!activeKeys.has(key)) heightCacheRef.current.delete(key);\r\n }\r\n }, [measurementKeys]);\r\n\r\n useLayoutEffect(() => {\r\n if (heightVersion > 0) notifyLayoutChange?.();\r\n }, [heightVersion, notifyLayoutChange]);\r\n\r\n const measure = useCallback((measurementKey: string, rows: number) => {\r\n const height = Math.max(1, Math.floor(rows));\r\n if (heightCacheRef.current.get(measurementKey) === height) return;\r\n heightCacheRef.current.set(measurementKey, height);\r\n setHeightVersion((version) => version + 1);\r\n }, []);\r\n\r\n const shouldVirtualize = enabled && viewport !== null;\r\n const range = useMemo(() => {\r\n if (!shouldVirtualize) {\r\n const totalRows = heights.reduce((sum, rows) => sum + rows, 0);\r\n return {\r\n startIndex: 0,\r\n endIndex: items.length,\r\n topSpacerRows: 0,\r\n bottomSpacerRows: 0,\r\n totalRows,\r\n };\r\n }\r\n\r\n return getVirtualTranscriptRange(\r\n heights,\r\n Math.max(0, viewport.scrollTop - Math.max(0, leadingRows)),\r\n viewport.viewportRows,\r\n Math.max(12, viewport.viewportRows),\r\n viewport.followBottom,\r\n );\r\n }, [heights, items.length, leadingRows, shouldVirtualize, viewport]);\r\n\r\n return {\r\n ...range,\r\n entries: items.slice(range.startIndex, range.endIndex).map((item, offset) => {\r\n const index = range.startIndex + offset;\r\n return { item, index, key: itemKeys[index]!, measurementKey: measurementKeys[index]! };\r\n }),\r\n measure,\r\n virtualized: shouldVirtualize,\r\n estimatedTotalRows,\r\n };\r\n}\r\n\r\nexport const VirtualTranscriptRow = React.memo(function VirtualTranscriptRow({\r\n measurementKey,\r\n onMeasure,\r\n children,\r\n}: {\r\n measurementKey: string;\r\n onMeasure: (measurementKey: string, rows: number) => void;\r\n children: React.ReactNode;\r\n}) {\r\n const rowRef = useRef<DOMElement>(null);\r\n\r\n useLayoutEffect(() => {\r\n if (!rowRef.current) return;\r\n onMeasure(measurementKey, measureElement(rowRef.current).height);\r\n }, [children, measurementKey, onMeasure]);\r\n\r\n return (\r\n <Box ref={rowRef} flexDirection=\"column\" flexShrink={0}>\r\n {children}\r\n </Box>\r\n );\r\n});\r\n","import { Box, Text } from 'ink';\r\nimport { useState, useCallback, useEffect, useRef, useMemo } from 'react';\r\nimport { useInput } from 'ink';\r\nimport { useTheme } from '../theme.js';\r\nimport { CommandMenu } from './CommandMenu.js';\r\nimport { FileMentionMenu } from './FileMentionMenu.js';\r\nimport { SkillMentionMenu } from './SkillMentionMenu.js';\r\nimport type { PermissionMode } from '../../types/runtime.js';\r\nimport type { ImageAttachment } from '../../types/messages.js';\r\nimport type { SlashCommand } from '../../types/commands.js';\r\nimport type { Skill } from '../../skills.js';\r\nimport { isShortcutsToggleKey } from '../tool-presentation.js';\r\nimport { frameGrid } from '../layout.js';\r\nimport {\r\n findActiveFileMention,\r\n getFileMentionCandidates,\r\n replaceActiveFileMention,\r\n type ActiveFileMention,\r\n type FileMentionCandidate,\r\n} from '../../input/file-mentions.js';\r\nimport {\r\n findActiveSkillMention,\r\n getSkillMentionCandidates,\r\n replaceActiveSkillMention,\r\n type ActiveSkillMention,\r\n type SkillMentionCandidate,\r\n} from '../../input/skill-mentions.js';\r\nimport { recordCommandUse } from '../../commands/recent.js';\r\nimport {\r\n getCommandsForEmptyQuery,\r\n getCommandsForQuery,\r\n type CommandItem,\r\n} from '../../commands/filter.js';\r\nimport { createUiDebugLogger } from '../../debug-log.js';\r\nimport { useDebugMount } from '../debug.js';\r\nimport { stripSgrMouseSequences } from '../mouse.js';\r\nimport { InputBox } from './InputBox.js';\r\n\r\nconst uiLog = createUiDebugLogger('tui:inputbar');\r\nconst FILE_MENTION_DEBOUNCE_MS = 40;\r\n\r\n/**\r\n * Ctrl chords InputBox handles as text edits while the composer holds a draft.\r\n *\r\n * Kept here rather than imported from InputBox so the two lists cannot drift\r\n * apart silently: this is the routing half of the same decision.\r\n */\r\nconst COMPOSER_EDIT_KEYS = new Set(['a', 'e', 'w', 'u', 'k', 'y']);\r\n\r\ninterface InputBarProps {\r\n onSubmit: (value: string, attachments?: ImageAttachment[]) => void;\r\n onPasteImage?: () => Promise<ImageAttachment | null>;\r\n submissionMode: 'submit' | 'queue' | 'blocked';\r\n mode: PermissionMode;\r\n onCycleMode: () => void;\r\n terminalWidth?: number;\r\n maxMenuRows?: number;\r\n compact?: boolean;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n /**\r\n * True when a higher-priority modal (permission prompt) owns the keyboard.\r\n * Ink's `useInput` fans every keypress to ALL registered handlers regardless\r\n * of focus, so InputBar must silence BOTH its own `useInput` and InputBox's\r\n * (via `focus`) while a modal is up — otherwise Enter/Tab/Esc double-fire and\r\n * the user confirming a permission accidentally interrupts the stream.\r\n */\r\n inputSuppressed?: boolean;\r\n /**\r\n * Whether the thing holding the keyboard is actually asking the user something\r\n * — a permission prompt, a plan approval, a question, an elicitation.\r\n *\r\n * `inputSuppressed` covers that *and* the sheets that merely take the keys\r\n * while they are open (`/config`, `/model`, the rules list, the task\r\n * surface). Both silence the composer, but only the first is a prompt, and\r\n * telling someone to \"answer\" a settings menu describes a question that is\r\n * not being asked.\r\n */\r\n awaitingAnswer?: boolean;\r\n /** Allows immediate local commands such as /tasks while the parent is running. */\r\n canSubmitWhileBusy?: (value: string) => boolean;\r\n /** Allows conversational input to be queued while the parent is running. */\r\n canQueueWhileBusy?: (value: string) => boolean;\r\n /** Receives accepted queued input. Return false when the queue is full. */\r\n onQueue?: (value: string, attachments?: ImageAttachment[]) => boolean;\r\n /** Recalls the newest queued input when the composer is empty. */\r\n onRecallQueued?: () => string | { value: string; attachments?: ImageAttachment[] } | undefined;\r\n /** Cancels the queued input currently being edited. */\r\n onCancelQueuedEdit?: () => void;\r\n /** True while the composer contains a recalled queued input. */\r\n editingQueuedInput?: boolean;\r\n /** Keeps the parent aware of the live draft for interrupt restoration. */\r\n onDraftChange?: (value: string, attachments?: ImageAttachment[]) => void;\r\n /** Moves focus from an empty prompt to the first background task when available. */\r\n onFocusBackgroundTask?: () => boolean;\r\n /**\r\n * Cycles focus through main + spawned agents on Tab from an empty prompt.\r\n * Returns false when there are no agents so Tab falls back to its default.\r\n */\r\n onCycleAgentFocus?: () => boolean;\r\n /** Forward unrecognized global keyboard shortcuts to the parent App. */\r\n onGlobalShortcut?: (\r\n input: string,\r\n key: {\r\n ctrl?: boolean;\r\n meta?: boolean;\r\n shift?: boolean;\r\n tab?: boolean;\r\n home?: boolean;\r\n end?: boolean;\r\n },\r\n ) => boolean;\r\n /** Commands for the autocomplete menu (from discoverCommands). */\r\n commands?: SlashCommand[];\r\n /** Discovered skills offered for explicit `$name` invocation. */\r\n skills?: Skill[];\r\n /** Keyed request used by conversation rewind to restore a prior prompt draft. */\r\n draftRestore?: { key: number; value: string; attachments?: ImageAttachment[] };\r\n}\r\n\r\n/**\r\n * Normalize a string to NFC (Canonical Composition) for consistent Unicode handling.\r\n */\r\nfunction normalizeInput(value: string): string {\r\n return value.normalize('NFC');\r\n}\r\n\r\nfunction getFilteredCommands(commands: SlashCommand[], filter: string): CommandItem[] {\r\n if (!filter) {\r\n return getCommandsForEmptyQuery(commands);\r\n }\r\n return getCommandsForQuery(commands, filter);\r\n}\r\n\r\nfunction getSelectedCommandValue(\r\n commands: SlashCommand[],\r\n filter: string,\r\n selectedIndex: number,\r\n): string | null {\r\n const matches = getFilteredCommands(commands, filter);\r\n if (matches.length === 0) return null;\r\n const index = Math.max(0, Math.min(selectedIndex, matches.length - 1));\r\n return '/' + matches[index].name;\r\n}\r\n\r\nfunction getSelectedFileMention(\r\n candidates: FileMentionCandidate[],\r\n selectedIndex: number,\r\n): FileMentionCandidate | null {\r\n if (candidates.length === 0) return null;\r\n const index = Math.max(0, Math.min(selectedIndex, candidates.length - 1));\r\n return candidates[index];\r\n}\r\n\r\nfunction getSelectedSkillMention(\r\n candidates: SkillMentionCandidate[],\r\n selectedIndex: number,\r\n): SkillMentionCandidate | null {\r\n if (candidates.length === 0) return null;\r\n const index = Math.max(0, Math.min(selectedIndex, candidates.length - 1));\r\n return candidates[index];\r\n}\r\n\r\n/**\r\n * Extract the command name from a slash command submission for usage tracking.\r\n */\r\nfunction extractCommandName(value: string): string | null {\r\n const match = value.match(/^\\/(\\S+)/);\r\n return match ? match[1] : null;\r\n}\r\n\r\n/**\r\n * Claude Code-style input bar with command autocomplete menu.\r\n *\r\n * When the user types `/` at the start of input, a command menu appears above\r\n * the input showing matching commands. Arrow keys navigate, Tab auto-fills,\r\n * and Enter on a selected item submits the command.\r\n *\r\n * Empty \"/\" shows commands categorized: recently used → builtins → user → project.\r\n * Typing after \"/\" uses fuzzy search with exact > prefix > fuzzy ranking.\r\n */\r\nexport function InputBar({\r\n onSubmit,\r\n onPasteImage,\r\n submissionMode,\r\n onCycleMode,\r\n canSubmitWhileBusy,\r\n canQueueWhileBusy,\r\n onQueue,\r\n onRecallQueued,\r\n onCancelQueuedEdit,\r\n editingQueuedInput = false,\r\n onDraftChange,\r\n onFocusBackgroundTask,\r\n onCycleAgentFocus,\r\n onGlobalShortcut,\r\n inputSuppressed = false,\r\n awaitingAnswer = false,\r\n commands = [],\r\n skills = [],\r\n terminalWidth = 80,\r\n maxMenuRows = 8,\r\n compact = false,\r\n reducedMotion = false,\r\n screenReader = false,\r\n draftRestore,\r\n}: InputBarProps) {\r\n const theme = useTheme();\r\n useDebugMount(uiLog, { compact, screenReader, commandsLen: commands.length });\r\n const [value, setValue] = useState('');\r\n const [history, setHistory] = useState<string[]>([]);\r\n const [historyIndex, setHistoryIndex] = useState(-1);\r\n const [attachments, setAttachments] = useState<ImageAttachment[]>([]);\r\n const [attachmentError, setAttachmentError] = useState<string | undefined>();\r\n const suggestion = compact ? 'Ask...' : 'Ask me anything...';\r\n\r\n // Command menu state\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n const [menuFilter, setMenuFilter] = useState('');\r\n const [menuSelected, setMenuSelected] = useState(0);\r\n const menuVisibleRef = useRef(false);\r\n const menuFilterRef = useRef('');\r\n const menuSelectedRef = useRef(0);\r\n\r\n // File mention menu state\r\n const [fileMenuVisible, setFileMenuVisible] = useState(false);\r\n const [fileMention, setFileMention] = useState<ActiveFileMention | null>(null);\r\n const [fileCandidates, setFileCandidates] = useState<FileMentionCandidate[]>([]);\r\n const [fileSelected, setFileSelected] = useState(0);\r\n const fileMenuVisibleRef = useRef(false);\r\n const fileMentionRef = useRef<ActiveFileMention | null>(null);\r\n const fileSelectedRef = useRef(0);\r\n const fileCandidatesRef = useRef<FileMentionCandidate[]>([]);\r\n\r\n // Skill mention menu state\r\n const [skillMenuVisible, setSkillMenuVisible] = useState(false);\r\n const [skillMention, setSkillMention] = useState<ActiveSkillMention | null>(null);\r\n const [skillSelected, setSkillSelected] = useState(0);\r\n const skillMenuVisibleRef = useRef(false);\r\n const skillMentionRef = useRef<ActiveSkillMention | null>(null);\r\n const skillSelectedRef = useRef(0);\r\n const skillCandidates = useMemo(\r\n () => getSkillMentionCandidates(skills, skillMention?.query ?? ''),\r\n [skillMention?.query, skills],\r\n );\r\n const skillCandidatesRef = useRef<SkillMentionCandidate[]>([]);\r\n\r\n useEffect(() => {\r\n onDraftChange?.(value, attachments.length > 0 ? attachments : undefined);\r\n }, [attachments, onDraftChange, value]);\r\n\r\n const filteredCmds = useMemo(\r\n () => getFilteredCommands(commands, menuFilter),\r\n [commands, menuFilter],\r\n );\r\n const resolveSubmissionAction = useCallback(\r\n (candidate: string): 'submit' | 'queue' | 'blocked' => {\r\n if (submissionMode === 'submit' || canSubmitWhileBusy?.(candidate)) return 'submit';\r\n if (submissionMode === 'queue' && (canQueueWhileBusy?.(candidate) ?? true)) return 'queue';\r\n return 'blocked';\r\n },\r\n [canQueueWhileBusy, canSubmitWhileBusy, submissionMode],\r\n );\r\n const workspace = process.env.BOOK_WORKSPACE || process.cwd();\r\n\r\n const pasteImage = useCallback(() => {\r\n if (!onPasteImage) return;\r\n void onPasteImage()\r\n .then((attachment) => {\r\n if (!attachment) return;\r\n setAttachmentError(undefined);\r\n setAttachments((current) => {\r\n if (current.length >= 4) {\r\n setAttachmentError('At most 4 images can be attached to one message.');\r\n return current;\r\n }\r\n return [...current, attachment];\r\n });\r\n })\r\n .catch((error) => {\r\n setAttachmentError(error instanceof Error ? error.message : String(error));\r\n });\r\n }, [onPasteImage]);\r\n\r\n useEffect(() => {\r\n if (!fileMention) {\r\n setFileCandidates([]);\r\n return;\r\n }\r\n\r\n const controller = new AbortController();\r\n const query = fileMention.query;\r\n const timer = setTimeout(() => {\r\n void getFileMentionCandidates(workspace, query, 50, controller.signal)\r\n .then((candidates) => {\r\n if (controller.signal.aborted) return;\r\n setFileCandidates(candidates);\r\n setFileSelected((selected) =>\r\n candidates.length === 0 ? 0 : Math.min(selected, candidates.length - 1),\r\n );\r\n })\r\n .catch((error) => {\r\n if (!controller.signal.aborted) {\r\n uiLog.event('file-menu:error', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n setFileCandidates([]);\r\n }\r\n });\r\n }, FILE_MENTION_DEBOUNCE_MS);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n controller.abort();\r\n };\r\n }, [fileMention?.query, workspace]);\r\n\r\n menuVisibleRef.current = menuVisible;\r\n menuFilterRef.current = menuFilter;\r\n menuSelectedRef.current = menuSelected;\r\n fileMenuVisibleRef.current = fileMenuVisible;\r\n fileMentionRef.current = fileMention;\r\n fileSelectedRef.current = fileSelected;\r\n fileCandidatesRef.current = fileCandidates;\r\n skillMenuVisibleRef.current = skillMenuVisible;\r\n skillMentionRef.current = skillMention;\r\n skillSelectedRef.current = skillSelected;\r\n skillCandidatesRef.current = skillCandidates;\r\n\r\n useEffect(() => {\r\n if (!draftRestore) return;\r\n setValue(normalizeInput(draftRestore.value));\r\n setAttachments(draftRestore.attachments ?? []);\r\n setHistoryIndex(-1);\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n setSkillMenuVisible(false);\r\n setSkillMention(null);\r\n setSkillSelected(0);\r\n }, [draftRestore?.key]);\r\n\r\n const acceptSelectedFileMention = useCallback(\r\n (currentValue: string, trigger: 'Tab' | 'Enter'): boolean => {\r\n const mention = fileMentionRef.current;\r\n const selected = getSelectedFileMention(fileCandidatesRef.current, fileSelectedRef.current);\r\n if (!mention || !selected) return false;\r\n\r\n const nextValue = replaceActiveFileMention(currentValue, mention, selected.path);\r\n setValue(nextValue);\r\n const nextMention = findActiveFileMention(nextValue);\r\n setFileMention(nextMention);\r\n setFileMenuVisible(!!nextMention);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n uiLog.event(`input:${trigger}`, { action: 'autofill-file-mention', path: selected.path });\r\n return true;\r\n },\r\n [],\r\n );\r\n\r\n const acceptSelectedSkillMention = useCallback(\r\n (currentValue: string, trigger: 'Tab' | 'Enter'): boolean => {\r\n const mention = skillMentionRef.current;\r\n const selected = getSelectedSkillMention(\r\n skillCandidatesRef.current,\r\n skillSelectedRef.current,\r\n );\r\n if (!mention || !selected) return false;\r\n\r\n const nextValue = replaceActiveSkillMention(currentValue, mention, selected.name);\r\n setValue(nextValue);\r\n setSkillMention(null);\r\n setSkillMenuVisible(false);\r\n setSkillSelected(0);\r\n uiLog.event(`input:${trigger}`, { action: 'autofill-skill-mention', skill: selected.name });\r\n return true;\r\n },\r\n [],\r\n );\r\n\r\n useInput((_input, key) => {\r\n // TranscriptView owns mouse reports. Drop them before menu/history routing\r\n // so wheel movement, clicks, and drags cannot reach the prompt draft.\r\n if (_input.startsWith('[<') || _input.startsWith('\\x1b[<')) return;\r\n\r\n // While a modal (permission prompt) owns the keyboard, ignore all keys —\r\n // PermissionButtons handles them. Without this, Ink fires every `useInput`\r\n // handler on every keypress, so Enter/Tab/Esc would double-fire.\r\n if (inputSuppressed) return;\r\n if (key.meta && _input.toLowerCase() === 'v') {\r\n pasteImage();\r\n return;\r\n }\r\n // Alt+Backspace is a composer edit, not a shortcut: InputBox deletes the\r\n // previous word, and restoring the pre-event value here would undo it.\r\n if (key.meta && (key.backspace || key.delete)) return;\r\n // Filter out Alt/Meta-modified keys — they're shortcuts, not text input.\r\n // Preserve the editor value while the parent handles Alt/Meta shortcuts.\r\n if (key.meta) {\r\n const preservedValue = value;\r\n queueMicrotask(() => setValue(preservedValue));\r\n return;\r\n }\r\n\r\n if (key.backspace && !value && attachments.length > 0) {\r\n setAttachments((current) => current.slice(0, -1));\r\n setAttachmentError(undefined);\r\n return;\r\n }\r\n\r\n if (key.shift && key.tab) {\r\n onCycleMode();\r\n uiLog.event('input:Shift+Tab', { action: 'cycle-mode' });\r\n return;\r\n }\r\n\r\n // ---- Command menu keyboard handling ----\r\n if (menuVisible) {\r\n // Escape: dismiss menu\r\n if (key.escape) {\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n uiLog.event('input:Escape', { action: 'dismiss-menu' });\r\n return;\r\n }\r\n // Tab: auto-fill selected command\r\n if (key.tab) {\r\n if (filteredCmds.length > 0) {\r\n const sel = Math.max(0, Math.min(menuSelected, filteredCmds.length - 1));\r\n const cmd = filteredCmds[sel];\r\n setValue('/' + cmd.name + ' ');\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n uiLog.event('input:Tab', { action: 'autofill-command', command: cmd.name });\r\n }\r\n return;\r\n }\r\n // Down arrow: next item\r\n if (key.downArrow) {\r\n setMenuSelected((prev) => {\r\n const next = prev + 1;\r\n return next >= filteredCmds.length ? 0 : next;\r\n });\r\n uiLog.event('input:Down', { action: 'menu-next-item' });\r\n return;\r\n }\r\n // Up arrow: previous item\r\n if (key.upArrow) {\r\n setMenuSelected((prev) => {\r\n const next = prev - 1;\r\n return next < 0 ? Math.max(0, filteredCmds.length - 1) : next;\r\n });\r\n uiLog.event('input:Up', { action: 'menu-prev-item' });\r\n return;\r\n }\r\n // Enter is resolved in handleSubmit, where InputBox passes the current value.\r\n if (key.return) return;\r\n // Character keys update the filter via onChange — stay visible so the\r\n // user can continue typing the command name. The menu is dismissed by\r\n // onChange when a space is typed or the leading / is removed.\r\n }\r\n\r\n // ---- Explicit skill mention menu keyboard handling ----\r\n if (skillMenuVisible) {\r\n if (key.escape) {\r\n setSkillMenuVisible(false);\r\n setSkillMention(null);\r\n setSkillSelected(0);\r\n uiLog.event('input:Escape', { action: 'dismiss-skill-menu' });\r\n return;\r\n }\r\n if (key.tab) {\r\n acceptSelectedSkillMention(value, 'Tab');\r\n return;\r\n }\r\n if (key.downArrow) {\r\n setSkillSelected((prev) => {\r\n const next = prev + 1;\r\n return next >= skillCandidates.length ? 0 : next;\r\n });\r\n return;\r\n }\r\n if (key.upArrow) {\r\n setSkillSelected((prev) => {\r\n const next = prev - 1;\r\n return next < 0 ? Math.max(0, skillCandidates.length - 1) : next;\r\n });\r\n return;\r\n }\r\n if (key.return) return;\r\n }\r\n\r\n // ---- File mention menu keyboard handling ----\r\n if (fileMenuVisible) {\r\n if (key.escape) {\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n uiLog.event('input:Escape', { action: 'dismiss-file-menu' });\r\n return;\r\n }\r\n if (key.tab) {\r\n acceptSelectedFileMention(value, 'Tab');\r\n return;\r\n }\r\n if (key.downArrow) {\r\n setFileSelected((prev) => {\r\n const next = prev + 1;\r\n return next >= fileCandidates.length ? 0 : next;\r\n });\r\n uiLog.event('input:Down', { action: 'file-menu-next-item' });\r\n return;\r\n }\r\n if (key.upArrow) {\r\n setFileSelected((prev) => {\r\n const next = prev - 1;\r\n return next < 0 ? Math.max(0, fileCandidates.length - 1) : next;\r\n });\r\n uiLog.event('input:Up', { action: 'file-menu-prev-item' });\r\n return;\r\n }\r\n if (key.return) return;\r\n }\r\n\r\n if (key.escape && editingQueuedInput) {\r\n setValue('');\r\n setHistoryIndex(-1);\r\n onCancelQueuedEdit?.();\r\n uiLog.event('input:Escape', { action: 'cancel-queued-edit' });\r\n return;\r\n }\r\n\r\n // ---- Normal mode (no menu) ----\r\n // Tab from an empty prompt cycles focus through main + spawned agents\r\n // (Claude-Code-style flat switching). Falls back to accepting the\r\n // placeholder suggestion when there are no agents to cycle.\r\n if (key.tab && !value) {\r\n if (onCycleAgentFocus?.()) {\r\n uiLog.event('input:Tab', { action: 'cycle-agent-focus' });\r\n return;\r\n }\r\n setValue(normalizeInput(suggestion));\r\n uiLog.event('input:Tab', { action: 'accept-suggestion' });\r\n return;\r\n }\r\n // Ctrl+J / Shift+Enter insert a newline without submitting. InputBox does\r\n // not expose cursor position to the parent, so append at the end of the prompt.\r\n if ((key.ctrl && (_input === 'j' || _input === '\\n')) || (key.shift && key.return)) {\r\n setValue(value + '\\n');\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n uiLog.event(key.ctrl ? 'input:Ctrl+J' : 'input:Shift+Enter', { action: 'insert-newline' });\r\n return;\r\n }\r\n // A draft in the composer claims the readline chords for editing; an empty\r\n // one leaves them to the transcript, where Ctrl+E expands a tool and\r\n // Ctrl+U scrolls. Forwarding them while there is text to edit would let the\r\n // parent consume the key and then restore the pre-event value, undoing the\r\n // edit InputBox just made.\r\n if (key.ctrl && value.length > 0 && COMPOSER_EDIT_KEYS.has(_input.toLowerCase())) return;\r\n // Forward Ctrl-based shortcuts to the parent App. As with Alt chords,\r\n // restore the pre-event value when consumed to keep shortcut routing defensive.\r\n // Ctrl+/ arrives as a bare US byte with no `ctrl` flag (see\r\n // `isShortcutsToggleKey`), so gating on `key.ctrl` alone would swallow it here.\r\n if ((key.ctrl || isShortcutsToggleKey(_input, key)) && onGlobalShortcut) {\r\n if (onGlobalShortcut(_input, key)) {\r\n const preservedValue = value;\r\n queueMicrotask(() => setValue(preservedValue));\r\n return;\r\n }\r\n }\r\n // Claude Code-style task access: Down from a fresh, empty prompt moves\r\n // focus into the task list. Enter is then handled by SubagentPanel.\r\n if (key.downArrow && !value && historyIndex < 0 && onFocusBackgroundTask?.()) {\r\n uiLog.event('input:Down', { action: 'focus-background-task' });\r\n return;\r\n }\r\n if (key.upArrow && !value) {\r\n const recalled = onRecallQueued?.();\r\n if (recalled !== undefined) {\r\n setHistoryIndex(-1);\r\n if (typeof recalled === 'string') {\r\n setValue(recalled);\r\n } else {\r\n setValue(recalled.value);\r\n setAttachments(recalled.attachments ?? []);\r\n }\r\n uiLog.event('input:Up', { action: 'recall-queued-input' });\r\n return;\r\n }\r\n }\r\n // Up arrow — navigate history backward\r\n if (key.upArrow && history.length > 0 && historyIndex < history.length - 1) {\r\n const newIdx = historyIndex + 1;\r\n setHistoryIndex(newIdx);\r\n setValue(history[newIdx]);\r\n uiLog.event('input:Up', { action: 'history-back', newIdx });\r\n return;\r\n }\r\n // Down arrow — navigate history forward\r\n if (key.downArrow && historyIndex >= 0) {\r\n const newIdx = historyIndex - 1;\r\n setHistoryIndex(newIdx);\r\n setValue(newIdx >= 0 ? history[newIdx] : '');\r\n uiLog.event('input:Down', { action: 'history-forward', newIdx });\r\n return;\r\n }\r\n });\r\n\r\n const safeOnChange = useCallback((val: string) => {\r\n const clean = normalizeInput(stripSgrMouseSequences(val));\r\n setValue(clean);\r\n\r\n // Detect / at start for command menu.\r\n // Show menu when: starts with /, no space (still typing command name).\r\n if (clean.startsWith('/') && !clean.includes(' ')) {\r\n if (!menuVisibleRef.current) {\r\n uiLog.event('menu:visible', { filter: clean.slice(1) });\r\n }\r\n setMenuVisible(true);\r\n setMenuFilter(clean.slice(1));\r\n setMenuSelected(0);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setSkillMenuVisible(false);\r\n setSkillMention(null);\r\n setSkillSelected(0);\r\n return;\r\n } else if (clean.startsWith('/') && clean.includes(' ')) {\r\n // User typed a space after command name — dismiss menu, they're typing args.\r\n if (menuVisibleRef.current) {\r\n uiLog.event('menu:hidden', { reason: 'space-after-command' });\r\n }\r\n setMenuVisible(false);\r\n } else {\r\n if (menuVisibleRef.current) {\r\n uiLog.event('menu:hidden', { reason: 'leading-slash-removed' });\r\n }\r\n setMenuVisible(false);\r\n }\r\n\r\n const activeSkillMention = findActiveSkillMention(clean);\r\n if (activeSkillMention) {\r\n if (!skillMenuVisibleRef.current) {\r\n uiLog.event('skill-menu:visible', { filter: activeSkillMention.query });\r\n }\r\n setSkillMention(activeSkillMention);\r\n setSkillSelected(0);\r\n setSkillMenuVisible(true);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n return;\r\n }\r\n if (skillMenuVisibleRef.current) {\r\n uiLog.event('skill-menu:hidden', { reason: 'no-active-mention' });\r\n }\r\n setSkillMenuVisible(false);\r\n setSkillMention(null);\r\n setSkillSelected(0);\r\n\r\n const activeMention = findActiveFileMention(clean);\r\n setFileMention(activeMention);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n const showFileMenu = !!activeMention;\r\n if (showFileMenu && !fileMenuVisibleRef.current) {\r\n uiLog.event('file-menu:visible', { filter: activeMention.query });\r\n }\r\n if (!showFileMenu && fileMenuVisibleRef.current) {\r\n uiLog.event('file-menu:hidden', { reason: 'no-active-mention' });\r\n }\r\n setFileMenuVisible(showFileMenu);\r\n }, []);\r\n\r\n const handleSubmit = useCallback(\r\n (val: string) => {\r\n if (menuVisibleRef.current) {\r\n const commandValue = getSelectedCommandValue(\r\n commands,\r\n menuFilterRef.current,\r\n menuSelectedRef.current,\r\n );\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n if (!commandValue) {\r\n setValue('');\r\n uiLog.event('submit:menu', { result: 'no-command-value' });\r\n return;\r\n }\r\n const action = resolveSubmissionAction(commandValue);\r\n if (action === 'blocked') {\r\n uiLog.event('submit:menu', {\r\n result: 'blocked',\r\n command: commandValue.slice(1),\r\n submissionMode,\r\n });\r\n setValue(commandValue);\r\n } else if (action === 'queue') {\r\n const accepted = onQueue?.(commandValue) ?? false;\r\n uiLog.event('submit:menu', {\r\n result: accepted ? 'queued' : 'queue-full',\r\n command: commandValue.slice(1),\r\n });\r\n setValue(accepted ? '' : commandValue);\r\n } else {\r\n uiLog.event('submit:menu', {\r\n result: 'command',\r\n command: commandValue.slice(1),\r\n });\r\n setHistory((h) => [commandValue, ...h].slice(0, 100));\r\n setHistoryIndex(-1);\r\n recordCommandUse(commandValue.slice(1));\r\n onSubmit(commandValue);\r\n setValue('');\r\n }\r\n return;\r\n }\r\n\r\n if (skillMenuVisibleRef.current && acceptSelectedSkillMention(val, 'Enter')) {\r\n return;\r\n }\r\n\r\n if (fileMenuVisibleRef.current && acceptSelectedFileMention(val, 'Enter')) {\r\n return;\r\n }\r\n\r\n // Dismiss menus on submit.\r\n setMenuVisible(false);\r\n setMenuSelected(0);\r\n setFileMenuVisible(false);\r\n setFileMention(null);\r\n setFileCandidates([]);\r\n setFileSelected(0);\r\n setSkillMenuVisible(false);\r\n setSkillMention(null);\r\n setSkillSelected(0);\r\n\r\n const normalized = normalizeInput(val);\r\n if (!normalized.trim() && attachments.length === 0) {\r\n uiLog.event('submit:text', { result: 'empty' });\r\n return;\r\n }\r\n if (normalized.trimStart().startsWith('/') && attachments.length > 0) {\r\n setAttachmentError('Image attachments cannot be combined with slash commands.');\r\n return;\r\n }\r\n const action = resolveSubmissionAction(normalized);\r\n if (action === 'blocked') {\r\n uiLog.event('submit:text', { result: 'blocked', len: normalized.length, submissionMode });\r\n return;\r\n }\r\n if (action === 'queue') {\r\n const accepted =\r\n attachments.length > 0\r\n ? (onQueue?.(normalized, attachments) ?? false)\r\n : (onQueue?.(normalized) ?? false);\r\n uiLog.event('submit:text', {\r\n result: accepted ? 'queued' : 'queue-full',\r\n len: normalized.length,\r\n });\r\n if (!accepted) return;\r\n } else {\r\n uiLog.event('submit:text', { result: 'submitted', len: normalized.length });\r\n }\r\n setHistory((h) => [normalized, ...h].slice(0, 100));\r\n setHistoryIndex(-1);\r\n\r\n // Track command usage for autocomplete ranking.\r\n const cmdName = extractCommandName(normalized);\r\n if (cmdName) recordCommandUse(cmdName);\r\n\r\n if (action === 'submit') {\r\n if (attachments.length > 0) onSubmit(normalized, attachments);\r\n else onSubmit(normalized);\r\n }\r\n setValue('');\r\n setAttachments([]);\r\n setAttachmentError(undefined);\r\n },\r\n [\r\n acceptSelectedFileMention,\r\n acceptSelectedSkillMention,\r\n commands,\r\n onQueue,\r\n onSubmit,\r\n resolveSubmissionAction,\r\n submissionMode,\r\n attachments,\r\n pasteImage,\r\n ],\r\n );\r\n\r\n // Keep the composer calm and stable while the status line carries the\r\n // permission mode. The focused input is the primary action in this surface;\r\n // changing its border colour with every mode made the whole frame feel like\r\n // a warning badge even when nothing needed attention.\r\n const baseBorderColor = inputSuppressed ? theme.border : theme.promptBorder;\r\n\r\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\r\n // The composer spans the transcript rather than floating over it, so it takes\r\n // the full terminal like the rows above it -- not the bounded panel measure.\r\n const frame = frameGrid(outerWidth);\r\n const editorWidth = Math.max(8, frame.width - 4);\r\n const inputWidth = Math.max(1, editorWidth - 2);\r\n const promptColor = inputSuppressed ? theme.subtle : theme.promptBorder;\r\n // A modal owns the keyboard, so the composer accepts nothing — saying\r\n // \"Type a follow-up\" here invited the user to type into a locked field while\r\n // the prompt above was reading their keystrokes as answers. Which of the two\r\n // things is holding the keys decides what to say instead: a prompt wants an\r\n // answer, a sheet just wants closing, and every sheet that suppresses input\r\n // closes on Esc.\r\n const placeholder = inputSuppressed\r\n ? awaitingAnswer\r\n ? compact\r\n ? 'Answer above'\r\n : 'Answer the prompt above'\r\n : compact\r\n ? 'Esc closes'\r\n : 'Esc closes this'\r\n : submissionMode === 'queue'\r\n ? compact\r\n ? 'Enter queues'\r\n : 'Type a follow-up; Enter queues it'\r\n : submissionMode === 'blocked'\r\n ? compact\r\n ? 'Please wait...'\r\n : 'Input is temporarily unavailable'\r\n : suggestion;\r\n\r\n const selIdx = Math.max(0, Math.min(menuSelected, filteredCmds.length - 1));\r\n const fileSelIdx = Math.max(0, Math.min(fileSelected, fileCandidates.length - 1));\r\n const skillSelIdx = Math.max(0, Math.min(skillSelected, skillCandidates.length - 1));\r\n\r\n return (\r\n <Box flexDirection=\"column\" width={outerWidth}>\r\n <CommandMenu\r\n items={filteredCmds}\r\n filterText={menuFilter}\r\n selectedIndex={selIdx}\r\n visible={menuVisible}\r\n terminalWidth={outerWidth}\r\n maxRows={maxMenuRows}\r\n compact={compact}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n <SkillMentionMenu\r\n items={skillCandidates}\r\n filterText={skillMention?.query ?? ''}\r\n selectedIndex={skillSelIdx}\r\n visible={skillMenuVisible && !menuVisible}\r\n terminalWidth={outerWidth}\r\n maxRows={maxMenuRows}\r\n compact={compact}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n <FileMentionMenu\r\n items={fileCandidates}\r\n filterText={fileMention?.query ?? ''}\r\n selectedIndex={fileSelIdx}\r\n visible={fileMenuVisible && !menuVisible && !skillMenuVisible}\r\n terminalWidth={outerWidth}\r\n maxRows={maxMenuRows}\r\n compact={compact}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n\r\n {attachments.length > 0 ? (\r\n <Box marginX={frame.marginX} paddingX={1}>\r\n <Text color={theme.brand}>\r\n {attachments.map(\r\n (attachment, index) =>\r\n `${index > 0 ? ' ' : ''}[image ${index + 1} ${(attachment.byteSize / 1024).toFixed(0)} KB]`,\r\n )}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {attachmentError ? (\r\n <Text color={theme.warning} wrap=\"wrap\">\r\n Image paste failed: {attachmentError}\r\n </Text>\r\n ) : null}\r\n\r\n <Box\r\n borderStyle=\"round\"\r\n borderColor={baseBorderColor}\r\n paddingX={1}\r\n width={frame.width}\r\n marginX={frame.marginX}\r\n >\r\n <Text color={promptColor}>{screenReader ? '> ' : '› '}</Text>\r\n <Box width={inputWidth} flexShrink={1}>\r\n <InputBox\r\n value={value}\r\n onChange={safeOnChange}\r\n onSubmit={handleSubmit}\r\n placeholder={placeholder}\r\n // Stay focused while busy so Enter can queue a follow-up; only yield\r\n // to a modal (permission prompt). `focus` here maps\r\n // to InputBox's internal `useInput` isActive — see inputSuppressed.\r\n focus={!inputSuppressed}\r\n />\r\n </Box>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import { Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport { usePulse } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { CommandItem } from '../../commands/filter.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\nimport { createRenderDebugLogger } from '../../debug-log.js';\r\nimport { floatingFrameMetrics, PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\nimport { useDebugRender } from '../debug.js';\r\n\r\nconst renderLog = createRenderDebugLogger('tui:cmdmenu');\r\n\r\ninterface CommandMenuProps {\r\n /** Pre-filtered and categorized command items to display. */\r\n items: CommandItem[];\r\n /** Current filter text (empty = show categorized sections). */\r\n filterText: string;\r\n /** Index of the currently selected item in the flattened list. */\r\n selectedIndex: number;\r\n /** Whether the menu is visible. */\r\n visible: boolean;\r\n /** Available width, excluding any parent padding. */\r\n terminalWidth?: number;\r\n /** Maximum command rows to render. */\r\n maxRows?: number;\r\n /** Compact rendering for narrow or short terminals. */\r\n compact?: boolean;\r\n /** Disable motion for accessibility. */\r\n reducedMotion?: boolean;\r\n /** Render plain, non-decorative output for screen readers. */\r\n screenReader?: boolean;\r\n}\r\n\r\n/** Narrower than this and a description is a stub, not a description. */\r\nconst MIN_DESC_WIDTH = 12;\r\n\r\nconst DESC_SEPARATOR = ' — ';\r\n\r\nconst CATEGORY_LABELS: Record<CommandItem['category'], string> = {\r\n recent: 'Recent',\r\n builtin: 'Built-in',\r\n user: 'User',\r\n project: 'Project',\r\n};\r\n\r\nconst COMPACT_CATEGORY_LABELS: Record<CommandItem['category'], string> = {\r\n recent: 'R',\r\n builtin: 'B',\r\n user: 'U',\r\n project: 'P',\r\n};\r\n\r\nexport function getCommandMenuWindow(\r\n itemCount: number,\r\n selectedIndex: number,\r\n maxRows: number,\r\n): { start: number; end: number } {\r\n const safeCount = Math.max(0, itemCount);\r\n const safeRows = Math.max(1, Math.floor(maxRows));\r\n if (safeCount <= safeRows) return { start: 0, end: safeCount };\r\n\r\n const selected = Math.max(0, Math.min(selectedIndex, safeCount - 1));\r\n const half = Math.floor(safeRows / 2);\r\n let start = Math.max(0, selected - half);\r\n start = Math.min(start, safeCount - safeRows);\r\n return { start, end: start + safeRows };\r\n}\r\n\r\n/** The runs of one command row, each free to carry its own colour. */\r\nexport interface CommandRow {\r\n marker: string;\r\n name: string;\r\n /** Argument syntax. Empty except on the selected row. */\r\n hint: string;\r\n /** Category badge. Empty when every visible row shares one category. */\r\n badge: string;\r\n desc: string;\r\n}\r\n\r\nexport interface CommandRowOptions {\r\n selected: boolean;\r\n width: number;\r\n compact: boolean;\r\n shimmer: boolean;\r\n screenReader: boolean;\r\n /** False when the visible rows are all one category, making a badge noise. */\r\n showBadge: boolean;\r\n}\r\n\r\n/**\r\n * Lay out one command row.\r\n *\r\n * Three things used to compete for the same line. The argument syntax sat\r\n * between the name and the description, so `/agent` read\r\n * `<id>|send <id> <message>|stop <id> [Built-in] — Inspec…` — the grammar of the\r\n * command before any hint of what it does, and then the meaning truncated away.\r\n * The badge repeated `[Built-in]` down every row of a list that was entirely\r\n * built-ins. And the whole row was one colour, so the name did not stand out\r\n * from its own description.\r\n *\r\n * So: the description always follows the name, the syntax appears only on the\r\n * selected row — the list is for finding a command, the syntax matters once you\r\n * have found it — and the badge appears only when the rows actually differ.\r\n * The description absorbs whatever width is left, which is the part a reader\r\n * can lose a tail of and still recognize.\r\n */\r\nexport function composeCommandRow(item: CommandItem, options: CommandRowOptions): CommandRow {\r\n const { selected, width, compact, shimmer, screenReader, showBadge } = options;\r\n const marker = screenReader\r\n ? selected\r\n ? 'selected '\r\n : ''\r\n : selected\r\n ? shimmer\r\n ? '▸ '\r\n : '› '\r\n : ' ';\r\n const name = `/${item.name}`;\r\n const badge =\r\n showBadge && !screenReader\r\n ? ` [${compact ? COMPACT_CATEGORY_LABELS[item.category] : CATEGORY_LABELS[item.category]}]`\r\n : '';\r\n const hint = selected && item.hint ? ` ${item.hint}` : '';\r\n\r\n const fixed = displayWidth(marker) + displayWidth(name) + displayWidth(badge);\r\n // The syntax is only worth its columns if enough of the row survives to still\r\n // read as a row; below that the name and what it does win.\r\n const hintFits = hint && fixed + displayWidth(hint) + MIN_DESC_WIDTH <= width;\r\n const keptHint = hintFits ? hint : '';\r\n const descBudget = width - fixed - displayWidth(keptHint) - DESC_SEPARATOR.length;\r\n const desc =\r\n item.desc && !compact && descBudget >= MIN_DESC_WIDTH\r\n ? `${DESC_SEPARATOR}${truncateDisplay(item.desc, descBudget)}`\r\n : '';\r\n\r\n return { marker, name, hint: keptHint, badge, desc };\r\n}\r\n\r\n/** Slash-command palette. Filtering/ranking lives in commands/filter.ts. */\r\nexport function CommandMenu({\r\n items,\r\n filterText,\r\n selectedIndex,\r\n visible,\r\n terminalWidth = 80,\r\n maxRows = 8,\r\n compact = false,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: CommandMenuProps) {\r\n const theme = useTheme();\r\n const shimmer = usePulse(visible && !reducedMotion && !screenReader, 360);\r\n\r\n const width = Math.max(20, Math.floor(terminalWidth));\r\n const frame = floatingFrameMetrics(width);\r\n const contentWidth = Math.max(8, frame.width - 4);\r\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\r\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\r\n const window = useMemo(\r\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\r\n [items.length, selIdx, safeMaxRows],\r\n );\r\n const visibleItems = items.slice(window.start, window.end);\r\n // A badge every row shares carries no information: `[Built-in]` down a list of\r\n // nothing but built-ins is a column of noise between the name and its meaning.\r\n // Derived from the whole filtered list rather than the visible window, so the\r\n // column does not appear and vanish as the selection scrolls a differing row\r\n // in and out of view.\r\n const showBadge = useMemo(() => new Set(items.map((item) => item.category)).size > 1, [items]);\r\n const hiddenBefore = window.start;\r\n const hiddenAfter = Math.max(0, items.length - window.end);\r\n const hiddenTotal = hiddenBefore + hiddenAfter;\r\n\r\n useDebugRender(renderLog, {\r\n items: items.length,\r\n visible: visibleItems.length,\r\n selected: selIdx,\r\n window: `[${window.start}..${window.end})`,\r\n hidden: hiddenTotal,\r\n filter: filterText || '(empty)',\r\n });\r\n\r\n if (!visible) return null;\r\n\r\n const title = filterText\r\n ? truncateDisplay(`Commands matching “${filterText}”`, contentWidth)\r\n : 'Commands';\r\n\r\n return (\r\n <SoftPanel width={frame.width} marginX={frame.marginX}>\r\n <PanelTitle>{title}</PanelTitle>\r\n\r\n {items.length === 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n No matching commands\r\n </Text>\r\n ) : (\r\n visibleItems.map((item, index) => {\r\n const globalIndex = window.start + index;\r\n const isSelected = globalIndex === selIdx;\r\n const row = composeCommandRow(item, {\r\n selected: isSelected,\r\n width: contentWidth,\r\n compact,\r\n shimmer,\r\n screenReader,\r\n showBadge,\r\n });\r\n // A selected row is a single highlighted block, so its runs inherit\r\n // one colour; an unselected one uses colour to separate the name from\r\n // what it does.\r\n return (\r\n <SelectionRow\r\n key={`${item.category}-${item.name}-${globalIndex}`}\r\n selected={isSelected}\r\n width={contentWidth}\r\n >\r\n {isSelected ? (\r\n `${row.marker}${row.name}${row.hint}${row.badge}${row.desc}`\r\n ) : (\r\n <>\r\n <Text>{row.marker}</Text>\r\n <Text color={theme.brand}>{row.name}</Text>\r\n <Text color={theme.subtle}>{row.hint}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {row.badge}\r\n </Text>\r\n <Text color={theme.subtle}>{row.desc}</Text>\r\n </>\r\n )}\r\n </SelectionRow>\r\n );\r\n })\r\n )}\r\n\r\n {hiddenTotal > 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(`… ${hiddenTotal} more, type to filter`, contentWidth)}\r\n </Text>\r\n ) : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport type { ReactNode } from 'react';\r\nimport { useTheme } from '../theme.js';\r\nimport { panelGrid } from '../layout.js';\r\n\r\nexport type PanelTone = 'neutral' | 'brand' | 'permission' | 'plan' | 'error';\r\n\r\nfunction toneColor(tone: PanelTone, theme: ReturnType<typeof useTheme>): string {\r\n switch (tone) {\r\n case 'brand':\r\n return theme.brand;\r\n case 'permission':\r\n return theme.permission;\r\n case 'plan':\r\n return theme.planMode;\r\n case 'error':\r\n return theme.error;\r\n default:\r\n return theme.border;\r\n }\r\n}\r\n\r\nexport function SoftPanel({\r\n children,\r\n tone = 'neutral',\r\n width,\r\n marginX = 0,\r\n paddingX = 1,\r\n}: {\r\n children: ReactNode;\r\n tone?: PanelTone;\r\n width?: number;\r\n marginX?: number;\r\n paddingX?: number;\r\n}) {\r\n const theme = useTheme();\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={toneColor(tone, theme)}\r\n paddingX={paddingX}\r\n width={width}\r\n marginX={marginX}\r\n >\r\n {children}\r\n </Box>\r\n );\r\n}\r\n\r\nexport function PanelTitle({\r\n children,\r\n tone = 'brand',\r\n}: {\r\n children: ReactNode;\r\n tone?: PanelTone;\r\n}) {\r\n const theme = useTheme();\r\n return (\r\n <Text bold color={toneColor(tone, theme)}>\r\n {children}\r\n </Text>\r\n );\r\n}\r\n\r\nexport function SelectionRow({\r\n selected,\r\n children,\r\n width,\r\n}: {\r\n selected: boolean;\r\n children: ReactNode;\r\n width?: number;\r\n}) {\r\n const theme = useTheme();\r\n return (\r\n <Box width={width} backgroundColor={selected ? theme.surfaceActive : undefined}>\r\n <Text color={selected ? theme.selectionText : theme.text} bold={selected}>\r\n {children}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Prefer {@link panelGrid} directly. Kept so every floating surface\r\n * keeps a single call site while they migrate to the grid.\r\n *\r\n * Note this is {@link panelGrid}, not {@link frameGrid}: everything that reaches\r\n * here floats over the transcript, so it is bounded. The composer is the one\r\n * bordered surface that spans the transcript, and it calls `frameGrid` itself.\r\n */\r\nexport function floatingFrameMetrics(terminalWidth: number): { width: number; marginX: number } {\r\n return panelGrid(terminalWidth);\r\n}\r\n","import { Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport { usePulse } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { FileMentionCandidate } from '../../input/file-mentions.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { getCommandMenuWindow } from './CommandMenu.js';\r\nimport { floatingFrameMetrics, PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\n\r\ninterface FileMentionMenuProps {\r\n items: FileMentionCandidate[];\r\n filterText: string;\r\n selectedIndex: number;\r\n visible: boolean;\r\n terminalWidth?: number;\r\n maxRows?: number;\r\n compact?: boolean;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}\r\n\r\nfunction formatFileRow(\r\n item: FileMentionCandidate,\r\n selected: boolean,\r\n width: number,\r\n compact: boolean,\r\n shimmer: boolean,\r\n screenReader: boolean,\r\n): string {\r\n const marker = screenReader\r\n ? selected\r\n ? 'selected '\r\n : ''\r\n : selected\r\n ? shimmer\r\n ? '▸ '\r\n : '› '\r\n : ' ';\r\n const badge =\r\n item.kind === 'directory' ? (compact ? ' [D]' : ' [Directory]') : compact ? ' [F]' : ' [File]';\r\n const desc = item.desc && !compact ? ` — ${item.desc}` : '';\r\n return truncateDisplay(`${marker}@${item.path}${badge}${desc}`, width);\r\n}\r\n\r\n/** Workspace file picker for @ mentions. */\r\nexport function FileMentionMenu({\r\n items,\r\n filterText,\r\n selectedIndex,\r\n visible,\r\n terminalWidth = 80,\r\n maxRows = 8,\r\n compact = false,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: FileMentionMenuProps) {\r\n const theme = useTheme();\r\n const shimmer = usePulse(visible && !reducedMotion && !screenReader, 360);\r\n\r\n const width = Math.max(20, Math.floor(terminalWidth));\r\n const frame = floatingFrameMetrics(width);\r\n const contentWidth = Math.max(8, frame.width - 4);\r\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\r\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\r\n const window = useMemo(\r\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\r\n [items.length, selIdx, safeMaxRows],\r\n );\r\n const visibleItems = items.slice(window.start, window.end);\r\n const hiddenTotal = window.start + Math.max(0, items.length - window.end);\r\n\r\n if (!visible) return null;\r\n\r\n const title = filterText\r\n ? truncateDisplay(`Files matching “${filterText}”`, contentWidth)\r\n : 'Files';\r\n\r\n return (\r\n <SoftPanel width={frame.width} marginX={frame.marginX}>\r\n <PanelTitle>{title}</PanelTitle>\r\n\r\n {items.length === 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n No matching files\r\n </Text>\r\n ) : (\r\n visibleItems.map((item, index) => {\r\n const globalIndex = window.start + index;\r\n const isSelected = globalIndex === selIdx;\r\n return (\r\n <SelectionRow\r\n key={`${item.kind}-${item.path}-${globalIndex}`}\r\n selected={isSelected}\r\n width={contentWidth}\r\n >\r\n {formatFileRow(item, isSelected, contentWidth, compact, shimmer, screenReader)}\r\n </SelectionRow>\r\n );\r\n })\r\n )}\r\n\r\n {hiddenTotal > 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(`… ${hiddenTotal} more, type to filter`, contentWidth)}\r\n </Text>\r\n ) : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import { Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport { usePulse } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { SkillMentionCandidate } from '../../input/skill-mentions.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { getCommandMenuWindow } from './CommandMenu.js';\r\nimport { floatingFrameMetrics, PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\n\r\ninterface SkillMentionMenuProps {\r\n items: SkillMentionCandidate[];\r\n filterText: string;\r\n selectedIndex: number;\r\n visible: boolean;\r\n terminalWidth?: number;\r\n maxRows?: number;\r\n compact?: boolean;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}\r\n\r\nfunction formatSkillRow(\r\n item: SkillMentionCandidate,\r\n selected: boolean,\r\n width: number,\r\n compact: boolean,\r\n shimmer: boolean,\r\n screenReader: boolean,\r\n): string {\r\n const marker = screenReader\r\n ? selected\r\n ? 'selected '\r\n : ''\r\n : selected\r\n ? shimmer\r\n ? '▸ '\r\n : '› '\r\n : ' ';\r\n const desc = item.description && !compact ? ` — ${item.description}` : '';\r\n return truncateDisplay(`${marker}$${item.name}${desc}`, width);\r\n}\r\n\r\n/** Skill picker for explicit `$name` mentions. */\r\nexport function SkillMentionMenu({\r\n items,\r\n filterText,\r\n selectedIndex,\r\n visible,\r\n terminalWidth = 80,\r\n maxRows = 8,\r\n compact = false,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: SkillMentionMenuProps) {\r\n const theme = useTheme();\r\n const shimmer = usePulse(visible && !reducedMotion && !screenReader, 360);\r\n const width = Math.max(20, Math.floor(terminalWidth));\r\n const frame = floatingFrameMetrics(width);\r\n const contentWidth = Math.max(8, frame.width - 4);\r\n const safeMaxRows = Math.max(1, Math.floor(maxRows));\r\n const selIdx = Math.max(0, Math.min(selectedIndex, items.length - 1));\r\n const window = useMemo(\r\n () => getCommandMenuWindow(items.length, selIdx, safeMaxRows),\r\n [items.length, selIdx, safeMaxRows],\r\n );\r\n const visibleItems = items.slice(window.start, window.end);\r\n const hiddenTotal = window.start + Math.max(0, items.length - window.end);\r\n\r\n if (!visible) return null;\r\n\r\n return (\r\n <SoftPanel width={frame.width} marginX={frame.marginX}>\r\n <PanelTitle>\r\n {filterText ? truncateDisplay(`Skills matching “${filterText}”`, contentWidth) : 'Skills'}\r\n </PanelTitle>\r\n {items.length === 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n No matching skills\r\n </Text>\r\n ) : (\r\n visibleItems.map((item, index) => {\r\n const globalIndex = window.start + index;\r\n const selected = globalIndex === selIdx;\r\n return (\r\n <SelectionRow\r\n key={`${item.source}:${item.rootKind}:${item.name}:${globalIndex}`}\r\n selected={selected}\r\n width={contentWidth}\r\n >\r\n {formatSkillRow(item, selected, contentWidth, compact, shimmer, screenReader)}\r\n </SelectionRow>\r\n );\r\n })\r\n )}\r\n {hiddenTotal > 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(`… ${hiddenTotal} more, type to filter`, contentWidth)}\r\n </Text>\r\n ) : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import type { Skill } from '../skills.js';\r\n\r\nexport interface ActiveSkillMention {\r\n start: number;\r\n end: number;\r\n query: string;\r\n}\r\n\r\nexport interface SkillMentionCandidate {\r\n name: string;\r\n description: string;\r\n source: Skill['source'];\r\n rootKind: Skill['rootKind'];\r\n}\r\n\r\nfunction isMentionBoundary(input: string, index: number): boolean {\r\n if (index === 0) return true;\r\n return /[\\s([{<\"']/.test(input[index - 1]);\r\n}\r\n\r\n/** Find an unfinished `$skill-name` mention at the end of the prompt. */\r\nexport function findActiveSkillMention(input: string): ActiveSkillMention | null {\r\n for (let index = input.length - 1; index >= 0; index--) {\r\n if (input[index] !== '$' || !isMentionBoundary(input, index)) continue;\r\n\r\n const query = input.slice(index + 1);\r\n if (!/^[a-z0-9-]*$/i.test(query)) return null;\r\n return { start: index, end: input.length, query };\r\n }\r\n return null;\r\n}\r\n\r\n/** Rank valid, explicitly invocable skills for the active mention. */\r\nexport function getSkillMentionCandidates(\r\n skills: readonly Skill[],\r\n query: string,\r\n limit = 50,\r\n): SkillMentionCandidate[] {\r\n const normalizedQuery = query.toLowerCase();\r\n const candidates: Array<SkillMentionCandidate & { score: number }> = [];\r\n\r\n for (const skill of skills) {\r\n // This is the explicit `$name` picker, so Claude-compatible\r\n // `disable-model-invocation` remains intentionally invocable by the user.\r\n if (!skill.valid || skill.activation === 'off' || skill.execution === 'deny') continue;\r\n\r\n const name = skill.name.toLowerCase();\r\n const description = skill.description.toLowerCase();\r\n let score: number | null = null;\r\n if (!normalizedQuery) score = 3;\r\n else if (name === normalizedQuery) score = 0;\r\n else if (name.startsWith(normalizedQuery)) score = 1;\r\n else if (name.includes(normalizedQuery)) score = 2;\r\n else if (description.includes(normalizedQuery)) score = 4;\r\n if (score === null) continue;\r\n\r\n candidates.push({\r\n name: skill.name,\r\n description: skill.description,\r\n source: skill.source,\r\n rootKind: skill.rootKind,\r\n score,\r\n });\r\n }\r\n\r\n candidates.sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\r\n return candidates.slice(0, limit).map(({ score: _score, ...candidate }) => candidate);\r\n}\r\n\r\nexport function replaceActiveSkillMention(\r\n input: string,\r\n mention: ActiveSkillMention,\r\n skillName: string,\r\n): string {\r\n return input.slice(0, mention.start) + `$${skillName} ` + input.slice(mention.end);\r\n}\r\n","/**\r\n * Session-level recently-used command tracker.\r\n *\r\n * Tracks how many times each command has been invoked via `/` in the current\r\n * session. Used to surface frequently-used commands at the top of the `/`\r\n * autocomplete when the user types an empty query.\r\n */\r\n\r\nconst usage = new Map<string, number>();\r\n\r\nexport function recordCommandUse(name: string): void {\r\n usage.set(name, (usage.get(name) ?? 0) + 1);\r\n}\r\n\r\nexport function getRecentCommands(limit = 5): string[] {\r\n return Array.from(usage.entries())\r\n .sort((a, b) => b[1] - a[1])\r\n .slice(0, limit)\r\n .map(([name]) => name);\r\n}\r\n","/**\r\n * Slash command filtering with categorized display and fuzzy search.\r\n *\r\n * Two modes:\r\n * - Empty query (\"/\"): categorized list with recently-used at top\r\n * - Typed query (\"/com\"): Fuse.js fuzzy search with priority ranking\r\n */\r\n\r\nimport Fuse from 'fuse.js';\r\nimport type { SlashCommand } from '../types/commands.js';\r\nimport { BUILTIN_COMMANDS } from './builtins.js';\r\nimport { getRecentCommands } from './recent.js';\r\n\r\nexport interface CommandItem {\r\n name: string;\r\n hint: string;\r\n desc: string;\r\n /** Category badge: 'recent' | 'builtin' | 'user' | 'project' */\r\n category: 'recent' | 'builtin' | 'user' | 'project';\r\n}\r\n\r\n// ── Fuse.js index (built once per commands array identity via memoization) ──\r\n\r\nlet _fuseCommands: SlashCommand[] | null = null;\r\nlet _fuse: Fuse<{ name: string; desc: string; hint: string }> | null = null;\r\n\r\nfunction getFuse(commands: SlashCommand[]): Fuse<{ name: string; desc: string; hint: string }> {\r\n // Build a unified list: builtins + custom\r\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\r\n\r\n const items: Array<{ name: string; desc: string; hint: string }> = [];\r\n\r\n for (const b of BUILTIN_COMMANDS) {\r\n if (!b.isHidden) {\r\n items.push({ name: b.name, desc: b.description, hint: b.argumentHint ?? '' });\r\n }\r\n }\r\n\r\n for (const cmd of commands) {\r\n if (builtinNames.has(cmd.name)) continue;\r\n if (cmd.isHidden) continue;\r\n items.push({ name: cmd.name, desc: cmd.description, hint: cmd.argumentHint ?? '' });\r\n }\r\n\r\n // Only rebuild if commands changed\r\n if (_fuseCommands === commands && _fuse) return _fuse;\r\n\r\n _fuseCommands = commands;\r\n _fuse = new Fuse(items, {\r\n keys: [\r\n { name: 'name', weight: 3 },\r\n { name: 'desc', weight: 0.5 },\r\n ],\r\n threshold: 0.3,\r\n location: 0,\r\n distance: 100,\r\n });\r\n\r\n return _fuse;\r\n}\r\n\r\n// ── Empty query: categorized display ──\r\n\r\nexport function getCommandsForEmptyQuery(commands: SlashCommand[]): CommandItem[] {\r\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\r\n const recentNames = new Set(getRecentCommands());\r\n\r\n const result: CommandItem[] = [];\r\n\r\n // 1. Recently used (sorted by frequency)\r\n for (const name of getRecentCommands()) {\r\n const builtin = BUILTIN_COMMANDS.find((b) => b.name === name);\r\n if (builtin && !builtin.isHidden) {\r\n result.push({\r\n name: builtin.name,\r\n hint: builtin.argumentHint ?? '',\r\n desc: builtin.description,\r\n category: 'recent',\r\n });\r\n }\r\n }\r\n\r\n // 2. Built-in commands (alphabetical, excluding recently used and hidden)\r\n const builtins: CommandItem[] = [];\r\n for (const b of BUILTIN_COMMANDS) {\r\n if (b.isHidden || recentNames.has(b.name)) continue;\r\n builtins.push({\r\n name: b.name,\r\n hint: b.argumentHint ?? '',\r\n desc: b.description,\r\n category: 'builtin',\r\n });\r\n }\r\n builtins.sort((a, b) => {\r\n if (a.name === 'clear') return -1;\r\n if (b.name === 'clear') return 1;\r\n return a.name.localeCompare(b.name);\r\n });\r\n result.push(...builtins);\r\n\r\n // 3. User commands (alphabetical, excluding recently used)\r\n const userCmds: CommandItem[] = [];\r\n for (const cmd of commands) {\r\n if (builtinNames.has(cmd.name) || recentNames.has(cmd.name) || cmd.isHidden) continue;\r\n if (cmd.source === 'user') {\r\n userCmds.push({\r\n name: cmd.name,\r\n hint: cmd.argumentHint ?? '',\r\n desc: cmd.description,\r\n category: 'user',\r\n });\r\n }\r\n }\r\n userCmds.sort((a, b) => a.name.localeCompare(b.name));\r\n result.push(...userCmds);\r\n\r\n // 4. Project commands (alphabetical)\r\n const projectCmds: CommandItem[] = [];\r\n for (const cmd of commands) {\r\n if (builtinNames.has(cmd.name) || recentNames.has(cmd.name) || cmd.isHidden) continue;\r\n if (cmd.source === 'project') {\r\n projectCmds.push({\r\n name: cmd.name,\r\n hint: cmd.argumentHint ?? '',\r\n desc: cmd.description,\r\n category: 'project',\r\n });\r\n }\r\n }\r\n projectCmds.sort((a, b) => a.name.localeCompare(b.name));\r\n result.push(...projectCmds);\r\n\r\n return result;\r\n}\r\n\r\n// ── Typed query: Fuse.js fuzzy search with priority ranking ──\r\n\r\nexport function getCommandsForQuery(commands: SlashCommand[], query: string): CommandItem[] {\r\n const fuse = getFuse(commands);\r\n const q = query.toLowerCase().trim();\r\n const builtinNames = new Set(BUILTIN_COMMANDS.map((c) => c.name));\r\n\r\n const searchResults = fuse.search(q);\r\n\r\n // Build a lookup for custom command → source\r\n const customSource = new Map<string, 'user' | 'project'>();\r\n for (const cmd of commands) {\r\n if (!builtinNames.has(cmd.name)) {\r\n customSource.set(cmd.name, cmd.source);\r\n }\r\n }\r\n\r\n // Score each result: 0 = exact name, 1 = prefix name, 2 = fuzzy\r\n const scored = searchResults.map((r) => {\r\n const name = r.item.name.toLowerCase();\r\n let priority: number;\r\n if (name === q) {\r\n priority = 0;\r\n } else if (name.startsWith(q)) {\r\n priority = 1;\r\n } else {\r\n priority = 2;\r\n }\r\n\r\n const isBuiltin = builtinNames.has(r.item.name);\r\n const category: CommandItem['category'] = isBuiltin\r\n ? 'builtin'\r\n : customSource.get(r.item.name) === 'project'\r\n ? 'project'\r\n : 'user';\r\n\r\n return {\r\n name: r.item.name,\r\n hint: r.item.hint,\r\n desc: r.item.desc,\r\n category,\r\n priority,\r\n };\r\n });\r\n\r\n // Sort: priority first, then alphabetically\r\n scored.sort((a, b) => {\r\n if (a.priority !== b.priority) return a.priority - b.priority;\r\n return a.name.localeCompare(b.name);\r\n });\r\n\r\n return scored.map(({ priority: _priority, ...item }) => item);\r\n}\r\n","export type SgrMouseEventType = 'press' | 'release' | 'move' | 'wheel';\r\nexport type SgrMouseButton = 'left' | 'middle' | 'right' | 'none' | 'wheel-up' | 'wheel-down';\r\n\r\nexport interface SgrMouseEvent {\r\n type: SgrMouseEventType;\r\n button: SgrMouseButton;\r\n x: number;\r\n y: number;\r\n shift: boolean;\r\n alt: boolean;\r\n ctrl: boolean;\r\n}\r\n\r\nconst SGR_MOUSE_PATTERN = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)(M|m)$/;\r\nconst COMPLETE_SGR_MOUSE_SEQUENCE_PATTERN = /\\x1b\\[<\\d+;\\d+;\\d+[Mm]/g;\r\nconst INPUT_SGR_MOUSE_SEQUENCE_PATTERN = /(?:\\x1b)?\\[<\\d+;\\d+;\\d+[Mm]/g;\r\n\r\n/** Remove complete SGR mouse reports, with or without the escape byte Ink may consume. */\r\nexport function stripSgrMouseSequences(input: string): string {\r\n return input.replace(INPUT_SGR_MOUSE_SEQUENCE_PATTERN, '');\r\n}\r\n\r\n/** Parse one complete SGR mouse report into a typed, 1-based terminal event. */\r\nexport function parseSgrMouseEvent(input: string): SgrMouseEvent | null {\r\n const match = SGR_MOUSE_PATTERN.exec(input);\r\n if (!match) return null;\r\n\r\n const code = Number(match[1]);\r\n const x = Number(match[2]);\r\n const y = Number(match[3]);\r\n if (![code, x, y].every(Number.isSafeInteger) || x < 1 || y < 1) return null;\r\n\r\n const shift = (code & 4) !== 0;\r\n const alt = (code & 8) !== 0;\r\n const ctrl = (code & 16) !== 0;\r\n const isWheel = (code & 64) !== 0;\r\n const isMove = (code & 32) !== 0;\r\n const buttonCode = code & 3;\r\n\r\n if (isWheel) {\r\n if (buttonCode > 1 || match[4] === 'm') return null;\r\n return {\r\n type: 'wheel',\r\n button: buttonCode === 0 ? 'wheel-up' : 'wheel-down',\r\n x,\r\n y,\r\n shift,\r\n alt,\r\n ctrl,\r\n };\r\n }\r\n\r\n const button: SgrMouseButton =\r\n buttonCode === 0 ? 'left' : buttonCode === 1 ? 'middle' : buttonCode === 2 ? 'right' : 'none';\r\n const type: SgrMouseEventType =\r\n match[4] === 'm' ? 'release' : isMove ? 'move' : buttonCode === 3 ? 'release' : 'press';\r\n return { type, button, x, y, shift, alt, ctrl };\r\n}\r\n\r\n/** Parse every complete SGR mouse report from a coalesced terminal input chunk. */\r\nexport function parseSgrMouseEvents(input: string): SgrMouseEvent[] {\r\n const events: SgrMouseEvent[] = [];\r\n for (const match of input.matchAll(COMPLETE_SGR_MOUSE_SEQUENCE_PATTERN)) {\r\n const event = parseSgrMouseEvent(match[0]);\r\n if (event) events.push(event);\r\n }\r\n return events;\r\n}\r\n","import { Text, useInput } from 'ink';\r\nimport { useReducer, useRef } from 'react';\r\n\r\ninterface InputBoxProps {\r\n value: string;\r\n onChange: (value: string) => void;\r\n onSubmit?: (value: string) => void;\r\n placeholder?: string;\r\n focus?: boolean;\r\n}\r\n\r\ninterface EditState {\r\n value: string;\r\n cursorOffset: number;\r\n}\r\n\r\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\r\n\r\nfunction previousGraphemeBoundary(value: string, offset: number): number {\r\n let previous = 0;\r\n for (const segment of graphemeSegmenter.segment(value)) {\r\n if (segment.index >= offset) break;\r\n previous = segment.index;\r\n }\r\n return previous;\r\n}\r\n\r\nfunction nextGraphemeBoundary(value: string, offset: number): number {\r\n for (const segment of graphemeSegmenter.segment(value)) {\r\n if (segment.index > offset) return segment.index;\r\n }\r\n return value.length;\r\n}\r\n\r\n/**\r\n * Offset of the start of the word before `offset`.\r\n *\r\n * Skips the whitespace immediately behind the cursor, then the run of\r\n * non-whitespace before that — readline's `unix-word-rubout`, which is what\r\n * Ctrl+W and Alt+Backspace both mean to a terminal user.\r\n */\r\nfunction previousWordBoundary(value: string, offset: number): number {\r\n let index = offset;\r\n while (index > 0 && /\\s/.test(value[index - 1]!)) index -= 1;\r\n while (index > 0 && !/\\s/.test(value[index - 1]!)) index -= 1;\r\n return index;\r\n}\r\n\r\n/** Remove `[start, end)` and leave the cursor where the text was. */\r\nfunction cut(value: string, start: number, end: number): { edit: EditState; killed: string } {\r\n return {\r\n edit: { value: value.slice(0, start) + value.slice(end), cursorOffset: start },\r\n killed: value.slice(start, end),\r\n };\r\n}\r\n\r\nfunction normalizeEdit(value: string, cursorOffset: number): EditState {\r\n return {\r\n value: value.normalize('NFC'),\r\n cursorOffset: value.slice(0, cursorOffset).normalize('NFC').length,\r\n };\r\n}\r\n\r\nfunction deletePreviousGrapheme(value: string, cursorOffset: number): EditState {\r\n if (cursorOffset <= 0) return { value, cursorOffset };\r\n const previousOffset = previousGraphemeBoundary(value, cursorOffset);\r\n return {\r\n value: value.slice(0, previousOffset) + value.slice(cursorOffset),\r\n cursorOffset: previousOffset,\r\n };\r\n}\r\n\r\n/** Apply a raw terminal input chunk, including IME backspace/replacement sequences. */\r\nexport function applyInputSequence(value: string, cursorOffset: number, input: string): EditState {\r\n let edit = { value, cursorOffset };\r\n\r\n for (const character of input) {\r\n if (character === '\\b' || character === '\\x7f') {\r\n edit = deletePreviousGrapheme(edit.value, edit.cursorOffset);\r\n continue;\r\n }\r\n\r\n // Ignore control bytes that should never become visible prompt text.\r\n if (character < ' ' && character !== '\\n' && character !== '\\t') continue;\r\n\r\n edit = {\r\n value:\r\n edit.value.slice(0, edit.cursorOffset) + character + edit.value.slice(edit.cursorOffset),\r\n cursorOffset: edit.cursorOffset + character.length,\r\n };\r\n }\r\n\r\n return normalizeEdit(edit.value, edit.cursorOffset);\r\n}\r\n\r\n/**\r\n * Unicode input editor that keeps its draft in refs so rapid IME replacement\r\n * events never operate on stale React render state.\r\n */\r\nexport function InputBox({\r\n value,\r\n onChange,\r\n onSubmit,\r\n placeholder = '',\r\n focus = true,\r\n}: InputBoxProps) {\r\n const valueRef = useRef(value);\r\n const cursorOffsetRef = useRef(value.length);\r\n // Kill ring. The three kill keys are the only edits here that can destroy a\r\n // long prompt in one keystroke, and Ctrl+U in particular used to scroll the\r\n // transcript instead — so the recovery key ships with them, not after them.\r\n const killRingRef = useRef('');\r\n const [, rerender] = useReducer((version: number) => version + 1, 0);\r\n\r\n // Parent-driven changes such as history navigation and autocomplete own the cursor.\r\n if (value !== valueRef.current) {\r\n valueRef.current = value;\r\n cursorOffsetRef.current = value.length;\r\n }\r\n\r\n const commit = (edit: EditState) => {\r\n const changed = edit.value !== valueRef.current;\r\n valueRef.current = edit.value;\r\n cursorOffsetRef.current = edit.cursorOffset;\r\n rerender();\r\n if (changed) onChange(edit.value);\r\n };\r\n\r\n const killTo = (start: number, end: number) => {\r\n const { edit, killed } = cut(valueRef.current, start, end);\r\n if (!killed) return;\r\n killRingRef.current = killed;\r\n commit(edit);\r\n };\r\n\r\n useInput(\r\n (input, key) => {\r\n // Alt+Backspace deletes the previous word, as it does in every other\r\n // terminal composer.\r\n if (key.meta && (key.backspace || key.delete)) {\r\n const cursor = cursorOffsetRef.current;\r\n killTo(previousWordBoundary(valueRef.current, cursor), cursor);\r\n return;\r\n }\r\n\r\n // Readline motions. The composer dropped every Ctrl chord, so fixing a\r\n // typo halfway through a long prompt meant holding Backspace — slower\r\n // still in a language where one character can take several keystrokes to\r\n // compose.\r\n if (key.ctrl && !key.meta) {\r\n const cursor = cursorOffsetRef.current;\r\n const current = valueRef.current;\r\n switch (input.toLowerCase()) {\r\n case 'a':\r\n commit({ value: current, cursorOffset: 0 });\r\n return;\r\n case 'e':\r\n commit({ value: current, cursorOffset: current.length });\r\n return;\r\n case 'w':\r\n killTo(previousWordBoundary(current, cursor), cursor);\r\n return;\r\n case 'u':\r\n killTo(0, cursor);\r\n return;\r\n case 'k':\r\n killTo(cursor, current.length);\r\n return;\r\n case 'y': {\r\n const yanked = killRingRef.current;\r\n if (!yanked) return;\r\n commit({\r\n value: current.slice(0, cursor) + yanked + current.slice(cursor),\r\n cursorOffset: cursor + yanked.length,\r\n });\r\n return;\r\n }\r\n default:\r\n return;\r\n }\r\n }\r\n\r\n if (key.upArrow || key.downArrow || key.tab || key.ctrl || key.meta || key.escape) {\r\n return;\r\n }\r\n\r\n if (key.return) {\r\n if (!key.shift) onSubmit?.(valueRef.current);\r\n return;\r\n }\r\n\r\n if (key.leftArrow) {\r\n commit({\r\n value: valueRef.current,\r\n cursorOffset: previousGraphemeBoundary(valueRef.current, cursorOffsetRef.current),\r\n });\r\n return;\r\n }\r\n\r\n if (key.rightArrow) {\r\n commit({\r\n value: valueRef.current,\r\n cursorOffset: nextGraphemeBoundary(valueRef.current, cursorOffsetRef.current),\r\n });\r\n return;\r\n }\r\n\r\n if (key.home) {\r\n commit({ value: valueRef.current, cursorOffset: 0 });\r\n return;\r\n }\r\n\r\n if (key.end) {\r\n commit({ value: valueRef.current, cursorOffset: valueRef.current.length });\r\n return;\r\n }\r\n\r\n if (key.backspace || key.delete) {\r\n commit(deletePreviousGrapheme(valueRef.current, cursorOffsetRef.current));\r\n return;\r\n }\r\n\r\n if (input) {\r\n commit(applyInputSequence(valueRef.current, cursorOffsetRef.current, input));\r\n }\r\n },\r\n { isActive: focus },\r\n );\r\n\r\n const currentValue = valueRef.current;\r\n if (!focus) {\r\n return <Text>{currentValue || placeholder}</Text>;\r\n }\r\n\r\n if (!currentValue) {\r\n const [first = ' ', ...rest] = [...placeholder];\r\n return (\r\n <Text color=\"gray\">\r\n <Text inverse>{first}</Text>\r\n {rest.join('')}\r\n </Text>\r\n );\r\n }\r\n\r\n const cursorOffset = cursorOffsetRef.current;\r\n const nextOffset = nextGraphemeBoundary(currentValue, cursorOffset);\r\n const before = currentValue.slice(0, cursorOffset);\r\n const cursor = currentValue.slice(cursorOffset, nextOffset) || ' ';\r\n const after = currentValue.slice(nextOffset);\r\n\r\n return (\r\n <Text>\r\n {before}\r\n <Text inverse>{cursor}</Text>\r\n {after}\r\n </Text>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport type { QueuedInput } from '../queued-inputs.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\ninterface QueuedInputPreviewProps {\r\n items: readonly QueuedInput[];\r\n terminalWidth: number;\r\n notice?: string;\r\n}\r\n\r\nexport function QueuedInputPreview({ items, terminalWidth, notice }: QueuedInputPreviewProps) {\r\n const theme = useTheme();\r\n if (items.length === 0 && !notice) return null;\r\n\r\n const width = Math.max(8, Math.floor(terminalWidth) - 6);\r\n const visible = items.slice(0, 3);\r\n const hidden = items.length - visible.length;\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1}>\r\n {items.length > 0 ? (\r\n <Text bold color={theme.brand}>\r\n Queued follow-up inputs ({items.length})\r\n </Text>\r\n ) : null}\r\n {visible.map((item) => (\r\n <Text key={item.id} color={theme.subtle}>\r\n {' ↳ '}\r\n {item.attachments?.length\r\n ? `[${item.attachments.length} image${item.attachments.length === 1 ? '' : 's'}] `\r\n : ''}\r\n {truncateDisplay(item.value.replace(/\\s+/g, ' ').trim(), width)}\r\n </Text>\r\n ))}\r\n {hidden > 0 ? <Text color={theme.inactive}> ... {hidden} more</Text> : null}\r\n {notice ? <Text color={theme.warning}>{truncateDisplay(notice, width + 4)}</Text> : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport { usePulse, useTimedFlash } from '../hooks/useAnimation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { PermissionMode } from '../../types/runtime.js';\r\nimport type { ContextWindowSource } from '../../types/messages.js';\r\nimport { DEFAULT_CONTEXT_WINDOW } from '../../models.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\nimport { createRenderDebugLogger } from '../../debug-log.js';\r\nimport { modeColorToken, modeLabel } from '../mode-style.js';\r\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\r\nimport { useDebugRender } from '../debug.js';\r\n\r\nconst renderLog = createRenderDebugLogger('tui:statusline');\r\n\r\n/** Marks the permission mode, the one safety-relevant fact in the footer. */\r\nconst MODE_CHIP = '◆';\r\n\r\n/** `useGitStatus` reports a clean tree as a check mark. */\r\nconst CLEAN_TREE = '✓';\r\n\r\n/**\r\n * Segments are separated by space, not `·`.\r\n *\r\n * With every segment the same grey, the dots were the only thing separating\r\n * them. Now that mode, context pressure and a dirty tree each carry their own\r\n * colour, the dots are noise the colour already handles.\r\n */\r\nconst SEGMENT_SEPARATOR = ' ';\r\n\r\ninterface StatusLineProps {\r\n model: string;\r\n tokenCount: number;\r\n maxTokens?: number;\r\n maxTokensSource?: ContextWindowSource;\r\n mode: PermissionMode;\r\n taskCount: number;\r\n activeTaskCount: number;\r\n /** Current branch, when the workspace is a git repository. */\r\n gitBranch?: string;\r\n /** Short working-tree summary: `✓` clean, or `+2 ~1`. */\r\n gitStatus?: string;\r\n agentCount?: number;\r\n activeAgentCount?: number;\r\n needsInputAgentCount?: number;\r\n terminalWidth?: number;\r\n compact?: boolean;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}\r\n\r\n/**\r\n * Pack colored status segments from left to right, skipping an oversized\r\n * segment so that later short, higher-value segments can still be shown.\r\n */\r\nexport function buildColoredSegments(\r\n segments: Array<{ text: string; color?: string }>,\r\n maxWidth: number,\r\n separatorText = ' · ',\r\n): Array<{ text: string; color: string }> {\r\n const result: Array<{ text: string; color: string }> = [];\r\n let totalWidth = 0;\r\n\r\n for (const segment of segments) {\r\n const separator = result.length === 0 ? '' : separatorText;\r\n const candidateWidth = totalWidth + displayWidth(separator) + displayWidth(segment.text);\r\n if (candidateWidth > maxWidth) continue;\r\n\r\n const color = segment.color ?? 'text';\r\n if (separator) result.push({ text: separator, color });\r\n result.push({ text: segment.text, color });\r\n totalWidth = candidateWidth;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Single-row responsive status line.\r\n *\r\n * The row aggressively shortens low-priority details before Ink can wrap them,\r\n * keeping the input area stable while the terminal is resized.\r\n */\r\nexport function StatusLine({\r\n model,\r\n tokenCount,\r\n maxTokens = DEFAULT_CONTEXT_WINDOW,\r\n maxTokensSource,\r\n mode,\r\n taskCount,\r\n activeTaskCount,\r\n gitBranch,\r\n gitStatus,\r\n agentCount = 0,\r\n activeAgentCount = 0,\r\n needsInputAgentCount = 0,\r\n terminalWidth = 80,\r\n compact = false,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: StatusLineProps) {\r\n const theme = useTheme();\r\n const width = transcriptGrid(terminalWidth).width;\r\n // Footer rows share the transcript's content column so the status text, the\r\n // activity label and every tool row start on the same column.\r\n const horizontalInset = CONTENT_COLUMN;\r\n const contentWidth = Math.max(8, width - horizontalInset - 1);\r\n\r\n const usageFraction = maxTokens > 0 ? tokenCount / maxTokens : 0;\r\n const usagePercent = Math.round(usageFraction * 100);\r\n const usageNearLimit = usageFraction > 0.8;\r\n const usageCritical = usageFraction > 0.95;\r\n const motionDisabled = reducedMotion || screenReader;\r\n const usageBlink = usePulse(usageCritical && tokenCount > 0 && !motionDisabled, 500);\r\n const modeFlash = useTimedFlash(mode, 260, motionDisabled);\r\n\r\n const costEstimate = tokenCount > 0 ? (tokenCount / 1_000_000) * 5 : 0;\r\n useDebugRender(renderLog, {\r\n width,\r\n contentWidth,\r\n compact,\r\n usagePercent,\r\n tokenCount,\r\n maxTokensSource,\r\n mode,\r\n taskCount,\r\n activeTaskCount,\r\n });\r\n\r\n // Most of the footer is metadata. Reserve saturated colour for a state that\r\n // needs a decision, so the transcript and composer keep visual priority.\r\n // `default` is not a decision — it is the absence of one — so it stays as\r\n // grey as the model name beside it, whatever the palette's `modeDefault` is.\r\n const modeColor = mode === 'default' ? theme.subtle : (theme[modeColorToken(mode)] as string);\r\n const activeModeColor = modeFlash ? theme.brandShimmer : modeColor;\r\n // Context pressure earns colour only when it is close to the limit. Healthy\r\n // usage stays quiet so the footer does not compete with the active turn.\r\n const contextColor =\r\n usageCritical && usageBlink\r\n ? theme.usageMeterCritical\r\n : usageCritical\r\n ? theme.error\r\n : usageNearLimit\r\n ? theme.warning\r\n : theme.subtle;\r\n\r\n const coloredRuns = useMemo(() => {\r\n // The branch outranks the model when the row gets tight. Both are identity,\r\n // but the branch is the one that changes under you — you chose the model and\r\n // it stays chosen, while a rebase or a checkout in another worktree moves\r\n // the branch without asking. At 56 columns the old budgets cut\r\n // `research/next-task` to `research/ne…` and left `scripted/scripted` whole,\r\n // which is the wrong thing to be sure about.\r\n //\r\n // Both shrink together rather than one taking the row: packing is first-fit\r\n // and skips what will not fit, so a branch budget generous enough to crowd\r\n // the model drops the model entirely instead of shortening it.\r\n const modelBudget = width < 44 ? 8 : width < 72 ? 12 : 30;\r\n const branchBudget = width < 44 ? 10 : width < 72 ? 16 : 24;\r\n // Ordered by what the reader needs first. Packing is first-fit, not\r\n // truncating: a segment too wide for the remaining space is skipped and\r\n // later, shorter ones still get their turn.\r\n const segments: Array<{ text: string; color?: string }> = [\r\n { text: `${MODE_CHIP} ${modeLabel(mode)}`, color: activeModeColor },\r\n // Packing skips a segment it cannot fit and keeps later short ones, so a\r\n // long label here loses the number entirely while the branch behind it\r\n // survives. Drop the word before dropping the figure.\r\n {\r\n text: contentWidth < 40 ? `${usagePercent}%` : `ctx ${usagePercent}%`,\r\n color: contextColor,\r\n },\r\n ];\r\n\r\n if (gitBranch && gitBranch !== '?') {\r\n const dirty = Boolean(gitStatus && gitStatus !== CLEAN_TREE);\r\n segments.push({\r\n text: `${truncateDisplay(gitBranch, branchBudget)}${dirty ? '*' : ''}`,\r\n color: dirty ? theme.warning : theme.subtle,\r\n });\r\n }\r\n\r\n segments.push({ text: truncateDisplay(model, modelBudget), color: theme.subtle });\r\n\r\n // Qualifies the ctx% two segments back: it says that number rests on a\r\n // family guess or the bare default rather than a declared window. That\r\n // makes it worth more than the cost estimate when the row gets tight, so\r\n // it is packed before cost, not after it. The gate matches its neighbours'\r\n // — the old bare `width >= 72` was the actual defect, dropping the\r\n // annotation between 64 and 71 columns while `$0.003` sailed through.\r\n if (!compact && width >= 64 && maxTokensSource && maxTokensSource !== 'declared') {\r\n segments.push({ text: `(${maxTokensSource})`, color: theme.subtle });\r\n }\r\n\r\n if (taskCount > 0) {\r\n segments.push({\r\n text: `tasks ${activeTaskCount > 0 ? `${activeTaskCount}/` : ''}${taskCount}`,\r\n color: theme.subtle,\r\n });\r\n }\r\n\r\n if (agentCount > 0) {\r\n segments.push({\r\n text:\r\n needsInputAgentCount > 0\r\n ? `agents ${activeAgentCount} | ${needsInputAgentCount} needs input`\r\n : `agents ${activeAgentCount}/${agentCount}`,\r\n color: needsInputAgentCount > 0 ? theme.warning : theme.subtle,\r\n });\r\n }\r\n\r\n if (tokenCount > 0 && !compact && width >= 64) {\r\n segments.push({ text: `$${costEstimate.toFixed(3)}`, color: theme.subtle });\r\n }\r\n\r\n return buildColoredSegments(segments, contentWidth, SEGMENT_SEPARATOR);\r\n }, [\r\n gitBranch,\r\n gitStatus,\r\n activeTaskCount,\r\n activeAgentCount,\r\n agentCount,\r\n compact,\r\n contentWidth,\r\n costEstimate,\r\n maxTokens,\r\n mode,\r\n activeModeColor,\r\n contextColor,\r\n model,\r\n taskCount,\r\n needsInputAgentCount,\r\n maxTokensSource,\r\n tokenCount,\r\n usagePercent,\r\n width,\r\n ]);\r\n\r\n return (\r\n <Box paddingLeft={horizontalInset} width={width} flexDirection=\"row\" flexWrap=\"nowrap\">\r\n {coloredRuns.map((run, i) => (\r\n <Text key={i} color={run.color}>\r\n {run.text}\r\n </Text>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n","import type { PermissionMode } from '../types/runtime.js';\r\n\r\nexport type ModeColorToken =\r\n 'modeDefault' | 'modeAuto' | 'modePlan' | 'modeAcceptEdits' | 'modeDontAsk' | 'modeBypass';\r\n\r\nexport const MODE_COLOR_TOKENS: Record<PermissionMode, ModeColorToken> = {\r\n default: 'modeDefault',\r\n auto: 'modeAuto',\r\n plan: 'modePlan',\r\n 'accept-edits': 'modeAcceptEdits',\r\n dontAsk: 'modeDontAsk',\r\n bypassPermissions: 'modeBypass',\r\n};\r\n\r\nexport function modeColorToken(mode: PermissionMode): ModeColorToken {\r\n return MODE_COLOR_TOKENS[mode];\r\n}\r\n\r\nexport function modeLabel(mode: PermissionMode): string {\r\n switch (mode) {\r\n case 'accept-edits':\r\n return 'accept edits';\r\n case 'dontAsk':\r\n return \"don't ask\";\r\n case 'bypassPermissions':\r\n return 'bypass';\r\n default:\r\n return mode;\r\n }\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useLayoutEffect, useRef, useState } from 'react';\r\nimport type { Message } from '../../types/messages.js';\r\nimport type { RetryPhase } from '../../types/runtime.js';\r\nimport type {\r\n PendingElicitationRequest,\r\n PendingPermissionRequest,\r\n PendingPlanApprovalRequest,\r\n PendingUserQuestionRequest,\r\n} from '../../session/agent-interactions.js';\r\nimport { useAnimatedProgress, useGradientSpinner } from '../hooks/useAnimation.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { ThemeTokens } from '../../types/theme.js';\r\nimport { deriveWorkingActivity } from '../working-activity.js';\r\nimport type { ActivityTone } from '../working-activity.js';\r\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\r\nimport { formatElapsedDuration } from './SubagentRow.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\n\r\ninterface WorkingIndicatorProps {\r\n isThinking: boolean;\r\n /** True while /compact or auto-compact summarization is running. */\r\n isCompacting?: boolean;\r\n /** Auto vs manual compact busy label. */\r\n compactTrigger?: 'manual' | 'auto';\r\n /** True only after compaction has completed successfully. */\r\n compactComplete?: boolean;\r\n messages: Message[];\r\n streamingMessageId?: string | null;\r\n pendingPermission?: PendingPermissionRequest | null;\r\n pendingPlanApproval?: PendingPlanApprovalRequest | null;\r\n pendingUserQuestion?: PendingUserQuestionRequest | null;\r\n pendingElicitation?: PendingElicitationRequest | null;\r\n retryPhase?: RetryPhase;\r\n retryAttempt?: number;\r\n retryMax?: number;\r\n retryCountdownMs?: number;\r\n terminalWidth?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}\r\n\r\nfunction useElapsedSeconds(active: boolean, disabled: boolean): number {\r\n const running = active && !disabled;\r\n const startedAtRef = useRef(Date.now());\r\n const resetPendingRef = useRef(true);\r\n const wasRunningRef = useRef(false);\r\n const [, refresh] = useState(0);\r\n const tick = useUiClock('slow', running);\r\n\r\n useLayoutEffect(() => {\r\n if (running && !wasRunningRef.current) {\r\n startedAtRef.current = Date.now();\r\n resetPendingRef.current = false;\r\n wasRunningRef.current = true;\r\n refresh((value) => value + 1);\r\n } else if (!running && wasRunningRef.current) {\r\n resetPendingRef.current = true;\r\n wasRunningRef.current = false;\r\n }\r\n }, [running]);\r\n\r\n if (!running || resetPendingRef.current) return 0;\r\n void tick;\r\n return Math.floor(Math.max(0, Date.now() - startedAtRef.current) / 1000);\r\n}\r\n\r\n/**\r\n * Fit `[label][elapsed][hint]` into one row.\r\n *\r\n * The three runs come back separately so each can carry its own colour: the\r\n * label is the live agent voice, the elapsed time is quiet metadata, the hint\r\n * is quieter still. Elapsed is dropped first when the row is tight — a duration\r\n * is the piece a reader can most afford to lose — then the hint, and only then\r\n * does the label truncate.\r\n */\r\nfunction fitActivityLine(\r\n label: string,\r\n elapsed: string,\r\n hint: string,\r\n maxWidth: number,\r\n): { label: string; elapsed: string; hint: string } {\r\n const minimumLabelWidth = Math.min(8, maxWidth);\r\n let suffix = { elapsed, hint };\r\n const suffixWidth = () => displayWidth(suffix.elapsed) + displayWidth(suffix.hint);\r\n\r\n if (suffixWidth() > maxWidth - minimumLabelWidth) suffix = { elapsed: '', hint };\r\n if (suffixWidth() > maxWidth - minimumLabelWidth) suffix = { elapsed: '', hint: '' };\r\n\r\n const labelWidth = Math.max(1, maxWidth - suffixWidth());\r\n return { label: truncateDisplay(label, labelWidth), ...suffix };\r\n}\r\n\r\nexport interface ActivityPalette {\r\n /** The spinner glyph, or `◇` when the turn is blocked on the user. */\r\n indicator: string;\r\n /** The activity wording. */\r\n label: string;\r\n /** Elapsed time and the keyboard hint behind it. */\r\n meta: string;\r\n}\r\n\r\n/**\r\n * Colours for the activity row.\r\n *\r\n * The wording rides the spinner's own colour instead of sitting in `text`. Body\r\n * prose, plan steps and tool targets are all `text`, so leaving the activity\r\n * there made the one row that is actually *changing* the hardest row to pick\r\n * out — a moving glyph welded to a sentence that looked like every other\r\n * sentence. Sage is the agent's own voice, the same hue as the glyph in front\r\n * of it, so glyph and wording read as one live element: distinct from the plan\r\n * (clay) above it and from the transcript around it.\r\n *\r\n * A blocked or retrying row is not the agent talking, so it keeps its status\r\n * colour and the row stops looking live.\r\n */\r\nexport function activityPalette(\r\n tone: ActivityTone,\r\n theme: ThemeTokens,\r\n spinnerColor: string,\r\n): ActivityPalette {\r\n if (tone === 'warning') {\r\n return { indicator: theme.warning, label: theme.warning, meta: theme.warning };\r\n }\r\n if (tone === 'waiting') {\r\n return { indicator: theme.permission, label: theme.permission, meta: theme.subtle };\r\n }\r\n return { indicator: spinnerColor, label: spinnerColor, meta: theme.subtle };\r\n}\r\n\r\nexport function WorkingIndicator({\r\n isThinking,\r\n isCompacting = false,\r\n compactTrigger,\r\n compactComplete = false,\r\n messages,\r\n streamingMessageId,\r\n pendingPermission,\r\n pendingPlanApproval,\r\n pendingUserQuestion,\r\n pendingElicitation,\r\n retryPhase = 'none',\r\n retryAttempt = 0,\r\n retryMax = 0,\r\n retryCountdownMs = 0,\r\n terminalWidth = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: WorkingIndicatorProps) {\r\n const theme = useTheme();\r\n const motionDisabled = reducedMotion || screenReader;\r\n const shouldTrackElapsed =\r\n isThinking &&\r\n !isCompacting &&\r\n retryPhase === 'none' &&\r\n !pendingPermission &&\r\n !pendingPlanApproval &&\r\n !pendingUserQuestion &&\r\n !pendingElicitation;\r\n const elapsedSeconds = useElapsedSeconds(shouldTrackElapsed, motionDisabled);\r\n const activity = deriveWorkingActivity({\r\n isThinking,\r\n isCompacting,\r\n compactTrigger,\r\n messages,\r\n streamingMessageId,\r\n pendingPermission: Boolean(pendingPermission),\r\n pendingPlanApproval: Boolean(pendingPlanApproval),\r\n // An MCP form asks the user for input just like a question does.\r\n pendingUserQuestion: Boolean(pendingUserQuestion || pendingElicitation),\r\n retryPhase,\r\n retryAttempt,\r\n retryMax,\r\n retryCountdownMs,\r\n elapsedSeconds,\r\n });\r\n\r\n const width = transcriptGrid(terminalWidth).width;\r\n // Footer rows share the transcript's content column so the status text, the\r\n // activity label and every tool row start on the same column.\r\n const horizontalInset = CONTENT_COLUMN;\r\n const contentWidth = Math.max(8, width - horizontalInset - 1);\r\n const showCompactProgress =\r\n (isCompacting || compactComplete) && retryPhase === 'none' && !motionDisabled;\r\n const compactProgress = useAnimatedProgress(isCompacting, 2_400, motionDisabled);\r\n const spinner = useGradientSpinner(\r\n Boolean(activity) && !showCompactProgress && !motionDisabled && !activity?.blocked,\r\n 'dots',\r\n motionDisabled,\r\n );\r\n\r\n if (!activity && !showCompactProgress) return null;\r\n if (showCompactProgress) {\r\n const displayProgress = compactComplete ? 100 : compactProgress;\r\n const compactLabel = compactComplete\r\n ? width < 30\r\n ? 'Done'\r\n : 'Compacted'\r\n : compactTrigger === 'auto'\r\n ? width < 36\r\n ? 'Auto'\r\n : 'Auto-compacting'\r\n : width < 30\r\n ? 'Compact'\r\n : 'Compacting';\r\n const percent = `${String(displayProgress).padStart(3, ' ')}%`;\r\n const hint = isCompacting && !compactComplete && width >= 52 ? ' · Esc to cancel' : '';\r\n const barWidth = Math.max(\r\n 1,\r\n Math.min(\r\n 24,\r\n contentWidth - displayWidth(compactLabel) - displayWidth(percent) - displayWidth(hint) - 2,\r\n ),\r\n );\r\n const filled = Math.min(barWidth, Math.round((displayProgress / 100) * barWidth));\r\n const progressColor = compactComplete ? theme.success : theme.brand;\r\n\r\n return (\r\n <Box paddingLeft={horizontalInset} width={width} flexDirection=\"row\" flexWrap=\"nowrap\">\r\n <Text color={theme.subtle} dimColor>\r\n {compactLabel}{' '}\r\n </Text>\r\n <Text color={progressColor}>{'█'.repeat(filled)}</Text>\r\n <Text color={theme.subtle} dimColor>\r\n {'░'.repeat(barWidth - filled)}\r\n </Text>\r\n <Text color={compactComplete ? theme.success : theme.brandShimmer}> {percent}</Text>\r\n {hint ? (\r\n <Text color={theme.subtle} dimColor>\r\n {hint}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n }\r\n\r\n const hint = pendingPlanApproval\r\n ? ' · choose approve, adjust, or reject above'\r\n : pendingUserQuestion || pendingElicitation\r\n ? ' · answer the question above'\r\n : pendingPermission\r\n ? ' · Esc to deny'\r\n : isThinking || isCompacting\r\n ? ' · Esc to cancel'\r\n : '';\r\n // Rolls up to `4m 8s` / `1h 2m 3s` past a minute, matching subagent rows,\r\n // background shells and tool rows. A bare second count stops being readable\r\n // as a duration somewhere around three digits.\r\n const elapsed =\r\n shouldTrackElapsed && !motionDisabled ? ` · ${formatElapsedDuration(elapsedSeconds)}` : '';\r\n const line = fitActivityLine(activity?.label ?? '', elapsed, hint, Math.max(1, contentWidth - 2));\r\n const indicator = activity?.blocked ? '◇' : spinner.frame;\r\n const tone = activity?.tone ?? 'normal';\r\n const palette = activityPalette(tone, theme, spinner.color);\r\n\r\n return (\r\n <Box width={width} flexWrap=\"nowrap\">\r\n <Text color={palette.indicator}>{indicator} </Text>\r\n <Text color={palette.label} bold={tone === 'normal'} dimColor={tone !== 'normal'}>\r\n {line.label}\r\n </Text>\r\n {line.elapsed ? <Text color={palette.meta}>{line.elapsed}</Text> : null}\r\n {line.hint ? (\r\n <Text color={palette.meta} dimColor>\r\n {line.hint}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import type { Message } from '../types/messages.js';\r\nimport type { RetryPhase } from '../types/runtime.js';\r\nimport type { ToolCall } from '../types/tools.js';\r\nimport { canonicalToolName } from '../tools/aliases.js';\r\nimport { getPrimaryArg } from '../tools/primary-arg.js';\r\nimport { parseMcpToolName } from './tool-presentation.js';\r\n\r\nexport type ActivityTone = 'normal' | 'waiting' | 'warning';\r\n\r\nexport interface WorkingActivity {\r\n label: string;\r\n tone: ActivityTone;\r\n blocked?: boolean;\r\n}\r\n\r\ninterface WorkingActivityInput {\r\n isThinking: boolean;\r\n isCompacting: boolean;\r\n compactTrigger?: 'manual' | 'auto';\r\n messages: Message[];\r\n streamingMessageId?: string | null;\r\n pendingPermission: boolean;\r\n pendingPlanApproval: boolean;\r\n pendingUserQuestion: boolean;\r\n retryPhase: RetryPhase;\r\n retryAttempt: number;\r\n retryMax: number;\r\n retryCountdownMs: number;\r\n elapsedSeconds: number;\r\n}\r\n\r\n/**\r\n * Widest a phrase may be, in columns.\r\n *\r\n * The activity row is one line and the label shares it with an elapsed time and\r\n * a keyboard hint — about 50 columns on an 80-column terminal. A phrase is only\r\n * the frame; the target inside it (a path, a pattern, a shell command) is the\r\n * part the reader is actually waiting to see. `Peeking between the covers of`\r\n * spent 29 of those columns on a joke and then truncated the filename it was\r\n * introducing. Short phrases are funnier anyway: the gag lands before the eye\r\n * has finished the line, and what the run is *doing* survives.\r\n */\r\nexport const MAX_PHRASE_WIDTH = 28;\r\n\r\n/**\r\n * The reasoning phases.\r\n *\r\n * Shown while the model is thinking and nothing more specific is known, one\r\n * every three seconds, in this order — so the openers are the ones a short turn\r\n * will actually show. Each line is a small joke about *thinking*, never a claim\r\n * about progress the run has not made: `Almost there` would be a lie the\r\n * indicator has no way to check.\r\n */\r\nexport const REASONING_PHASES = [\r\n 'Pondering the plot twist',\r\n 'Consulting the footnotes',\r\n 'Untangling a subplot',\r\n 'Sharpening a tiny pencil',\r\n 'Rearranging the bookshelves',\r\n 'Following the semicolons',\r\n 'Asking the rubber duck',\r\n 'Turning it sideways',\r\n 'Reading between the lines',\r\n 'Negotiating with edge cases',\r\n 'Chasing a runaway thought',\r\n 'Auditioning better verbs',\r\n 'Squinting at the margins',\r\n 'Arguing with a footnote',\r\n 'Letting the ink dry',\r\n 'Rereading that paragraph',\r\n 'Hunting a missing comma',\r\n 'Blaming the typesetter',\r\n 'Checking the index twice',\r\n 'Dog-earing the good bit',\r\n 'Filing off a rough edge',\r\n 'Weighing two adjectives',\r\n 'Drafting in the margins',\r\n 'Counting the loose ends',\r\n 'Consulting the errata',\r\n 'Retracing the outline',\r\n 'Second-guessing chapter two',\r\n 'Plotting the next twist',\r\n] as const;\r\n\r\n/**\r\n * One phrase list per tool.\r\n *\r\n * Kept in a single catalog rather than inline in the switch so the set can be\r\n * read — and width-checked — in one place. Phrases that take a target end where\r\n * the target begins, so they read as one clause: `Redlining src/tui/app.tsx`,\r\n * `Chewing on npm test`.\r\n */\r\nconst TOOL_PHRASES = {\r\n read: ['Cracking open', 'Leafing through', 'Skimming', 'Peeking inside'],\r\n write: ['Putting ink to', 'Drafting', 'Inking'],\r\n applyPatch: ['Patching', 'Stitching an edit into', 'Reworking'],\r\n edit: ['Redlining', 'Polishing', 'Rewording', 'Marking up'],\r\n notebookEdit: ['Scribbling in', 'Annotating', 'Adding marginalia to'],\r\n glob: ['Scanning shelves for', 'Checking spines for', 'Combing the stacks for'],\r\n grep: ['Hunting for', 'Combing the lines for', 'Tracking down', 'Grilling the code for'],\r\n bash: ['Running', 'Poking the shell with', 'Chewing on'],\r\n bashOutput: ['Listening to shell', 'Eavesdropping on shell', 'Checking in on shell'],\r\n killShell: ['Quieting shell', 'Hushing shell', 'Pulling the plug on shell'],\r\n dismissShell: ['Clearing shell', 'Filing away shell', 'Tidying up shell'],\r\n webFetch: ['Fetching', 'Pulling a page from', 'Borrowing ink from'],\r\n webSearch: ['Roaming the web for', 'Chasing links for', 'Asking the internet about'],\r\n gitStatus: [\r\n \"Taking the repo's pulse\",\r\n 'Asking Git what changed',\r\n 'Seeing if Git looks nervous',\r\n \"Reading the repo's mood\",\r\n ],\r\n gitDiff: ['Reading the red ink', 'Studying the markup', 'Comparing drafts'],\r\n gitLog: ['Flipping through history', \"Reading the repo's diary\", 'Checking old plot twists'],\r\n gitCommit: ['Binding the chapter', 'Stamping a bookmark', 'Filing this chapter away'],\r\n gitBranch: [\"Following Git's branches\", 'Climbing the branches', 'Checking other timelines'],\r\n todoWrite: ['Redrawing the plan', 'Shuffling the plot points', 'Updating the quest log'],\r\n task: ['Handing off a subplot:', 'Sending a side quest:', 'Recruiting help for:'],\r\n taskCreate: ['Adding a plot point:', 'Pinning a new quest:', 'Writing a task card:'],\r\n taskList: ['Checking the plot points', 'Reviewing the quest log', 'Counting loose ends'],\r\n taskGet: ['Opening plot point', 'Checking quest', 'Reading the card for'],\r\n taskUpdate: ['Revising plot point', 'Moving quest along', 'Updating the card for'],\r\n taskStop: ['Dropping plot point', 'Calling off quest', 'Closing the card for'],\r\n invokeSkill: ['Opening the playbook:', 'Equipping', 'Dusting off'],\r\n readSkillResource: ['Turning to', 'Opening', 'Consulting'],\r\n toolSearch: ['Rummaging the toolbox for', 'Sizing up tools for', 'Hunting a tool for'],\r\n askUserQuestion: ['Composing a question', 'Preparing a tiny pop quiz', 'Wording it carefully'],\r\n enterPlanMode: [\r\n 'Outlining the next chapter',\r\n 'Unrolling the parchment',\r\n 'Sketching the treasure map',\r\n ],\r\n exitPlanMode: ['Closing the outline', 'Folding the treasure map', 'Setting the plan in motion'],\r\n sessionHistorySearch: [\r\n 'Flipping back for',\r\n 'Searching old chapters for',\r\n 'Checking the recap for',\r\n ],\r\n sessionHistoryRead: [\r\n 'Rereading an old chapter',\r\n 'Catching up on the lore',\r\n 'Checking last episode',\r\n ],\r\n agentPlan: ['Planning the handoff', 'Drawing up the roster', 'Casting the chapter'],\r\n agentSpawn: ['Commissioning:', 'Handing off:', 'Hiring a ghostwriter:'],\r\n agentList: ['Counting the ghostwriters', 'Taking attendance', 'Checking the writers room'],\r\n agentGet: ['Checking on agent', 'Asking after agent', 'Looking in on agent'],\r\n agentRead: ['Reading back agent', 'Collecting notes from', 'Opening the report from'],\r\n agentSend: ['Passing a note:', 'Nudging the agent:', 'Sending word:'],\r\n agentWait: ['Waiting on agent', 'Holding for agent', 'Letting agent finish'],\r\n agentStop: ['Calling back agent', 'Stopping agent', 'Pulling agent off the job'],\r\n agentApply: ['Accepting the patch', 'Taking the draft', 'Folding in the patch'],\r\n evidencePublish: ['Filing evidence:', 'Pinning up:', 'Logging the receipt:'],\r\n evidenceList: ['Checking the evidence', 'Counting the receipts', 'Reviewing the exhibits'],\r\n evidenceReview: ['Weighing the evidence', 'Reading the exhibits', 'Second-opinioning'],\r\n} as const;\r\n\r\n/** Every static phrase list in this module, for the width budget check. */\r\nexport const ACTIVITY_PHRASE_LISTS: readonly (readonly string[])[] = [\r\n REASONING_PHASES,\r\n ...Object.values(TOOL_PHRASES),\r\n];\r\n\r\nfunction stringArg(args: Record<string, unknown>, ...names: string[]): string | undefined {\r\n for (const name of names) {\r\n const value = args[name];\r\n if (typeof value === 'string' && value.trim()) return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction cleanTarget(value: string | undefined): string | undefined {\r\n if (!value) return undefined;\r\n const clean = value\r\n .replace(/[\\u0000-\\u001f\\u007f]+/g, ' ')\r\n .replace(/\\s+/g, ' ')\r\n .trim();\r\n return clean || undefined;\r\n}\r\n\r\nfunction withTarget(action: string, target: string | undefined): string {\r\n const clean = cleanTarget(target);\r\n if (!clean) return action.endsWith(':') ? action.slice(0, -1) : action;\r\n return `${action} ${clean}`;\r\n}\r\n\r\nfunction humanizeToolName(name: string): string {\r\n return name\r\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\r\n .replace(/[_-]+/g, ' ')\r\n .trim()\r\n .toLowerCase();\r\n}\r\n\r\nfunction pickPhrase(call: ToolCall, phrases: readonly string[]): string {\r\n const seed = `${call.name}:${call.id}:${getPrimaryArg(call.arguments)}`;\r\n let hash = 0;\r\n for (let index = 0; index < seed.length; index++) {\r\n hash = (Math.imul(hash, 31) + seed.charCodeAt(index)) >>> 0;\r\n }\r\n return phrases[hash % phrases.length];\r\n}\r\n\r\nfunction playfulTarget(call: ToolCall, phrases: readonly string[], target: string | undefined) {\r\n return withTarget(pickPhrase(call, phrases), target);\r\n}\r\n\r\nexport function toolActivityText(call: ToolCall): string {\r\n const canonicalName = canonicalToolName(call.name);\r\n const args = call.arguments;\r\n const primary = getPrimaryArg(args);\r\n const filePath = stringArg(args, 'filePath', 'file_path', 'path') ?? primary;\r\n const mcp = parseMcpToolName(call.name);\r\n\r\n if (mcp) {\r\n return withTarget(\r\n pickPhrase(call, [\r\n `Asking ${mcp.server} to`,\r\n `Nudging ${mcp.server} to`,\r\n `Calling on ${mcp.server} to`,\r\n ]),\r\n mcp.tool,\r\n );\r\n }\r\n\r\n switch (canonicalName) {\r\n case 'Read':\r\n return playfulTarget(call, TOOL_PHRASES.read, filePath);\r\n case 'Write':\r\n return playfulTarget(call, TOOL_PHRASES.write, filePath);\r\n case 'ApplyPatch':\r\n // `getPrimaryArg` digs the touched file out of the `*** Update File:`\r\n // envelope, so the row can name it instead of saying `workspace files`.\r\n return playfulTarget(call, TOOL_PHRASES.applyPatch, primary);\r\n case 'Edit':\r\n case 'MultiEdit':\r\n return playfulTarget(call, TOOL_PHRASES.edit, filePath);\r\n case 'NotebookEdit':\r\n return playfulTarget(\r\n call,\r\n TOOL_PHRASES.notebookEdit,\r\n stringArg(args, 'notebook_path', 'path') ?? primary,\r\n );\r\n case 'Glob':\r\n return playfulTarget(call, TOOL_PHRASES.glob, stringArg(args, 'pattern') ?? primary);\r\n case 'Grep':\r\n return playfulTarget(call, TOOL_PHRASES.grep, stringArg(args, 'pattern') ?? primary);\r\n case 'Bash':\r\n return playfulTarget(call, TOOL_PHRASES.bash, primary);\r\n case 'BashOutput':\r\n return playfulTarget(call, TOOL_PHRASES.bashOutput, primary);\r\n case 'KillShell':\r\n return playfulTarget(call, TOOL_PHRASES.killShell, primary);\r\n case 'DismissShell':\r\n return playfulTarget(call, TOOL_PHRASES.dismissShell, primary);\r\n case 'WebFetch':\r\n return playfulTarget(call, TOOL_PHRASES.webFetch, stringArg(args, 'url') ?? primary);\r\n case 'WebSearch':\r\n return playfulTarget(call, TOOL_PHRASES.webSearch, stringArg(args, 'query') ?? primary);\r\n case 'GitStatus':\r\n return pickPhrase(call, TOOL_PHRASES.gitStatus);\r\n case 'GitDiff':\r\n return pickPhrase(call, TOOL_PHRASES.gitDiff);\r\n case 'GitLog':\r\n return pickPhrase(call, TOOL_PHRASES.gitLog);\r\n case 'GitCommit':\r\n return pickPhrase(call, TOOL_PHRASES.gitCommit);\r\n case 'GitBranch':\r\n return pickPhrase(call, TOOL_PHRASES.gitBranch);\r\n case 'TodoWrite':\r\n return pickPhrase(call, TOOL_PHRASES.todoWrite);\r\n case 'Task':\r\n return playfulTarget(\r\n call,\r\n TOOL_PHRASES.task,\r\n stringArg(args, 'subject', 'description', 'prompt', 'agent') ?? primary,\r\n );\r\n case 'TaskCreate':\r\n return playfulTarget(call, TOOL_PHRASES.taskCreate, stringArg(args, 'subject') ?? primary);\r\n case 'TaskList':\r\n return pickPhrase(call, TOOL_PHRASES.taskList);\r\n case 'TaskGet':\r\n return playfulTarget(call, TOOL_PHRASES.taskGet, primary);\r\n case 'TaskUpdate':\r\n return playfulTarget(call, TOOL_PHRASES.taskUpdate, primary);\r\n case 'TaskStop':\r\n return playfulTarget(call, TOOL_PHRASES.taskStop, primary);\r\n case 'InvokeSkill':\r\n return playfulTarget(call, TOOL_PHRASES.invokeSkill, stringArg(args, 'skill') ?? primary);\r\n case 'ReadSkillResource':\r\n return playfulTarget(\r\n call,\r\n TOOL_PHRASES.readSkillResource,\r\n stringArg(args, 'path') ?? primary,\r\n );\r\n case 'ToolSearch':\r\n return playfulTarget(call, TOOL_PHRASES.toolSearch, stringArg(args, 'query') ?? primary);\r\n case 'AskUserQuestion':\r\n return pickPhrase(call, TOOL_PHRASES.askUserQuestion);\r\n case 'EnterPlanMode':\r\n return pickPhrase(call, TOOL_PHRASES.enterPlanMode);\r\n case 'ExitPlanMode':\r\n return pickPhrase(call, TOOL_PHRASES.exitPlanMode);\r\n case 'SessionHistorySearch':\r\n return playfulTarget(\r\n call,\r\n TOOL_PHRASES.sessionHistorySearch,\r\n stringArg(args, 'query') ?? primary,\r\n );\r\n case 'SessionHistoryRead':\r\n return pickPhrase(call, TOOL_PHRASES.sessionHistoryRead);\r\n case 'AgentPlan':\r\n return pickPhrase(call, TOOL_PHRASES.agentPlan);\r\n case 'AgentSpawn':\r\n return playfulTarget(\r\n call,\r\n TOOL_PHRASES.agentSpawn,\r\n stringArg(args, 'description', 'agent') ?? primary,\r\n );\r\n case 'AgentList':\r\n return pickPhrase(call, TOOL_PHRASES.agentList);\r\n case 'AgentGet':\r\n return playfulTarget(call, TOOL_PHRASES.agentGet, stringArg(args, 'agentId') ?? primary);\r\n case 'AgentRead':\r\n return playfulTarget(call, TOOL_PHRASES.agentRead, stringArg(args, 'agentId') ?? primary);\r\n case 'AgentSend':\r\n return playfulTarget(call, TOOL_PHRASES.agentSend, stringArg(args, 'message') ?? primary);\r\n case 'AgentWait':\r\n return playfulTarget(call, TOOL_PHRASES.agentWait, stringArg(args, 'agentId') ?? primary);\r\n case 'AgentStop':\r\n return playfulTarget(call, TOOL_PHRASES.agentStop, stringArg(args, 'agentId') ?? primary);\r\n case 'AgentApply':\r\n return pickPhrase(call, TOOL_PHRASES.agentApply);\r\n case 'EvidencePublish':\r\n // Deliberately no `?? primary` fallback, unlike its siblings: this call's\r\n // arguments carry no path or query, so `getPrimaryArg` falls through to\r\n // the first string key and hands back the `kind` enum. A row reading\r\n // `Filing evidence: blocker` names a category, not the finding; better to\r\n // drop the target and let the phrase stand alone.\r\n return playfulTarget(call, TOOL_PHRASES.evidencePublish, stringArg(args, 'summary'));\r\n case 'EvidenceList':\r\n return pickPhrase(call, TOOL_PHRASES.evidenceList);\r\n case 'EvidenceReview':\r\n return pickPhrase(call, TOOL_PHRASES.evidenceReview);\r\n default: {\r\n const toolName = humanizeToolName(canonicalName) || 'a tool';\r\n if (!primary) {\r\n return pickPhrase(call, [\r\n `Trying ${toolName}`,\r\n `Running ${toolName}`,\r\n `Giving ${toolName} a whirl`,\r\n ]);\r\n }\r\n return withTarget(\r\n pickPhrase(call, [\r\n `Trying ${toolName} on`,\r\n `Running ${toolName} on`,\r\n `Pointing ${toolName} at`,\r\n ]),\r\n primary,\r\n );\r\n }\r\n }\r\n}\r\n\r\nfunction queuedActivity(label: string, count: number): string {\r\n if (count <= 1) return label;\r\n const waiting = count - 1;\r\n return `${label} · ${waiting} ${waiting === 1 ? 'tool' : 'tools'} in the wings`;\r\n}\r\n\r\nfunction activeToolText(message: Message | undefined): string | null {\r\n if (!message) return null;\r\n\r\n const pendingNested = (message.nestedToolInvocations ?? []).filter(\r\n (invocation) => !invocation.result,\r\n );\r\n if (pendingNested.length > 0) {\r\n const active = pendingNested[pendingNested.length - 1];\r\n return queuedActivity(toolActivityText(active.call), pendingNested.length);\r\n }\r\n\r\n const completed = new Set((message.toolResults ?? []).map((result) => result.toolCallId));\r\n const pending = (message.toolCalls ?? []).filter((call) => !completed.has(call.id));\r\n if (pending.length === 0) return null;\r\n return queuedActivity(toolActivityText(pending[0]), pending.length);\r\n}\r\n\r\nfunction retryText(\r\n phase: RetryPhase,\r\n attempt: number,\r\n max: number,\r\n countdownMs: number,\r\n): string | null {\r\n if (phase === 'none') return null;\r\n\r\n const countdown = Math.max(0, Math.ceil(countdownMs / 1000));\r\n const attemptText = max > 0 ? `attempt ${attempt}/${max}` : `attempt ${attempt}`;\r\n\r\n if (phase === 'stalled') return `Waiting for API response · retrying in ${countdown}s`;\r\n if (phase === 'tool') return `Waiting for tool response · retrying in ${countdown}s`;\r\n if (phase === 'watchdog') return `Retrying watchdog · ${attemptText}`;\r\n return `Retrying in ${countdown}s · ${attemptText}`;\r\n}\r\n\r\nexport function deriveWorkingActivity({\r\n isThinking,\r\n isCompacting,\r\n compactTrigger,\r\n messages,\r\n streamingMessageId,\r\n pendingPermission,\r\n pendingPlanApproval,\r\n pendingUserQuestion,\r\n retryPhase,\r\n retryAttempt,\r\n retryMax,\r\n retryCountdownMs,\r\n elapsedSeconds,\r\n}: WorkingActivityInput): WorkingActivity | null {\r\n const retry = retryText(retryPhase, retryAttempt, retryMax, retryCountdownMs);\r\n if (retry) return { label: retry, tone: 'warning' };\r\n if (isCompacting) {\r\n return {\r\n label: compactTrigger === 'auto' ? 'Auto-compacting…' : 'Compacting…',\r\n tone: 'normal',\r\n };\r\n }\r\n if (!isThinking) return null;\r\n // The blocked labels stay plain on purpose: the run has stopped and is asking\r\n // the reader for something, which is the one moment a joke is in the way.\r\n if (pendingPlanApproval) {\r\n return { label: 'Waiting for plan approval', tone: 'waiting', blocked: true };\r\n }\r\n if (pendingUserQuestion) {\r\n return { label: 'Waiting for your answer', tone: 'waiting', blocked: true };\r\n }\r\n if (pendingPermission) {\r\n return { label: 'Waiting for permission', tone: 'waiting', blocked: true };\r\n }\r\n\r\n // The streaming message is at (or near) the end; scan backwards so this\r\n // per-render lookup stays O(1) on long transcripts.\r\n let activeMessage: Message | undefined;\r\n if (streamingMessageId) {\r\n for (let index = messages.length - 1; index >= 0; index--) {\r\n if (messages[index].id === streamingMessageId) {\r\n activeMessage = messages[index];\r\n break;\r\n }\r\n }\r\n }\r\n const toolText = activeToolText(activeMessage);\r\n if (toolText) return { label: toolText, tone: 'normal' };\r\n if (\r\n (activeMessage?.toolCalls?.length ?? 0) > 0 ||\r\n (activeMessage?.nestedToolInvocations?.length ?? 0) > 0\r\n ) {\r\n return { label: 'Reading what came back', tone: 'normal' };\r\n }\r\n if (activeMessage?.content) return { label: 'Writing the final page', tone: 'normal' };\r\n\r\n const phase = Math.floor(elapsedSeconds / 3) % REASONING_PHASES.length;\r\n return { label: REASONING_PHASES[phase], tone: 'normal' };\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { createRenderDebugLogger } from '../../debug-log.js';\r\nimport {\r\n createBookRuneMask,\r\n STARTUP_FIRE_TOTAL_TICKS,\r\n StartupFireSimulation,\r\n startupFireStepOptions,\r\n} from '../startup-fire.js';\r\nimport { composeStartupFireFrame } from '../startup-fire-frame.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\n\r\nconst fireLog = createRenderDebugLogger('tui:startup-fire');\r\n\r\ninterface StartupFireProps {\r\n width: number;\r\n height: number;\r\n onComplete: () => void;\r\n}\r\n\r\nexport function StartupFire({ width, height, onComplete }: StartupFireProps) {\r\n const theme = useTheme();\r\n const safeWidth = Math.max(1, Math.floor(width));\r\n const safeHeight = Math.max(1, Math.floor(height));\r\n const simulationRef = useRef(new StartupFireSimulation(safeWidth, safeHeight * 2));\r\n const [tick, setTick] = useState(0);\r\n const tickRef = useRef(0);\r\n const completedRef = useRef(false);\r\n const clock = useUiClock('cinematic', tick < STARTUP_FIRE_TOTAL_TICKS);\r\n\r\n useEffect(() => {\r\n fireLog.event('start', { width: safeWidth, height: safeHeight });\r\n return () => fireLog.event('stop', { tick: tickRef.current });\r\n // Only log the lifecycle, not every animation tick.\r\n }, []);\r\n\r\n useEffect(() => {\r\n const simulation = simulationRef.current;\r\n simulation.resize(safeWidth, safeHeight * 2);\r\n const currentTick = tickRef.current;\r\n if (currentTick >= STARTUP_FIRE_TOTAL_TICKS) return;\r\n const rune =\r\n currentTick >= 24 && currentTick < 44\r\n ? createBookRuneMask(safeWidth, safeHeight * 2).mask\r\n : undefined;\r\n const step = startupFireStepOptions(currentTick);\r\n simulation.step({ ...step, protectedMask: rune });\r\n simulation.step({ ...step, protectedMask: rune });\r\n tickRef.current = Math.min(STARTUP_FIRE_TOTAL_TICKS, currentTick + 1);\r\n setTick(tickRef.current);\r\n }, [clock, safeHeight, safeWidth]);\r\n\r\n useEffect(() => {\r\n if (tick < STARTUP_FIRE_TOTAL_TICKS || completedRef.current) return;\r\n completedRef.current = true;\r\n fireLog.event('complete', { width: safeWidth, height: safeHeight });\r\n onComplete();\r\n }, [onComplete, safeHeight, safeWidth, tick]);\r\n\r\n const frame = composeStartupFireFrame(simulationRef.current, tick, safeHeight, theme);\r\n return (\r\n <Box flexDirection=\"column\" width={safeWidth} height={safeHeight} overflow=\"hidden\">\r\n {frame.rows.map((runs, rowIndex) => (\r\n <Box key={rowIndex} width={safeWidth} height={1} flexShrink={0}>\r\n {runs.map((run, runIndex) => (\r\n <Text\r\n key={runIndex}\r\n color={run.color}\r\n backgroundColor={run.backgroundColor}\r\n bold={run.bold}\r\n dimColor={run.dimColor}\r\n >\r\n {run.text}\r\n </Text>\r\n ))}\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * Deterministic terminal fire inspired by the PSX DOOM heat-buffer effect documented at\r\n * https://fabiensanglard.net/doom_fire_psx/. This is an independent implementation adapted for\r\n * Book's bounded, testable TUI renderer.\r\n */\r\n\r\nexport interface FireStepOptions {\r\n sourceStrength: number;\r\n sourceWidth: number;\r\n wind: number;\r\n protectedMask?: Uint8Array;\r\n}\r\n\r\nexport interface BookRuneLayout {\r\n mask: Uint8Array;\r\n terminalTop: number;\r\n terminalHeight: number;\r\n}\r\n\r\nconst GLYPHS: Record<string, readonly string[]> = {\r\n B: ['####.', '#...#', '####.', '#...#', '####.'],\r\n O: ['.###.', '#...#', '#...#', '#...#', '.###.'],\r\n K: ['#..#.', '#.#..', '##...', '#.#..', '#..#.'],\r\n};\r\n\r\nfunction clampByte(value: number): number {\r\n return Math.max(0, Math.min(255, Math.round(value)));\r\n}\r\n\r\nfunction mixSeed(seed: number): number {\r\n let value = seed >>> 0;\r\n value ^= value << 13;\r\n value ^= value >>> 17;\r\n value ^= value << 5;\r\n return value >>> 0;\r\n}\r\n\r\nexport function hashNoise(...values: number[]): number {\r\n let hash = 0x9e3779b9;\r\n for (const value of values) hash = mixSeed(hash ^ Math.imul(value | 0, 0x85ebca6b));\r\n return hash >>> 0;\r\n}\r\n\r\nexport function createBookRuneMask(width: number, pixelHeight: number): BookRuneLayout {\r\n const safeWidth = Math.max(1, Math.floor(width));\r\n const safeHeight = Math.max(2, Math.floor(pixelHeight));\r\n const terminalHeight = Math.floor(safeHeight / 2);\r\n const scaleX = safeWidth >= 72 ? 2 : 1;\r\n const letters = 'BOOK';\r\n const glyphWidth = 5 * scaleX;\r\n const gap = scaleX;\r\n const runeWidth = letters.length * glyphWidth + (letters.length - 1) * gap;\r\n const left = Math.max(0, Math.floor((safeWidth - runeWidth) / 2));\r\n const terminalTop = Math.max(1, Math.floor(terminalHeight * 0.42) - 2);\r\n const mask = new Uint8Array(safeWidth * safeHeight);\r\n\r\n for (let letterIndex = 0; letterIndex < letters.length; letterIndex++) {\r\n const glyph = GLYPHS[letters[letterIndex]];\r\n const glyphLeft = left + letterIndex * (glyphWidth + gap);\r\n for (let row = 0; row < glyph.length; row++) {\r\n for (let column = 0; column < glyph[row].length; column++) {\r\n if (glyph[row][column] !== '#') continue;\r\n for (let scale = 0; scale < scaleX; scale++) {\r\n const x = glyphLeft + column * scaleX + scale;\r\n const terminalY = terminalTop + row;\r\n if (x < 0 || x >= safeWidth || terminalY < 0 || terminalY >= terminalHeight) continue;\r\n mask[terminalY * 2 * safeWidth + x] = 1;\r\n mask[(terminalY * 2 + 1) * safeWidth + x] = 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { mask, terminalTop, terminalHeight: 5 };\r\n}\r\n\r\nexport class StartupFireSimulation {\r\n private current: Uint8Array;\r\n private next: Uint8Array;\r\n private randomState: number;\r\n\r\n width: number;\r\n pixelHeight: number;\r\n\r\n constructor(width: number, pixelHeight: number, seed = 0x00b00c) {\r\n this.width = Math.max(1, Math.floor(width));\r\n this.pixelHeight = Math.max(2, Math.floor(pixelHeight));\r\n this.current = new Uint8Array(this.width * this.pixelHeight);\r\n this.next = new Uint8Array(this.current.length);\r\n this.randomState = seed >>> 0;\r\n }\r\n\r\n private random(maxExclusive: number): number {\r\n this.randomState = mixSeed(this.randomState || 1);\r\n return this.randomState % Math.max(1, maxExclusive);\r\n }\r\n\r\n get heat(): Uint8Array {\r\n return this.current;\r\n }\r\n\r\n step({ sourceStrength, sourceWidth, wind, protectedMask }: FireStepOptions): void {\r\n const width = this.width;\r\n const height = this.pixelHeight;\r\n const bottom = (height - 1) * width;\r\n const halfSource = Math.max(0, Math.min(width / 2, (width * sourceWidth) / 2));\r\n const center = (width - 1) / 2;\r\n\r\n for (let x = 0; x < width; x++) {\r\n const insideSource = Math.abs(x - center) <= halfSource;\r\n this.current[bottom + x] = insideSource\r\n ? clampByte(sourceStrength - this.random(28))\r\n : Math.max(0, this.current[bottom + x] - 28);\r\n }\r\n\r\n this.next.fill(0);\r\n for (let y = 0; y < height - 1; y++) {\r\n const belowY = y + 1;\r\n const lowerY = Math.min(height - 1, y + 2);\r\n for (let x = 0; x < width; x++) {\r\n const gust = Math.round(wind) + this.random(3) - 1;\r\n const sampleX = Math.max(0, Math.min(width - 1, x - gust));\r\n const left = Math.max(0, sampleX - 1);\r\n const right = Math.min(width - 1, sampleX + 1);\r\n const below = belowY * width;\r\n const lower = lowerY * width;\r\n const average =\r\n (this.current[below + sampleX] * 3 +\r\n this.current[below + left] +\r\n this.current[below + right] +\r\n this.current[lower + sampleX] * 2) /\r\n 7;\r\n this.next[y * width + x] = clampByte(average - 2 - this.random(11));\r\n }\r\n }\r\n this.next.set(this.current.subarray(bottom, bottom + width), bottom);\r\n\r\n if (protectedMask?.length === this.next.length) {\r\n for (let index = 0; index < protectedMask.length; index++) {\r\n if (!protectedMask[index]) continue;\r\n this.next[index] = 0;\r\n }\r\n for (let index = 0; index < protectedMask.length; index++) {\r\n if (!protectedMask[index]) continue;\r\n const x = index % width;\r\n if (x > 0 && !protectedMask[index - 1]) {\r\n this.next[index - 1] = Math.max(this.next[index - 1], 190);\r\n }\r\n if (x + 1 < width && !protectedMask[index + 1]) {\r\n this.next[index + 1] = Math.max(this.next[index + 1], 190);\r\n }\r\n }\r\n }\r\n\r\n [this.current, this.next] = [this.next, this.current];\r\n }\r\n\r\n resize(width: number, pixelHeight: number): void {\r\n const nextWidth = Math.max(1, Math.floor(width));\r\n const nextHeight = Math.max(2, Math.floor(pixelHeight));\r\n if (nextWidth === this.width && nextHeight === this.pixelHeight) return;\r\n\r\n const resized = new Uint8Array(nextWidth * nextHeight);\r\n for (let y = 0; y < nextHeight; y++) {\r\n const sourceY = Math.min(\r\n this.pixelHeight - 1,\r\n Math.floor((y / nextHeight) * this.pixelHeight),\r\n );\r\n for (let x = 0; x < nextWidth; x++) {\r\n const sourceX = Math.min(this.width - 1, Math.floor((x / nextWidth) * this.width));\r\n resized[y * nextWidth + x] = this.current[sourceY * this.width + sourceX];\r\n }\r\n }\r\n this.width = nextWidth;\r\n this.pixelHeight = nextHeight;\r\n this.current = resized;\r\n this.next = new Uint8Array(resized.length);\r\n }\r\n}\r\n\r\nexport const STARTUP_FIRE_TOTAL_TICKS = 56;\r\n\r\nexport function startupFireStepOptions(tick: number): Omit<FireStepOptions, 'protectedMask'> {\r\n if (tick < 7) {\r\n return {\r\n sourceStrength: 255,\r\n sourceWidth: 0.04 + tick * 0.035,\r\n wind: Math.sin(tick * 0.6) * 0.7,\r\n };\r\n }\r\n if (tick < 34) {\r\n return {\r\n sourceStrength: 255,\r\n sourceWidth: Math.min(1.1, 0.28 + (tick - 7) * 0.08),\r\n wind: Math.sin(tick * 0.35) * 1.2,\r\n };\r\n }\r\n if (tick < 47) {\r\n const remaining = 1 - (tick - 34) / 13;\r\n return {\r\n sourceStrength: 255 * remaining,\r\n sourceWidth: 1,\r\n wind: Math.sin(tick * 0.42) * 1.5,\r\n };\r\n }\r\n return { sourceStrength: 0, sourceWidth: 0, wind: 0 };\r\n}\r\n","import type { ThemeTokens } from '../types/theme.js';\r\nimport { createBookRuneMask, hashNoise, type StartupFireSimulation } from './startup-fire.js';\r\n\r\nexport interface StartupFireRun {\r\n text: string;\r\n color?: string;\r\n backgroundColor?: string;\r\n bold?: boolean;\r\n dimColor?: boolean;\r\n}\r\n\r\nexport interface StartupFireFrame {\r\n rows: StartupFireRun[][];\r\n phase: 'spark' | 'inferno' | 'reveal' | 'ashes' | 'awakened';\r\n}\r\n\r\ninterface CellStyle {\r\n text: string;\r\n color?: string;\r\n backgroundColor?: string;\r\n bold?: boolean;\r\n dimColor?: boolean;\r\n}\r\n\r\nconst HEAT_PALETTE = [\r\n '#070707',\r\n '#1d0707',\r\n '#3a0907',\r\n '#5b0d06',\r\n '#7f1405',\r\n '#a52205',\r\n '#c93405',\r\n '#e84a07',\r\n '#f5660b',\r\n '#ff8612',\r\n '#ffaa22',\r\n '#ffcb43',\r\n '#ffe477',\r\n '#fff1b3',\r\n '#ffffff',\r\n] as const;\r\n\r\nconst CODE_FRAGMENTS = ['{}', '=>', 'git', '@file', 'async', '<T>', '/help'];\r\nconst ASH_GLYPHS = ['·', '.', \"'\", '`'];\r\n\r\nfunction phaseFor(tick: number): StartupFireFrame['phase'] {\r\n if (tick < 7) return 'spark';\r\n if (tick < 24) return 'inferno';\r\n if (tick < 44) return 'reveal';\r\n if (tick < 52) return 'ashes';\r\n return 'awakened';\r\n}\r\n\r\nexport function heatColor(intensity: number): string | undefined {\r\n if (intensity < 5) return undefined;\r\n const index = Math.min(\r\n HEAT_PALETTE.length - 1,\r\n Math.floor((intensity / 255) * HEAT_PALETTE.length),\r\n );\r\n return HEAT_PALETTE[index];\r\n}\r\n\r\nfunction sameStyle(left: CellStyle, right: CellStyle): boolean {\r\n return (\r\n left.color === right.color &&\r\n left.backgroundColor === right.backgroundColor &&\r\n left.bold === right.bold &&\r\n left.dimColor === right.dimColor\r\n );\r\n}\r\n\r\nfunction toRuns(cells: CellStyle[]): StartupFireRun[] {\r\n const runs: StartupFireRun[] = [];\r\n for (const cell of cells) {\r\n const previous = runs.at(-1);\r\n if (previous && sameStyle(previous, cell)) {\r\n previous.text += cell.text;\r\n } else {\r\n runs.push({ ...cell });\r\n }\r\n }\r\n return runs;\r\n}\r\n\r\nfunction writeText(\r\n cells: CellStyle[][],\r\n row: number,\r\n text: string,\r\n style: Omit<CellStyle, 'text'>,\r\n centered = true,\r\n): void {\r\n if (row < 0 || row >= cells.length) return;\r\n const left = centered ? Math.max(0, Math.floor((cells[row].length - text.length) / 2)) : 0;\r\n for (let index = 0; index < text.length && left + index < cells[row].length; index++) {\r\n cells[row][left + index] = { text: text[index], ...style };\r\n }\r\n}\r\n\r\nfunction addAtmosphere(\r\n cells: CellStyle[][],\r\n tick: number,\r\n theme: ThemeTokens,\r\n phase: StartupFireFrame['phase'],\r\n): void {\r\n const height = cells.length;\r\n const width = cells[0]?.length ?? 0;\r\n if (phase === 'spark') {\r\n for (let index = 0; index < CODE_FRAGMENTS.length; index++) {\r\n const text = CODE_FRAGMENTS[index];\r\n const x = hashNoise(index, width) % Math.max(1, width - text.length);\r\n const y = Math.min(height - 1, 1 + (hashNoise(index, height) % Math.max(1, height - 5)));\r\n for (let offset = 0; offset < text.length && x + offset < width; offset++) {\r\n cells[y][x + offset] = { text: text[offset], color: theme.subtle, dimColor: true };\r\n }\r\n }\r\n const sparkRow = Math.max(0, height - 3 - Math.floor(tick / 2));\r\n writeText(cells, sparkRow, tick < 3 ? '·' : tick < 5 ? '✦' : '⟡', {\r\n color: tick < 4 ? '#ffffff' : theme.brandShimmer,\r\n bold: true,\r\n });\r\n if (tick >= 3) {\r\n writeText(cells, Math.max(0, height - 5), 'KNOWLEDGE HAS A SPARK', {\r\n color: theme.brand,\r\n dimColor: tick < 5,\r\n });\r\n }\r\n }\r\n\r\n if (phase === 'inferno' || phase === 'reveal') {\r\n const emberCount = Math.min(32, Math.max(6, Math.floor(width / 5)));\r\n for (let index = 0; index < emberCount; index++) {\r\n const x = hashNoise(tick, index, width) % width;\r\n const y = hashNoise(tick - index, height, index) % Math.max(1, height - 2);\r\n if (cells[y][x].text !== ' ') continue;\r\n const glyph = ['·', '•', '*', '✦'][hashNoise(index, tick) % 4];\r\n cells[y][x] = {\r\n text: glyph,\r\n color: hashNoise(tick, x, y) % 4 === 0 ? '#fff1b3' : '#f5660b',\r\n bold: glyph === '✦',\r\n };\r\n }\r\n }\r\n\r\n if (phase === 'ashes' || phase === 'awakened') {\r\n const count = phase === 'ashes' ? Math.min(48, Math.floor(width / 2)) : 6;\r\n for (let index = 0; index < count; index++) {\r\n const x = hashNoise(index, tick, width) % width;\r\n const y = hashNoise(index * 7, tick, height) % Math.max(1, height - 1);\r\n if (cells[y][x].text !== ' ') continue;\r\n cells[y][x] = {\r\n text: ASH_GLYPHS[hashNoise(tick, index) % ASH_GLYPHS.length],\r\n color: theme.subtle,\r\n dimColor: true,\r\n };\r\n }\r\n }\r\n}\r\n\r\nexport function composeStartupFireFrame(\r\n simulation: StartupFireSimulation,\r\n tick: number,\r\n terminalHeight: number,\r\n theme: ThemeTokens,\r\n): StartupFireFrame {\r\n const width = simulation.width;\r\n const height = Math.max(1, Math.floor(terminalHeight));\r\n const heat = simulation.heat;\r\n const phase = phaseFor(tick);\r\n const rune = createBookRuneMask(width, simulation.pixelHeight);\r\n const cells: CellStyle[][] = Array.from({ length: height }, (_, y) =>\r\n Array.from({ length: width }, (_, x): CellStyle => {\r\n const topIndex = y * 2 * width + x;\r\n const bottomIndex = Math.min(simulation.pixelHeight - 1, y * 2 + 1) * width + x;\r\n const top = heat[topIndex] ?? 0;\r\n const bottom = heat[bottomIndex] ?? 0;\r\n const topColor = heatColor(top);\r\n const bottomColor = heatColor(bottom);\r\n if (!topColor && !bottomColor) return { text: ' ' };\r\n return {\r\n text: '▀',\r\n color: topColor ?? '#070707',\r\n backgroundColor: bottomColor ?? '#070707',\r\n };\r\n }),\r\n );\r\n\r\n if (phase === 'reveal') {\r\n const revealThreshold = Math.min(width, Math.max(0, (tick - 24) * Math.ceil(width / 14)));\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const topIndex = y * 2 * width + x;\r\n if (!rune.mask[topIndex]) continue;\r\n const distanceFromCenter = Math.abs(x - width / 2) * 2;\r\n if (distanceFromCenter > revealThreshold) continue;\r\n cells[y][x] = {\r\n text: '█',\r\n color: tick < 29 ? '#ffffff' : tick < 34 ? '#fff1b3' : theme.brandShimmer,\r\n bold: true,\r\n };\r\n }\r\n }\r\n if (tick >= 35) {\r\n writeText(\r\n cells,\r\n Math.min(height - 2, rune.terminalTop + rune.terminalHeight + 2),\r\n 'WHAT SURVIVES BECOMES KNOWLEDGE',\r\n {\r\n color: theme.brand,\r\n bold: true,\r\n },\r\n );\r\n }\r\n }\r\n\r\n addAtmosphere(cells, tick, theme, phase);\r\n\r\n if (phase === 'ashes' || phase === 'awakened') {\r\n const center = Math.floor(height / 2);\r\n writeText(cells, center - 1, '╭ BOOK', { color: theme.assistantAccent, bold: true });\r\n writeText(cells, center, '╰ Your coding workspace, indexed.', { color: theme.text });\r\n if (phase === 'awakened') {\r\n writeText(cells, center + 2, 'AGENT AWAKENED ✦', {\r\n color: theme.brandShimmer,\r\n bold: true,\r\n });\r\n }\r\n }\r\n\r\n if (phase !== 'awakened' && width >= 18) {\r\n const hint = 'Esc skip';\r\n const row = cells[height - 1];\r\n const start = Math.max(0, width - hint.length - 1);\r\n for (let index = 0; index < hint.length; index++) {\r\n row[start + index] = { text: hint[index], color: theme.subtle, dimColor: true };\r\n }\r\n }\r\n\r\n return { phase, rows: cells.map(toRuns) };\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useEffect } from 'react';\r\nimport type { CompactUiState } from '../hooks/useAgent.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\nexport interface CompactDiffCardProps {\r\n state: CompactUiState;\r\n terminalWidth?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n onSettled?: () => void;\r\n}\r\n\r\nfunction compactSummary(state: CompactUiState): string {\r\n const details: string[] = [];\r\n if (state.trigger === 'auto') details.push('automatic');\r\n if (state.preMessages !== undefined) {\r\n details.push(`${state.preMessages} ${state.preMessages === 1 ? 'message' : 'messages'}`);\r\n }\r\n if (state.preContextTokens !== undefined && state.preContextTokens > 0) {\r\n details.push(`~${Math.round(state.preContextTokens / 100) / 10}k context`);\r\n }\r\n if (state.degraded) details.unshift('reduced fidelity');\r\n return ['Compact conversation', ...details].join(' · ');\r\n}\r\n\r\n/** Post-compact status rendered like a tool result without creating a tool invocation. */\r\nexport function CompactDiffCard({\r\n state,\r\n terminalWidth = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n onSettled,\r\n}: CompactDiffCardProps) {\r\n const theme = useTheme();\r\n const width = Math.max(12, Math.floor(terminalWidth) - 2);\r\n const summaryWidth = Math.max(4, width - 4);\r\n\r\n useEffect(() => {\r\n if (state.phase !== 'diff' || !onSettled) return;\r\n if (reducedMotion || screenReader) {\r\n onSettled();\r\n return;\r\n }\r\n const timer = setTimeout(onSettled, 760);\r\n return () => clearTimeout(timer);\r\n }, [onSettled, reducedMotion, screenReader, state.phase]);\r\n\r\n if (state.phase === 'working') return null;\r\n\r\n const failed = state.phase === 'error';\r\n const skipped = state.phase === 'skipped';\r\n const symbol = failed ? '×' : skipped ? '–' : '✓';\r\n const color = failed ? theme.error : skipped ? theme.warning : theme.success;\r\n const summary =\r\n failed || skipped ? (state.message ?? compactSummary(state)) : compactSummary(state);\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginLeft={2} width={width}>\r\n <Box>\r\n <Text color={color}>{symbol} </Text>\r\n <Text color={failed ? theme.error : theme.text}>\r\n {truncateDisplay(summary, summaryWidth)}\r\n </Text>\r\n </Box>\r\n {state.degraded && state.warning ? (\r\n <Box\r\n marginLeft={2}\r\n borderStyle=\"single\"\r\n borderLeft\r\n borderTop={false}\r\n borderRight={false}\r\n borderBottom={false}\r\n borderLeftColor={theme.toolRail}\r\n paddingLeft={1}\r\n >\r\n <Text color={theme.warning}>\r\n {truncateDisplay(state.warning, Math.max(8, width - 6))}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Component } from 'react';\r\nimport { Box, Text, useApp, useInput } from 'ink';\r\nimport { createUiDebugLogger } from '../../debug-log.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\nconst uiLog = createUiDebugLogger('tui:errorboundary');\r\n\r\ninterface ErrorBoundaryProps {\r\n children: React.ReactNode;\r\n /**\r\n * The command that reopens this conversation, shown so a render crash does not\r\n * read as lost work. The session file is durable by the time anything can\r\n * crash — `SessionStore.create` appends the `session_meta` header\r\n * synchronously at startup and every record after it lands the same way — so\r\n * for a persisted session this is a promise the store can keep.\r\n *\r\n * Left undefined when persistence is off, and when the session holds nothing\r\n * worth reopening. A resume line that fails, or that reopens an empty\r\n * conversation, is worse than no resume line at all.\r\n */\r\n resumeCommand?: string;\r\n /**\r\n * How the host leaves. The fallback has to own this itself: the app's global\r\n * key handler is still mounted and still holds whatever state it had when the\r\n * render blew up, so it swallows Ctrl+C whenever a picker was open and turns\r\n * it into a stream interrupt whenever a turn was in flight. Neither reaches\r\n * an exit, and Ink runs with `exitOnCtrlC: false` with no SIGINT handler\r\n * behind it, so nothing else would either.\r\n */\r\n onExit?: () => void;\r\n}\r\n\r\ninterface ErrorBoundaryState {\r\n hasError: boolean;\r\n error: Error | null;\r\n /** First frames of the stack, kept for the box — see `componentDidCatch`. */\r\n origin: string | null;\r\n}\r\n\r\nconst CLEAR_STATE: ErrorBoundaryState = { hasError: false, error: null, origin: null };\r\n\r\n/** Longest stack frame the box will print before it starts costing more than it tells. */\r\nconst ORIGIN_WIDTH = 72;\r\n\r\n/**\r\n * The single most useful line of a stack: where the throw came from, and which\r\n * component was rendering. Node stacks carry absolute paths, which on Windows\r\n * are long enough to wrap the box on their own, so only the tail of the path\r\n * survives.\r\n */\r\nfunction describeOrigin(error: Error, componentStack?: string | null): string | null {\r\n const shorten = (line: string) =>\r\n line.replace(/(?:file:\\/\\/)?(?:[A-Za-z]:)?[\\\\/][^\\s)]*[\\\\/]/g, '').trim();\r\n const component = componentStack\r\n ?.split('\\n')\r\n .map((line) => line.trim())\r\n .find(Boolean);\r\n const frame = error.stack\r\n ?.split('\\n')\r\n .slice(1)\r\n .map((line) => line.trim())\r\n .find((line) => line.startsWith('at '));\r\n // The component stack usually carries the location too, and for a throw in\r\n // the component's own body both name the same symbol — so the raw frame is\r\n // only worth the width when it points somewhere else.\r\n const symbol = (line?: string) => line?.replace(/^at\\s+/, '').split(/[\\s(]/)[0] ?? '';\r\n const best = component ? shorten(component) : frame ? shorten(frame) : '';\r\n const extra = frame && component && symbol(frame) !== symbol(component) ? shorten(frame) : '';\r\n const line = [best, extra].filter(Boolean).join(' — ');\r\n if (!line) return null;\r\n return line.length > ORIGIN_WIDTH ? `${line.slice(0, ORIGIN_WIDTH - 1)}…` : line;\r\n}\r\n\r\nfunction ErrorReport({\r\n error,\r\n origin,\r\n resumeCommand,\r\n onExit,\r\n onRetry,\r\n}: {\r\n error: Error | null;\r\n origin: string | null;\r\n resumeCommand?: string;\r\n onExit?: () => void;\r\n onRetry: () => void;\r\n}) {\r\n const theme = useTheme();\r\n const { exit } = useApp();\r\n\r\n useInput((input, key) => {\r\n if (key.ctrl && input === 'c') {\r\n (onExit ?? exit)();\r\n return;\r\n }\r\n if (input.toLowerCase() === 'r') onRetry();\r\n });\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.error} padding={1}>\r\n <Text bold color={theme.error}>\r\n Something went wrong\r\n </Text>\r\n <Text color={theme.subtle}>{error?.message ?? 'Unknown error'}</Text>\r\n {origin ? <Text color={theme.subtle}>{origin}</Text> : null}\r\n {resumeCommand ? (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color={theme.text}>This conversation is saved. Reopen it with:</Text>\r\n <Text color={theme.brand}>{resumeCommand}</Text>\r\n </Box>\r\n ) : (\r\n <Box marginTop={1}>\r\n <Text color={theme.subtle}>Restart Book to recover.</Text>\r\n </Box>\r\n )}\r\n <Text color={theme.subtle}>Press R to try again, or Ctrl+C to exit.</Text>\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * React error boundary for the Ink TUI. Catches render errors in child\r\n * components and displays a friendly error message instead of crashing\r\n * the entire terminal UI.\r\n *\r\n * The fallback is a component rather than inline JSX so that it can hold the\r\n * keyboard: once the boundary is showing, it is the only thing on screen, and\r\n * it has to be able to both leave and retry. Retrying is worth offering because\r\n * plenty of render throws are transient — one bad message, a momentarily zero\r\n * width — and the surrounding app has kept running the whole time.\r\n */\r\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\r\n constructor(props: ErrorBoundaryProps) {\r\n super(props);\r\n this.state = CLEAR_STATE;\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\r\n // No `console.warn` here: it printed `error.message` — already the second\r\n // line of the box — as raw text over the alternate screen, so a crashing\r\n // user's first sight was a smeared frame with a duplicated message. Its\r\n // diagnostic value is replaced rather than dropped. `uiLog` is a no-op\r\n // unless BOOK_DEBUG is set, so it cannot be the only record; the box itself\r\n // carries the throw site, which is what a bug report actually needs.\r\n this.setState({ origin: describeOrigin(error, errorInfo.componentStack) });\r\n uiLog.warn('caught', {\r\n name: error.name,\r\n message: error.message,\r\n stack: error.stack?.split('\\n').slice(0, 3).join(' | '),\r\n componentStack: errorInfo.componentStack\r\n ?.split('\\n')\r\n .map((s) => s.trim())\r\n .filter(Boolean)\r\n .slice(0, 6)\r\n .join(' > '),\r\n });\r\n }\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return (\r\n <ErrorReport\r\n error={this.state.error}\r\n origin={this.state.origin}\r\n resumeCommand={this.props.resumeCommand}\r\n onExit={this.props.onExit}\r\n onRetry={() => this.setState(CLEAR_STATE)}\r\n />\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useTheme } from '../theme.js';\r\nimport { STATUS_INDICATORS } from '../status-indicators.js';\r\nimport type { Task } from '../hooks/useTasks.js';\r\n\r\ninterface TaskListProps {\r\n tasks: Task[];\r\n onUpdateStatus: (id: string, status: Task['status']) => void;\r\n onRemove: (id: string) => void;\r\n}\r\n\r\nexport function TaskList({ tasks }: TaskListProps) {\r\n const theme = useTheme();\r\n const visible = tasks.slice(0, 5);\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Text color={theme.brand} bold>\r\n Tasks ({tasks.length})\r\n </Text>\r\n {visible.length === 0 && (\r\n <Text color={theme.subtle}>No tasks yet. Use /task &lt;description&gt; to create one.</Text>\r\n )}\r\n {visible.map((task) => {\r\n const indicator = STATUS_INDICATORS[task.status];\r\n return (\r\n <Box key={task.id}>\r\n <Text color={theme[indicator.colorToken]}>{indicator.icon} </Text>\r\n <Text\r\n color={task.status === 'completed' ? theme.subtle : theme.text}\r\n strikethrough={task.status === 'completed'}\r\n >\r\n {task.subject}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n {tasks.length > 5 && <Text color={theme.subtle}>...and {tasks.length - 5} more</Text>}\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * Shared status glyphs and colour tokens for plan rows and task rows.\r\n *\r\n * The glyphs are chosen for *width* as much as for looks. `○` and `◉` are East\r\n * Asian **Ambiguous**: plenty of terminals draw them two cells wide even though\r\n * every width table the TUI consults calls them one. When that happens the\r\n * glyph swallows the space behind it, so the row's text lands a column left of\r\n * the transcript grid and butts straight against its own marker — the plan is\r\n * the one block in the transcript that visibly fails to line up.\r\n *\r\n * This set is the light vocabulary already proven elsewhere in the TUI: `✓` on\r\n * tool rows, `›` on managed-agent rows, `·` as the separator in every status\r\n * line. Each one renders one cell wide next to text.\r\n *\r\n * Colours keep the roles apart. Clay (`brand`) is product chrome and belongs to\r\n * the plan; sage stays with the spinner, which is the agent itself speaking.\r\n */\r\nexport const STATUS_INDICATORS = {\r\n pending: { icon: '·' as const, colorToken: 'inactive' as const },\r\n in_progress: { icon: '›' as const, colorToken: 'brand' as const },\r\n completed: { icon: '✓' as const, colorToken: 'success' as const },\r\n};\r\n","import { Box, Text } from 'ink';\r\nimport { useTheme } from '../theme.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { STATUS_INDICATORS } from '../status-indicators.js';\r\nimport { CONTENT_COLUMN, transcriptGrid } from '../layout.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport type { Todo } from '../../tools/todo.js';\r\n\r\ninterface AgentTodoListProps {\r\n todos: Todo[];\r\n terminalWidth?: number;\r\n}\r\n\r\n/**\r\n * The header meter runs one cell per step, so it reads as a scale model of the\r\n * rows underneath it rather than as an unrelated percentage bar. Long plans are\r\n * scaled into this many cells instead.\r\n */\r\nconst METER_MAX_CELLS = 12;\r\n\r\n/** Below this measure the header keeps the count and drops the meter. */\r\nconst METER_MIN_WIDTH = 44;\r\n\r\nexport function visibleAgentTodos(todos: readonly Todo[]): Todo[] {\r\n const visible = todos.slice(0, 5);\r\n const activeTodo = todos.find((todo) => todo.status === 'in_progress');\r\n if (activeTodo && !visible.includes(activeTodo)) visible.splice(4, 1, activeTodo);\r\n return visible;\r\n}\r\n\r\nexport function shouldShowAgentPlan(todos: readonly Todo[], showTasks: boolean): boolean {\r\n return todos.length > 0 && (showTasks || todos.some((todo) => todo.status !== 'completed'));\r\n}\r\n\r\n/** Filled cells for `done` of `total`, never rounding an unfinished plan up to full. */\r\nexport function planMeterFill(done: number, total: number, cells: number): number {\r\n if (total <= 0 || cells <= 0) return 0;\r\n if (done >= total) return cells;\r\n return Math.min(cells - 1, Math.round((done / total) * cells));\r\n}\r\n\r\nexport function AgentTodoList({ todos, terminalWidth = 80 }: AgentTodoListProps) {\r\n const theme = useTheme();\r\n const { majorBlockGap } = useDensityMetrics();\r\n if (todos.length === 0) return null;\r\n\r\n const visible = visibleAgentTodos(todos);\r\n const done = todos.filter((todo) => todo.status === 'completed').length;\r\n const complete = done === todos.length;\r\n const grid = transcriptGrid(terminalWidth);\r\n // A plan row is `[marker][text]` on the transcript grid, exactly like a tool\r\n // row or a paragraph. Truncating to the content measure keeps a long step on\r\n // one line: an Ink wrap would send the overflow back to column 0, under the\r\n // marker column, where it reads as a new item rather than a continuation.\r\n const textWidth = grid.content;\r\n const cells = Math.min(todos.length, METER_MAX_CELLS);\r\n const filled = planMeterFill(done, todos.length, cells);\r\n const showMeter = grid.width >= METER_MIN_WIDTH;\r\n const hidden = todos.length - visible.length;\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginTop={majorBlockGap}>\r\n <Box paddingLeft={CONTENT_COLUMN} flexWrap=\"nowrap\">\r\n <Text color={theme.brand} bold>\r\n Plan\r\n </Text>\r\n {showMeter ? (\r\n <Text color={complete ? theme.success : theme.brand}>{` ${'█'.repeat(filled)}`}</Text>\r\n ) : null}\r\n {showMeter ? <Text color={theme.toolRail}>{'░'.repeat(cells - filled)}</Text> : null}\r\n <Text color={complete ? theme.success : theme.subtle}>{` ${done}/${todos.length}`}</Text>\r\n </Box>\r\n {visible.map((todo, index) => {\r\n const indicator = STATUS_INDICATORS[todo.status];\r\n const active = todo.status === 'in_progress';\r\n const finished = todo.status === 'completed';\r\n // Three weights, so the eye lands on the step in flight: the finished\r\n // ones recede, the queued ones stay legible, the active one is the only\r\n // row set in full text colour.\r\n const color = finished ? theme.inactive : active ? theme.text : theme.subtle;\r\n return (\r\n <Box key={index} flexWrap=\"nowrap\">\r\n <Text color={theme[indicator.colorToken]} bold={active}>\r\n {indicator.icon}{' '}\r\n </Text>\r\n <Text color={color} bold={active} strikethrough={finished}>\r\n {truncateDisplay(\r\n active && todo.activeForm ? todo.activeForm : todo.content,\r\n textWidth,\r\n )}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n {hidden > 0 ? (\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.inactive}>{`+${hidden} more`}</Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport TextInput from './TextInputField.js';\r\nimport { useState, useCallback, useRef, useEffect, useMemo } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { AgentConfig } from '../../types/runtime.js';\r\nimport type { ProviderConfig } from '../../settings.js';\r\nimport { resolveSecret } from '../../config.js';\r\nimport { discoverModels, type ModelDiscoveryOptions } from '../../provider/model-discovery.js';\r\nimport {\r\n parseModelIds,\r\n type ModelPickerOption,\r\n type ProviderSaveRequest,\r\n} from '../model-options.js';\r\nimport { EFFORT_LEVELS, type EffortLevel, type EffortResult } from '../../commands/effort.js';\r\nimport { ByokWizard } from './ByokWizard.js';\r\nimport { modelPickerHints } from './model-picker-hints.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { stripSgrMouseSequences } from '../mouse.js';\r\n\r\nexport type ProviderRemovalResult =\r\n | {\r\n ok: true;\r\n providerId: string;\r\n removedModelCount: number;\r\n activeModel: string;\r\n switched: boolean;\r\n inheritedProviderRevealed: boolean;\r\n }\r\n | {\r\n ok: false;\r\n error: string;\r\n };\r\n\r\ninterface ModelPickerProps {\r\n title?: string;\r\n options: ModelPickerOption[];\r\n currentModel: string;\r\n currentEffort?: AgentConfig['effort'];\r\n effortLevels?: readonly EffortLevel[];\r\n hasPriorOutput: boolean;\r\n warnings?: string[];\r\n providers: Record<string, ProviderConfig>;\r\n workspace: string;\r\n retry: AgentConfig['retry'];\r\n compact?: boolean;\r\n maxVisibleModels?: number;\r\n discover?: (options: ModelDiscoveryOptions) => Promise<Array<{ id: string; label?: string }>>;\r\n onPick: (model: string, saveDefault: boolean) => { ok: boolean; error?: string } | void;\r\n onPickEffort: (level: EffortLevel) => EffortResult;\r\n onSaveProvider: (request: ProviderSaveRequest) => { ok: boolean; error?: string };\r\n removableProviderIds: ReadonlySet<string>;\r\n removableProviderModelCounts?: ReadonlyMap<string, number>;\r\n onRemoveProvider: (providerId: string) => ProviderRemovalResult;\r\n onProviderSaved?: (request: ProviderSaveRequest) => void;\r\n allowProviderManagement?: boolean;\r\n onCancel: () => void;\r\n}\r\n\r\nconst EMPTY_PROVIDER_IDS: ReadonlySet<string> = new Set();\r\n\r\nfunction plural(count: number): string {\r\n return count === 1 ? '' : 's';\r\n}\r\n\r\nexport function ModelPicker({\r\n title,\r\n options,\r\n currentModel,\r\n currentEffort,\r\n effortLevels = EFFORT_LEVELS,\r\n hasPriorOutput,\r\n warnings = [],\r\n providers,\r\n workspace,\r\n retry,\r\n compact = false,\r\n maxVisibleModels = 10,\r\n discover = discoverModels,\r\n onPick,\r\n onPickEffort,\r\n onSaveProvider,\r\n removableProviderIds = EMPTY_PROVIDER_IDS,\r\n removableProviderModelCounts,\r\n onRemoveProvider,\r\n onProviderSaved,\r\n allowProviderManagement = true,\r\n onCancel,\r\n}: ModelPickerProps) {\r\n const theme = useTheme();\r\n const density = useDensityMetrics();\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n const [filter, setFilter] = useState('');\r\n const [onEffort, setOnEffort] = useState(false);\r\n const [showWizard, setShowWizard] = useState(false);\r\n const [refreshing, setRefreshing] = useState<string>();\r\n const [manualEntry, setManualEntry] = useState<{ providerId: string; value: string }>();\r\n const [removal, setRemoval, currentRemoval] = useKeyState<\r\n { providerId: string; modelCount: number; active: boolean } | undefined\r\n >(undefined);\r\n const [error, setError] = useState<string>();\r\n const [notice, setNotice] = useState<string>();\r\n const pickedRef = useRef(false);\r\n const removalInFlightRef = useRef(false);\r\n const reanchorRef = useRef<string | undefined>(undefined);\r\n const filteredOptions = useMemo(() => {\r\n const query = filter.trim().toLowerCase();\r\n if (!query) return options;\r\n return options.filter(\r\n (option) =>\r\n option.id.toLowerCase().includes(query) ||\r\n option.label.toLowerCase().includes(query) ||\r\n option.providerId?.toLowerCase().includes(query),\r\n );\r\n }, [filter, options]);\r\n const itemCount = filteredOptions.length + (allowProviderManagement ? 1 : 0);\r\n const addIndex = filteredOptions.length;\r\n\r\n useEffect(() => {\r\n setSelected(Math.min(currentSelected(), Math.max(0, itemCount - 1)));\r\n }, [filteredOptions.length, itemCount]);\r\n\r\n // Refreshing or extending a catalog re-sorts the list under the cursor, so a\r\n // row can slide out from under the highlight and Enter would then save a\r\n // model the user never looked at. Re-anchor on the id that was selected.\r\n useEffect(() => {\r\n const anchor = reanchorRef.current;\r\n if (!anchor) return;\r\n reanchorRef.current = undefined;\r\n const index = filteredOptions.findIndex((option) => option.id === anchor);\r\n if (index >= 0) setSelected(index);\r\n }, [filteredOptions]);\r\n\r\n // Catalog edits are written to the user-global settings layer. Doing that for\r\n // a provider inherited from a project layer would copy its credential into a\r\n // second file and make the inherited copy look removable, so the same\r\n // ownership rule that guards removal guards refresh and manual entry.\r\n const ownsProvider = useCallback(\r\n (providerId: string) => {\r\n if (removableProviderIds.has(providerId)) return true;\r\n setError('Only BYOK providers you added can be changed.');\r\n return false;\r\n },\r\n [removableProviderIds],\r\n );\r\n\r\n const handlePick = useCallback(\r\n (model: string, saveDefault: boolean) => {\r\n if (pickedRef.current) return;\r\n const result = onPick(model, saveDefault);\r\n if (result && !result.ok) {\r\n setError(result.error ?? 'Could not save the selected model.');\r\n return;\r\n }\r\n pickedRef.current = true;\r\n },\r\n [onPick],\r\n );\r\n\r\n const refreshProvider = useCallback(\r\n async (providerId: string) => {\r\n const provider = providers[providerId];\r\n if (!provider) return;\r\n const apiKey = resolveSecret(provider.apiKey, workspace);\r\n if (!apiKey) {\r\n setError(`No usable API key is configured for ${providerId}.`);\r\n return;\r\n }\r\n setError(undefined);\r\n setNotice(undefined);\r\n setRefreshing(providerId);\r\n try {\r\n const models = await discover({\r\n type: provider.type,\r\n baseUrl: provider.baseURL ?? provider.baseUrl ?? '',\r\n apiKey,\r\n retry,\r\n });\r\n if (models.length === 0) {\r\n setError(`${providerId} did not return any models.`);\r\n return;\r\n }\r\n const currentForProvider = options.find(\r\n (option) => option.providerId === providerId && option.id === currentModel,\r\n );\r\n const activeModelId = currentForProvider\r\n ? currentForProvider.id.slice(providerId.length + 1)\r\n : models[0].id;\r\n const request: ProviderSaveRequest = {\r\n providerId,\r\n type: provider.type,\r\n baseURL: provider.baseURL ?? provider.baseUrl ?? '',\r\n apiKey: provider.apiKey ?? apiKey,\r\n models,\r\n activeModelId,\r\n replaceModels: true,\r\n activate: false,\r\n };\r\n const result = onSaveProvider(request);\r\n if (!result.ok) setError(result.error ?? 'Could not save refreshed models.');\r\n else setNotice(`${providerId}: ${models.length} model${plural(models.length)} listed.`);\r\n } catch (caught) {\r\n setError(caught instanceof Error ? caught.message : 'Could not refresh models.');\r\n } finally {\r\n setRefreshing(undefined);\r\n }\r\n },\r\n [currentModel, discover, onSaveProvider, options, providers, retry, workspace],\r\n );\r\n\r\n // Add hand-typed model IDs to a provider without touching its credentials or\r\n // the active selection — the catalog grows, nothing else moves.\r\n const addManualModels = useCallback(\r\n (providerId: string, raw: string) => {\r\n const provider = providers[providerId];\r\n if (!provider) {\r\n setError(`${providerId} is no longer configured.`);\r\n return;\r\n }\r\n let ids: string[];\r\n try {\r\n ids = parseModelIds(raw);\r\n } catch (caught) {\r\n setError(caught instanceof Error ? caught.message : 'Enter at least one model ID.');\r\n return;\r\n }\r\n const result = onSaveProvider({\r\n providerId,\r\n type: provider.type,\r\n baseURL: provider.baseURL ?? provider.baseUrl ?? '',\r\n apiKey: provider.apiKey ?? '',\r\n models: ids.map((id) => ({ id })),\r\n activeModelId: ids[0],\r\n manual: true,\r\n activate: false,\r\n });\r\n if (!result.ok) {\r\n setError(result.error ?? 'Could not save the model.');\r\n return;\r\n }\r\n setManualEntry(undefined);\r\n setError(undefined);\r\n setNotice(`Added ${ids.length} model${plural(ids.length)} to ${providerId}.`);\r\n },\r\n [onSaveProvider, providers],\r\n );\r\n\r\n useInput(\r\n (input, key) => {\r\n if (showWizard) return;\r\n // The text field owns every other key while it is open.\r\n if (manualEntry) {\r\n if (key.escape) {\r\n reanchorRef.current = undefined;\r\n setManualEntry(undefined);\r\n setError(undefined);\r\n }\r\n return;\r\n }\r\n // Read back rather than closing over `removal`: Alt+D and the `y` that\r\n // confirms it can arrive in one chunk, and the second key would then be\r\n // dispatched by the branch that was live before the prompt opened.\r\n const pendingRemoval = currentRemoval();\r\n if (pendingRemoval) {\r\n if (key.escape || input.toLowerCase() === 'n') {\r\n removalInFlightRef.current = false;\r\n setRemoval(undefined);\r\n setError(undefined);\r\n return;\r\n }\r\n if (key.return || input.toLowerCase() === 'y') {\r\n if (removalInFlightRef.current) return;\r\n removalInFlightRef.current = true;\r\n let result: ProviderRemovalResult;\r\n try {\r\n result = onRemoveProvider(pendingRemoval.providerId);\r\n } catch (caught) {\r\n result = {\r\n ok: false,\r\n error: caught instanceof Error ? caught.message : 'Could not remove the provider.',\r\n };\r\n }\r\n if (!result.ok) {\r\n removalInFlightRef.current = false;\r\n setError(result.error);\r\n }\r\n return;\r\n }\r\n return;\r\n }\r\n if (key.escape) {\r\n if (filter) {\r\n setFilter('');\r\n setSelected(0);\r\n return;\r\n }\r\n onCancel();\r\n return;\r\n }\r\n if (onEffort) {\r\n if (input === 'e') {\r\n setOnEffort(false);\r\n return;\r\n }\r\n const currentIndex = currentEffort ? effortLevels.indexOf(currentEffort) : -1;\r\n const idx = currentIndex >= 0 ? currentIndex : 0;\r\n const nextLevel = key.leftArrow\r\n ? effortLevels[Math.max(0, idx - 1)]\r\n : key.rightArrow\r\n ? effortLevels[Math.min(effortLevels.length - 1, idx + 1)]\r\n : undefined;\r\n if (nextLevel) {\r\n const result = onPickEffort(nextLevel);\r\n setError(result.ok ? undefined : (result.error ?? 'Could not save effort level.'));\r\n }\r\n return;\r\n }\r\n if (key.return) {\r\n if (allowProviderManagement && currentSelected() === addIndex) setShowWizard(true);\r\n else {\r\n const option = filteredOptions[currentSelected()];\r\n if (option) handlePick(option.id, true);\r\n }\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n if (filter) {\r\n setFilter((value) => value.slice(0, -1));\r\n setSelected(0);\r\n }\r\n return;\r\n }\r\n if (key.upArrow) {\r\n setSelected((currentSelected() - 1 + itemCount) % itemCount);\r\n setNotice(undefined);\r\n return;\r\n }\r\n if (key.downArrow) {\r\n setSelected((currentSelected() + 1) % itemCount);\r\n setNotice(undefined);\r\n return;\r\n }\r\n if (allowProviderManagement && key.meta && input === 'a') {\r\n setShowWizard(true);\r\n setError(undefined);\r\n return;\r\n }\r\n if (\r\n key.meta &&\r\n input === 'e' &&\r\n effortLevels.length > 0 &&\r\n currentSelected() !== addIndex &&\r\n filteredOptions[currentSelected()]?.effort\r\n ) {\r\n setOnEffort(true);\r\n return;\r\n }\r\n if (key.meta && input === 's' && currentSelected() !== addIndex) {\r\n const option = filteredOptions[currentSelected()];\r\n if (option) handlePick(option.id, false);\r\n return;\r\n }\r\n if (allowProviderManagement && key.meta && input === 'r' && currentSelected() !== addIndex) {\r\n const providerId = filteredOptions[currentSelected()]?.providerId;\r\n if (!providerId || refreshing) return;\r\n if (!ownsProvider(providerId)) return;\r\n reanchorRef.current = filteredOptions[currentSelected()]?.id;\r\n void refreshProvider(providerId);\r\n return;\r\n }\r\n if (allowProviderManagement && key.meta && input === 'm' && currentSelected() !== addIndex) {\r\n const providerId = filteredOptions[currentSelected()]?.providerId;\r\n if (!providerId) {\r\n setError('Only custom providers can take extra models.');\r\n return;\r\n }\r\n if (refreshing || !ownsProvider(providerId)) return;\r\n // The form swallows every key, so this row stays selected until it closes.\r\n reanchorRef.current = filteredOptions[currentSelected()]?.id;\r\n setManualEntry({ providerId, value: '' });\r\n setError(undefined);\r\n setNotice(undefined);\r\n return;\r\n }\r\n if (allowProviderManagement && key.meta && input === 'd' && currentSelected() !== addIndex) {\r\n const option = filteredOptions[currentSelected()];\r\n const providerId = option?.providerId;\r\n if (!providerId) return;\r\n if (!removableProviderIds.has(providerId)) {\r\n setError('Only BYOK providers you added can be removed.');\r\n return;\r\n }\r\n const provider = providers[providerId];\r\n setRemoval({\r\n providerId,\r\n modelCount:\r\n removableProviderModelCounts?.get(providerId) ??\r\n (provider ? Object.keys(provider.models).length : 0),\r\n active: currentModel.startsWith(`${providerId}/`),\r\n });\r\n setError(undefined);\r\n return;\r\n }\r\n const typed = stripSgrMouseSequences(input);\r\n if (typed && !key.ctrl && !key.meta) {\r\n setFilter((value) => value + typed);\r\n setSelected(0);\r\n }\r\n },\r\n { isActive: true },\r\n );\r\n\r\n if (showWizard) {\r\n return (\r\n <ByokWizard\r\n retry={retry}\r\n compact={compact}\r\n maxVisibleModels={maxVisibleModels}\r\n discover={discover}\r\n onCancel={() => setShowWizard(false)}\r\n onSave={(request) => {\r\n const result = onSaveProvider(request);\r\n if (result.ok) onProviderSaved?.(request);\r\n return result;\r\n }}\r\n />\r\n );\r\n }\r\n\r\n if (manualEntry) {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Text bold color={theme.brand}>\r\n Add models to {manualEntry.providerId}\r\n </Text>\r\n <Text bold>Model IDs</Text>\r\n <Box>\r\n <Text color={theme.brand}>› </Text>\r\n <TextInput\r\n value={manualEntry.value}\r\n onChange={(value) => setManualEntry({ providerId: manualEntry.providerId, value })}\r\n onSubmit={(value) => addManualModels(manualEntry.providerId, value)}\r\n />\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n Comma-separate to add several. Kept when the list is refreshed.\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Enter add · Esc cancel\r\n </Text>\r\n {error && <Text color={theme.error}>✕ {error}</Text>}\r\n </Box>\r\n );\r\n }\r\n\r\n if (removal) {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Text bold color={theme.error}>\r\n Remove BYOK provider?\r\n </Text>\r\n <Text>\r\n Provider: <Text bold>{removal.providerId}</Text>\r\n </Text>\r\n <Text>Models: {removal.modelCount}</Text>\r\n <Text>Settings: .book/settings.local.json</Text>\r\n <Text color={theme.warning ?? theme.subtle}>Removes credentials and all saved models.</Text>\r\n <Text color={theme.subtle}>\r\n {removal.active\r\n ? 'Active provider: switches to next configured default.'\r\n : 'Active model: remains unchanged.'}\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Enter or Y remove · N or Esc cancel\r\n </Text>\r\n {error && <Text color={theme.error}>✕ {error}</Text>}\r\n </Box>\r\n );\r\n }\r\n\r\n const effortIndex = currentEffort ? effortLevels.indexOf(currentEffort) : -1;\r\n const displayedEffort = effortIndex >= 0 ? effortLevels[effortIndex] : effortLevels[0];\r\n const windowStart = Math.max(\r\n 0,\r\n Math.min(selected - Math.floor(maxVisibleModels / 2), itemCount - maxVisibleModels),\r\n );\r\n const rows = [\r\n ...filteredOptions.map((option) => ({ type: 'model' as const, option })),\r\n ...(allowProviderManagement ? [{ type: 'add' as const }] : []),\r\n ].slice(windowStart, windowStart + maxVisibleModels);\r\n const hasRemovableProviders = removableProviderIds.size > 0;\r\n // Catalog actions only mean something on a row that belongs to a provider, so\r\n // they are announced there instead of crowding the always-on footer.\r\n const selectedProviderId =\r\n allowProviderManagement && selected !== addIndex\r\n ? filteredOptions[selected]?.providerId\r\n : undefined;\r\n const editableProviderId =\r\n selectedProviderId && removableProviderIds.has(selectedProviderId)\r\n ? selectedProviderId\r\n : undefined;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Text bold color={theme.brand}>\r\n {title ?? (allowProviderManagement ? 'Models & BYOK providers' : 'Choose subagent model')}\r\n </Text>\r\n <Text color={theme.brand}>Filter: {filter || '(type to filter)'}</Text>\r\n <Box flexDirection=\"column\">\r\n {rows.map((row, visibleIndex) => {\r\n const index = windowStart + visibleIndex;\r\n const isSelected = index === selected && !onEffort;\r\n if (row.type === 'add') {\r\n return (\r\n <Text\r\n key=\"add-byok\"\r\n backgroundColor={isSelected ? theme.surfaceActive : undefined}\r\n color={isSelected ? theme.selectionText : theme.brand}\r\n bold={isSelected}\r\n >\r\n {isSelected ? '›' : ' '} + Add BYOK provider…\r\n </Text>\r\n );\r\n }\r\n const option = row.option;\r\n const isCurrent = option.id === currentModel;\r\n return (\r\n <Text\r\n key={option.id}\r\n backgroundColor={isSelected ? theme.surfaceActive : undefined}\r\n color={isSelected ? theme.selectionText : isCurrent ? theme.brand : theme.subtle}\r\n bold={isSelected || isCurrent}\r\n >\r\n {isSelected ? '›' : ' '} {option.label}\r\n {option.providerId ? ` ${option.providerId}` : ''}\r\n {option.providerId && removableProviderIds.has(option.providerId) ? ' [BYOK]' : ''}\r\n {isCurrent ? ' (current)' : ''}\r\n </Text>\r\n );\r\n })}\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n {modelPickerHints({\r\n allowProviderManagement,\r\n hasRemovableProviders,\r\n canSetEffort:\r\n effortLevels.length > 0 &&\r\n selected !== addIndex &&\r\n Boolean(filteredOptions[selected]?.effort),\r\n // Refresh and add-model are announced only on a row they would act\r\n // on, which is also the only state in which they fire.\r\n editableProviderId: refreshing ? undefined : editableProviderId,\r\n compact: compact || !density.showOptionalHelp,\r\n filterable: true,\r\n }).map((line) => (\r\n <Text key={line} color={theme.subtle} dimColor>\r\n {line}\r\n </Text>\r\n ))}\r\n {refreshing && <Text color={theme.brand}>Refreshing {refreshing} models…</Text>}\r\n {notice && !refreshing && <Text color={theme.success}>✓ {notice}</Text>}\r\n {onEffort && (\r\n <Text color={theme.brand} bold>\r\n Effort [{displayedEffort}] <Text color={theme.subtle}>← → adjust</Text>\r\n </Text>\r\n )}\r\n {error && <Text color={theme.error}>✕ {error}</Text>}\r\n {hasPriorOutput && (\r\n <Text color={theme.warning ?? theme.subtle} dimColor>\r\n ⚠ Switching now re-reads full history on the next turn (uncached).\r\n </Text>\r\n )}\r\n {warnings.map((warning, index) => (\r\n <Text key={index} color={theme.warning ?? theme.subtle} dimColor>\r\n ⚠ {warning}\r\n </Text>\r\n ))}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import InkTextInput, { type Props as InkTextInputProps } from 'ink-text-input';\r\nimport { useCallback, useState } from 'react';\r\nimport { stripSgrMouseSequences } from '../mouse.js';\r\n\r\nexport type TextInputFieldProps = InkTextInputProps;\r\n\r\n/**\r\n * `ink-text-input` splices whatever Ink reports as input straight into the value,\r\n * so a mouse report can otherwise be typed into the focused field. Every Book\r\n * text field goes through this wrapper so reports used by the transcript never\r\n * become form data.\r\n *\r\n * Dropping the report is only half the job. `ink-text-input` advances its own\r\n * cursor by the length of the raw input and re-clamps it only when the `value`\r\n * prop changes, so a stripped report leaves the cursor pointing past the end of\r\n * a value that never changed — the next Backspace then deletes the wrong\r\n * character, invisibly in a masked field. Remounting on the strip re-seats the\r\n * cursor at the end of the value that survived.\r\n */\r\nexport function TextInputField({ onChange, ...props }: TextInputFieldProps) {\r\n const [strippedCount, setStrippedCount] = useState(0);\r\n\r\n const handleChange = useCallback(\r\n (value: string) => {\r\n const clean = stripSgrMouseSequences(value);\r\n if (clean !== value) setStrippedCount((count) => count + 1);\r\n onChange(clean);\r\n },\r\n [onChange],\r\n );\r\n\r\n return <InkTextInput key={strippedCount} {...props} onChange={handleChange} />;\r\n}\r\n\r\nexport default TextInputField;\r\n","import { useCallback, useRef, useState } from 'react';\r\n\r\n/**\r\n * State a key handler can read back inside the same keypress batch.\r\n *\r\n * Ink hands a whole chunk of stdin to its handlers in one go, and React batches\r\n * every `setState` made while that runs. So two keys delivered together — a\r\n * paste, a held arrow that repeats faster than a frame, buffered input over a\r\n * slow link — reach the handler with state still showing what it was before the\r\n * first key touched it. Anything the handler *reads back* is therefore stale:\r\n *\r\n * - a cursor, so Enter opens the row the user was on two keys ago\r\n * - a mode flag, so the key meant for a confirmation prompt is dispatched by\r\n * the branch that was live before the prompt opened, and does nothing\r\n *\r\n * Both were live defects. They were also why the picker suites had to sleep\r\n * between keypresses to let React flush, which is what made them flake on a\r\n * loaded CI runner (#148): the sleep was buying correctness, not just settling\r\n * the frame.\r\n *\r\n * `read()` returns the value as of the last `set()`, whether or not React has\r\n * re-rendered. `set` is the only writer, so the two cannot drift — which a\r\n * hand-rolled `useState` + `useRef` pair does the moment one update forgets the\r\n * ref.\r\n *\r\n * The hook only makes the value it holds batch-safe. Anything derived from\r\n * that value during render — the item a cursor points at, the question an\r\n * index selects, a list a filter narrows — is still one batch behind when the\r\n * handler runs. So a helper invoked from a key handler must resolve indices\r\n * against props or `read()`, never against a value computed during render,\r\n * and take what it acts on as an argument. Passing the index alone is not\r\n * enough if the helper then looks it up in a render-derived value.\r\n *\r\n * A batch-safe mode flag has one more consequence: a keypress a child text\r\n * input consumes through `onSubmit` is also seen by the parent handler, which\r\n * by then reads the flag already flipped and dispatches the same key again.\r\n * Give Enter a single owner — either the text input's `onSubmit` with the flag\r\n * left as plain state, or the parent handler with no `onSubmit` at all.\r\n *\r\n * Use it for state a `useInput` handler reads. Plain `useState` is right for\r\n * everything a handler only writes (an error string, a filter echoed back into\r\n * the render).\r\n */\r\nexport function useKeyState<T>(initial: T | (() => T)): [T, (next: T) => void, () => T] {\r\n const [value, setValue] = useState(initial);\r\n const ref = useRef(value);\r\n const set = useCallback((next: T) => {\r\n ref.current = next;\r\n setValue(next);\r\n }, []);\r\n const read = useCallback(() => ref.current, []);\r\n return [value, set, read];\r\n}\r\n","import type { RetryConfig } from '../types/runtime.js';\r\n\r\nexport type ProviderProtocol = 'openai' | 'anthropic';\r\n\r\nexport interface DiscoveredModel {\r\n id: string;\r\n label?: string;\r\n}\r\n\r\nimport { systemClock, type Clock } from '../clock.js';\r\n\r\nexport interface ModelDiscoveryOptions {\r\n type: ProviderProtocol;\r\n baseUrl: string;\r\n apiKey: string;\r\n retry: RetryConfig;\r\n signal?: AbortSignal;\r\n fetchImpl?: typeof fetch;\r\n onRetry?: (attempt: number, max: number, delayMs: number) => void;\r\n /** Injected by tests; the retry budget below is a duration, not a stamp. */\r\n clock?: Clock;\r\n}\r\n\r\nexport const DEFAULT_PROVIDER_BASE_URLS: Record<ProviderProtocol, string> = {\r\n openai: 'https://api.openai.com/v1',\r\n anthropic: 'https://api.anthropic.com',\r\n};\r\n\r\nconst RETRYABLE_STATUSES = new Set([408, 429, 529]);\r\nconst MAX_ANTHROPIC_PAGES = 100;\r\n\r\nexport class ModelDiscoveryError extends Error {\r\n constructor(\r\n message: string,\r\n readonly code: 'aborted' | 'auth' | 'unsupported' | 'invalid_response' | 'network' | 'request',\r\n ) {\r\n super(message);\r\n this.name = 'ModelDiscoveryError';\r\n }\r\n}\r\n\r\nexport function normalizeProviderBaseUrl(_type: ProviderProtocol, raw: string): string {\r\n const trimmed = raw.trim();\r\n let url: URL;\r\n try {\r\n url = new URL(trimmed);\r\n } catch {\r\n throw new ModelDiscoveryError('Enter a valid HTTP(S) base URL.', 'request');\r\n }\r\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\r\n throw new ModelDiscoveryError('Base URL must use HTTP or HTTPS.', 'request');\r\n }\r\n if (url.username || url.password) {\r\n throw new ModelDiscoveryError('Base URL cannot contain embedded credentials.', 'request');\r\n }\r\n url.search = '';\r\n url.hash = '';\r\n url.pathname = url.pathname.replace(/\\/+$/, '') || '/';\r\n return url.toString().replace(/\\/$/, '');\r\n}\r\n\r\nfunction discoveryUrl(type: ProviderProtocol, baseUrl: string, afterId?: string): string {\r\n const base = normalizeProviderBaseUrl(type, baseUrl);\r\n if (type === 'openai') return `${base}/models`;\r\n const url = new URL(`${base}${/\\/v1$/i.test(new URL(base).pathname) ? '' : '/v1'}/models`);\r\n url.searchParams.set('limit', '100');\r\n if (afterId) url.searchParams.set('after_id', afterId);\r\n return url.toString();\r\n}\r\n\r\nfunction safeStatusError(status: number): ModelDiscoveryError {\r\n if (status === 401 || status === 403) {\r\n return new ModelDiscoveryError(\r\n 'Model discovery was not authorized. Check the API key and endpoint permissions.',\r\n 'auth',\r\n );\r\n }\r\n if (status === 404 || status === 405 || status === 501) {\r\n return new ModelDiscoveryError(\r\n 'This endpoint does not expose a supported model-list API.',\r\n 'unsupported',\r\n );\r\n }\r\n return new ModelDiscoveryError(`Model discovery request failed with HTTP ${status}.`, 'request');\r\n}\r\n\r\nfunction retryDelay(attempt: number, retry: RetryConfig, retryAfter: string | null): number {\r\n const retryAfterSeconds = retryAfter === null ? NaN : Number(retryAfter);\r\n if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0) {\r\n return Math.min(retryAfterSeconds * 1000, retry.maxDelayMs);\r\n }\r\n return Math.min(retry.baseDelayMs * 2 ** attempt, retry.maxDelayMs);\r\n}\r\n\r\nfunction wait(ms: number, signal?: AbortSignal): Promise<void> {\r\n if (signal?.aborted) {\r\n return Promise.reject(new ModelDiscoveryError('Model discovery was cancelled.', 'aborted'));\r\n }\r\n return new Promise((resolve, reject) => {\r\n const abort = () => {\r\n clearTimeout(timer);\r\n reject(new ModelDiscoveryError('Model discovery was cancelled.', 'aborted'));\r\n };\r\n const timer = setTimeout(() => {\r\n signal?.removeEventListener('abort', abort);\r\n resolve();\r\n }, ms);\r\n signal?.addEventListener('abort', abort, { once: true });\r\n });\r\n}\r\n\r\nasync function fetchWithRetry(\r\n url: string,\r\n init: RequestInit,\r\n options: ModelDiscoveryOptions,\r\n): Promise<Response> {\r\n const fetchImpl = options.fetchImpl ?? fetch;\r\n const clock = options.clock ?? systemClock;\r\n const startedAt = clock.monotonicNowMs();\r\n let lastNetworkError: unknown;\r\n\r\n for (let attempt = 0; attempt <= options.retry.maxAttempts; attempt++) {\r\n if (options.signal?.aborted) {\r\n throw new ModelDiscoveryError('Model discovery was cancelled.', 'aborted');\r\n }\r\n\r\n const controller = new AbortController();\r\n const abortFromCaller = () => controller.abort(options.signal?.reason);\r\n options.signal?.addEventListener('abort', abortFromCaller, { once: true });\r\n const timeout = setTimeout(\r\n () => controller.abort(new Error('request timeout')),\r\n options.retry.requestTimeoutMs,\r\n );\r\n\r\n let response: Response | undefined;\r\n try {\r\n response = await fetchImpl(url, { ...init, signal: controller.signal });\r\n } catch (error) {\r\n if (options.signal?.aborted) {\r\n throw new ModelDiscoveryError('Model discovery was cancelled.', 'aborted');\r\n }\r\n lastNetworkError = error;\r\n } finally {\r\n clearTimeout(timeout);\r\n options.signal?.removeEventListener('abort', abortFromCaller);\r\n }\r\n\r\n if (response && !(RETRYABLE_STATUSES.has(response.status) || response.status >= 500)) {\r\n return response;\r\n }\r\n\r\n if (attempt >= options.retry.maxAttempts) {\r\n if (response) return response;\r\n throw new ModelDiscoveryError('Could not reach the model-list endpoint.', 'network');\r\n }\r\n if (\r\n options.retry.totalBudgetMs > 0 &&\r\n clock.monotonicNowMs() - startedAt >= options.retry.totalBudgetMs\r\n ) {\r\n if (response) return response;\r\n throw new ModelDiscoveryError('Could not reach the model-list endpoint.', 'network');\r\n }\r\n\r\n const delay = retryDelay(attempt, options.retry, response?.headers.get('retry-after') ?? null);\r\n options.onRetry?.(attempt + 1, options.retry.maxAttempts, delay);\r\n await wait(delay, options.signal);\r\n }\r\n\r\n throw new ModelDiscoveryError(\r\n lastNetworkError ? 'Could not reach the model-list endpoint.' : 'Model discovery failed.',\r\n 'network',\r\n );\r\n}\r\n\r\nfunction parseModels(payload: unknown, type: ProviderProtocol): DiscoveredModel[] {\r\n if (!payload || typeof payload !== 'object') {\r\n throw new ModelDiscoveryError(\r\n 'The model-list endpoint returned invalid JSON.',\r\n 'invalid_response',\r\n );\r\n }\r\n const data = (payload as { data?: unknown }).data;\r\n if (!Array.isArray(data)) {\r\n throw new ModelDiscoveryError(\r\n 'The model-list endpoint returned an unsupported response shape.',\r\n 'invalid_response',\r\n );\r\n }\r\n\r\n const models: DiscoveredModel[] = [];\r\n for (const item of data) {\r\n if (!item || typeof item !== 'object') continue;\r\n const record = item as Record<string, unknown>;\r\n const id = typeof record.id === 'string' ? record.id.trim() : '';\r\n if (!id || /[\\x00-\\x1f\\x7f]/.test(id)) continue;\r\n const rawLabel =\r\n type === 'anthropic'\r\n ? record.display_name\r\n : (record.name ?? record.display_name ?? record.label);\r\n const label = typeof rawLabel === 'string' && rawLabel.trim() ? rawLabel.trim() : undefined;\r\n models.push({ id, label });\r\n }\r\n return models;\r\n}\r\n\r\nexport async function discoverModels(options: ModelDiscoveryOptions): Promise<DiscoveredModel[]> {\r\n const headers: Record<string, string> =\r\n options.type === 'anthropic'\r\n ? {\r\n 'x-api-key': options.apiKey,\r\n 'anthropic-version': '2023-06-01',\r\n }\r\n : { Authorization: `Bearer ${options.apiKey}` };\r\n\r\n const discovered: DiscoveredModel[] = [];\r\n let afterId: string | undefined;\r\n let finished = false;\r\n\r\n for (let page = 0; page < MAX_ANTHROPIC_PAGES; page++) {\r\n const response = await fetchWithRetry(\r\n discoveryUrl(options.type, options.baseUrl, afterId),\r\n { method: 'GET', headers },\r\n options,\r\n );\r\n if (!response.ok) throw safeStatusError(response.status);\r\n\r\n let payload: unknown;\r\n try {\r\n payload = await response.json();\r\n } catch {\r\n throw new ModelDiscoveryError(\r\n 'The model-list endpoint returned invalid JSON.',\r\n 'invalid_response',\r\n );\r\n }\r\n discovered.push(...parseModels(payload, options.type));\r\n\r\n if (options.type !== 'anthropic') {\r\n finished = true;\r\n break;\r\n }\r\n const pageInfo = payload as { has_more?: unknown; last_id?: unknown };\r\n if (pageInfo.has_more !== true) {\r\n finished = true;\r\n break;\r\n }\r\n const nextId = typeof pageInfo.last_id === 'string' ? pageInfo.last_id : undefined;\r\n if (!nextId || nextId === afterId) {\r\n throw new ModelDiscoveryError(\r\n 'The model-list endpoint returned invalid pagination metadata.',\r\n 'invalid_response',\r\n );\r\n }\r\n afterId = nextId;\r\n }\r\n\r\n if (options.type === 'anthropic' && !finished) {\r\n throw new ModelDiscoveryError(\r\n 'The model-list endpoint exceeded the pagination limit.',\r\n 'invalid_response',\r\n );\r\n }\r\n\r\n const deduped = new Map<string, DiscoveredModel>();\r\n for (const model of discovered) {\r\n const existing = deduped.get(model.id);\r\n deduped.set(model.id, existing?.label ? existing : model);\r\n }\r\n const models = [...deduped.values()].sort((a, b) => a.id.localeCompare(b.id));\r\n if (models.length === 0) {\r\n throw new ModelDiscoveryError(\r\n 'The endpoint did not return any usable models.',\r\n 'invalid_response',\r\n );\r\n }\r\n return models;\r\n}\r\n","import { AVAILABLE_MODELS, modelSupportsEffort } from '../models.js';\r\nimport type { ProviderConfig, ResolvedSettings } from '../settings.js';\r\nimport {\r\n normalizeProviderBaseUrl,\r\n type DiscoveredModel,\r\n type ProviderProtocol,\r\n} from '../provider/model-discovery.js';\r\n\r\nexport interface ModelPickerOption {\r\n id: string;\r\n label: string;\r\n effort: boolean;\r\n custom: boolean;\r\n providerId?: string;\r\n}\r\n\r\nexport interface ByokProviderDraft {\r\n providerId: string;\r\n type: ProviderProtocol;\r\n baseURL: string;\r\n apiKey: string;\r\n models: DiscoveredModel[];\r\n activeModelId: string;\r\n activeLabel?: string;\r\n}\r\n\r\nexport interface ProviderSaveRequest extends ByokProviderDraft {\r\n replaceModels?: boolean;\r\n /** False when refreshing a catalog without changing the active model. */\r\n activate?: boolean;\r\n /** True when `models` were typed by hand instead of discovered. */\r\n manual?: boolean;\r\n}\r\n\r\nexport function buildModelOptions(settings: ResolvedSettings): ModelPickerOption[] {\r\n const options = new Map<string, ModelPickerOption>();\r\n for (const model of AVAILABLE_MODELS) {\r\n options.set(model.id, {\r\n id: model.id,\r\n label: model.label,\r\n effort: Boolean(model.effort),\r\n custom: false,\r\n });\r\n }\r\n\r\n for (const providerId of Object.keys(settings.provider).sort()) {\r\n const provider = settings.provider[providerId];\r\n for (const modelId of Object.keys(provider.models).sort()) {\r\n const id = `${providerId}/${modelId}`;\r\n const metadata = provider.models[modelId];\r\n const existing = options.get(id);\r\n options.set(id, {\r\n id,\r\n label: metadata.label ?? existing?.label ?? modelId,\r\n effort:\r\n metadata.effort === false\r\n ? false\r\n : typeof metadata.effort === 'object'\r\n ? true\r\n : (existing?.effort ?? modelSupportsEffort(modelId)),\r\n custom: true,\r\n providerId,\r\n });\r\n }\r\n }\r\n return [...options.values()];\r\n}\r\n\r\nexport function validateProviderId(raw: string): string {\r\n const value = raw.trim().toLowerCase();\r\n if (!/^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$/.test(value)) {\r\n throw new Error('Use 1–64 lowercase letters, numbers, hyphens, or underscores.');\r\n }\r\n return value;\r\n}\r\n\r\nexport function validateModelId(raw: string): string {\r\n const value = raw.trim();\r\n if (!value || value.length > 256 || /[\\x00-\\x1f\\x7f]/.test(value)) {\r\n throw new Error('Enter a model ID of 1–256 characters without control characters.');\r\n }\r\n return value;\r\n}\r\n\r\n/**\r\n * Split a hand-typed model list on commas or newlines so one prompt can add\r\n * several models at once. Order is preserved and duplicates collapse.\r\n */\r\nexport function parseModelIds(raw: string): string[] {\r\n const ids: string[] = [];\r\n for (const part of raw.split(/[,\\n]/)) {\r\n if (!part.trim()) continue;\r\n const id = validateModelId(part);\r\n if (!ids.includes(id)) ids.push(id);\r\n }\r\n if (ids.length === 0) throw new Error('Enter at least one model ID.');\r\n return ids;\r\n}\r\n\r\nexport function validateDisplayLabel(raw: string): string | undefined {\r\n const value = raw.trim();\r\n if (!value) return undefined;\r\n if (value.length > 100 || /[\\x00-\\x1f\\x7f]/.test(value)) {\r\n throw new Error('Use at most 100 characters without control characters.');\r\n }\r\n return value;\r\n}\r\n\r\nexport function validateApiKey(raw: string): string {\r\n if (!raw.trim()) throw new Error('API key is required.');\r\n if (/[\\r\\n\\x00]/.test(raw)) throw new Error('API key cannot contain line breaks.');\r\n return raw;\r\n}\r\n\r\nexport function validateBaseUrl(type: ProviderProtocol, raw: string): string {\r\n return normalizeProviderBaseUrl(type, raw);\r\n}\r\n\r\nexport function providerConfigFromDraft(\r\n draft: ProviderSaveRequest,\r\n existing?: ProviderConfig,\r\n replaceModels = false,\r\n): ProviderConfig {\r\n // A refresh replaces the discovered catalog with whatever the endpoint now\r\n // reports, but hand-entered models survive it: they were typed in because\r\n // the model-list API does not return them, so dropping them here would undo\r\n // the user's work on every refresh.\r\n const models: ProviderConfig['models'] = replaceModels\r\n ? Object.fromEntries(\r\n Object.entries(existing?.models ?? {}).filter(([, metadata]) => metadata.manual),\r\n )\r\n : { ...(existing?.models ?? {}) };\r\n for (const model of draft.models) {\r\n const previous = existing?.models[model.id];\r\n models[model.id] = {\r\n ...previous,\r\n label:\r\n model.id === draft.activeModelId\r\n ? (draft.activeLabel ?? model.label ?? previous?.label)\r\n : (model.label ?? previous?.label),\r\n manual: draft.manual ? true : undefined,\r\n };\r\n if (!models[model.id].label) delete models[model.id].label;\r\n // Discovery now vouches for this id, so it no longer needs the manual\r\n // marker to survive the next refresh.\r\n if (!models[model.id].manual) delete models[model.id].manual;\r\n }\r\n // Only overwrite credentials the draft actually carries; adding a model to an\r\n // existing provider leaves its base URL and key exactly as configured.\r\n const config: ProviderConfig = { ...existing, type: draft.type, models };\r\n if (draft.baseURL) {\r\n config.baseURL = draft.baseURL;\r\n // Readers prefer `baseURL`, so a surviving legacy `baseUrl` would sit in\r\n // settings.json as a stale value that looks live.\r\n delete config.baseUrl;\r\n }\r\n if (draft.apiKey) config.apiKey = draft.apiKey;\r\n return config;\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport TextInput from './TextInputField.js';\r\nimport { useCallback, useMemo, useRef, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport type { RetryConfig } from '../../types/runtime.js';\r\nimport {\r\n DEFAULT_PROVIDER_BASE_URLS,\r\n discoverModels,\r\n type DiscoveredModel,\r\n type ModelDiscoveryOptions,\r\n type ProviderProtocol,\r\n} from '../../provider/model-discovery.js';\r\nimport {\r\n parseModelIds,\r\n validateApiKey,\r\n validateBaseUrl,\r\n validateDisplayLabel,\r\n validateProviderId,\r\n type ProviderSaveRequest,\r\n} from '../model-options.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { stripSgrMouseSequences } from '../mouse.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\nexport interface ByokWizardProps {\r\n retry: RetryConfig;\r\n compact?: boolean;\r\n maxVisibleModels?: number;\r\n discover?: (options: ModelDiscoveryOptions) => Promise<DiscoveredModel[]>;\r\n onSave: (\r\n request: ProviderSaveRequest,\r\n ) => { ok: boolean; error?: string } | Promise<{ ok: boolean; error?: string }>;\r\n onCancel: () => void;\r\n}\r\n\r\ntype Step =\r\n | 'provider'\r\n | 'protocol'\r\n | 'base-url'\r\n | 'api-key'\r\n | 'model-source'\r\n | 'discovering'\r\n | 'discovery-error'\r\n | 'choose-models'\r\n | 'manual-model'\r\n | 'label'\r\n | 'review';\r\n\r\n/** Where this provider's model list comes from. */\r\ntype ModelSource = 'discover' | 'manual';\r\n\r\nconst TOTAL_STEPS = 9;\r\n\r\nconst STEP_NUMBER: Partial<Record<Step, number>> = {\r\n provider: 1,\r\n protocol: 2,\r\n 'base-url': 3,\r\n 'api-key': 4,\r\n 'model-source': 5,\r\n discovering: 6,\r\n 'discovery-error': 6,\r\n 'choose-models': 7,\r\n 'manual-model': 7,\r\n label: 8,\r\n review: 9,\r\n};\r\n\r\nconst MODEL_SOURCES: readonly { value: ModelSource; title: string; hint: string }[] = [\r\n {\r\n value: 'discover',\r\n title: 'Discover models automatically',\r\n hint: 'Asks the endpoint for its model list.',\r\n },\r\n {\r\n value: 'manual',\r\n title: 'Enter model IDs manually',\r\n hint: 'Use this when the endpoint has no model-list API.',\r\n },\r\n];\r\n\r\nfunction errorMessage(error: unknown): string {\r\n return error instanceof Error ? error.message : 'Model discovery failed.';\r\n}\r\n\r\nfunction filterModels(models: DiscoveredModel[], filter: string): DiscoveredModel[] {\r\n const query = filter.trim().toLowerCase();\r\n return query\r\n ? models.filter(\r\n (model) =>\r\n model.id.toLowerCase().includes(query) || model.label?.toLowerCase().includes(query),\r\n )\r\n : models;\r\n}\r\n\r\nexport function ByokWizard({\r\n retry,\r\n compact = false,\r\n maxVisibleModels = 8,\r\n discover = discoverModels,\r\n onSave,\r\n onCancel,\r\n}: ByokWizardProps) {\r\n const theme = useTheme();\r\n const density = useDensityMetrics();\r\n // `step` deliberately stays plain render state. On the text-field steps Enter\r\n // belongs to the field's `onSubmit`, and the handler below relies on still\r\n // reading the old step when Ink hands it the same keypress; a batch-safe step\r\n // would let a double Enter submit the field and then advance a second time.\r\n const [step, setStep] = useState<Step>('provider');\r\n const [providerId, setProviderId] = useState('');\r\n // Everything else the key handler reads back is batch-safe. Ink runs the\r\n // handler once per stdin chunk, so with plain state a batched arrow+Space\r\n // toggled the model above the highlighted one, arrow+Enter on the source step\r\n // discovered models the user had just declined, Space+Enter saved a provider\r\n // with no models, and two arrows on the protocol step toggled it once.\r\n const [type, setType, currentType] = useKeyState<ProviderProtocol>('openai');\r\n const [baseURL, setBaseURL] = useState('');\r\n const [apiKey, setApiKey] = useState('');\r\n const [modelSource, setModelSource, currentSource] = useKeyState<ModelSource>('discover');\r\n const [models, setModels] = useState<DiscoveredModel[]>([]);\r\n const [selectedIds, setSelectedIds, currentSelected] = useKeyState<string[]>([]);\r\n const [modelCursor, setModelCursor, currentModel] = useKeyState(0);\r\n const [modelFilter, setModelFilter, currentFilter] = useKeyState('');\r\n const [manualModel, setManualModel] = useState('');\r\n const [label, setLabel] = useState('');\r\n const [error, setError] = useState<string>();\r\n const [saving, setSaving] = useState(false);\r\n const discoveryAbortRef = useRef<AbortController | null>(null);\r\n const saveRef = useRef(false);\r\n\r\n const filteredModels = useMemo(() => filterModels(models, modelFilter), [modelFilter, models]);\r\n\r\n const activeModelId = selectedIds[0] ?? '';\r\n\r\n const startDiscovery = useCallback(async () => {\r\n setError(undefined);\r\n setStep('discovering');\r\n const controller = new AbortController();\r\n discoveryAbortRef.current = controller;\r\n try {\r\n const discovered = await discover({\r\n type,\r\n baseUrl: validateBaseUrl(type, baseURL),\r\n apiKey: validateApiKey(apiKey),\r\n retry,\r\n signal: controller.signal,\r\n });\r\n if (controller.signal.aborted) return;\r\n if (discovered.length === 0) {\r\n // The error screen's own fallback is the way forward, so route there\r\n // rather than into an empty picker that refuses to continue.\r\n setError('The endpoint did not return any models.');\r\n setStep('discovery-error');\r\n return;\r\n }\r\n setModelSource('discover');\r\n setModels(discovered);\r\n setSelectedIds(discovered.map((model) => model.id));\r\n setModelCursor(0);\r\n setModelFilter('');\r\n setStep('choose-models');\r\n } catch (caught) {\r\n if (controller.signal.aborted) {\r\n setStep('model-source');\r\n return;\r\n }\r\n setError(errorMessage(caught));\r\n setStep('discovery-error');\r\n } finally {\r\n if (discoveryAbortRef.current === controller) discoveryAbortRef.current = null;\r\n }\r\n }, [apiKey, baseURL, discover, retry, type]);\r\n\r\n const goBack = useCallback(() => {\r\n setError(undefined);\r\n switch (step) {\r\n case 'provider':\r\n onCancel();\r\n break;\r\n case 'protocol':\r\n setStep('provider');\r\n break;\r\n case 'base-url':\r\n setStep('protocol');\r\n break;\r\n case 'api-key':\r\n setStep('base-url');\r\n break;\r\n case 'model-source':\r\n setStep('api-key');\r\n break;\r\n case 'discovering':\r\n discoveryAbortRef.current?.abort();\r\n break;\r\n case 'discovery-error':\r\n case 'choose-models':\r\n case 'manual-model':\r\n setStep('model-source');\r\n break;\r\n case 'label':\r\n setStep(modelSource === 'manual' ? 'manual-model' : 'choose-models');\r\n break;\r\n case 'review':\r\n setStep('label');\r\n break;\r\n }\r\n }, [modelSource, onCancel, step]);\r\n\r\n useInput(\r\n (input, key) => {\r\n if (key.ctrl && input === 'c') {\r\n discoveryAbortRef.current?.abort();\r\n onCancel();\r\n return;\r\n }\r\n if (key.escape) {\r\n goBack();\r\n return;\r\n }\r\n if (step === 'protocol') {\r\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {\r\n const next: ProviderProtocol = currentType() === 'openai' ? 'anthropic' : 'openai';\r\n setType(next);\r\n setBaseURL(DEFAULT_PROVIDER_BASE_URLS[next]);\r\n return;\r\n }\r\n if (key.return) setStep('base-url');\r\n return;\r\n }\r\n if (step === 'model-source') {\r\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {\r\n setModelSource(currentSource() === 'discover' ? 'manual' : 'discover');\r\n return;\r\n }\r\n if (key.return) {\r\n if (currentSource() === 'discover') void startDiscovery();\r\n else {\r\n setError(undefined);\r\n setModels([]);\r\n setSelectedIds([]);\r\n setStep('manual-model');\r\n }\r\n }\r\n return;\r\n }\r\n if (step === 'discovery-error') {\r\n if (input === 'r') void startDiscovery();\r\n if (input === 'm') {\r\n setError(undefined);\r\n setModelSource('manual');\r\n setModels([]);\r\n setSelectedIds([]);\r\n setStep('manual-model');\r\n }\r\n return;\r\n }\r\n if (step === 'choose-models') {\r\n const typed = stripSgrMouseSequences(input);\r\n if (key.return) {\r\n if (currentSelected().length === 0) setError('Select at least one model.');\r\n else {\r\n setError(undefined);\r\n setStep('label');\r\n }\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n setModelFilter(currentFilter().slice(0, -1));\r\n setModelCursor(0);\r\n return;\r\n }\r\n // The list a filter character earlier in this chunk produced, not the\r\n // one the last render showed — otherwise Down and Space act on a model\r\n // the new filter hides.\r\n const visible = filterModels(models, currentFilter());\r\n if (visible.length === 0) {\r\n if (typed && typed !== ' ' && !key.ctrl && !key.meta) {\r\n setModelFilter(currentFilter() + typed);\r\n }\r\n return;\r\n }\r\n if (key.upArrow) {\r\n setModelCursor((currentModel() - 1 + visible.length) % visible.length);\r\n return;\r\n }\r\n if (key.downArrow) {\r\n setModelCursor((currentModel() + 1) % visible.length);\r\n return;\r\n }\r\n if (input === ' ') {\r\n const id = visible[currentModel()]?.id;\r\n if (!id) return;\r\n const current = currentSelected();\r\n setSelectedIds(\r\n current.includes(id) ? current.filter((value) => value !== id) : [...current, id],\r\n );\r\n return;\r\n }\r\n if (typed && !key.ctrl && !key.meta) {\r\n setModelFilter(currentFilter() + typed);\r\n setModelCursor(0);\r\n }\r\n return;\r\n }\r\n if (step === 'review' && key.return && !saving && !saveRef.current) {\r\n saveRef.current = true;\r\n setSaving(true);\r\n setError(undefined);\r\n const chosen = models.filter((model) => selectedIds.includes(model.id));\r\n void Promise.resolve(\r\n onSave({\r\n providerId,\r\n type,\r\n baseURL,\r\n apiKey,\r\n models: chosen.length > 0 ? chosen : [{ id: activeModelId }],\r\n activeModelId,\r\n activeLabel: label || undefined,\r\n manual: modelSource === 'manual',\r\n }),\r\n ).then((result) => {\r\n if (!result.ok) {\r\n saveRef.current = false;\r\n setSaving(false);\r\n setError(result.error ?? 'Could not save provider settings.');\r\n }\r\n });\r\n }\r\n },\r\n { isActive: true },\r\n );\r\n\r\n const submitProvider = (value: string) => {\r\n try {\r\n setProviderId(validateProviderId(value));\r\n setError(undefined);\r\n setStep('protocol');\r\n } catch (caught) {\r\n setError(errorMessage(caught));\r\n }\r\n };\r\n\r\n const submitBaseUrl = (value: string) => {\r\n try {\r\n setBaseURL(validateBaseUrl(type, value || DEFAULT_PROVIDER_BASE_URLS[type]));\r\n setError(undefined);\r\n setStep('api-key');\r\n } catch (caught) {\r\n setError(errorMessage(caught));\r\n }\r\n };\r\n\r\n const submitApiKey = (value: string) => {\r\n try {\r\n setApiKey(validateApiKey(value));\r\n setError(undefined);\r\n setStep('model-source');\r\n } catch (caught) {\r\n setError(errorMessage(caught));\r\n }\r\n };\r\n\r\n const submitManualModel = (value: string) => {\r\n try {\r\n const ids = parseModelIds(value);\r\n setManualModel(ids.join(', '));\r\n setModelSource('manual');\r\n setModels(ids.map((id) => ({ id })));\r\n setSelectedIds(ids);\r\n setError(undefined);\r\n setStep('label');\r\n } catch (caught) {\r\n setError(errorMessage(caught));\r\n }\r\n };\r\n\r\n const submitLabel = (value: string) => {\r\n try {\r\n setLabel(validateDisplayLabel(value) ?? '');\r\n setError(undefined);\r\n setStep('review');\r\n } catch (caught) {\r\n setError(errorMessage(caught));\r\n }\r\n };\r\n\r\n const stepNumber = STEP_NUMBER[step];\r\n const modelWindowStart = Math.max(\r\n 0,\r\n Math.min(\r\n modelCursor - Math.floor(maxVisibleModels / 2),\r\n filteredModels.length - maxVisibleModels,\r\n ),\r\n );\r\n const visibleModels = filteredModels.slice(modelWindowStart, modelWindowStart + maxVisibleModels);\r\n const showOptionalHelp = !compact && density.showOptionalHelp;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Box justifyContent=\"space-between\">\r\n <Text bold color={theme.brand}>\r\n Add BYOK provider\r\n </Text>\r\n {stepNumber && (\r\n <Text color={theme.subtle} dimColor>\r\n Step {stepNumber}/{TOTAL_STEPS}\r\n </Text>\r\n )}\r\n </Box>\r\n\r\n <Box flexDirection=\"column\">\r\n {step === 'provider' && (\r\n <Field\r\n label=\"Provider ID\"\r\n hint={showOptionalHelp ? 'Example: openrouter' : undefined}\r\n value={providerId}\r\n onChange={setProviderId}\r\n onSubmit={submitProvider}\r\n />\r\n )}\r\n {step === 'protocol' && (\r\n <>\r\n <Text bold>Protocol</Text>\r\n {(['openai', 'anthropic'] as const).map((value) => (\r\n <Text key={value} color={type === value ? theme.brand : theme.subtle}>\r\n {type === value ? '›' : ' '}{' '}\r\n {value === 'openai' ? 'OpenAI-compatible' : 'Anthropic'}\r\n </Text>\r\n ))}\r\n </>\r\n )}\r\n {step === 'base-url' && (\r\n <Field\r\n label=\"Base URL\"\r\n hint={\r\n !showOptionalHelp\r\n ? undefined\r\n : type === 'openai'\r\n ? 'Include /v1 when required by the endpoint.'\r\n : 'Book adds /v1 for Anthropic requests.'\r\n }\r\n placeholder={DEFAULT_PROVIDER_BASE_URLS[type]}\r\n value={baseURL}\r\n onChange={setBaseURL}\r\n onSubmit={submitBaseUrl}\r\n />\r\n )}\r\n {step === 'api-key' && (\r\n <Field\r\n label=\"API key\"\r\n hint={\r\n showOptionalHelp\r\n ? 'Stored in ~/.book/settings.json (shared across all your projects).'\r\n : undefined\r\n }\r\n value={apiKey}\r\n onChange={setApiKey}\r\n onSubmit={submitApiKey}\r\n mask=\"•\"\r\n />\r\n )}\r\n {step === 'model-source' && (\r\n <>\r\n <Text bold>Models</Text>\r\n {MODEL_SOURCES.map((source) => (\r\n <Text\r\n key={source.value}\r\n color={modelSource === source.value ? theme.brand : theme.subtle}\r\n >\r\n {modelSource === source.value ? '›' : ' '} {source.title}\r\n </Text>\r\n ))}\r\n {showOptionalHelp && (\r\n <Text color={theme.subtle} dimColor>\r\n {MODEL_SOURCES.find((source) => source.value === modelSource)?.hint}\r\n </Text>\r\n )}\r\n </>\r\n )}\r\n {step === 'discovering' && (\r\n <>\r\n <Text bold>Discover models</Text>\r\n <Text color={theme.brand}>Discovering models…</Text>\r\n </>\r\n )}\r\n {step === 'discovery-error' && (\r\n <>\r\n <Text bold>Discover models</Text>\r\n <Text color={theme.error}>✕ {error}</Text>\r\n <Text color={theme.subtle}>r retry · m enter model manually · Esc back</Text>\r\n </>\r\n )}\r\n {step === 'choose-models' && (\r\n <>\r\n <Text bold>Choose models</Text>\r\n <Text color={theme.subtle}>Filter: {modelFilter || '(type to filter)'}</Text>\r\n {visibleModels.length === 0 ? (\r\n <Text color={theme.subtle}>(no matching models)</Text>\r\n ) : (\r\n visibleModels.map((model, index) => {\r\n const absoluteIndex = modelWindowStart + index;\r\n return (\r\n <Text\r\n key={model.id}\r\n backgroundColor={\r\n absoluteIndex === modelCursor ? theme.surfaceActive : undefined\r\n }\r\n color={absoluteIndex === modelCursor ? theme.selectionText : theme.subtle}\r\n bold={absoluteIndex === modelCursor}\r\n >\r\n {absoluteIndex === modelCursor ? '›' : ' '}{' '}\r\n {selectedIds.includes(model.id) ? '◉' : '○'} {model.label ?? model.id}\r\n {model.label && model.label !== model.id ? ` ${model.id}` : ''}\r\n </Text>\r\n );\r\n })\r\n )}\r\n <Text color={theme.subtle} dimColor>\r\n ↑↓ move · Space toggle · Enter continue ({selectedIds.length} selected)\r\n </Text>\r\n </>\r\n )}\r\n {step === 'manual-model' && (\r\n <Field\r\n label=\"Model IDs\"\r\n hint={\r\n showOptionalHelp\r\n ? 'Example: deepseek-chat, deepseek-reasoner — comma-separate to add several.'\r\n : undefined\r\n }\r\n value={manualModel}\r\n onChange={setManualModel}\r\n onSubmit={submitManualModel}\r\n />\r\n )}\r\n {step === 'label' && (\r\n <Field\r\n label=\"Display label (optional)\"\r\n value={label}\r\n onChange={setLabel}\r\n onSubmit={submitLabel}\r\n />\r\n )}\r\n {step === 'review' && (\r\n <>\r\n <Text bold>Review</Text>\r\n <Summary label=\"Provider\" value={providerId} />\r\n <Summary\r\n label=\"Protocol\"\r\n value={type === 'openai' ? 'OpenAI-compatible' : 'Anthropic'}\r\n />\r\n <Summary label=\"Base URL\" value={baseURL} />\r\n <Summary label=\"API key\" value=\"•••••••• (stored in ~/.book)\" />\r\n <Summary\r\n label=\"Models\"\r\n value={`${selectedIds.length} selected (${modelSource === 'manual' ? 'entered manually' : 'discovered'})`}\r\n />\r\n <Summary label=\"Active\" value={activeModelId} />\r\n {label && <Summary label=\"Label\" value={label} />}\r\n </>\r\n )}\r\n </Box>\r\n\r\n {error && step !== 'discovery-error' && <Text color={theme.error}>✕ {error}</Text>}\r\n <Text color={theme.subtle} dimColor>\r\n {saving\r\n ? 'Saving…'\r\n : step === 'review'\r\n ? 'Enter save & use · Esc back · Ctrl+C cancel'\r\n : step === 'discovering'\r\n ? 'Esc cancel request'\r\n : step === 'choose-models' || step === 'discovery-error'\r\n ? ''\r\n : step === 'protocol' || step === 'model-source'\r\n ? '↑↓ choose · Enter continue · Esc back'\r\n : showOptionalHelp\r\n ? 'Enter continue · Esc back · Ctrl+C cancel'\r\n : 'Enter continue · Esc back'}\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\nfunction Field({\r\n label,\r\n hint,\r\n placeholder,\r\n value,\r\n onChange,\r\n onSubmit,\r\n mask,\r\n}: {\r\n label: string;\r\n hint?: string;\r\n placeholder?: string;\r\n value: string;\r\n onChange: (value: string) => void;\r\n onSubmit: (value: string) => void;\r\n mask?: string;\r\n}) {\r\n const theme = useTheme();\r\n return (\r\n <>\r\n <Text bold>{label}</Text>\r\n <Box>\r\n <Text color={theme.brand}>› </Text>\r\n <TextInput\r\n value={value}\r\n onChange={onChange}\r\n onSubmit={onSubmit}\r\n placeholder={placeholder}\r\n mask={mask}\r\n />\r\n </Box>\r\n {hint && (\r\n <Text color={theme.subtle} dimColor>\r\n {hint}\r\n </Text>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\nfunction Summary({ label, value }: { label: string; value: string }) {\r\n const theme = useTheme();\r\n return (\r\n <Box>\r\n <Box width={12}>\r\n <Text color={theme.subtle}>{label}</Text>\r\n </Box>\r\n <Text>{value}</Text>\r\n </Box>\r\n );\r\n}\r\n","/**\r\n * What `/model` tells you it can do.\r\n *\r\n * The picker binds six Alt-chords. The footer used to be four hand-written\r\n * strings chosen by two booleans, and between them they left holes:\r\n *\r\n * - **`Alt+E` was advertised nowhere at all.** Setting a model's effort was\r\n * reachable only by guessing, and the row it opens (`Effort [high] ← →\r\n * adjust`) is only visible *after* you have already found the key.\r\n * - **`Alt+S` disappeared whenever a removable BYOK provider existed**, because\r\n * that branch spent the line on `Alt+A` and `Alt+D` instead — so the chord\r\n * that always works was hidden by the presence of one that sometimes does.\r\n *\r\n * Both came from writing the sentence out per case. This builds it from what is\r\n * actually available, so a chord cannot be advertised when it will not fire, and\r\n * cannot be dropped because a different one appeared.\r\n *\r\n * Two lines, split by what they act on: choosing a model, and managing the\r\n * catalog. That split is the reason it fits — six chords and the navigation keys\r\n * do not fit on one 80-column line, and a wrapped footer is what this replaces.\r\n */\r\nexport interface ModelPickerHintState {\r\n /** BYOK management is offered at all. */\r\n allowProviderManagement: boolean;\r\n /** Some provider in the list can be removed. */\r\n hasRemovableProviders: boolean;\r\n /** The selected row is a model that carries per-model effort. */\r\n canSetEffort: boolean;\r\n /** The selected row belongs to a provider the user owns. */\r\n editableProviderId?: string;\r\n /** Drop the descriptions, keep every chord. */\r\n compact: boolean;\r\n /** The list can be typed at. */\r\n filterable: boolean;\r\n}\r\n\r\n/** The footer, as one or two lines. Never empty; never missing a live chord. */\r\nexport function modelPickerHints(state: ModelPickerHintState): string[] {\r\n const { compact } = state;\r\n\r\n // Descriptions stay terse in both widths. The line this replaces was 81\r\n // columns and fit; spelling the chords out (\"use for this session\") pushes\r\n // past 100 and wraps, which is the defect. Compact drops the filter hint\r\n // rather than a chord — typing is discoverable by doing it, a chord is not.\r\n const choosing = [\r\n '↑↓ select',\r\n state.filterable && !compact ? 'type filter' : undefined,\r\n 'Enter save',\r\n 'Alt+S session',\r\n state.canSetEffort ? 'Alt+E effort' : undefined,\r\n 'Esc cancel',\r\n ].filter(Boolean) as string[];\r\n\r\n const managing = state.allowProviderManagement\r\n ? ([\r\n compact ? 'Alt+A add' : 'Alt+A add BYOK',\r\n // \"remove BYOK\" survives compact: `Alt+D` is the one chord here that\r\n // deletes something, and \"remove\" alone does not say what.\r\n state.hasRemovableProviders ? 'Alt+D remove BYOK' : undefined,\r\n state.editableProviderId\r\n ? compact\r\n ? 'Alt+R refresh'\r\n : `Alt+R refresh ${state.editableProviderId}`\r\n : undefined,\r\n state.editableProviderId ? 'Alt+M add model' : undefined,\r\n ].filter(Boolean) as string[])\r\n : [];\r\n\r\n return managing.length > 0\r\n ? [choosing.join(' · '), managing.join(' · ')]\r\n : [choosing.join(' · ')];\r\n}\r\n","import { useMemo, useState } from 'react';\r\nimport { ListPicker } from './ListPicker.js';\r\nimport type { EffortLevel, EffortResult } from '../../commands/effort.js';\r\n\r\nconst DESCRIPTIONS: Record<EffortLevel, string> = {\r\n low: 'Fast responses with lighter reasoning',\r\n medium: 'Balanced reasoning for everyday tasks',\r\n high: 'Deeper reasoning for complex work',\r\n xhigh: 'Extended reasoning for difficult problems',\r\n max: 'Maximum reasoning depth for the hardest tasks',\r\n};\r\n\r\ninterface EffortPickerProps {\r\n current?: EffortLevel;\r\n availableLevels: readonly EffortLevel[];\r\n onSelect: (level: EffortLevel) => EffortResult;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function EffortPicker({ current, availableLevels, onSelect, onCancel }: EffortPickerProps) {\r\n const [error, setError] = useState<string>();\r\n\r\n const items = useMemo(\r\n () =>\r\n availableLevels.map((level) => ({\r\n key: level,\r\n label: `${level.padEnd(6)} ${DESCRIPTIONS[level]}`,\r\n note: level === current ? '(current)' : undefined,\r\n accent: level === current,\r\n })),\r\n [availableLevels, current],\r\n );\r\n\r\n return (\r\n <ListPicker\r\n title=\"Set effort level\"\r\n subtitle=\"Choose how much reasoning Book uses on future requests.\"\r\n items={items}\r\n initialIndex={Math.max(0, current ? availableLevels.indexOf(current) : 0)}\r\n enterHint=\"save\"\r\n error={error}\r\n onSelect={(index) => {\r\n const level = availableLevels[index];\r\n if (!level) return;\r\n const result = onSelect(level);\r\n setError(\r\n result.ok ? undefined : (result.error ?? 'Could not save the selected effort level.'),\r\n );\r\n }}\r\n onCancel={onCancel}\r\n />\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport type { Key } from 'ink';\r\nimport { useEffect, useMemo } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\n\r\n/**\r\n * One row. The caller formats `label` — padding, columns, whatever the list\r\n * needs — and `ListPicker` owns the marker, the colours and the window.\r\n */\r\nexport interface ListPickerItem {\r\n /** React key; also the default filter text. */\r\n key: string;\r\n label: string;\r\n /** Shown indented under the row, only while it is selected. */\r\n detail?: string;\r\n /** Appended to the label, e.g. `(current)` or `(unavailable)`. */\r\n note?: string;\r\n /** The row that is already in effect: coloured `brand` when not selected. */\r\n accent?: boolean;\r\n /** Render unselected rows subtle rather than as body text. */\r\n muted?: boolean;\r\n /** Dimmed, and Enter refuses it. */\r\n disabled?: boolean;\r\n /** Matched against the typed filter when `filterable`. Defaults to `label`. */\r\n filterText?: string;\r\n}\r\n\r\ninterface ListPickerProps {\r\n title: string;\r\n subtitle?: string;\r\n items: readonly ListPickerItem[];\r\n /** Shown in place of the list when `items` is empty. */\r\n emptyText?: string;\r\n /** Where the cursor starts, and where it returns when this value changes. */\r\n initialIndex?: number;\r\n /** Rows drawn at once. Longer lists window around the cursor and page. */\r\n maxVisible?: number;\r\n width?: number;\r\n marginX?: number;\r\n /** The verb after Enter — \"save\", \"resume\", \"sign in\". */\r\n enterHint: string;\r\n /**\r\n * The verb after Esc. Dialogs used to pick their own — cancel, back, close,\r\n * not now — so the same key was described four ways depending on which one\r\n * you had open. `cancel` is the default because abandoning the choice is what\r\n * Esc does in a picker; override only where it genuinely returns to a\r\n * previous step, which is the one case a different word earns.\r\n */\r\n escHint?: string;\r\n /** Extra chords to advertise, already formatted: `R reset to inherit`. */\r\n extraHints?: string;\r\n /** Tab as \"next row\". Off by default: Tab means completion in the composer. */\r\n tabMovesNext?: boolean;\r\n /** Let printable keys filter the list. */\r\n filterable?: boolean;\r\n error?: string;\r\n /** Rendered above the hint line — \"Restoring...\". */\r\n status?: string;\r\n /** Stop taking keys without unmounting — a picker waiting on its own work. */\r\n isActive?: boolean;\r\n onSelect: (index: number) => void;\r\n onCancel: () => void;\r\n /**\r\n * Component-specific keys. Return `true` to claim the keypress; `ListPicker`\r\n * gives it first refusal on everything except Esc, so a picker can bind `R`\r\n * without reimplementing the cursor. Receives the batch-safe row index.\r\n */\r\n onKey?: (input: string, key: Key, index: number) => boolean;\r\n}\r\n\r\n/**\r\n * The list dialog every picker was rebuilding.\r\n *\r\n * Seven components carried their own copy of \"cursor, wrap on the arrows, Enter\r\n * acts, Esc leaves, and a dim hint line at the bottom\". They drifted, in the\r\n * ways duplicated code drifts: `SessionPicker` wrapped its cursor over every\r\n * session while drawing only the first twelve, so past the twelfth nothing was\r\n * highlighted and Enter resumed a session that was never on screen; `LoginPicker`\r\n * marked its selection with `❯` after the rest of the TUI had settled on `›`;\r\n * none of them paged, so a long list could only be walked one row at a time.\r\n *\r\n * The cursor lives in `useKeyState`, so every adopter is batch-safe against the\r\n * paste and key-repeat case (#165) without having to remember to be.\r\n */\r\nexport function ListPicker({\r\n title,\r\n subtitle,\r\n items,\r\n emptyText = '(nothing to choose from)',\r\n initialIndex = 0,\r\n maxVisible = 10,\r\n width,\r\n marginX,\r\n enterHint,\r\n escHint = 'cancel',\r\n extraHints,\r\n tabMovesNext = false,\r\n filterable = false,\r\n error,\r\n status,\r\n isActive = true,\r\n onSelect,\r\n onCancel,\r\n onKey,\r\n}: ListPickerProps) {\r\n const theme = useTheme();\r\n const density = useDensityMetrics();\r\n const [filter, setFilter, currentFilter] = useKeyState('');\r\n const [selected, setSelected, currentSelected] = useKeyState(initialIndex);\r\n\r\n const visibleItems = useMemo(() => {\r\n const needle = filter.trim().toLowerCase();\r\n if (!needle) return items;\r\n return items.filter((item) => (item.filterText ?? item.label).toLowerCase().includes(needle));\r\n }, [filter, items]);\r\n\r\n // Re-home the cursor when the caller's idea of \"current\" moves, and keep it\r\n // inside a list that just got shorter — a filter keystroke can strand it past\r\n // the end, which is how Enter ends up acting on nothing.\r\n //\r\n // The first effect clamps against `visibleItems` without depending on it, so\r\n // items must be present at mount. Every adopter builds them synchronously; an\r\n // adopter that loaded them asynchronously with a non-zero `initialIndex`\r\n // would clamp against an empty list and never re-run.\r\n useEffect(() => {\r\n setSelected(Math.max(0, Math.min(initialIndex, visibleItems.length - 1)));\r\n }, [initialIndex, setSelected]);\r\n useEffect(() => {\r\n if (currentSelected() > visibleItems.length - 1) {\r\n setSelected(Math.max(0, visibleItems.length - 1));\r\n }\r\n }, [visibleItems.length, currentSelected, setSelected]);\r\n\r\n const move = (next: number) => {\r\n if (visibleItems.length === 0) return;\r\n setSelected(((next % visibleItems.length) + visibleItems.length) % visibleItems.length);\r\n };\r\n // Paging clamps rather than wraps. Page-Down on the last screen of a long list\r\n // should land on the end, not spring back to the top.\r\n const page = (delta: number) => {\r\n if (visibleItems.length === 0) return;\r\n setSelected(Math.max(0, Math.min(visibleItems.length - 1, currentSelected() + delta)));\r\n };\r\n\r\n useInput(\r\n (input, key) => {\r\n if (key.escape) return onCancel();\r\n if (onKey?.(input, key, currentSelected())) return;\r\n if (key.upArrow) return move(currentSelected() - 1);\r\n if (key.downArrow || (tabMovesNext && key.tab && !key.shift)) {\r\n return move(currentSelected() + 1);\r\n }\r\n if (tabMovesNext && key.tab && key.shift) return move(currentSelected() - 1);\r\n if (key.pageUp) return page(-maxVisible);\r\n if (key.pageDown) return page(maxVisible);\r\n if (key.return) {\r\n const item = visibleItems[currentSelected()];\r\n if (!item || item.disabled) return;\r\n onSelect(items.indexOf(item));\r\n return;\r\n }\r\n if (!filterable || key.ctrl || key.meta) return;\r\n if (key.backspace || key.delete) {\r\n setFilter(currentFilter().slice(0, -1));\r\n return;\r\n }\r\n if (input && input >= ' ') setFilter(currentFilter() + input);\r\n },\r\n { isActive },\r\n );\r\n\r\n // Centre the cursor once the list is longer than the window, and stop the\r\n // window running off the end.\r\n const start =\r\n visibleItems.length <= maxVisible\r\n ? 0\r\n : Math.max(\r\n 0,\r\n Math.min(selected - Math.floor(maxVisible / 2), visibleItems.length - maxVisible),\r\n );\r\n const window = visibleItems.slice(start, start + maxVisible);\r\n const hidden = visibleItems.length - window.length;\r\n\r\n return (\r\n <SoftPanel tone=\"brand\" width={width} marginX={marginX}>\r\n <PanelTitle>{title}</PanelTitle>\r\n {subtitle ? <Text color={theme.subtle}>{subtitle}</Text> : null}\r\n {filterable && filter ? <Text color={theme.subtle}>filter: {filter}</Text> : null}\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {visibleItems.length === 0 ? (\r\n <Text color={theme.subtle}>{filter ? '(no matches)' : emptyText}</Text>\r\n ) : (\r\n window.map((item, offset) => {\r\n const index = start + offset;\r\n const isSelected = index === selected;\r\n return (\r\n <Box key={item.key} flexDirection=\"column\">\r\n <SelectionRow selected={isSelected} width={width ? width - 4 : undefined}>\r\n <Text\r\n color={\r\n item.disabled\r\n ? theme.subtle\r\n : isSelected\r\n ? theme.selectionText\r\n : item.accent\r\n ? theme.brand\r\n : item.muted\r\n ? theme.subtle\r\n : theme.text\r\n }\r\n bold={(isSelected || item.accent) && !item.disabled}\r\n dimColor={item.disabled}\r\n >\r\n {isSelected ? '›' : ' '} {item.label}\r\n {item.note ? ` ${item.note}` : ''}\r\n </Text>\r\n </SelectionRow>\r\n {isSelected && item.detail ? (\r\n <Text color={theme.subtle} dimColor>\r\n {' '}\r\n {item.detail}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n })\r\n )}\r\n {hidden > 0 ? <Text color={theme.subtle}>+{hidden} more</Text> : null}\r\n </Box>\r\n {status ? <Text color={theme.brand}>{status}</Text> : null}\r\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\r\n {density.showOptionalHelp ? (\r\n <Text color={theme.subtle} dimColor>\r\n {[\r\n '↑↓ select',\r\n visibleItems.length > maxVisible ? 'PgUp/PgDn page' : undefined,\r\n filterable ? 'type to filter' : undefined,\r\n `Enter ${enterHint}`,\r\n extraHints,\r\n `Esc ${escHint}`,\r\n ]\r\n .filter(Boolean)\r\n .join(' · ')}\r\n </Text>\r\n ) : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import { useMemo, useState } from 'react';\r\nimport { ListPicker } from './ListPicker.js';\r\nimport type { PermissionMode } from '../../types/runtime.js';\r\n\r\nexport interface PermissionModeSelectionResult {\r\n ok: boolean;\r\n error?: string;\r\n}\r\n\r\ninterface PermissionModePickerProps {\r\n current: PermissionMode;\r\n availableModes: readonly PermissionMode[];\r\n onSelect: (mode: PermissionMode) => PermissionModeSelectionResult;\r\n onCancel: () => void;\r\n}\r\n\r\nconst DESCRIPTIONS: Record<PermissionMode, string> = {\r\n default: 'Ask according to configured permission rules',\r\n auto: 'Automatically approve eligible tool calls',\r\n plan: 'Plan changes before applying them',\r\n 'accept-edits': 'Automatically approve file edits',\r\n dontAsk: 'Deny calls that would require prompting',\r\n bypassPermissions: 'Run without permission checks',\r\n};\r\n\r\nexport function PermissionModePicker({\r\n current,\r\n availableModes,\r\n onSelect,\r\n onCancel,\r\n}: PermissionModePickerProps) {\r\n const [error, setError] = useState<string>();\r\n\r\n const items = useMemo(\r\n () =>\r\n availableModes.map((mode) => ({\r\n key: mode,\r\n label: `${mode.padEnd(18)} ${DESCRIPTIONS[mode]}`,\r\n note: mode === current ? '(current)' : undefined,\r\n accent: mode === current,\r\n })),\r\n [availableModes, current],\r\n );\r\n\r\n return (\r\n <ListPicker\r\n title=\"Default permission mode\"\r\n subtitle=\"Choose the mode used when a run does not specify one.\"\r\n items={items}\r\n initialIndex={Math.max(0, availableModes.indexOf(current))}\r\n enterHint=\"save globally\"\r\n error={error}\r\n onSelect={(index) => {\r\n const mode = availableModes[index];\r\n if (!mode) return;\r\n const result = onSelect(mode);\r\n setError(\r\n result.ok ? undefined : (result.error ?? 'Could not save the default permission mode.'),\r\n );\r\n }}\r\n onCancel={onCancel}\r\n />\r\n );\r\n}\r\n","import { useMemo, useState } from 'react';\r\nimport { ListPicker } from './ListPicker.js';\r\n\r\nexport interface ThemeSelectionResult {\r\n ok: boolean;\r\n error?: string;\r\n}\r\n\r\ninterface ThemePickerProps {\r\n current: string;\r\n customThemes?: readonly string[];\r\n onSelect: (name: string) => ThemeSelectionResult;\r\n onCancel: () => void;\r\n}\r\n\r\nconst BUILTIN_THEMES = [\r\n { name: 'apple', description: 'Near-black neutrals with one blue accent' },\r\n { name: 'dark', description: 'Warm charcoal and muted sage' },\r\n { name: 'light', description: 'Soft parchment with grounded contrast' },\r\n { name: 'auto', description: 'Follow the terminal background' },\r\n { name: 'catppuccin', description: 'Soothing pastel mocha' },\r\n { name: 'nord', description: 'Arctic and glacial slate' },\r\n { name: 'gruvbox', description: 'Warm retro earthy dark' },\r\n { name: 'solarized-dark', description: 'Engineered low-fatigue teal' },\r\n] as const;\r\n\r\nconst NO_CUSTOM_THEMES: readonly string[] = [];\r\n\r\nexport function ThemePicker({\r\n current,\r\n customThemes = NO_CUSTOM_THEMES,\r\n onSelect,\r\n onCancel,\r\n}: ThemePickerProps) {\r\n const options = useMemo(\r\n () => [\r\n ...BUILTIN_THEMES,\r\n ...customThemes\r\n .filter((name) => !BUILTIN_THEMES.some((builtin) => builtin.name === name))\r\n .map((name) => ({ name, description: 'Project theme' })),\r\n ],\r\n [customThemes],\r\n );\r\n const [error, setError] = useState<string>();\r\n\r\n const items = useMemo(\r\n () =>\r\n options.map((option) => ({\r\n key: option.name,\r\n label: `${option.name.padEnd(16)} ${option.description}`,\r\n note: option.name === current ? '(current)' : undefined,\r\n accent: option.name === current,\r\n })),\r\n [current, options],\r\n );\r\n\r\n return (\r\n <ListPicker\r\n title=\"Choose theme\"\r\n subtitle=\"Select a palette for this workspace.\"\r\n items={items}\r\n initialIndex={Math.max(\r\n 0,\r\n options.findIndex((option) => option.name === current),\r\n )}\r\n enterHint=\"save\"\r\n error={error}\r\n onSelect={(index) => {\r\n const option = options[index];\r\n if (!option) return;\r\n const result = onSelect(option.name);\r\n setError(result.ok ? undefined : (result.error ?? 'Could not save the selected theme.'));\r\n }}\r\n onCancel={onCancel}\r\n />\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { floatingFrameMetrics, PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\nimport { displayWidth, truncateDisplay } from './word-wrap.js';\r\n\r\nexport type ConfigSection =\r\n 'model' | 'compact-model' | 'effort' | 'theme' | 'agents' | 'skills' | 'permission-mode';\r\n\r\ninterface ConfigMenuProps {\r\n model: string;\r\n compactModel?: string;\r\n effort?: string;\r\n themeName: string;\r\n memoryAutoSave: boolean;\r\n showThinking: boolean;\r\n startupAnimation?: boolean;\r\n agentCount: number;\r\n skillCount: number;\r\n defaultPermissionMode: string;\r\n terminalWidth?: number;\r\n /**\r\n * Row the cursor starts on. The menu closes while a sub-picker is open and\r\n * remounts when that picker hands control back, so without this the return\r\n * trip always landed on Model — the user pressed `S`, cancelled, and found\r\n * the cursor four rows above where they had been.\r\n */\r\n initialSelection?: number;\r\n onOpen: (section: ConfigSection, rowIndex: number) => void;\r\n onToggleMemory: () => void;\r\n onToggleThinking: () => void;\r\n onToggleStartupAnimation?: () => void;\r\n onCancel: () => void;\r\n}\r\n\r\n/**\r\n * One table drives the cursor, the accelerator keys, and the letter each row\r\n * prints. The letters used to live in a separate `if` chain: five of the nine\r\n * were advertised nowhere, `memory` had no letter at all, and two of them (`i`,\r\n * `f`) flipped a setting on a row the cursor was not sitting on — so the only\r\n * feedback was a value changing somewhere else on the screen. Deriving the key\r\n * and its label from the same row is what stops a shortcut from drifting away\r\n * from the thing it acts on.\r\n *\r\n * `memory` keeps no accelerator rather than being given a contrived one; every\r\n * other free letter reads as a worse lie than a blank does. It is still\r\n * reachable with the arrows, and the blank column says so honestly.\r\n */\r\nconst ROWS = [\r\n { row: 'model', key: 'm' },\r\n { row: 'compact-model', key: 'c' },\r\n { row: 'effort', key: 'e' },\r\n { row: 'thinking', key: 'i' },\r\n { row: 'startup-animation', key: 'f' },\r\n { row: 'theme', key: 't' },\r\n { row: 'permission-mode', key: 'p' },\r\n { row: 'agents', key: 'a' },\r\n { row: 'skills', key: 's' },\r\n { row: 'memory' },\r\n] as const satisfies ReadonlyArray<{ row: string; key?: string }>;\r\ntype Row = (typeof ROWS)[number]['row'];\r\n\r\n/**\r\n * The cursor marker, the accelerator, and the gaps around them, as the string\r\n * the row actually prints. Measuring it beats a hand-kept column count: the\r\n * budget then cannot drift away from the prefix it is supposed to describe.\r\n */\r\nfunction rowPrefix(selected: boolean, key?: string): string {\r\n return `${selected ? '›' : ' '} ${key ? key.toUpperCase() : ' '} `;\r\n}\r\n\r\nexport function ConfigMenu({\r\n model,\r\n compactModel,\r\n effort,\r\n themeName,\r\n memoryAutoSave,\r\n showThinking,\r\n startupAnimation = true,\r\n agentCount,\r\n skillCount,\r\n defaultPermissionMode,\r\n terminalWidth = 80,\r\n initialSelection = 0,\r\n onOpen,\r\n onToggleMemory,\r\n onToggleThinking,\r\n onToggleStartupAnimation = () => {},\r\n onCancel,\r\n}: ConfigMenuProps) {\r\n const theme = useTheme();\r\n // An accelerator sets the cursor and acts on it in the same keypress, so the\r\n // handler cannot read `selected` back from state — React has not flushed it.\r\n const [selected, moveSelection, currentSelected] = useKeyState(\r\n Math.min(Math.max(0, initialSelection), ROWS.length - 1),\r\n );\r\n const frame = floatingFrameMetrics(terminalWidth);\r\n const contentWidth = Math.max(16, frame.width - 4);\r\n\r\n const activate = (row: Row, index: number) => {\r\n if (row === 'memory') onToggleMemory();\r\n else if (row === 'thinking') onToggleThinking();\r\n else if (row === 'startup-animation') onToggleStartupAnimation();\r\n else onOpen(row, index);\r\n };\r\n\r\n useInput((input, key) => {\r\n if (key.escape) return onCancel();\r\n // Shift+Tab is back-tab everywhere else it appears; treating a bare\r\n // `key.tab` as \"next\" sent it forward, one row past whatever the user was\r\n // aiming at.\r\n if (key.upArrow || (key.tab && key.shift)) {\r\n moveSelection((currentSelected() - 1 + ROWS.length) % ROWS.length);\r\n return;\r\n }\r\n if (key.downArrow || key.tab) {\r\n moveSelection((currentSelected() + 1) % ROWS.length);\r\n return;\r\n }\r\n if (key.return) {\r\n const index = currentSelected();\r\n activate(ROWS[index].row, index);\r\n return;\r\n }\r\n if (key.ctrl || key.meta) return;\r\n // An accelerator moves the cursor before it acts, so the row that changes is\r\n // the row you are looking at. Pressing `i` used to toggle \"Show thinking\"\r\n // while the highlight sat on \"Model\" four rows above it.\r\n const shortcut = input.toLowerCase();\r\n const index = ROWS.findIndex((entry) => 'key' in entry && entry.key === shortcut);\r\n if (index < 0) return;\r\n moveSelection(index);\r\n activate(ROWS[index].row, index);\r\n });\r\n\r\n // Keyed rather than ordered: `ROWS` owns the order, so the two lists cannot\r\n // fall out of step and leave the cursor pointing at a row it does not render.\r\n const details: Record<Row, { label: string; value: string; description: string }> = {\r\n model: { label: 'Model', value: model, description: 'Default model for the main agent' },\r\n 'compact-model': {\r\n label: 'Compact model',\r\n value: compactModel ?? 'same as main',\r\n description: 'Reducer used only for conversation checkpoints',\r\n },\r\n effort: {\r\n label: 'Effort',\r\n value: effort ?? 'model default',\r\n description: 'Reasoning depth for supported models',\r\n },\r\n thinking: {\r\n label: 'Show thinking',\r\n value: showThinking ? 'on' : 'off',\r\n description: 'Display the model reasoning in the transcript',\r\n },\r\n 'startup-animation': {\r\n label: 'Startup fire',\r\n value: startupAnimation ? 'on' : 'off',\r\n description: 'Burn the terminal into the Book welcome screen',\r\n },\r\n theme: { label: 'Theme', value: themeName, description: 'Terminal color palette' },\r\n 'permission-mode': {\r\n label: 'Default permissions',\r\n value: defaultPermissionMode,\r\n description: 'Mode for runs without an explicit override',\r\n },\r\n agents: {\r\n label: 'Subagent profiles',\r\n value: `${agentCount} available`,\r\n description: 'Choose a model for explorer, patcher, or validator',\r\n },\r\n skills: {\r\n label: 'Skills',\r\n value: `${skillCount} discovered`,\r\n description: 'Control automatic matching and explicit use',\r\n },\r\n memory: {\r\n label: 'Memory auto-capture',\r\n value: memoryAutoSave ? 'on' : 'off',\r\n description: 'Capture useful corrections for approval later',\r\n },\r\n };\r\n\r\n return (\r\n <SoftPanel tone=\"brand\" width={frame.width} marginX={frame.marginX}>\r\n <PanelTitle>Settings</PanelTitle>\r\n <Text color={theme.subtle}>Choose a setting to change.</Text>\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {ROWS.map((entry, index) => {\r\n const item = details[entry.row];\r\n const prefix = rowPrefix(index === selected, 'key' in entry ? entry.key : undefined);\r\n return (\r\n <SelectionRow key={entry.row} selected={index === selected} width={contentWidth}>\r\n {prefix}\r\n {truncateDisplay(\r\n `${item.label.padEnd(22)} ${item.value} — ${item.description}`,\r\n contentWidth - displayWidth(prefix),\r\n )}\r\n </SelectionRow>\r\n );\r\n })}\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n ↑↓ select · Enter choose · or press the letter · Esc close\r\n </Text>\r\n </SoftPanel>\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport type { Skill } from '../../skills.js';\r\nimport type { SkillLifecycleEvent } from '../../skill-registry.js';\r\nimport type { SkillActivation, SkillExecution } from '../../settings.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { stripSgrMouseSequences } from '../mouse.js';\r\nimport { floatingFrameMetrics, PanelTitle, SelectionRow, SoftPanel } from './chrome.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\nconst ACTIVATIONS: readonly SkillActivation[] = ['auto', 'name-only', 'manual', 'off'];\r\nconst EXECUTIONS: readonly SkillExecution[] = ['inherit', 'ask', 'deny'];\r\n\r\nconst ACTIVATION_HELP: Record<SkillActivation, string> = {\r\n auto: 'Name and description are visible; Book may activate it automatically.',\r\n 'name-only': 'Only the name is visible; explicit use remains reliable.',\r\n manual: 'Hidden from automatic matching; invoke it explicitly with $name.',\r\n off: 'Hidden and blocked from invocation.',\r\n};\r\n\r\nconst EXECUTION_HELP: Record<SkillExecution, string> = {\r\n inherit: 'Use the normal workspace and permission policy.',\r\n ask: 'Ask before activating this skill.',\r\n deny: 'Block this skill even when explicitly mentioned.',\r\n};\r\n\r\nexport interface SkillManagerResult {\r\n ok: boolean;\r\n error?: string;\r\n}\r\n\r\ninterface SkillManagerProps {\r\n skills: readonly Skill[];\r\n enabled?: boolean;\r\n watcherError?: string;\r\n lifecycleEvents?: readonly SkillLifecycleEvent[];\r\n activeSkillNames?: readonly string[];\r\n terminalWidth?: number;\r\n maxVisible?: number;\r\n onChangeActivation: (skillName: string, activation: SkillActivation) => SkillManagerResult;\r\n onChangeExecution: (skillName: string, execution: SkillExecution) => SkillManagerResult;\r\n onChangeEnabled: (enabled: boolean) => SkillManagerResult;\r\n onUse: (skill: Skill) => void;\r\n onReload: () => void;\r\n onCancel: () => void;\r\n}\r\n\r\nfunction nextValue<T>(values: readonly T[], current: T): T {\r\n const index = values.indexOf(current);\r\n return values[(index + 1) % values.length] ?? values[0];\r\n}\r\n\r\nexport function SkillManager({\r\n skills,\r\n enabled = true,\r\n watcherError,\r\n lifecycleEvents = [],\r\n activeSkillNames = [],\r\n terminalWidth = 80,\r\n maxVisible = 8,\r\n onChangeActivation,\r\n onChangeExecution,\r\n onChangeEnabled,\r\n onUse,\r\n onReload,\r\n onCancel,\r\n}: SkillManagerProps) {\r\n const theme = useTheme();\r\n // Both of these are read back by the key handler, so they have to survive a\r\n // React batch: Ink hands a whole stdin chunk over at once. With plain state a\r\n // batched `↓`+Space wrote an activation change to the skill above the\r\n // highlighted one, and a batched `/`+letter ran the letter as a command\r\n // instead of typing it into the search field.\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n const [error, setError] = useState<string>();\r\n const [query, setQuery] = useState('');\r\n const [searching, setSearching, isSearching] = useKeyState(false);\r\n const frame = floatingFrameMetrics(terminalWidth);\r\n const contentWidth = Math.max(16, frame.width - 4);\r\n const filteredSkills = useMemo(() => {\r\n const normalized = query.trim().toLowerCase();\r\n if (!normalized) return skills;\r\n return skills.filter((skill) =>\r\n [skill.name, skill.description, skill.source, skill.rootKind, skill.path]\r\n .join(' ')\r\n .toLowerCase()\r\n .includes(normalized),\r\n );\r\n }, [query, skills]);\r\n\r\n useEffect(() => {\r\n setSelected(Math.max(0, Math.min(currentSelected(), filteredSkills.length - 1)));\r\n }, [filteredSkills.length, setSelected, currentSelected]);\r\n\r\n const window = useMemo(() => {\r\n if (filteredSkills.length <= maxVisible) return { start: 0, items: filteredSkills };\r\n const half = Math.floor(maxVisible / 2);\r\n const start = Math.max(0, Math.min(selected - half, filteredSkills.length - maxVisible));\r\n return { start, items: filteredSkills.slice(start, start + maxVisible) };\r\n }, [filteredSkills, maxVisible, selected]);\r\n\r\n useInput((input, key) => {\r\n if (isSearching()) {\r\n if (key.escape || key.return) {\r\n setSearching(false);\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n setQuery((current) => current.slice(0, -1));\r\n return;\r\n }\r\n const typed = stripSgrMouseSequences(input);\r\n if (!key.ctrl && !key.meta && typed && !key.upArrow && !key.downArrow) {\r\n setQuery((current) => current + typed);\r\n }\r\n return;\r\n }\r\n\r\n if (key.escape) return onCancel();\r\n if (input === '/') {\r\n setSearching(true);\r\n setQuery('');\r\n setError(undefined);\r\n return;\r\n }\r\n if (input.toLowerCase() === 'r') {\r\n setError(undefined);\r\n onReload();\r\n return;\r\n }\r\n if (input.toLowerCase() === 'g') {\r\n const result = onChangeEnabled(!enabled);\r\n setError(\r\n result.ok ? undefined : (result.error ?? 'Could not save the global skill setting.'),\r\n );\r\n return;\r\n }\r\n if (filteredSkills.length === 0) return;\r\n if (key.upArrow) {\r\n setSelected((currentSelected() - 1 + filteredSkills.length) % filteredSkills.length);\r\n setError(undefined);\r\n return;\r\n }\r\n if (key.downArrow || key.tab) {\r\n setSelected((currentSelected() + 1) % filteredSkills.length);\r\n setError(undefined);\r\n return;\r\n }\r\n\r\n const skill = filteredSkills[currentSelected()];\r\n if (!skill) return;\r\n if (input === ' ') {\r\n const activation = nextValue(ACTIVATIONS, skill.activation);\r\n const result = onChangeActivation(skill.name, activation);\r\n setError(result.ok ? undefined : (result.error ?? 'Could not save the skill setting.'));\r\n return;\r\n }\r\n if (input.toLowerCase() === 'e') {\r\n const execution = nextValue(EXECUTIONS, skill.execution);\r\n const result = onChangeExecution(skill.name, execution);\r\n setError(result.ok ? undefined : (result.error ?? 'Could not save the consent setting.'));\r\n return;\r\n }\r\n if (key.return) {\r\n if (!enabled) {\r\n setError('Skills are globally disabled. Press G to enable them before use.');\r\n return;\r\n }\r\n if (!skill.valid) {\r\n setError('This skill is invalid. Review its diagnostics before use.');\r\n return;\r\n }\r\n if (skill.activation === 'off' || skill.execution === 'deny') {\r\n setError('This skill is blocked. Change its activation or consent policy before use.');\r\n return;\r\n }\r\n onUse(skill);\r\n }\r\n });\r\n\r\n const active = filteredSkills[selected];\r\n const lastLifecycleEvent = active\r\n ? [...lifecycleEvents].reverse().find((event) => event.skill === active.name)\r\n : undefined;\r\n\r\n return (\r\n <SoftPanel tone=\"brand\" width={frame.width} marginX={frame.marginX}>\r\n <PanelTitle>Manage skills</PanelTitle>\r\n <Text color={enabled ? theme.success : theme.warning}>\r\n {enabled ? 'Enabled' : 'Globally off'} · {skills.length} discovered\r\n {query ? ` · ${filteredSkills.length} matching \"${query}\"` : ''}\r\n </Text>\r\n {searching ? <Text color={theme.brand}>Search: {query || '_'}</Text> : null}\r\n {watcherError ? (\r\n <Text color={theme.warning}>\r\n Watcher: {truncateDisplay(watcherError, Math.max(8, contentWidth - 9))}\r\n </Text>\r\n ) : null}\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {filteredSkills.length === 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n {skills.length === 0\r\n ? 'No skills found in .book, .agents, .claude, or .opencode skill roots.'\r\n : 'No skills match this search.'}\r\n </Text>\r\n ) : (\r\n window.items.map((skill, offset) => {\r\n const index = window.start + offset;\r\n const validity = skill.valid ? 'ok' : 'invalid';\r\n const activeState = activeSkillNames.includes(skill.name) ? 'active' : 'idle';\r\n const row = `${skill.name.padEnd(20)} ${skill.activation.padEnd(9)} ${skill.execution.padEnd(7)} ${activeState.padEnd(6)} ${skill.rootKind}/${skill.source} ${validity}`;\r\n return (\r\n <SelectionRow key={`${skill.source}:${skill.path}`} selected={index === selected}>\r\n {index === selected ? '›' : ' '} {truncateDisplay(row, contentWidth - 2)}\r\n </SelectionRow>\r\n );\r\n })\r\n )}\r\n </Box>\r\n {active ? (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color={theme.text}>\r\n {truncateDisplay(active.description, Math.max(8, contentWidth))}\r\n </Text>\r\n <Text color={theme.text}>{ACTIVATION_HELP[active.activation]}</Text>\r\n <Text color={theme.subtle}>\r\n {active.execution === 'inherit' && active.source === 'project'\r\n ? 'Project instructions require consent unless an InvokeSkill rule already allows them.'\r\n : EXECUTION_HELP[active.execution]}\r\n </Text>\r\n <Text color={theme.subtle}>\r\n {active.version} · {active.entryByteSize} bytes · {active.resources.length} resources\r\n {active.shadowed.length ? ` · shadows ${active.shadowed.length}` : ''}\r\n </Text>\r\n {active.whenToUse ? (\r\n <Text color={theme.subtle}>\r\n Trigger: {truncateDisplay(active.whenToUse, Math.max(8, contentWidth - 9))}\r\n </Text>\r\n ) : null}\r\n {active.compatibility ? (\r\n <Text color={theme.subtle}>\r\n Compatibility: {truncateDisplay(active.compatibility, Math.max(8, contentWidth - 15))}\r\n </Text>\r\n ) : null}\r\n {active.resources.slice(0, 2).map((resource) => (\r\n <Text key={resource.relativePath} color={theme.subtle}>\r\n Resource: {truncateDisplay(resource.relativePath, Math.max(8, contentWidth - 10))}\r\n </Text>\r\n ))}\r\n {active.resources.length > 2 ? (\r\n <Text color={theme.subtle}>+{active.resources.length - 2} more resources</Text>\r\n ) : null}\r\n {active.shadowed.slice(0, 2).map((shadowed) => (\r\n <Text key={shadowed.path} color={theme.warning}>\r\n Shadows: {truncateDisplay(shadowed.path, Math.max(8, contentWidth - 9))}\r\n </Text>\r\n ))}\r\n {active.shadowed.length > 2 ? (\r\n <Text color={theme.warning}>+{active.shadowed.length - 2} more shadowed sources</Text>\r\n ) : null}\r\n {active.issues.slice(0, 3).map((issue) => (\r\n <Text\r\n key={`${issue.code}:${issue.message}`}\r\n color={issue.severity === 'error' ? theme.error : theme.warning}\r\n >\r\n {issue.severity}: {truncateDisplay(issue.message, Math.max(8, contentWidth - 9))}\r\n </Text>\r\n ))}\r\n {active.issues.length > 3 ? (\r\n <Text color={theme.warning}>+{active.issues.length - 3} more validation issues</Text>\r\n ) : null}\r\n {lastLifecycleEvent ? (\r\n <Text color={theme.subtle}>\r\n Last event: {lastLifecycleEvent.type}\r\n {typeof lastLifecycleEvent.details?.code === 'string'\r\n ? ` (${lastLifecycleEvent.details.code})`\r\n : ''}\r\n </Text>\r\n ) : null}\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(active.path, contentWidth)}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {/* Two lines, split by what the keys act on. As one line this was eight\r\n chords that did not fit, so Ink wrapped it — and the wrap landed after\r\n a trailing separator, leaving \"Esc close\" stranded on a line of its\r\n own under a dangling \"·\". */}\r\n <Text color={theme.subtle} dimColor>\r\n ↑↓ select · / search · Enter insert · Esc close\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Space activation · E consent · G global · R reload\r\n </Text>\r\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import { useMemo } from 'react';\r\nimport type { ManagedAgentDef } from '../../agents/profiles.js';\r\nimport { floatingFrameMetrics } from './chrome.js';\r\nimport { ListPicker } from './ListPicker.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\ninterface AgentProfilePickerProps {\r\n profiles: readonly ManagedAgentDef[];\r\n parentModel: string;\r\n configuredModels: Readonly<Record<string, string | undefined>>;\r\n terminalWidth?: number;\r\n onSelect: (profile: string) => void;\r\n onReset: (profile: string) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nfunction effectiveModel(\r\n profile: ManagedAgentDef,\r\n parentModel: string,\r\n configuredModels: Readonly<Record<string, string | undefined>>,\r\n): { value: string; inherited: boolean } {\r\n const configured = configuredModels[profile.name];\r\n if (configured === 'inherit') return { value: parentModel, inherited: true };\r\n if (configured && configured !== 'inherit') return { value: configured, inherited: false };\r\n return { value: profile.model ?? parentModel, inherited: true };\r\n}\r\n\r\nexport function AgentProfilePicker({\r\n profiles,\r\n parentModel,\r\n configuredModels,\r\n terminalWidth = 80,\r\n onSelect,\r\n onReset,\r\n onCancel,\r\n}: AgentProfilePickerProps) {\r\n const frame = floatingFrameMetrics(terminalWidth);\r\n const contentWidth = Math.max(16, frame.width - 4);\r\n\r\n const items = useMemo(\r\n () =>\r\n profiles.map((profile) => {\r\n const model = effectiveModel(profile, parentModel, configuredModels);\r\n return {\r\n key: profile.name,\r\n label: truncateDisplay(\r\n `${profile.name.padEnd(12)} ${model.value}${model.inherited ? ' (inherit)' : ''} · ${profile.role} · ${profile.isolation}`,\r\n contentWidth - 2,\r\n ),\r\n detail: profile.description,\r\n };\r\n }),\r\n [configuredModels, contentWidth, parentModel, profiles],\r\n );\r\n\r\n return (\r\n <ListPicker\r\n title=\"Subagent profiles\"\r\n subtitle=\"Select a profile to choose its model for future runs.\"\r\n items={items}\r\n emptyText=\"No profiles discovered.\"\r\n width={frame.width}\r\n marginX={frame.marginX}\r\n tabMovesNext\r\n enterHint=\"choose model\"\r\n extraHints=\"R reset to inherit\"\r\n escHint=\"back\"\r\n onKey={(input, key, index) => {\r\n if (key.ctrl || key.meta) return false;\r\n if (input.toLowerCase() !== 'r') return false;\r\n const profile = profiles[index];\r\n if (profile) onReset(profile.name);\r\n return true;\r\n }}\r\n onSelect={(index) => {\r\n const profile = profiles[index];\r\n if (profile) onSelect(profile.name);\r\n }}\r\n onCancel={onCancel}\r\n />\r\n );\r\n}\r\n","import { useMemo } from 'react';\r\nimport { ListPicker } from './ListPicker.js';\r\nimport type { SessionMeta } from '../../types/sessions.js';\r\nimport { displaySessionName } from '../../session/name.js';\r\n\r\ninterface SessionPickerProps {\r\n sessions: SessionMeta[];\r\n currentSessionId: string;\r\n onPick: (session: SessionMeta) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nfunction formatAge(timestamp: number): string {\r\n const seconds = Math.max(0, Math.floor((Date.now() - timestamp) / 1000));\r\n if (seconds < 60) return 'just now';\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m ago`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h ago`;\r\n return `${Math.floor(hours / 24)}d ago`;\r\n}\r\n\r\nexport function SessionPicker({\r\n sessions,\r\n currentSessionId,\r\n onPick,\r\n onCancel,\r\n}: SessionPickerProps) {\r\n const choices = useMemo(\r\n () => sessions.filter((session) => session.id !== currentSessionId),\r\n [currentSessionId, sessions],\r\n );\r\n\r\n const items = useMemo(\r\n () =>\r\n choices.map((session) => ({\r\n key: session.id,\r\n label: `${displaySessionName(session.name)} · ${formatAge(session.updatedAt)} · ${session.messageCount} messages`,\r\n muted: true,\r\n })),\r\n [choices],\r\n );\r\n\r\n return (\r\n <ListPicker\r\n title=\"Resume conversation\"\r\n items={items}\r\n // This list used to be cut to twelve rows while the cursor still wrapped\r\n // over every session, so past the twelfth nothing was highlighted and\r\n // Enter resumed a conversation that had never been on screen. It windows\r\n // now, and it is the one list long enough to be worth filtering.\r\n maxVisible={12}\r\n filterable\r\n emptyText=\"(no other sessions in this workspace)\"\r\n enterHint=\"resume\"\r\n onSelect={(index) => {\r\n const session = choices[index];\r\n if (session) onPick(session);\r\n }}\r\n onCancel={onCancel}\r\n />\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useMemo, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport type { RewindAction, RewindTarget } from '../../types/sessions.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\ninterface RewindPickerProps {\r\n targets: RewindTarget[];\r\n isRewinding: boolean;\r\n onAction: (\r\n target: RewindTarget,\r\n action: RewindAction,\r\n ) => Promise<{ ok: true } | { ok: false; error: string }>;\r\n onCancel: () => void;\r\n}\r\n\r\ntype ActionChoice = {\r\n action: RewindAction | 'cancel';\r\n label: string;\r\n description: string;\r\n};\r\n\r\nconst ACTIONS: ActionChoice[] = [\r\n {\r\n action: 'conversation',\r\n label: 'Conversation',\r\n description: 'Remove this prompt and newer conversation, then restore the prompt.',\r\n },\r\n {\r\n action: 'code',\r\n label: 'Code',\r\n description: 'Restore workspace files while keeping the conversation.',\r\n },\r\n {\r\n action: 'both',\r\n label: 'Both',\r\n description: 'Restore workspace files and conversation together.',\r\n },\r\n { action: 'cancel', label: 'Cancel', description: 'Return without changing anything.' },\r\n];\r\n\r\nfunction formatAge(timestamp: number): string {\r\n const seconds = Math.max(0, Math.floor((Date.now() - timestamp) / 1000));\r\n if (seconds < 60) return 'just now';\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m ago`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h ago`;\r\n return `${Math.floor(hours / 24)}d ago`;\r\n}\r\n\r\nfunction promptPreview(prompt: string): string {\r\n const singleLine = prompt.replace(/\\s+/g, ' ').trim();\r\n return singleLine.length <= 72 ? singleLine : `${singleLine.slice(0, 69)}...`;\r\n}\r\n\r\nexport function RewindPicker({ targets, isRewinding, onAction, onCancel }: RewindPickerProps) {\r\n const theme = useTheme();\r\n const density = useDensityMetrics();\r\n // Stage and both cursors are read back by the key handler, so Enter that\r\n // advances the stage and Enter that acts on the new stage can arrive together.\r\n const [stage, setStage, currentStage] = useKeyState<'target' | 'action'>('target');\r\n const [selectedTarget, setSelectedTarget, currentTarget] = useKeyState(0);\r\n const [selectedAction, setSelectedAction, currentAction] = useKeyState(0);\r\n const [error, setError] = useState<string | null>(null);\r\n const target = targets[selectedTarget];\r\n const visibleTargets = useMemo(() => {\r\n const start = Math.max(0, Math.min(selectedTarget - 5, Math.max(0, targets.length - 12)));\r\n return { start, items: targets.slice(start, start + 12) };\r\n }, [selectedTarget, targets]);\r\n\r\n const chooseAction = async () => {\r\n // Called from the key handler, so the target comes from the ref as well:\r\n // an arrow, the Enter that picks a target and the Enter that acts on it can\r\n // all land in one batch, and `target` would still be the render-time row.\r\n const chosen = targets[currentTarget()];\r\n const choice = ACTIONS[currentAction()];\r\n if (!chosen || !choice || isRewinding) return;\r\n if (choice.action === 'cancel') return onCancel();\r\n if ((choice.action === 'code' || choice.action === 'both') && !chosen.codeAvailable) return;\r\n setError(null);\r\n const result = await onAction(chosen, choice.action);\r\n if (!result.ok) setError(result.error);\r\n };\r\n\r\n useInput(\r\n (_input, key) => {\r\n if (isRewinding) return;\r\n if (key.escape) {\r\n if (currentStage() === 'action') {\r\n setStage('target');\r\n setError(null);\r\n } else {\r\n onCancel();\r\n }\r\n return;\r\n }\r\n if (currentStage() === 'target') {\r\n if (targets.length === 0) return;\r\n if (key.upArrow) setSelectedTarget((currentTarget() - 1 + targets.length) % targets.length);\r\n if (key.downArrow) setSelectedTarget((currentTarget() + 1) % targets.length);\r\n if (key.return) {\r\n setSelectedAction(0);\r\n setError(null);\r\n setStage('action');\r\n }\r\n return;\r\n }\r\n if (key.upArrow) setSelectedAction((currentAction() - 1 + ACTIONS.length) % ACTIONS.length);\r\n if (key.downArrow) setSelectedAction((currentAction() + 1) % ACTIONS.length);\r\n if (key.return) void chooseAction();\r\n },\r\n { isActive: true },\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.border} paddingX={1}>\r\n <Text bold color={theme.brand}>\r\n Rewind\r\n </Text>\r\n {stage === 'target' ? (\r\n targets.length === 0 ? (\r\n <Text color={theme.subtle}>(no user prompts to rewind)</Text>\r\n ) : (\r\n visibleTargets.items.map((choice, visibleIndex) => {\r\n const index = visibleTargets.start + visibleIndex;\r\n const selected = index === selectedTarget;\r\n return (\r\n <Text\r\n key={choice.id}\r\n backgroundColor={selected ? theme.surfaceActive : undefined}\r\n color={selected ? theme.selectionText : theme.subtle}\r\n bold={selected}\r\n >\r\n {selected ? '›' : ' '} {promptPreview(choice.prompt)} ·{' '}\r\n {formatAge(choice.timestamp)} ·{' '}\r\n {choice.codeAvailable ? 'code ready' : 'conversation only'}\r\n </Text>\r\n );\r\n })\r\n )\r\n ) : (\r\n <>\r\n <Text color={theme.text}>{promptPreview(target?.prompt ?? '')}</Text>\r\n {ACTIONS.map((choice, index) => {\r\n const selected = index === selectedAction;\r\n const disabled =\r\n (choice.action === 'code' || choice.action === 'both') && !target?.codeAvailable;\r\n return (\r\n <Box key={choice.action} flexDirection=\"column\">\r\n <Text\r\n backgroundColor={selected ? theme.surfaceActive : undefined}\r\n color={disabled ? theme.subtle : selected ? theme.selectionText : theme.text}\r\n bold={selected && !disabled}\r\n dimColor={disabled}\r\n >\r\n {selected ? '›' : ' '} {choice.label}\r\n {disabled ? ' (unavailable)' : ''}\r\n </Text>\r\n {selected ? (\r\n <Text color={disabled ? theme.error : theme.subtle} dimColor={!disabled}>\r\n {' '}\r\n {disabled ? target?.codeUnavailableReason : choice.description}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n })}\r\n </>\r\n )}\r\n {isRewinding ? <Text color={theme.brand}>Restoring...</Text> : null}\r\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\r\n {density.showOptionalHelp ? (\r\n <Text color={theme.subtle} dimColor>\r\n ↑↓ select · Enter confirm · Esc back\r\n </Text>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, measureElement, useInput, useStdin, useStdout, type DOMElement } from 'ink';\r\nimport {\r\n useCallback,\r\n useEffect,\r\n useLayoutEffect,\r\n memo,\r\n useMemo,\r\n useRef,\r\n useState,\r\n type ReactNode,\r\n} from 'react';\r\nimport {\r\n createTranscriptScrollState,\r\n getTranscriptHalfPageRows,\r\n getTranscriptPageRows,\r\n getTranscriptWheelDrainRows,\r\n reconcileTranscriptScroll,\r\n scrollTranscriptBy,\r\n scrollTranscriptToEnd,\r\n scrollTranscriptToStart,\r\n type TranscriptMetrics,\r\n type TranscriptScrollState,\r\n} from '../transcript-scroll.js';\r\nimport { parseSgrMouseEvents, stripSgrMouseSequences } from '../mouse.js';\r\nimport { writeClipboard } from '../clipboard.js';\r\nimport { getFrameLines, getLastCursorPosition, subscribeToFrameUpdates } from '../frame-buffer.js';\r\nimport { paintSelection, restoreSelection } from '../selection-highlight.js';\r\nimport {\r\n extractSelectedText,\r\n normalizeSelectionRange,\r\n type SelectionCell,\r\n type SelectionRange,\r\n} from '../text-selection.js';\r\nimport {\r\n TranscriptHistoryContext,\r\n TranscriptLayoutContext,\r\n TranscriptViewportContext,\r\n type TranscriptHistoryLoader,\r\n type TranscriptViewportSnapshot,\r\n type TranscriptViewportStore,\r\n} from '../transcript-layout.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { setTranscriptScrollHint } from '../ink-scroll-renderer.js';\r\nimport { markTranscriptScrollActivity } from '../scroll-activity.js';\r\nimport {\r\n ToolRowInteractionContext,\r\n type ToolSummaryRowRegistration,\r\n} from './tool-row-interactions.js';\r\n\r\ninterface TranscriptViewProps {\r\n children: ReactNode;\r\n height?: number;\r\n width?: number;\r\n isActive?: boolean;\r\n followRequestKey?: number;\r\n /** Structural layout changes outside transcript components that self-report height updates. */\r\n layoutRevision?: unknown;\r\n onToggleTool?: (toolId: string, expanded: boolean) => void;\r\n onNotify?: (message: string) => void;\r\n onRedrawViewport?: () => void;\r\n}\r\n\r\nconst INITIAL_METRICS: TranscriptMetrics = { contentRows: 0, viewportRows: 1 };\r\nconst MOUSE_WHEEL_ROWS = 3;\r\n\r\ninterface DragState {\r\n anchor: SelectionCell;\r\n focus: SelectionCell;\r\n dragged: boolean;\r\n}\r\n\r\nconst selectionRangesEqual = (left: SelectionRange, right: SelectionRange): boolean =>\r\n left.start.x === right.start.x &&\r\n left.start.y === right.start.y &&\r\n left.end.x === right.end.x &&\r\n left.end.y === right.end.y;\r\n\r\nfunction getAbsolutePosition(node: DOMElement): { x: number; y: number } | undefined {\r\n let current: DOMElement | undefined = node;\r\n let x = 0;\r\n let y = 0;\r\n while (current?.parentNode) {\r\n if (!current.yogaNode) return undefined;\r\n x += current.yogaNode.getComputedLeft();\r\n y += current.yogaNode.getComputedTop();\r\n current = current.parentNode;\r\n }\r\n return { x, y };\r\n}\r\n\r\ninterface TranscriptContentProps {\r\n children: ReactNode;\r\n interactionRegistry: {\r\n register: (registration: ToolSummaryRowRegistration) => () => void;\r\n };\r\n historyRegistry: {\r\n register: (loader: TranscriptHistoryLoader) => () => void;\r\n };\r\n viewportStore: TranscriptViewportStore;\r\n onLayoutChange: () => void;\r\n}\r\n\r\nconst TranscriptContent = memo(function TranscriptContent({\r\n children,\r\n interactionRegistry,\r\n historyRegistry,\r\n viewportStore,\r\n onLayoutChange,\r\n}: TranscriptContentProps) {\r\n return (\r\n <TranscriptLayoutContext.Provider value={onLayoutChange}>\r\n <TranscriptHistoryContext.Provider value={historyRegistry}>\r\n <TranscriptViewportContext.Provider value={viewportStore}>\r\n <ToolRowInteractionContext.Provider value={interactionRegistry}>\r\n {children}\r\n </ToolRowInteractionContext.Provider>\r\n </TranscriptViewportContext.Provider>\r\n </TranscriptHistoryContext.Provider>\r\n </TranscriptLayoutContext.Provider>\r\n );\r\n});\r\n\r\nexport function TranscriptView({\r\n children,\r\n height,\r\n width,\r\n isActive = true,\r\n followRequestKey = 0,\r\n layoutRevision,\r\n onToggleTool,\r\n onNotify,\r\n onRedrawViewport,\r\n}: TranscriptViewProps) {\r\n const theme = useTheme();\r\n const { internal_eventEmitter } = useStdin();\r\n const { stdout } = useStdout();\r\n const viewportRef = useRef<DOMElement>(null);\r\n const contentRef = useRef<DOMElement>(null);\r\n const metricsRef = useRef(INITIAL_METRICS);\r\n const stateRef = useRef<TranscriptScrollState>(createTranscriptScrollState());\r\n const previousContentRowsRef = useRef(0);\r\n const previousFollowRequestRef = useRef(followRequestKey);\r\n const pendingWheelRowsRef = useRef(0);\r\n const wheelImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\r\n const layoutMeasureImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\r\n const onToggleToolRef = useRef(onToggleTool);\r\n const onNotifyRef = useRef(onNotify);\r\n const onRedrawViewportRef = useRef(onRedrawViewport);\r\n const dragRef = useRef<DragState | null>(null);\r\n const selectionRef = useRef<SelectionRange | null>(null);\r\n const repaintImmediateRef = useRef<ReturnType<typeof setImmediate> | null>(null);\r\n const [renderedScrollTop, setRenderedScrollTop] = useState(0);\r\n const [followBottom, setFollowBottom] = useState(true);\r\n const [hasNewOutput, setHasNewOutput] = useState(false);\r\n const historyLoaderRef = useRef<TranscriptHistoryLoader | null>(null);\r\n const viewportListenersRef = useRef(new Set<() => void>());\r\n const viewportRevisionRef = useRef(0);\r\n const viewportBucketRef = useRef('');\r\n const toolRowsRef = useRef(new Map<string, ToolSummaryRowRegistration>());\r\n const interactionRegistry = useMemo(\r\n () => ({\r\n register: (registration: ToolSummaryRowRegistration) => {\r\n toolRowsRef.current.set(registration.id, registration);\r\n return () => {\r\n if (toolRowsRef.current.get(registration.id) === registration) {\r\n toolRowsRef.current.delete(registration.id);\r\n }\r\n };\r\n },\r\n }),\r\n [],\r\n );\r\n const historyRegistry = useMemo(\r\n () => ({\r\n register: (loader: TranscriptHistoryLoader) => {\r\n historyLoaderRef.current = loader;\r\n return () => {\r\n if (historyLoaderRef.current === loader) historyLoaderRef.current = null;\r\n };\r\n },\r\n }),\r\n [],\r\n );\r\n const viewportSnapshotRef = useRef<{\r\n revision: number;\r\n snapshot: TranscriptViewportSnapshot;\r\n } | null>(null);\r\n const viewportStore = useMemo<TranscriptViewportStore>(\r\n () => ({\r\n subscribe: (listener) => {\r\n viewportListenersRef.current.add(listener);\r\n return () => viewportListenersRef.current.delete(listener);\r\n },\r\n getRevision: () => viewportRevisionRef.current,\r\n getSnapshot: () => {\r\n // Keep the snapshot referentially stable between revisions so consumers\r\n // can use it as a memo dependency without recomputing on every render.\r\n const revision = viewportRevisionRef.current;\r\n const cached = viewportSnapshotRef.current;\r\n if (cached?.revision === revision) return cached.snapshot;\r\n const snapshot = {\r\n scrollTop: stateRef.current.scrollTop,\r\n viewportRows: metricsRef.current.viewportRows,\r\n followBottom: stateRef.current.followBottom,\r\n };\r\n viewportSnapshotRef.current = { revision, snapshot };\r\n return snapshot;\r\n },\r\n }),\r\n [],\r\n );\r\n\r\n const publishViewport = useCallback((state: TranscriptScrollState) => {\r\n const viewportRows = metricsRef.current.viewportRows;\r\n const bucketRows = Math.max(1, getTranscriptHalfPageRows(viewportRows));\r\n const bucket = `${Math.floor(state.scrollTop / bucketRows)}:${viewportRows}:${state.followBottom}`;\r\n if (viewportBucketRef.current === bucket) return;\r\n\r\n viewportBucketRef.current = bucket;\r\n viewportRevisionRef.current++;\r\n for (const listener of viewportListenersRef.current) listener();\r\n }, []);\r\n\r\n const applyScrollState = useCallback(\r\n (next: TranscriptScrollState) => {\r\n const previous = stateRef.current;\r\n stateRef.current = next;\r\n if (previous.scrollTop !== next.scrollTop) markTranscriptScrollActivity();\r\n\r\n if (\r\n previous.scrollTop !== next.scrollTop &&\r\n previous.followBottom === next.followBottom &&\r\n viewportRef.current\r\n ) {\r\n const position = getAbsolutePosition(viewportRef.current);\r\n const viewportHeight = Math.max(1, Math.floor(measureElement(viewportRef.current).height));\r\n if (position) {\r\n setTranscriptScrollHint({\r\n top: position.y + 1,\r\n bottom: position.y + viewportHeight,\r\n delta: next.scrollTop - previous.scrollTop,\r\n });\r\n }\r\n }\r\n\r\n setRenderedScrollTop((current) => (current === next.scrollTop ? current : next.scrollTop));\r\n setFollowBottom((current) => (current === next.followBottom ? current : next.followBottom));\r\n if (next.followBottom) setHasNewOutput(false);\r\n publishViewport(next);\r\n },\r\n [publishViewport],\r\n );\r\n\r\n onToggleToolRef.current = onToggleTool;\r\n onNotifyRef.current = onNotify;\r\n onRedrawViewportRef.current = onRedrawViewport;\r\n\r\n const repaintSelection = useCallback(() => {\r\n const selection = selectionRef.current;\r\n if (!selection) return;\r\n paintSelection(\r\n (data) => stdout.write(data),\r\n getFrameLines(),\r\n selection,\r\n stdout.columns ?? width ?? 80,\r\n getLastCursorPosition(),\r\n );\r\n }, [stdout, width]);\r\n\r\n const cancelScheduledSelectionRepaint = useCallback(() => {\r\n if (repaintImmediateRef.current === null) return;\r\n clearImmediate(repaintImmediateRef.current);\r\n repaintImmediateRef.current = null;\r\n }, []);\r\n\r\n const scheduleSelectionRepaint = useCallback(() => {\r\n if (!selectionRef.current || repaintImmediateRef.current !== null) return;\r\n repaintImmediateRef.current = setImmediate(() => {\r\n repaintImmediateRef.current = null;\r\n repaintSelection();\r\n });\r\n }, [repaintSelection]);\r\n\r\n const clearSelection = useCallback(() => {\r\n cancelScheduledSelectionRepaint();\r\n const selection = selectionRef.current;\r\n if (!selection) return;\r\n selectionRef.current = null;\r\n restoreSelection(\r\n (data) => stdout.write(data),\r\n getFrameLines(),\r\n selection,\r\n getLastCursorPosition(),\r\n );\r\n }, [cancelScheduledSelectionRepaint, stdout]);\r\n\r\n const replaceSelection = useCallback(\r\n (selection: SelectionRange) => {\r\n const current = selectionRef.current;\r\n if (current && selectionRangesEqual(current, selection)) return;\r\n clearSelection();\r\n selectionRef.current = selection;\r\n repaintSelection();\r\n },\r\n [clearSelection, repaintSelection],\r\n );\r\n\r\n const cancelWheelScroll = useCallback(() => {\r\n pendingWheelRowsRef.current = 0;\r\n if (wheelImmediateRef.current !== null) {\r\n clearImmediate(wheelImmediateRef.current);\r\n wheelImmediateRef.current = null;\r\n }\r\n }, []);\r\n\r\n const flushWheelScroll = useCallback(() => {\r\n wheelImmediateRef.current = null;\r\n const rows = getTranscriptWheelDrainRows(\r\n pendingWheelRowsRef.current,\r\n metricsRef.current.viewportRows,\r\n );\r\n if (rows === 0) return;\r\n\r\n pendingWheelRowsRef.current -= rows;\r\n const previous = stateRef.current;\r\n const next = scrollTranscriptBy(previous, metricsRef.current, rows);\r\n applyScrollState(next);\r\n\r\n if (next.scrollTop === previous.scrollTop) {\r\n pendingWheelRowsRef.current = 0;\r\n return;\r\n }\r\n if (\r\n rows < 0 &&\r\n next.scrollTop === 0 &&\r\n pendingWheelRowsRef.current < 0 &&\r\n historyLoaderRef.current?.('page')\r\n ) {\r\n pendingWheelRowsRef.current = 0;\r\n return;\r\n }\r\n if (pendingWheelRowsRef.current !== 0) {\r\n wheelImmediateRef.current = setImmediate(flushWheelScroll);\r\n }\r\n }, [applyScrollState]);\r\n\r\n const scheduleWheelScroll = useCallback(\r\n (rows: number) => {\r\n pendingWheelRowsRef.current += rows;\r\n if (wheelImmediateRef.current !== null) return;\r\n // Coalesce a burst of terminal reports without a fixed frame delay.\r\n wheelImmediateRef.current = setImmediate(flushWheelScroll);\r\n },\r\n [flushWheelScroll],\r\n );\r\n\r\n const measureTranscript = useCallback(() => {\r\n const viewportRows = viewportRef.current\r\n ? Math.max(1, Math.floor(measureElement(viewportRef.current).height))\r\n : Math.max(1, Math.floor(height ?? 1));\r\n const contentRows = contentRef.current\r\n ? Math.max(0, Math.floor(measureElement(contentRef.current).height))\r\n : 0;\r\n const previousMetrics = metricsRef.current;\r\n const nextMetrics = { contentRows, viewportRows };\r\n\r\n if (\r\n contentRows > previousContentRowsRef.current &&\r\n !stateRef.current.followBottom &&\r\n previousContentRowsRef.current > 0\r\n ) {\r\n setHasNewOutput(true);\r\n }\r\n previousContentRowsRef.current = contentRows;\r\n\r\n if (\r\n previousMetrics.contentRows !== contentRows ||\r\n previousMetrics.viewportRows !== viewportRows\r\n ) {\r\n metricsRef.current = nextMetrics;\r\n applyScrollState(reconcileTranscriptScroll(stateRef.current, nextMetrics));\r\n }\r\n }, [applyScrollState, height]);\r\n\r\n const cancelScheduledLayoutMeasure = useCallback(() => {\r\n if (layoutMeasureImmediateRef.current !== null) {\r\n clearImmediate(layoutMeasureImmediateRef.current);\r\n layoutMeasureImmediateRef.current = null;\r\n }\r\n }, []);\r\n\r\n const scheduleLayoutMeasure = useCallback(() => {\r\n if (layoutMeasureImmediateRef.current !== null) return;\r\n layoutMeasureImmediateRef.current = setImmediate(() => {\r\n layoutMeasureImmediateRef.current = null;\r\n measureTranscript();\r\n });\r\n }, [measureTranscript]);\r\n\r\n const layoutDependency = layoutRevision === undefined ? children : layoutRevision;\r\n useLayoutEffect(() => {\r\n cancelScheduledLayoutMeasure();\r\n measureTranscript();\r\n }, [cancelScheduledLayoutMeasure, height, layoutDependency, measureTranscript, width]);\r\n\r\n useEffect(\r\n () => () => {\r\n cancelScheduledLayoutMeasure();\r\n },\r\n [cancelScheduledLayoutMeasure],\r\n );\r\n\r\n useLayoutEffect(() => {\r\n if (previousFollowRequestRef.current === followRequestKey) return;\r\n previousFollowRequestRef.current = followRequestKey;\r\n cancelWheelScroll();\r\n clearSelection();\r\n dragRef.current = null;\r\n applyScrollState(scrollTranscriptToEnd(metricsRef.current));\r\n }, [applyScrollState, cancelWheelScroll, clearSelection, followRequestKey]);\r\n\r\n useEffect(() => {\r\n if (!isActive) return;\r\n\r\n const viewportRowSpan = (): { top: number; bottom: number } | null => {\r\n if (!viewportRef.current) return null;\r\n const position = getAbsolutePosition(viewportRef.current);\r\n if (!position) return null;\r\n const rows = Math.max(1, Math.floor(measureElement(viewportRef.current).height));\r\n return { top: position.y + 1, bottom: position.y + rows };\r\n };\r\n\r\n const cancelDrag = () => {\r\n clearSelection();\r\n dragRef.current = null;\r\n };\r\n\r\n const toggleToolAt = (x: number, y: number) => {\r\n const toggleTool = onToggleToolRef.current;\r\n if (!toggleTool) return;\r\n\r\n const cellX = x - 1;\r\n const cellY = y - 1;\r\n for (const registration of toolRowsRef.current.values()) {\r\n if (!registration.expandable || !registration.element.current) continue;\r\n const rect = measureElement(registration.element.current);\r\n const position = getAbsolutePosition(registration.element.current);\r\n if (\r\n position &&\r\n cellX >= position.x &&\r\n cellX < position.x + rect.width &&\r\n cellY >= position.y &&\r\n cellY < position.y + rect.height\r\n ) {\r\n toggleTool(registration.id, registration.expanded);\r\n break;\r\n }\r\n }\r\n };\r\n\r\n const finishDragSelection = (range: SelectionRange) => {\r\n const frameLines = getFrameLines();\r\n if (frameLines.length === 0) {\r\n clearSelection();\r\n onRedrawViewportRef.current?.();\r\n return;\r\n }\r\n const text = extractSelectedText(frameLines, range);\r\n if (!text) return;\r\n void writeClipboard(text).then((outcome) => {\r\n onNotifyRef.current?.(\r\n outcome === 'clipboard'\r\n ? 'Copied selection to clipboard.'\r\n : outcome === 'terminal'\r\n ? 'Sent selection to the terminal clipboard.'\r\n : 'Selection copy was unavailable.',\r\n );\r\n });\r\n };\r\n\r\n const handleMouseInput = (input: string) => {\r\n const events = parseSgrMouseEvents(input);\r\n if (events.length === 0) return;\r\n\r\n for (const event of events) {\r\n if (event.type === 'wheel') {\r\n if (dragRef.current || selectionRef.current) cancelDrag();\r\n const rows = event.button === 'wheel-up' ? -MOUSE_WHEEL_ROWS : MOUSE_WHEEL_ROWS;\r\n if (rows < 0 && stateRef.current.scrollTop === 0 && historyLoaderRef.current?.('page')) {\r\n continue;\r\n }\r\n scheduleWheelScroll(rows);\r\n continue;\r\n }\r\n\r\n if (event.shift) {\r\n if (event.type === 'press') cancelDrag();\r\n continue;\r\n }\r\n if (event.button !== 'left') continue;\r\n\r\n if (event.type === 'press') {\r\n clearSelection();\r\n dragRef.current = null;\r\n const span = viewportRowSpan();\r\n if (!span || event.y < span.top || event.y > span.bottom) continue;\r\n dragRef.current = {\r\n anchor: { x: event.x, y: event.y },\r\n focus: { x: event.x, y: event.y },\r\n dragged: false,\r\n };\r\n continue;\r\n }\r\n\r\n const drag = dragRef.current;\r\n if (!drag) continue;\r\n\r\n if (event.type === 'move') {\r\n if (event.x !== drag.anchor.x || event.y !== drag.anchor.y) drag.dragged = true;\r\n if (!drag.dragged) continue;\r\n const span = viewportRowSpan();\r\n const focusY = span ? Math.min(Math.max(event.y, span.top), span.bottom) : event.y;\r\n drag.focus = { x: event.x, y: focusY };\r\n const range = normalizeSelectionRange(drag.anchor, drag.focus);\r\n replaceSelection(range);\r\n continue;\r\n }\r\n\r\n if (event.type !== 'release') continue;\r\n dragRef.current = null;\r\n const moved = drag.dragged || event.x !== drag.anchor.x || event.y !== drag.anchor.y;\r\n const span = viewportRowSpan();\r\n const focusY = span ? Math.min(Math.max(event.y, span.top), span.bottom) : event.y;\r\n drag.focus = { x: event.x, y: focusY };\r\n if (!moved) {\r\n toggleToolAt(event.x, event.y);\r\n continue;\r\n }\r\n const range = normalizeSelectionRange(drag.anchor, drag.focus);\r\n replaceSelection(range);\r\n finishDragSelection(range);\r\n }\r\n };\r\n\r\n const unsubscribeFrameUpdates = subscribeToFrameUpdates(scheduleSelectionRepaint);\r\n internal_eventEmitter.on('input', handleMouseInput);\r\n return () => {\r\n unsubscribeFrameUpdates();\r\n internal_eventEmitter.removeListener('input', handleMouseInput);\r\n cancelWheelScroll();\r\n if (dragRef.current || selectionRef.current) cancelDrag();\r\n };\r\n }, [\r\n cancelWheelScroll,\r\n clearSelection,\r\n internal_eventEmitter,\r\n isActive,\r\n replaceSelection,\r\n scheduleSelectionRepaint,\r\n scheduleWheelScroll,\r\n ]);\r\n\r\n useEffect(() => {\r\n const handleResize = () => {\r\n clearSelection();\r\n dragRef.current = null;\r\n };\r\n stdout.on('resize', handleResize);\r\n return () => {\r\n stdout.off('resize', handleResize);\r\n };\r\n }, [clearSelection, stdout]);\r\n\r\n useInput(\r\n (input, key) => {\r\n const inputWithoutMouse = stripSgrMouseSequences(input);\r\n if (inputWithoutMouse !== input && inputWithoutMouse.length === 0) return;\r\n if (key.eventType === 'release') return;\r\n clearSelection();\r\n dragRef.current = null;\r\n const metrics = metricsRef.current;\r\n let next: TranscriptScrollState | undefined;\r\n\r\n if (key.pageUp) {\r\n if (stateRef.current.scrollTop === 0 && historyLoaderRef.current?.('page')) return;\r\n next = scrollTranscriptBy(\r\n stateRef.current,\r\n metrics,\r\n -getTranscriptPageRows(metrics.viewportRows),\r\n );\r\n } else if (key.pageDown) {\r\n next = scrollTranscriptBy(\r\n stateRef.current,\r\n metrics,\r\n getTranscriptPageRows(metrics.viewportRows),\r\n );\r\n } else if (key.ctrl && key.home) {\r\n historyLoaderRef.current?.('all');\r\n next = scrollTranscriptToStart();\r\n } else if (key.ctrl && key.end) {\r\n next = scrollTranscriptToEnd(metrics);\r\n } else if (key.ctrl && input.toLowerCase() === 'u') {\r\n if (stateRef.current.scrollTop === 0 && historyLoaderRef.current?.('page')) return;\r\n next = scrollTranscriptBy(\r\n stateRef.current,\r\n metrics,\r\n -getTranscriptHalfPageRows(metrics.viewportRows),\r\n );\r\n } else if (key.ctrl && input.toLowerCase() === 'd') {\r\n next = scrollTranscriptBy(\r\n stateRef.current,\r\n metrics,\r\n getTranscriptHalfPageRows(metrics.viewportRows),\r\n );\r\n }\r\n\r\n if (next) {\r\n cancelWheelScroll();\r\n applyScrollState(next);\r\n }\r\n },\r\n { isActive },\r\n );\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n flexGrow={height === undefined ? 1 : 0}\r\n flexShrink={1}\r\n minHeight={1}\r\n height={height}\r\n width={width}\r\n >\r\n <Box flexShrink={0} height={1} justifyContent=\"flex-end\">\r\n {!followBottom ? (\r\n <Text color={theme.subtle} dimColor>\r\n ↑ browsing history{hasNewOutput ? ' · new output below' : ''}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n <Box ref={viewportRef} flexGrow={1} flexShrink={1} minHeight={1} overflowY=\"hidden\">\r\n <Box\r\n ref={contentRef}\r\n flexDirection=\"column\"\r\n flexShrink={0}\r\n position=\"absolute\"\r\n width={width}\r\n marginTop={-renderedScrollTop}\r\n >\r\n <TranscriptContent\r\n interactionRegistry={interactionRegistry}\r\n historyRegistry={historyRegistry}\r\n viewportStore={viewportStore}\r\n onLayoutChange={scheduleLayoutMeasure}\r\n >\r\n {children}\r\n </TranscriptContent>\r\n </Box>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","export interface TranscriptMetrics {\r\n contentRows: number;\r\n viewportRows: number;\r\n}\r\n\r\nexport interface TranscriptScrollState {\r\n scrollTop: number;\r\n followBottom: boolean;\r\n}\r\n\r\nexport function createTranscriptScrollState(): TranscriptScrollState {\r\n return { scrollTop: 0, followBottom: true };\r\n}\r\n\r\nexport function getMaxScrollTop(metrics: TranscriptMetrics): number {\r\n const contentRows = Math.max(0, Math.floor(metrics.contentRows));\r\n const viewportRows = Math.max(1, Math.floor(metrics.viewportRows));\r\n return Math.max(0, contentRows - viewportRows);\r\n}\r\n\r\nexport function reconcileTranscriptScroll(\r\n state: TranscriptScrollState,\r\n metrics: TranscriptMetrics,\r\n): TranscriptScrollState {\r\n const maxScrollTop = getMaxScrollTop(metrics);\r\n const scrollTop = state.followBottom\r\n ? maxScrollTop\r\n : Math.max(0, Math.min(Math.floor(state.scrollTop), maxScrollTop));\r\n\r\n return scrollTop === state.scrollTop ? state : { ...state, scrollTop };\r\n}\r\n\r\nexport function scrollTranscriptBy(\r\n state: TranscriptScrollState,\r\n metrics: TranscriptMetrics,\r\n rows: number,\r\n): TranscriptScrollState {\r\n const maxScrollTop = getMaxScrollTop(metrics);\r\n const scrollTop = Math.max(0, Math.min(state.scrollTop + Math.trunc(rows), maxScrollTop));\r\n const followBottom = rows > 0 && scrollTop === maxScrollTop;\r\n\r\n if (scrollTop === state.scrollTop && followBottom === state.followBottom) return state;\r\n return { scrollTop, followBottom };\r\n}\r\n\r\nexport function scrollTranscriptToStart(): TranscriptScrollState {\r\n return { scrollTop: 0, followBottom: false };\r\n}\r\n\r\nexport function scrollTranscriptToEnd(metrics: TranscriptMetrics): TranscriptScrollState {\r\n return { scrollTop: getMaxScrollTop(metrics), followBottom: true };\r\n}\r\n\r\nexport function getTranscriptPageRows(viewportRows: number): number {\r\n return Math.max(1, Math.floor(viewportRows) - 2);\r\n}\r\n\r\nexport function getTranscriptHalfPageRows(viewportRows: number): number {\r\n return Math.max(1, Math.floor(viewportRows / 2));\r\n}\r\n\r\nexport function getTranscriptWheelDrainRows(pendingRows: number, viewportRows: number): number {\r\n const pending = Math.trunc(pendingRows);\r\n if (pending === 0) return 0;\r\n\r\n const maxRows = Math.max(3, getTranscriptHalfPageRows(viewportRows));\r\n return Math.sign(pending) * Math.min(Math.abs(pending), maxRows);\r\n}\r\n","import { spawn } from 'node:child_process';\r\n\r\n/** OSC 52 clipboard-write sequence understood by modern terminals. */\r\nexport function buildOsc52Sequence(text: string): string {\r\n return `\\x1b]52;c;${Buffer.from(text, 'utf8').toString('base64')}\\x1b\\\\`;\r\n}\r\n\r\nexport interface ClipboardWriterDeps {\r\n platform?: NodeJS.Platform;\r\n stdout?: { write(data: string): unknown };\r\n spawn?: typeof spawn;\r\n}\r\n\r\nexport type ClipboardOutcome = 'clipboard' | 'terminal' | 'failed';\r\n\r\nconst CLIPBOARD_COMMAND_TIMEOUT_MS = 3_000;\r\n\r\nfunction pipeTextToCommand(\r\n spawnFn: typeof spawn,\r\n command: string,\r\n args: readonly string[],\r\n text: string,\r\n): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n let child;\r\n try {\r\n child = spawnFn(command, [...args], {\r\n stdio: ['pipe', 'ignore', 'ignore'],\r\n windowsHide: true,\r\n });\r\n } catch {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n let settled = false;\r\n const settle = (success: boolean) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n resolve(success);\r\n };\r\n const timer = setTimeout(() => {\r\n child.kill();\r\n settle(false);\r\n }, CLIPBOARD_COMMAND_TIMEOUT_MS);\r\n child.once('error', () => settle(false));\r\n child.once('close', (code) => settle(code === 0));\r\n child.stdin.once('error', () => {});\r\n child.stdin.end(text);\r\n });\r\n}\r\n\r\n/** Copy through OSC 52 and a best-effort local platform clipboard command. */\r\nexport async function writeClipboard(\r\n text: string,\r\n deps: ClipboardWriterDeps = {},\r\n): Promise<ClipboardOutcome> {\r\n if (!text) return 'failed';\r\n const platform = deps.platform ?? process.platform;\r\n const stdout = deps.stdout ?? process.stdout;\r\n const spawnFn = deps.spawn ?? spawn;\r\n let oscWritten = false;\r\n\r\n try {\r\n stdout.write(buildOsc52Sequence(text));\r\n oscWritten = true;\r\n } catch {\r\n // OSC 52 is optional; keep trying the local clipboard command.\r\n }\r\n\r\n const unconfirmed: ClipboardOutcome = oscWritten ? 'terminal' : 'failed';\r\n try {\r\n if (platform === 'win32') {\r\n return (await pipeTextToCommand(spawnFn, 'clip.exe', [], text)) ? 'clipboard' : unconfirmed;\r\n }\r\n if (platform === 'darwin') {\r\n return (await pipeTextToCommand(spawnFn, 'pbcopy', [], text)) ? 'clipboard' : unconfirmed;\r\n }\r\n if (await pipeTextToCommand(spawnFn, 'wl-copy', [], text)) return 'clipboard';\r\n return (await pipeTextToCommand(spawnFn, 'xclip', ['-selection', 'clipboard'], text))\r\n ? 'clipboard'\r\n : unconfirmed;\r\n } catch {\r\n return unconfirmed;\r\n }\r\n}\r\n","import { displayWidth, stripAnsi } from './components/word-wrap.js';\r\n\r\n/** 1-based terminal cell coordinates as reported by SGR mouse events. */\r\nexport interface SelectionCell {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport interface SelectionRange {\r\n start: SelectionCell;\r\n end: SelectionCell;\r\n}\r\n\r\nexport interface SelectionRowSegment {\r\n row: number;\r\n startColumn: number;\r\n endColumn: number;\r\n}\r\n\r\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\r\n\r\nconst normalizeCell = ({ x, y }: SelectionCell): SelectionCell => ({\r\n x: Math.max(1, Math.floor(x)),\r\n y: Math.max(1, Math.floor(y)),\r\n});\r\n\r\nconst compareCells = (left: SelectionCell, right: SelectionCell): number =>\r\n left.y === right.y ? left.x - right.x : left.y - right.y;\r\n\r\n/** Normalize anchor/focus into ordered, inclusive terminal-cell endpoints. */\r\nexport function normalizeSelectionRange(\r\n anchor: SelectionCell,\r\n focus: SelectionCell,\r\n): SelectionRange {\r\n const normalizedAnchor = normalizeCell(anchor);\r\n const normalizedFocus = normalizeCell(focus);\r\n return compareCells(normalizedAnchor, normalizedFocus) <= 0\r\n ? { start: normalizedAnchor, end: normalizedFocus }\r\n : { start: normalizedFocus, end: normalizedAnchor };\r\n}\r\n\r\n/** Return the selected inclusive columns for one rendered row. */\r\nexport function getSelectionRowSegment(\r\n range: SelectionRange,\r\n row: number,\r\n lineWidth: number,\r\n): SelectionRowSegment | null {\r\n const normalizedRow = Math.max(1, Math.floor(row));\r\n const normalizedWidth = Math.max(0, Math.floor(lineWidth));\r\n if (normalizedWidth === 0 || normalizedRow < range.start.y || normalizedRow > range.end.y) {\r\n return null;\r\n }\r\n\r\n const startColumn = normalizedRow === range.start.y ? range.start.x : 1;\r\n const requestedEnd = normalizedRow === range.end.y ? range.end.x : normalizedWidth;\r\n const endColumn = Math.min(normalizedWidth, requestedEnd);\r\n if (startColumn > normalizedWidth || endColumn < startColumn) return null;\r\n return { row: normalizedRow, startColumn, endColumn };\r\n}\r\n\r\n/** Slice plain text by an inclusive terminal-column range without splitting wide glyphs. */\r\nexport function sliceDisplayColumns(text: string, startColumn: number, endColumn: number): string {\r\n const plain = stripAnsi(text);\r\n const start = Math.max(1, Math.floor(startColumn));\r\n const end = Math.max(0, Math.floor(endColumn));\r\n if (!plain || end < start) return '';\r\n\r\n let column = 1;\r\n let selected = '';\r\n for (const { segment } of graphemeSegmenter.segment(plain)) {\r\n const width = displayWidth(segment);\r\n if (width === 0) {\r\n if (selected) selected += segment;\r\n continue;\r\n }\r\n\r\n const segmentEnd = column + width - 1;\r\n if (segmentEnd >= start && column <= end) selected += segment;\r\n column = segmentEnd + 1;\r\n if (column > end) break;\r\n }\r\n return selected;\r\n}\r\n\r\n/** Extract selected visible cells, removing terminal styling and layout padding. */\r\nexport function extractSelectedText(frameLines: readonly string[], range: SelectionRange): string {\r\n if (frameLines.length === 0) return '';\r\n const top = Math.max(1, range.start.y);\r\n const bottom = Math.min(frameLines.length, range.end.y);\r\n if (bottom < top) return '';\r\n\r\n const lines: string[] = [];\r\n for (let row = top; row <= bottom; row++) {\r\n const plain = stripAnsi(frameLines[row - 1] ?? '');\r\n const segment = getSelectionRowSegment(range, row, displayWidth(plain));\r\n lines.push(\r\n segment ? sliceDisplayColumns(plain, segment.startColumn, segment.endColumn).trimEnd() : '',\r\n );\r\n }\r\n while (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();\r\n return lines.join('\\n');\r\n}\r\n","import { displayWidth, stripAnsi } from './components/word-wrap.js';\r\nimport type { FrameCursorPosition } from './frame-buffer.js';\r\nimport { getSelectionRowSegment, type SelectionRange } from './text-selection.js';\r\n\r\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\r\nconst cursorTo = (row: number, column = 1): string =>\r\n `\\x1b[${Math.max(1, Math.floor(row))};${Math.max(1, Math.floor(column))}H`;\r\n\r\nexport interface SelectionHighlightSpan {\r\n startColumn: number;\r\n text: string;\r\n}\r\n\r\nfunction restoreCursorSequence(cursor: FrameCursorPosition | null, frameRows: number): string {\r\n if (cursor) {\r\n return `\\x1b[${cursor.y + 1};${cursor.x + 1}H\\x1b[?25h`;\r\n }\r\n return frameRows > 0 ? cursorTo(frameRows) + '\\x1b[?25l' : '';\r\n}\r\n\r\n/** Resolve the exact cells to repaint for one selected frame row. */\r\nexport function getSelectionHighlightSpan(\r\n frameLine: string,\r\n range: SelectionRange,\r\n row: number,\r\n columns: number,\r\n): SelectionHighlightSpan | null {\r\n const limit = Math.max(1, Math.floor(columns));\r\n const requested = getSelectionRowSegment(range, row, limit);\r\n if (!requested) return null;\r\n\r\n const plain = stripAnsi(frameLine);\r\n let startColumn = requested.startColumn;\r\n let endColumn = requested.endColumn;\r\n let column = 1;\r\n let text = '';\r\n\r\n for (const { segment: grapheme } of graphemeSegmenter.segment(plain)) {\r\n const width = displayWidth(grapheme);\r\n if (width === 0) {\r\n if (text) text += grapheme;\r\n continue;\r\n }\r\n\r\n const graphemeEnd = column + width - 1;\r\n if (graphemeEnd >= requested.startColumn && column <= requested.endColumn) {\r\n if (!text) startColumn = Math.min(startColumn, column);\r\n endColumn = Math.max(endColumn, graphemeEnd);\r\n text += grapheme;\r\n }\r\n column = graphemeEnd + 1;\r\n if (column > requested.endColumn && text) break;\r\n }\r\n\r\n const padding = Math.max(0, endColumn - startColumn + 1 - displayWidth(text));\r\n return { startColumn, text: text + ' '.repeat(padding) };\r\n}\r\n\r\n/** Paint a character-level selection and return the cursor to Ink's anchor. */\r\nexport function paintSelection(\r\n write: (data: string) => unknown,\r\n frameLines: readonly string[],\r\n range: SelectionRange,\r\n columns: number,\r\n cursor: FrameCursorPosition | null,\r\n): void {\r\n const top = Math.max(1, range.start.y);\r\n const bottom = Math.min(frameLines.length, range.end.y);\r\n let output = '';\r\n for (let row = top; row <= bottom; row++) {\r\n const highlighted = getSelectionHighlightSpan(frameLines[row - 1] ?? '', range, row, columns);\r\n if (highlighted !== null) {\r\n output += cursorTo(row, highlighted.startColumn) + '\\x1b[7m' + highlighted.text + '\\x1b[0m';\r\n }\r\n }\r\n if (output) write(output + restoreCursorSequence(cursor, frameLines.length));\r\n}\r\n\r\n/** Restore the frame rows under a selection and return the cursor to Ink's anchor. */\r\nexport function restoreSelection(\r\n write: (data: string) => unknown,\r\n frameLines: readonly string[],\r\n range: SelectionRange,\r\n cursor: FrameCursorPosition | null,\r\n): void {\r\n const top = Math.max(1, range.start.y);\r\n const bottom = Math.min(frameLines.length, range.end.y);\r\n let output = '';\r\n for (let row = top; row <= bottom; row++) {\r\n output += cursorTo(row) + (frameLines[row - 1] ?? '') + '\\x1b[K';\r\n }\r\n if (output) write(output + restoreCursorSequence(cursor, frameLines.length));\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useCallback, useMemo, useRef, useEffect, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { CONTENT_COLUMN, PANEL_CHROME, frameGrid } from '../layout.js';\r\nimport { useDensityMetrics } from '../density.js';\r\nimport { getPrimaryArg } from '../../tools/primary-arg.js';\r\nimport { canonicalToolName } from '../../tools/aliases.js';\r\nimport { isFileMutatingTool } from '../../tools/tool-capabilities.js';\r\nimport {\r\n isPreviewableMutation,\r\n previewMutation,\r\n type MutationPreview,\r\n type MutationPreviewFile,\r\n} from '../../tools/mutation-preview.js';\r\nimport { permissionRuleForToolCall, permissionRuleLadder } from '../../permissions.js';\r\nimport type { PermissionDecision, PermissionResult, ToolCall } from '../../types/tools.js';\r\nimport { createUiDebugLogger } from '../../debug-log.js';\r\nimport { useDebugMount } from '../debug.js';\r\nimport { DiffBlock, expandTabs } from './Diff.js';\r\nimport { displayWidth, hardWrapLine, truncateDisplay } from './word-wrap.js';\r\n\r\nconst uiLog = createUiDebugLogger('tui:permbtn');\r\nconst PERMISSION_PATTERN_DISPLAY_MAX_LENGTH = 40;\r\n\r\n/**\r\n * Rows the payload (a wrapped command, or a diff) may take before the card\r\n * marks a cut. The prompt sits under the transcript, so a bound is still\r\n * wanted — but it is a bound on rows the terminal can show, never a fixed\r\n * character count, and every cut is marked and can be opened with `D`.\r\n */\r\nconst COLLAPSED_COMMAND_ROWS = 6;\r\nconst COLLAPSED_DIFF_ROWS = 8;\r\n/** Rows the card keeps free for its own chrome, the buttons, and the composer. */\r\nconst RESERVED_ROWS = 12;\r\n/** A file shown with fewer diff rows than this says nothing; hide it instead. */\r\nconst MIN_DIFF_ROWS_PER_FILE = 4;\r\n\r\n/**\r\n * Marks the armed button, the same way {@link PlanApprovalActions} marks its own.\r\n *\r\n * The armed choice used to be carried by background colour and bold alone: the\r\n * only selection surface in the TUI without a glyph, while every menu, picker\r\n * and wizard has one. That was already an accessibility problem — a low-contrast\r\n * theme or a colour-blind reader has nothing left — and it got worse when `A`\r\n * became the way to *arm* \"Always allow\" and then step its scope rather than\r\n * fire it, because the whole interaction now depends on seeing which button is\r\n * armed. The brackets went with it: a marker and a pair of brackets are two\r\n * containers doing one job, and dropping them buys back columns the rule\r\n * pattern needs.\r\n */\r\nconst SELECTION_MARKER = '▸';\r\n\r\ninterface PermissionButtonsProps {\r\n toolCall: ToolCall;\r\n /**\r\n * Receives the decision. `always` carries the rule the user actually chose,\r\n * which is not always the exact command: the scope ladder lets them widen it.\r\n */\r\n onResolve: (decision: PermissionResult | PermissionDecision) => void;\r\n /** When true, disables all animations/colors for screen readers. */\r\n screenReader?: boolean;\r\n /** Terminal columns; the payload wraps to the card's interior. */\r\n terminalWidth?: number;\r\n /** Terminal rows; bounds how much of the payload `D` may open. */\r\n terminalRows?: number;\r\n /**\r\n * Workspace the pending call would mutate. When set, file mutations show\r\n * the diff they would produce before anything is written; without it the\r\n * card can only name the path.\r\n */\r\n workspaceRoot?: string;\r\n}\r\n\r\ninterface ButtonDef {\r\n label: string;\r\n value: PermissionResult;\r\n key: string;\r\n colorKey: 'permission' | 'remember' | 'subtle';\r\n}\r\n\r\nconst BUTTONS: ButtonDef[] = [\r\n { label: 'Run once', value: 'allow', key: 'r', colorKey: 'permission' },\r\n { label: 'Skip', value: 'deny', key: 's', colorKey: 'subtle' },\r\n { label: 'Always allow', value: 'always', key: 'a', colorKey: 'remember' },\r\n];\r\n\r\nexport function toolRiskLevel(toolCall: ToolCall): 'safe' | 'network' | 'write' | 'shell' {\r\n const name = canonicalToolName(toolCall.name);\r\n const lower = toolCall.name.toLowerCase();\r\n if (name === 'Bash' || name === 'KillShell' || lower.includes('bash') || lower === 'shell')\r\n return 'shell';\r\n if (isFileMutatingTool(name)) return 'write';\r\n if (name === 'WebFetch' || name === 'WebSearch') return 'network';\r\n return 'safe';\r\n}\r\n\r\nfunction riskHint(level: ReturnType<typeof toolRiskLevel>): string | null {\r\n if (level === 'shell') return 'This will run a shell command on your machine.';\r\n if (level === 'write') return 'This will modify files on disk.';\r\n if (level === 'network') return 'This will send a request to an external service.';\r\n return null;\r\n}\r\n\r\nexport function permissionPatternForTool(toolCall: ToolCall, primaryArg: string): string {\r\n void primaryArg;\r\n return permissionRuleForToolCall(toolCall);\r\n}\r\n\r\n/** Caption for a scope the user has widened past the exact command. */\r\nexport function scopeCaption(ladder: readonly string[], index: number): string | null {\r\n if (index === 0) return null;\r\n const remaining = ladder.length - 1 - index;\r\n return remaining > 0\r\n ? `Covers every command matching this pattern. A again widens further.`\r\n : `Covers every command matching this pattern. A again returns to the exact one.`;\r\n}\r\n\r\nexport function permissionPatternForDisplay(pattern: string): string {\r\n if (pattern.length <= PERMISSION_PATTERN_DISPLAY_MAX_LENGTH) return pattern;\r\n return `${pattern.slice(0, PERMISSION_PATTERN_DISPLAY_MAX_LENGTH - 3)}...`;\r\n}\r\n\r\n/**\r\n * The text the user is consenting to. For a shell command that is the whole\r\n * command, every line of it: {@link getPrimaryArg} keeps only the first line\r\n * because it serves rule matching, and a prompt built on it showed\r\n * `cd x &&` for a script whose second line was the `rm`.\r\n */\r\nexport function permissionPayloadText(toolCall: ToolCall): string {\r\n const command = toolCall.arguments?.command;\r\n if (typeof command === 'string') return command;\r\n return getPrimaryArg(toolCall.arguments ?? {});\r\n}\r\n\r\nexport interface WrappedPayload {\r\n /** Rows to draw, already cut to the budget. */\r\n rows: string[];\r\n /** Rows the budget hid; `0` when the payload fits. */\r\n hiddenRows: number;\r\n}\r\n\r\n/**\r\n * Wrap a payload to `width` columns and cut it to `maxRows` rows.\r\n *\r\n * A hard wrap, not a word wrap: a command's spacing is part of the command,\r\n * and a display that collapses `\"a b\"` to `\"a b\"` shows something the shell\r\n * will not run. Tabs are expanded to the columns they will occupy, and a\r\n * carriage return ends a row rather than reaching the terminal, where it\r\n * would drag the rest of the row back over the card's border. The cut always\r\n * leaves room for its own marker, so a reader can tell a payload that fits\r\n * from one that was trimmed.\r\n */\r\nexport function wrapPayload(text: string, width: number, maxRows: number): WrappedPayload {\r\n const columns = Math.max(4, Math.floor(width));\r\n const rows = text.split(/\\r\\n|\\r|\\n/).flatMap((line) => hardWrapLine(expandTabs(line), columns));\r\n const budget = Math.max(1, Math.floor(maxRows));\r\n if (rows.length <= budget) return { rows, hiddenRows: 0 };\r\n // The marker takes a row of its own, so one fewer payload row survives.\r\n const kept = Math.max(1, budget - 1);\r\n return { rows: rows.slice(0, kept), hiddenRows: rows.length - kept };\r\n}\r\n\r\nfunction previewSummary(files: readonly MutationPreviewFile[]): string {\r\n const added = files.reduce((total, file) => total + file.stats.addedLines, 0);\r\n const removed = files.reduce((total, file) => total + file.stats.removedLines, 0);\r\n return `+${added} −${removed}`;\r\n}\r\n\r\nfunction diffRowCount(file: MutationPreviewFile): number {\r\n return file.diff.length === 0 ? 0 : file.diff.split('\\n').length;\r\n}\r\n\r\n/**\r\n * Permission prompt card.\r\n *\r\n * Navigation:\r\n * ←/→ or Tab/Shift+Tab — cycle between buttons\r\n * Enter, or R/S — activate; A selects \"Always allow\" without activating it\r\n * D — open or close the rest of a cut payload (command rows, diff rows)\r\n * Esc — deny\r\n */\r\nexport function PermissionButtons({\r\n toolCall,\r\n onResolve,\r\n screenReader = false,\r\n terminalWidth = 80,\r\n terminalRows = 24,\r\n workspaceRoot,\r\n}: PermissionButtonsProps) {\r\n const theme = useTheme();\r\n const density = useDensityMetrics();\r\n // Enter reads the selection through `currentSelected()`, not from render\r\n // state. `A` now only arms \"Always allow\", so `A` then a quick Enter lands in\r\n // one React batch and an Enter handler closing over render state would still\r\n // see the previous index — resolving `allow` when the user asked for\r\n // `always`.\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n const resolvedToolCallIdRef = useRef<string | null>(null);\r\n const canonical = canonicalToolName(toolCall.name);\r\n const payload = permissionPayloadText(toolCall);\r\n const risk = toolRiskLevel(toolCall);\r\n const hint = riskHint(risk);\r\n // The rules \"Always allow\" may write, narrowest first. For a shell command\r\n // the exact rule matches that byte sequence and nothing else, so offering\r\n // only that made the button a no-op for the case it exists to serve; the user\r\n // steps the scope with `A` and always sees the pattern before Enter writes it.\r\n const ladder = useMemo(() => permissionRuleLadder(toolCall), [toolCall]);\r\n const ladderRef = useRef(ladder);\r\n ladderRef.current = ladder;\r\n const [scopeIndex, setScopeIndex, currentScope] = useKeyState(0);\r\n const alwaysPattern = ladder[scopeIndex] ?? ladder[0];\r\n const alwaysPatternDisplay = permissionPatternForDisplay(alwaysPattern);\r\n const scopeHint = scopeCaption(ladder, scopeIndex);\r\n const [expanded, setExpanded] = useState(false);\r\n\r\n // The card is a bordered surface flush at column 0, like the composer, so\r\n // its border plus padding land its text on the content column.\r\n const frame = frameGrid(Math.max(20, Math.floor(terminalWidth)));\r\n const contentWidth = Math.max(8, frame.width - PANEL_CHROME);\r\n // Visual rows the payload may spend once `D` opens it. The card lives in\r\n // the fixed region under the transcript, so a payload taller than the\r\n // terminal pushes its own buttons off the top of the screen.\r\n const rowBudget = Math.max(COLLAPSED_DIFF_ROWS, Math.floor(terminalRows) - RESERVED_ROWS);\r\n // A change-focused diff draws a `⋮ n rows omitted` marker between every run\r\n // of selected rows, so in the worst case each budgeted row costs two on\r\n // screen; the diff budget is the row budget halved.\r\n const expandedDiffRows = Math.floor(rowBudget / 2);\r\n const collapsedDiffRows = Math.min(COLLAPSED_DIFF_ROWS, expandedDiffRows);\r\n\r\n // The header carries the payload inline only when the whole thing fits on\r\n // that row; otherwise the payload takes rows of its own under it, wrapped\r\n // to the card. A fixed 72-character slice used to hide the tail of every\r\n // longer command with nothing to mark the cut.\r\n const header = `Permission required · ${canonical}`;\r\n const inlineRoom = contentWidth - displayWidth(header) - 1;\r\n const payloadInline =\r\n payload.length > 0 && !payload.includes('\\n') && displayWidth(payload) <= inlineRoom;\r\n const wrappedPayload = useMemo(\r\n () =>\r\n payloadInline || payload.length === 0\r\n ? { rows: [], hiddenRows: 0 }\r\n : wrapPayload(payload, contentWidth, expanded ? rowBudget : COLLAPSED_COMMAND_ROWS),\r\n [contentWidth, expanded, payload, payloadInline, rowBudget],\r\n );\r\n\r\n // File mutations show the diff they would make, computed from the pending\r\n // arguments against the file on disk. Nothing is written until the user\r\n // answers; the tool recomputes against the file it finds when it runs.\r\n const previewable = Boolean(workspaceRoot) && isPreviewableMutation(toolCall);\r\n const [preview, setPreview] = useState<MutationPreview | null>(null);\r\n const previewLoading = previewable && preview === null;\r\n // A managed agent's record is replaced wholesale on every agent event, so\r\n // the request object can change identity while the request does not; key\r\n // the preview on the call id and read the call through a ref.\r\n const toolCallRef = useRef(toolCall);\r\n toolCallRef.current = toolCall;\r\n useEffect(() => {\r\n setPreview(null);\r\n if (!previewable || !workspaceRoot) return;\r\n const controller = new AbortController();\r\n previewMutation(toolCallRef.current, workspaceRoot, controller.signal)\r\n .then((result) => {\r\n if (controller.signal.aborted || !result) return;\r\n setPreview(result);\r\n uiLog.event('preview', {\r\n tool: canonical,\r\n files: result.files.length,\r\n error: result.error ?? '',\r\n });\r\n })\r\n // Only the abort from the cleanup below rejects; nothing to show for it.\r\n .catch(() => undefined);\r\n return () => controller.abort();\r\n }, [canonical, previewable, toolCall.id, workspaceRoot]);\r\n\r\n // Row counts are constant for the life of a preview; the card re-renders on\r\n // every keypress and must not re-split a large diff each time.\r\n const diffRows = useMemo(\r\n () => new Map((preview?.files ?? []).map((file) => [file.filePath, diffRowCount(file)])),\r\n [preview],\r\n );\r\n const files = preview && !preview.error ? preview.files : [];\r\n const diffBudget = expanded ? expandedDiffRows : collapsedDiffRows;\r\n // The budget bounds the card, not each file: a patch across many files\r\n // shows as many as the budget can give a meaningful diff, and counts the rest.\r\n const filesShown =\r\n files.length === 0\r\n ? 0\r\n : Math.max(1, Math.min(files.length, Math.floor(diffBudget / MIN_DIFF_ROWS_PER_FILE)));\r\n const shownFiles = files.slice(0, filesShown);\r\n const hiddenFiles = files.slice(filesShown);\r\n const shownWithDiff = Math.max(\r\n 1,\r\n shownFiles.filter((file) => (diffRows.get(file.filePath) ?? 0) > 0).length,\r\n );\r\n const diffRowsPerFile = Math.max(MIN_DIFF_ROWS_PER_FILE, Math.floor(diffBudget / shownWithDiff));\r\n // `D` is offered only while it would show something more, or has. On a\r\n // terminal too short for a larger budget the diff already shows what it can.\r\n const diffHasMore =\r\n hiddenFiles.length > 0 ||\r\n shownFiles.some((file) => (diffRows.get(file.filePath) ?? 0) > diffRowsPerFile);\r\n const canExpand =\r\n expanded ||\r\n wrappedPayload.hiddenRows > 0 ||\r\n (diffHasMore && expandedDiffRows > collapsedDiffRows);\r\n\r\n // Track previous selection for old→new logging without stale closure issues.\r\n const prevSelectedRef = useRef(0);\r\n\r\n useDebugMount(uiLog, {\r\n tool: canonical,\r\n risk,\r\n primaryArg: payload ? payload.slice(0, 40) : null,\r\n });\r\n\r\n const moveSelection = useCallback((next: (current: number) => number) => {\r\n setSelected(next(currentSelected()));\r\n }, []);\r\n\r\n const handleResolve = useCallback(\r\n (value: PermissionResult) => {\r\n if (resolvedToolCallIdRef.current === toolCall.id) {\r\n uiLog.event('resolve:double-fire-prevented', {\r\n tool: canonical,\r\n attempt: value,\r\n });\r\n return;\r\n }\r\n resolvedToolCallIdRef.current = toolCall.id;\r\n const rule = value === 'always' ? ladderRef.current[currentScope()] : undefined;\r\n uiLog.event('resolve', {\r\n tool: canonical,\r\n result: value,\r\n selected,\r\n rule: rule ?? '',\r\n });\r\n onResolve(rule ? { result: value, rule } : value);\r\n },\r\n [canonical, onResolve, selected, toolCall.id],\r\n );\r\n\r\n useInput(\r\n (input, key) => {\r\n if (key.leftArrow) {\r\n const prev = selected;\r\n moveSelection((s) => (s - 1 + BUTTONS.length) % BUTTONS.length);\r\n uiLog.event('input:Left', { tool: canonical, selected: `${prev}->?` });\r\n return;\r\n }\r\n if (key.rightArrow) {\r\n const prev = selected;\r\n moveSelection((s) => (s + 1) % BUTTONS.length);\r\n uiLog.event('input:Right', { tool: canonical, selected: `${prev}->?` });\r\n return;\r\n }\r\n if (key.tab) {\r\n const prev = selected;\r\n moveSelection((s) =>\r\n key.shift ? (s - 1 + BUTTONS.length) % BUTTONS.length : (s + 1) % BUTTONS.length,\r\n );\r\n uiLog.event('input:Tab', { tool: canonical, shift: key.shift, selected: `${prev}->?` });\r\n return;\r\n }\r\n // Enter only. Space used to activate too, which put `always` two ordinary\r\n // keystrokes away — `a` then a space, the opening of any sentence\r\n // starting with \"a \" — and the card advertises Enter, never space.\r\n if (key.return) {\r\n const armed = currentSelected();\r\n uiLog.event('input:Enter', {\r\n tool: canonical,\r\n selected: armed,\r\n rule: BUTTONS[armed].value === 'always' ? ladder[currentScope()] : undefined,\r\n });\r\n handleResolve(BUTTONS[armed].value);\r\n return;\r\n }\r\n if (key.escape) {\r\n uiLog.event('input:Escape', { tool: canonical, action: 'deny' });\r\n handleResolve('deny');\r\n return;\r\n }\r\n if (input === 'r' || input === 'R') {\r\n uiLog.event('input:shortcut', { tool: canonical, key: 'R', action: 'allow' });\r\n handleResolve('allow');\r\n return;\r\n }\r\n if (input === 's' || input === 'S') {\r\n uiLog.event('input:shortcut', { tool: canonical, key: 'S', action: 'deny' });\r\n handleResolve('deny');\r\n return;\r\n }\r\n // `D` only changes what the card shows, never what it resolves, so a\r\n // stray press costs nothing. It does nothing at all while there is\r\n // nothing to open, so the card never claims to be expanded when it is not.\r\n if (input === 'd' || input === 'D') {\r\n if (!canExpand) return;\r\n setExpanded((current) => {\r\n uiLog.event('input:shortcut', {\r\n tool: canonical,\r\n key: 'D',\r\n action: current ? 'collapse-detail' : 'expand-detail',\r\n });\r\n return !current;\r\n });\r\n return;\r\n }\r\n // `A` deliberately has no single-key shortcut. `always` is the one choice\r\n // here that writes a permission rule to disk, and rules can only be\r\n // removed by hand, so it must not be reachable by one stray letter — a\r\n // lone `a` used to grant a persistent shell allow with no visible trace.\r\n // Select it and press Enter.\r\n if (input === 'a' || input === 'A') {\r\n const alwaysIndex = BUTTONS.findIndex((button) => button.value === 'always');\r\n // First `A` arms the button; each `A` after that widens the scope and\r\n // wraps back to the exact rule, so the key can explore every option\r\n // without ever committing one.\r\n if (currentSelected() === alwaysIndex && ladder.length > 1) {\r\n setScopeIndex((currentScope() + 1) % ladder.length);\r\n uiLog.event('input:shortcut', {\r\n tool: canonical,\r\n key: 'A',\r\n action: 'step-scope',\r\n rule: ladder[currentScope()],\r\n });\r\n return;\r\n }\r\n uiLog.event('input:shortcut', { tool: canonical, key: 'A', action: 'select-always' });\r\n moveSelection(() => alwaysIndex);\r\n return;\r\n }\r\n },\r\n { isActive: true },\r\n );\r\n\r\n // Log the resolved selection change with old→new after render.\r\n useEffect(() => {\r\n if (prevSelectedRef.current !== selected) {\r\n uiLog.event('selection:change', {\r\n tool: canonical,\r\n from: prevSelectedRef.current,\r\n to: selected,\r\n });\r\n prevSelectedRef.current = selected;\r\n }\r\n }, [selected, canonical]);\r\n\r\n if (screenReader) {\r\n return (\r\n <Box marginLeft={CONTENT_COLUMN} flexDirection=\"column\">\r\n <Text>Permission required for: {canonical}</Text>\r\n <Text>\r\n {risk === 'shell' ? 'Command' : 'Primary argument'}: {payload || '(none)'}\r\n </Text>\r\n {hint ? <Text>Warning: {hint}</Text> : null}\r\n {previewLoading ? <Text>Computing the change preview.</Text> : null}\r\n {preview?.error ? <Text>Cannot preview this change: {preview.error}</Text> : null}\r\n {files.map((file) => (\r\n <Text key={file.filePath}>\r\n Will {file.kind} {file.filePath}: {file.stats.addedLines} lines added,{' '}\r\n {file.stats.removedLines} lines removed.\r\n </Text>\r\n ))}\r\n <Text>Press: [R] Run once, [S] Skip, [Esc] Deny.</Text>\r\n <Text>Always allow: press [A] to select it, then Enter to confirm.</Text>\r\n <Text>Rule to be saved: {alwaysPattern}</Text>\r\n {ladder.length > 1 ? <Text>Press [A] again to widen or narrow that rule.</Text> : null}\r\n </Box>\r\n );\r\n }\r\n\r\n const helpKeys = [\r\n '← → select',\r\n 'Enter confirm',\r\n ladder.length > 1 ? 'A scope' : null,\r\n canExpand ? (expanded ? 'D less' : 'D more') : null,\r\n 'R run',\r\n 'S skip',\r\n 'Esc deny',\r\n ].filter((entry): entry is string => entry !== null);\r\n\r\n return (\r\n <Box\r\n marginLeft={frame.marginX}\r\n width={frame.width}\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={\r\n risk === 'shell' ? theme.error : risk === 'write' ? theme.warning : theme.permission\r\n }\r\n paddingX={1}\r\n >\r\n <Box>\r\n <Text bold color={theme.permission}>\r\n Permission required ·{' '}\r\n </Text>\r\n <Text bold color={theme.brand}>\r\n {canonical}\r\n </Text>\r\n {payloadInline ? <Text color={theme.text}> {payload}</Text> : null}\r\n </Box>\r\n {wrappedPayload.rows.map((row, index) => (\r\n <Box key={index}>\r\n <Text color={theme.text}>{row}</Text>\r\n </Box>\r\n ))}\r\n {wrappedPayload.hiddenRows > 0 ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(\r\n `… ${wrappedPayload.hiddenRows} more ${wrappedPayload.hiddenRows === 1 ? 'row' : 'rows'}${expanded ? '' : ' · D shows all'}`,\r\n contentWidth,\r\n )}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {hint ? (\r\n <Box>\r\n <Text color={risk === 'shell' ? theme.error : theme.warning}>{hint}</Text>\r\n </Box>\r\n ) : null}\r\n {previewLoading ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n Computing diff…\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {preview?.error ? (\r\n <Box>\r\n <Text color={theme.warning}>\r\n {truncateDisplay(`Cannot preview: ${preview.error}`, contentWidth)}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {files.length > 0 ? (\r\n <Box flexDirection=\"column\">\r\n {shownFiles.map((file) => {\r\n const noChange = file.diff.length === 0 ? ' no textual change' : '';\r\n const counts = ` +${file.stats.addedLines} −${file.stats.removedLines}`;\r\n // The path takes what the row's other segments leave it.\r\n const pathRoom =\r\n contentWidth - displayWidth(`${file.kind} `) - displayWidth(counts + noChange);\r\n return (\r\n <Box key={file.filePath} flexDirection=\"column\">\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {file.kind}{' '}\r\n </Text>\r\n <Text color={theme.text}>\r\n {truncateDisplay(file.filePath, Math.max(8, pathRoom))}\r\n </Text>\r\n <Text> </Text>\r\n <Text color={theme.success}>+{file.stats.addedLines}</Text>\r\n <Text> </Text>\r\n <Text color={theme.error}>−{file.stats.removedLines}</Text>\r\n {noChange ? (\r\n <Text color={theme.subtle} dimColor>\r\n {noChange}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n {file.diff.length > 0 ? (\r\n <DiffBlock\r\n output={file.diff}\r\n filePath={file.filePath}\r\n collapsed\r\n maxRows={diffRowsPerFile}\r\n expandHint={canExpand && !expanded ? 'D shows more' : ''}\r\n terminalWidth={contentWidth}\r\n />\r\n ) : null}\r\n </Box>\r\n );\r\n })}\r\n {hiddenFiles.length > 0 ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(\r\n `… ${hiddenFiles.length} more ${hiddenFiles.length === 1 ? 'file' : 'files'} · ${previewSummary(hiddenFiles)}${canExpand && !expanded ? ' · D shows more' : ''}`,\r\n contentWidth,\r\n )}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n {files.length > 1 ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {files.length} files · {previewSummary(files)}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n ) : null}\r\n {scopeHint ? (\r\n <Box>\r\n <Text color={theme.warning}>{scopeHint}</Text>\r\n </Box>\r\n ) : null}\r\n <Box>\r\n {BUTTONS.map((btn, i) => {\r\n const isSelected = i === selected;\r\n const btnColor = theme[btn.colorKey];\r\n const label = btn.value === 'always' ? `${btn.label} ${alwaysPatternDisplay}` : btn.label;\r\n return (\r\n <Box key={btn.label} marginRight={2}>\r\n <Text\r\n backgroundColor={isSelected ? theme.surfaceActive : undefined}\r\n color={isSelected ? theme.selectionText : btnColor}\r\n bold={isSelected}\r\n >\r\n {isSelected ? `${SELECTION_MARKER} ` : ' '}\r\n {label}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n {density.showOptionalHelp ? (\r\n <Box>\r\n <Text color={theme.subtle} dimColor>\r\n {helpKeys.join(' · ')}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { canonicalToolName } from './aliases.js';\r\nimport { renderDiffWithStatsAsync, type DiffStats } from './diff.js';\r\nimport { applySingleEdit } from './file.js';\r\nimport { readTextSnapshot, type TextSnapshot } from './mutation.js';\r\nimport { applyHunks, parsePatch, type PatchOperation } from './patch.js';\r\nimport { resolveWorkspacePath } from './path-utils.js';\r\nimport { toolResultErrorMessage } from './result.js';\r\nimport type { ToolCall, ToolResult } from '../types/tools.js';\r\n\r\n/**\r\n * Pre-execution preview of what a file-mutating tool call would change.\r\n *\r\n * The permission prompt is where the user consents to a mutation, so it has to\r\n * show the mutation, not just the path it lands on. The tools themselves only\r\n * produce a diff *after* writing; this module computes the same diff from the\r\n * pending call's arguments against the file as it is on disk right now, with\r\n * the same matching semantics the tool will use, and never writes anything.\r\n *\r\n * Arguments are read by their canonical names only. The agent loop runs\r\n * `registry.normalizeCall` on every call before hooks, permission evaluation\r\n * and the prompt see it (`src/agent/loop.ts`), so the pending call already\r\n * carries `filePath`, not `file_path`; a host that hands this module a raw\r\n * provider call must normalize it through the registry first.\r\n *\r\n * What is previewed is the textual change. The tools also gate on file\r\n * provenance (`file_not_observed`, `stale_file_observation`), which lives in\r\n * the tool context and is not consulted here.\r\n */\r\n\r\nexport interface MutationPreviewFile {\r\n /** Workspace-relative path the tool will write, delete, or create. */\r\n filePath: string;\r\n kind: 'create' | 'update' | 'delete';\r\n /** Unified diff hunks, empty when the change is textually a no-op. */\r\n diff: string;\r\n stats: DiffStats;\r\n}\r\n\r\nexport interface MutationPreview {\r\n files: MutationPreviewFile[];\r\n /**\r\n * Why no preview could be computed. This is the matching or path failure\r\n * the tool itself would report, surfaced at consent time so the user can\r\n * decline a call that is going to fail anyway.\r\n */\r\n error?: string;\r\n}\r\n\r\n/** Per-side line ceiling; the diff is trimmed to the changed span but still bounded here. */\r\nconst MAX_PREVIEW_LINES = 20_000;\r\nconst TOO_LARGE = 'File is too large to preview';\r\n\r\nconst PREVIEWABLE_TOOLS = new Set(['Write', 'Edit', 'MultiEdit', 'ApplyPatch']);\r\n\r\n/** Whether {@link previewMutation} can say anything about this call. */\r\nexport function isPreviewableMutation(toolCall: ToolCall): boolean {\r\n return PREVIEWABLE_TOOLS.has(canonicalToolName(toolCall.name));\r\n}\r\n\r\n/** A failure the tool would report; becomes {@link MutationPreview.error}. */\r\nclass PreviewError extends Error {}\r\n\r\nfunction fail(message: string): never {\r\n throw new PreviewError(message);\r\n}\r\n\r\nfunction failWith(result: ToolResult): never {\r\n return fail(toolResultErrorMessage(result) ?? result.content);\r\n}\r\n\r\nfunction stringArg(args: Record<string, unknown>, key: string): string | undefined {\r\n const value = args[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction lineCount(text: string): number {\r\n let count = 1;\r\n for (let index = text.indexOf('\\n'); index !== -1; index = text.indexOf('\\n', index + 1)) count++;\r\n return count;\r\n}\r\n\r\ninterface ResolvedTarget {\r\n filePath: string;\r\n canonicalPath: string;\r\n relativePath: string;\r\n}\r\n\r\nfunction resolveTarget(workspaceRoot: string, inputPath: string | undefined): ResolvedTarget {\r\n if (!inputPath) return fail('No file path given');\r\n return (\r\n resolveWorkspacePath(workspaceRoot, inputPath) ?? fail(`Path outside workspace: ${inputPath}`)\r\n );\r\n}\r\n\r\nasync function snapshotOf(target: ResolvedTarget, allowMissing: boolean): Promise<TextSnapshot> {\r\n let snapshot: TextSnapshot;\r\n try {\r\n snapshot = await readTextSnapshot(target.filePath, allowMissing);\r\n } catch (error) {\r\n const code = (error as NodeJS.ErrnoException).code;\r\n return code === 'ENOENT'\r\n ? fail(`File not found: ${target.relativePath}`)\r\n : fail(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`);\r\n }\r\n if (snapshot.binary) fail(`Binary file is unsupported: ${target.relativePath}`);\r\n // Bail before any matching work: every pass below is O(file).\r\n if (lineCount(snapshot.text) > MAX_PREVIEW_LINES) fail(TOO_LARGE);\r\n return snapshot;\r\n}\r\n\r\nasync function diffFile(\r\n target: ResolvedTarget,\r\n kind: MutationPreviewFile['kind'],\r\n before: string,\r\n after: string,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreviewFile> {\r\n if (lineCount(after) > MAX_PREVIEW_LINES) fail(TOO_LARGE);\r\n const { diff, stats } = await renderDiffWithStatsAsync(before, after, 3, signal);\r\n return { filePath: target.relativePath, kind, diff, stats };\r\n}\r\n\r\nasync function previewWrite(\r\n args: Record<string, unknown>,\r\n workspaceRoot: string,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreview> {\r\n const target = resolveTarget(workspaceRoot, stringArg(args, 'filePath'));\r\n const content = stringArg(args, 'content') ?? fail('No content given');\r\n const before = await snapshotOf(target, true);\r\n const after = before.exists ? content.replace(/\\r\\n/g, '\\n') : content;\r\n const kind = before.exists ? 'update' : 'create';\r\n return { files: [await diffFile(target, kind, before.text, after, signal)] };\r\n}\r\n\r\ninterface EditSpec {\r\n oldString: string;\r\n newString: string;\r\n replaceAll: boolean;\r\n}\r\n\r\nfunction editSpec(source: Record<string, unknown>): EditSpec {\r\n const oldString = stringArg(source, 'oldString');\r\n const newString = stringArg(source, 'newString');\r\n if (oldString === undefined || newString === undefined) fail('No edit given');\r\n return {\r\n oldString: oldString.replace(/\\r\\n/g, '\\n'),\r\n newString: newString.replace(/\\r\\n/g, '\\n'),\r\n replaceAll: source.replaceAll === true,\r\n };\r\n}\r\n\r\nfunction multiEditSpecs(args: Record<string, unknown>): EditSpec[] {\r\n const edits = args.edits;\r\n if (!Array.isArray(edits) || edits.length === 0) fail('No edits provided');\r\n return edits.map((item) =>\r\n item && typeof item === 'object' && !Array.isArray(item)\r\n ? editSpec(item as Record<string, unknown>)\r\n : fail('Malformed edit entry'),\r\n );\r\n}\r\n\r\nasync function previewEdits(\r\n args: Record<string, unknown>,\r\n edits: EditSpec[],\r\n atomic: boolean,\r\n workspaceRoot: string,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreview> {\r\n const target = resolveTarget(workspaceRoot, stringArg(args, 'filePath'));\r\n const snapshot = await snapshotOf(target, false);\r\n if (snapshot.mixedLineEndings)\r\n fail(\r\n `Mixed line endings are unsupported for ${atomic ? 'MultiEdit' : 'Edit'}: ${target.relativePath}`,\r\n );\r\n let content = snapshot.text;\r\n for (let index = 0; index < edits.length; index++) {\r\n const edit = edits[index];\r\n const application = await applySingleEdit(\r\n content,\r\n edit.oldString,\r\n edit.newString,\r\n edit.replaceAll,\r\n signal,\r\n atomic ? `Edit ${index + 1}: ` : '',\r\n atomic ? ' (no changes applied — MultiEdit is atomic)' : '',\r\n );\r\n if (!application.ok) failWith(application.failure);\r\n content = application.content;\r\n }\r\n return { files: [await diffFile(target, 'update', snapshot.text, content, signal)] };\r\n}\r\n\r\nasync function previewPatchOperation(\r\n operation: PatchOperation,\r\n target: ResolvedTarget,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreviewFile> {\r\n const before = await snapshotOf(target, operation.kind === 'add');\r\n if (operation.kind === 'add') {\r\n if (before.exists) fail(`File already exists: ${target.relativePath}`);\r\n const after = operation.lines.join('\\n') + (operation.lines.length > 0 ? '\\n' : '');\r\n return diffFile(target, 'create', '', after, signal);\r\n }\r\n if (!before.exists) fail(`File not found: ${target.relativePath}`);\r\n if (operation.kind === 'delete') return diffFile(target, 'delete', before.text, '', signal);\r\n if (before.mixedLineEndings)\r\n fail(`Mixed line endings are unsupported for patch updates: ${target.relativePath}`);\r\n const applied = applyHunks(before.text, operation.hunks);\r\n if (applied.mismatch)\r\n fail(\r\n `${target.relativePath}: ${toolResultErrorMessage(applied.mismatch) ?? applied.mismatch.content}`,\r\n );\r\n return diffFile(target, 'update', before.text, applied.text, signal);\r\n}\r\n\r\nasync function previewPatch(\r\n args: Record<string, unknown>,\r\n workspaceRoot: string,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreview> {\r\n const parsed = parsePatch(args.patch);\r\n if ('version' in parsed) failWith(parsed);\r\n const targets = parsed.operations.map((operation) =>\r\n resolveTarget(workspaceRoot, operation.path),\r\n );\r\n // The tool refuses a patch that names one file twice, before touching anything.\r\n const seen = new Set<string>();\r\n for (const target of targets) {\r\n const key =\r\n process.platform === 'win32' ? target.canonicalPath.toLowerCase() : target.canonicalPath;\r\n if (seen.has(key)) fail('A patch may contain only one operation per file');\r\n seen.add(key);\r\n }\r\n const files: MutationPreviewFile[] = [];\r\n for (let index = 0; index < parsed.operations.length; index++) {\r\n files.push(await previewPatchOperation(parsed.operations[index], targets[index], signal));\r\n }\r\n return { files };\r\n}\r\n\r\n/**\r\n * Compute the diff a pending mutation would produce, or `null` when the tool\r\n * is not one this module understands. Never throws for a bad call: every\r\n * failure the tool would report comes back as {@link MutationPreview.error}.\r\n * Only an aborted `signal` rejects.\r\n */\r\nexport async function previewMutation(\r\n toolCall: ToolCall,\r\n workspaceRoot: string,\r\n signal?: AbortSignal,\r\n): Promise<MutationPreview | null> {\r\n const args = toolCall.arguments ?? {};\r\n try {\r\n switch (canonicalToolName(toolCall.name)) {\r\n case 'Write':\r\n return await previewWrite(args, workspaceRoot, signal);\r\n case 'Edit':\r\n return await previewEdits(args, [editSpec(args)], false, workspaceRoot, signal);\r\n case 'MultiEdit':\r\n return await previewEdits(args, multiEditSpecs(args), true, workspaceRoot, signal);\r\n case 'ApplyPatch':\r\n return await previewPatch(args, workspaceRoot, signal);\r\n default:\r\n return null;\r\n }\r\n } catch (error) {\r\n if (signal?.aborted) throw error;\r\n if (error instanceof PreviewError) return { files: [], error: error.message };\r\n return {\r\n files: [],\r\n error: `Preview failed: ${error instanceof Error ? error.message : String(error)}`,\r\n };\r\n }\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport TextInput from './TextInputField.js';\r\nimport { useCallback, useRef, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { PlanApprovalResult } from '../../types/tools.js';\r\nimport { createUiDebugLogger } from '../../debug-log.js';\r\nimport { useDebugMount } from '../debug.js';\r\nimport { MarkdownBlock } from './MarkdownBlock.js';\r\n\r\nconst uiLog = createUiDebugLogger('tui:planapproval');\r\n\r\ninterface PlanApprovalProps {\r\n plan: string;\r\n screenReader?: boolean;\r\n terminalWidth?: number;\r\n}\r\n\r\ninterface PlanApprovalActionsProps extends PlanApprovalProps {\r\n onResolve: (result: PlanApprovalResult) => void;\r\n}\r\n\r\nconst BUTTONS = [\r\n { label: 'Approve plan', value: 'approve' as const, key: 'a', colorKey: 'success' as const },\r\n {\r\n label: 'Approve, fresh context',\r\n value: 'approve-fresh' as const,\r\n key: 'f',\r\n colorKey: 'success' as const,\r\n },\r\n { label: 'Adjust plan', value: 'revise' as const, key: 'e', colorKey: 'warning' as const },\r\n { label: 'Reject plan', value: 'reject' as const, key: 'r', colorKey: 'error' as const },\r\n];\r\n\r\n// Minimum terminal width to lay the buttons out in a row; below this they stack.\r\n// Derived from the labels (each renders as \"<prefix><label> (<Key>)\" with a margin)\r\n// so it scales automatically when buttons are added or renamed.\r\nconst ROW_LAYOUT_MIN_WIDTH = BUTTONS.reduce((sum, button) => sum + button.label.length + 8, 0) + 4;\r\n\r\nfunction countSteps(lines: string[]): number {\r\n return lines.filter((line) => /^\\d+[\\.\\)]\\s/.test(line)).length;\r\n}\r\n\r\nfunction normalizePlanMarkdown(lines: string[]): string {\r\n return lines\r\n .map((line) => {\r\n const indentedHeading = line.match(/^(\\s+)#{1,3}\\s+(.*)$/);\r\n return indentedHeading ? `${indentedHeading[1]}${indentedHeading[2]}` : line;\r\n })\r\n .join('\\n');\r\n}\r\n\r\nexport function PlanApprovalDetails({\r\n plan,\r\n screenReader = false,\r\n terminalWidth,\r\n}: PlanApprovalProps) {\r\n const theme = useTheme();\r\n const lines = plan.split('\\n');\r\n const stepCount = countSteps(lines);\r\n const normalizedPlan = normalizePlanMarkdown(lines);\r\n\r\n if (screenReader) return <Text>{plan}</Text>;\r\n\r\n return (\r\n <Box\r\n marginLeft={2}\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.planMode}\r\n paddingX={1}\r\n >\r\n <Box>\r\n <Text bold color={theme.planMode}>\r\n Plan\r\n </Text>\r\n <Text color={theme.subtle}> · approval</Text>\r\n {stepCount > 0 ? (\r\n <Text color={theme.subtle}>\r\n {' '}\r\n · {stepCount} step{stepCount === 1 ? '' : 's'}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n <Box flexDirection=\"column\" paddingLeft={1}>\r\n <MarkdownBlock\r\n content={normalizedPlan}\r\n terminalWidth={\r\n terminalWidth === undefined ? undefined : Math.max(12, Math.floor(terminalWidth) - 8)\r\n }\r\n />\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n\r\nexport function PlanApprovalActions({\r\n plan,\r\n onResolve,\r\n screenReader = false,\r\n terminalWidth,\r\n}: PlanApprovalActionsProps) {\r\n const theme = useTheme();\r\n // `useKeyState` rather than `useState`: both of these are read back by the\r\n // key handler, and Ink delivers a whole stdin chunk in one React batch. With\r\n // plain state a batched `→`+Enter resolved the button that was armed before\r\n // the arrow — approving a plan the user had moved off.\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n const [feedbackMode, setFeedbackMode, inFeedbackMode] = useKeyState(false);\r\n const [feedback, setFeedback] = useState('');\r\n const [feedbackError, setFeedbackError] = useState<string | null>(null);\r\n const resolvedRef = useRef(false);\r\n const lines = plan.split('\\n');\r\n useDebugMount(uiLog, {\r\n planLength: plan.length,\r\n lineCount: lines.length,\r\n stepCount: countSteps(lines),\r\n });\r\n\r\n const resolveOnce = useCallback(\r\n (value: PlanApprovalResult) => {\r\n if (resolvedRef.current) return;\r\n resolvedRef.current = true;\r\n uiLog.event('resolve', { result: value, selected: currentSelected() });\r\n onResolve(value);\r\n },\r\n [onResolve, currentSelected],\r\n );\r\n\r\n useInput((input, key) => {\r\n if (inFeedbackMode()) {\r\n if (key.escape) {\r\n setFeedbackMode(false);\r\n setFeedbackError(null);\r\n }\r\n return;\r\n }\r\n\r\n if (key.leftArrow || (key.shift && key.tab)) {\r\n setSelected((currentSelected() - 1 + BUTTONS.length) % BUTTONS.length);\r\n } else if (key.rightArrow || key.tab) {\r\n setSelected((currentSelected() + 1) % BUTTONS.length);\r\n } else if (key.return || input === ' ') {\r\n const value = BUTTONS[currentSelected()].value;\r\n if (value === 'revise') {\r\n setFeedbackMode(true);\r\n setFeedbackError(null);\r\n } else {\r\n resolveOnce(value);\r\n }\r\n } else if (key.escape) {\r\n resolveOnce('reject');\r\n } else if (input.toLowerCase() === 'a') {\r\n resolveOnce('approve');\r\n } else if (input.toLowerCase() === 'f') {\r\n resolveOnce('approve-fresh');\r\n } else if (input.toLowerCase() === 'e') {\r\n setSelected(BUTTONS.findIndex((button) => button.value === 'revise'));\r\n setFeedbackMode(true);\r\n setFeedbackError(null);\r\n } else if (['r', 's'].includes(input.toLowerCase())) {\r\n resolveOnce('reject');\r\n }\r\n });\r\n\r\n if (screenReader && !feedbackMode) {\r\n return (\r\n <Text>\r\n Plan approval required. Press A to approve, F to approve and implement with a fresh context,\r\n E to request adjustments, or R or Escape to reject.\r\n </Text>\r\n );\r\n }\r\n\r\n if (feedbackMode) {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.warning} paddingX={1}>\r\n <Text bold color={theme.warning}>\r\n Request plan adjustments\r\n </Text>\r\n <Text color={theme.subtle}>Tell Book what should change before implementation starts.</Text>\r\n <Box marginTop={1}>\r\n <Text color={theme.warning}>› </Text>\r\n <TextInput\r\n value={feedback}\r\n placeholder=\"Add feedback for the revised plan\"\r\n onChange={(value) => {\r\n setFeedback(value.slice(0, 2000));\r\n if (feedbackError) setFeedbackError(null);\r\n }}\r\n onSubmit={(value) => {\r\n const normalized = value.trim();\r\n if (!normalized) {\r\n setFeedbackError('Add feedback before requesting changes.');\r\n return;\r\n }\r\n resolveOnce({ decision: 'revise', feedback: normalized });\r\n }}\r\n />\r\n </Box>\r\n {feedbackError ? <Text color={theme.error}>{feedbackError}</Text> : null}\r\n <Text color={theme.subtle} dimColor>\r\n Enter send feedback · Esc return to choices\r\n </Text>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.planMode} paddingX={1}>\r\n <Box\r\n flexDirection={\r\n terminalWidth !== undefined && terminalWidth < ROW_LAYOUT_MIN_WIDTH ? 'column' : 'row'\r\n }\r\n >\r\n {BUTTONS.map((button, index) => {\r\n const active = index === selected;\r\n const color = theme[button.colorKey];\r\n return (\r\n <Box\r\n key={button.value}\r\n marginRight={\r\n terminalWidth !== undefined && terminalWidth < ROW_LAYOUT_MIN_WIDTH ? 0 : 2\r\n }\r\n >\r\n <Text\r\n backgroundColor={active ? theme.surfaceActive : undefined}\r\n color={active ? theme.selectionText : color}\r\n bold={active}\r\n >\r\n {active ? '▸ ' : ' '}\r\n {button.label} ({button.key.toUpperCase()})\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n ← → to select · Enter to confirm · A/F/E/R shortcuts · Esc to reject\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Fresh context (F) discards the planning conversation and implements the plan clean.\r\n </Text>\r\n </Box>\r\n );\r\n}\r\n\r\n/** Backward-compatible combined surface used by focused component tests. */\r\nexport function PlanApprovalButtons(props: PlanApprovalActionsProps) {\r\n return (\r\n <Box flexDirection=\"column\">\r\n <PlanApprovalDetails\r\n plan={props.plan}\r\n screenReader={props.screenReader}\r\n terminalWidth={props.terminalWidth}\r\n />\r\n <PlanApprovalActions {...props} />\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport TextInput from './TextInputField.js';\r\nimport { useCallback, useMemo, useRef, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport type { UserQuestion, UserQuestionRequest, UserQuestionResponse } from '../../types/tools.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { floatingFrameMetrics } from './chrome.js';\r\n\r\ninterface AskUserQuestionWizardProps {\r\n request: UserQuestionRequest;\r\n queueLength?: number;\r\n terminalWidth?: number;\r\n onResolve: (response: UserQuestionResponse) => void;\r\n screenReader?: boolean;\r\n}\r\n\r\n/**\r\n * Option labels chosen (single-select) or toggled (multi-select), by question\r\n * index. Keyed by index rather than by question text so a question the model\r\n * happened to call `constructor` or `__proto__` cannot read an inherited member\r\n * of `Object.prototype` where an array was expected.\r\n */\r\ntype Choices = Record<number, string[]>;\r\n\r\n/** The Other-row text, by question index. Kept apart from the labels: see {@link answerValues}. */\r\ntype CustomAnswers = Record<number, string>;\r\n\r\nfunction sourceLabel(request: UserQuestionRequest): string {\r\n if (request.source.kind === 'root') return 'Book';\r\n return request.source.agentPath.join(' / ');\r\n}\r\n\r\n/** The host validator compares answers this way; matching it here keeps a duplicate from leaving. */\r\nfunction normalizeLabel(value: string): string {\r\n return value.trim().toLocaleLowerCase();\r\n}\r\n\r\n/**\r\n * The value a question is answered with. Custom text lives beside the toggled\r\n * labels rather than among them, so toggling an option can never delete it and\r\n * an exact-match filter can never mistake one for the other.\r\n */\r\nfunction answerValues(\r\n question: UserQuestion,\r\n index: number,\r\n choices: Choices,\r\n custom: CustomAnswers,\r\n): string[] {\r\n const labels = choices[index] ?? [];\r\n const text = custom[index];\r\n if (question.multiSelect) return text ? [...labels, text] : labels;\r\n return text ? [text] : labels;\r\n}\r\n\r\nfunction normalizeAnswers(\r\n questions: UserQuestion[],\r\n choices: Choices,\r\n custom: CustomAnswers,\r\n): Record<string, string | string[]> | null {\r\n const entries: [string, string | string[]][] = [];\r\n for (const [index, question] of questions.entries()) {\r\n const values = answerValues(question, index, choices, custom);\r\n if (values.length === 0) return null;\r\n entries.push([question.question, question.multiSelect ? values : values[0]]);\r\n }\r\n // fromEntries defines own properties, so a question literally named\r\n // `__proto__` lands as an answer key rather than replacing the prototype.\r\n return Object.fromEntries(entries);\r\n}\r\n\r\nexport function AskUserQuestionWizard({\r\n request,\r\n queueLength = 1,\r\n terminalWidth = 80,\r\n onResolve,\r\n screenReader = false,\r\n}: AskUserQuestionWizardProps) {\r\n const theme = useTheme();\r\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\r\n const frame = floatingFrameMetrics(outerWidth);\r\n const contentWidth = Math.max(14, frame.width - 4);\r\n const compact = outerWidth < 60;\r\n // Everything the key handler reads back is batch-safe: Ink delivers a whole\r\n // stdin chunk in one React batch, so plain state would still show the value\r\n // from before the first key. Helpers take the question *index* and resolve it\r\n // against `request.questions` (props), never against `question` below, which\r\n // is one batch behind after a back + Enter.\r\n const [questionIndex, setQuestionIndex, currentQuestion] = useKeyState(0);\r\n const [cursor, setCursor, currentCursor] = useKeyState(0);\r\n const [choices, setChoices, currentChoices] = useKeyState<Choices>({});\r\n const [customAnswers, setCustomAnswers, currentCustom] = useKeyState<CustomAnswers>({});\r\n const [otherMode, setOtherMode, inOtherMode] = useKeyState(false);\r\n const [otherValue, setOtherValue, currentOtherValue] = useKeyState('');\r\n const [notice, setNotice] = useState<string | null>(null);\r\n const resolvedRef = useRef(false);\r\n const question = request.questions[questionIndex];\r\n const selected = choices[questionIndex] ?? [];\r\n const customAnswer = customAnswers[questionIndex];\r\n\r\n const resolveOnce = useCallback(\r\n (response: UserQuestionResponse) => {\r\n if (resolvedRef.current) return;\r\n resolvedRef.current = true;\r\n onResolve(response);\r\n },\r\n [onResolve],\r\n );\r\n\r\n const setChoice = useCallback(\r\n (index: number, labels: string[]) => {\r\n setChoices({ ...currentChoices(), [index]: labels });\r\n },\r\n [currentChoices, setChoices],\r\n );\r\n\r\n const setCustom = useCallback(\r\n (index: number, text: string | undefined) => {\r\n const next = { ...currentCustom() };\r\n if (text === undefined) delete next[index];\r\n else next[index] = text;\r\n setCustomAnswers(next);\r\n },\r\n [currentCustom, setCustomAnswers],\r\n );\r\n\r\n const advance = useCallback(() => {\r\n const index = currentQuestion();\r\n if (index === request.questions.length - 1) {\r\n const normalized = normalizeAnswers(request.questions, currentChoices(), currentCustom());\r\n if (!normalized) {\r\n setNotice('Choose at least one answer to continue.');\r\n return;\r\n }\r\n resolveOnce({ action: 'answer', answers: normalized });\r\n return;\r\n }\r\n setQuestionIndex(index + 1);\r\n setCursor(0);\r\n setNotice(null);\r\n }, [\r\n currentQuestion,\r\n currentChoices,\r\n currentCustom,\r\n request.questions,\r\n resolveOnce,\r\n setQuestionIndex,\r\n setCursor,\r\n ]);\r\n\r\n const chooseKnownOption = useCallback(\r\n (index: number, optionIndex: number) => {\r\n const target = request.questions[index];\r\n const label = target?.options[optionIndex]?.label;\r\n if (!label) return;\r\n setNotice(null);\r\n if (!target.multiSelect) {\r\n setCustom(index, undefined);\r\n setChoice(index, [label]);\r\n advance();\r\n return;\r\n }\r\n const labels = currentChoices()[index] ?? [];\r\n setChoice(\r\n index,\r\n labels.includes(label) ? labels.filter((value) => value !== label) : [...labels, label],\r\n );\r\n },\r\n [request.questions, currentChoices, setChoice, setCustom, advance],\r\n );\r\n\r\n const openOther = useCallback(\r\n (index: number) => {\r\n setOtherValue(currentCustom()[index] ?? '');\r\n setOtherMode(true);\r\n setNotice(null);\r\n },\r\n [currentCustom, setOtherValue, setOtherMode],\r\n );\r\n\r\n const submitOther = useCallback(\r\n (index: number) => {\r\n const target = request.questions[index];\r\n if (!target) return;\r\n const text = currentOtherValue().trim();\r\n if (!text) {\r\n setNotice('Type an answer before continuing.');\r\n return;\r\n }\r\n setOtherMode(false);\r\n setOtherValue('');\r\n // Text that names an option is that option. Stored as custom text it\r\n // would reach the host as a duplicate, and the validator then discards\r\n // every answer in the request.\r\n const key = normalizeLabel(text);\r\n const match = target.options.findIndex((option) => normalizeLabel(option.label) === key);\r\n if (match >= 0) {\r\n if (!target.multiSelect) {\r\n chooseKnownOption(index, match);\r\n return;\r\n }\r\n const label = target.options[match].label;\r\n const labels = currentChoices()[index] ?? [];\r\n setCustom(index, undefined);\r\n setChoice(index, labels.includes(label) ? labels : [...labels, label]);\r\n advance();\r\n return;\r\n }\r\n if (!target.multiSelect) setChoice(index, []);\r\n setCustom(index, text);\r\n advance();\r\n },\r\n [\r\n request.questions,\r\n currentOtherValue,\r\n currentChoices,\r\n setOtherMode,\r\n setOtherValue,\r\n setChoice,\r\n setCustom,\r\n chooseKnownOption,\r\n advance,\r\n ],\r\n );\r\n\r\n useInput((input, key) => {\r\n const index = currentQuestion();\r\n if (inOtherMode()) {\r\n // This handler is the only owner of Enter while the editor is open; the\r\n // TextInput below has no onSubmit. Two listeners on one keypress meant\r\n // the second saw the mode flag already flipped and answered the next\r\n // question with its first option before it was ever shown.\r\n if (key.return) submitOther(index);\r\n else if (key.escape) {\r\n setOtherMode(false);\r\n setNotice(null);\r\n }\r\n return;\r\n }\r\n\r\n const activeQuestion = request.questions[index];\r\n if (!activeQuestion) return;\r\n\r\n const activeCursor = currentCursor();\r\n const otherRow = activeQuestion.options.length;\r\n const rowCount = otherRow + 1;\r\n\r\n // A single digit, not anything Number() would coerce: a pasted line that\r\n // starts with \" 1\" or \"1.0\" is text, not the quick-choose the footer offers.\r\n if (/^[1-9]$/.test(input) && Number(input) <= otherRow) {\r\n setCursor(Number(input) - 1);\r\n chooseKnownOption(index, Number(input) - 1);\r\n return;\r\n }\r\n if (key.upArrow || (key.shift && key.tab)) {\r\n setCursor((activeCursor - 1 + rowCount) % rowCount);\r\n setNotice(null);\r\n } else if (key.downArrow || key.tab) {\r\n setCursor((activeCursor + 1) % rowCount);\r\n setNotice(null);\r\n } else if (input === ' ' && activeQuestion.multiSelect) {\r\n if (activeCursor === otherRow) {\r\n if (currentCustom()[index]) setCustom(index, undefined);\r\n else openOther(index);\r\n } else {\r\n chooseKnownOption(index, activeCursor);\r\n }\r\n } else if (key.return) {\r\n if (activeCursor === otherRow) {\r\n openOther(index);\r\n } else if (activeQuestion.multiSelect) {\r\n const values = answerValues(activeQuestion, index, currentChoices(), currentCustom());\r\n if (values.length === 0) setNotice('Select one or more options first.');\r\n else advance();\r\n } else {\r\n chooseKnownOption(index, activeCursor);\r\n }\r\n } else if (input.toLowerCase() === 'o') {\r\n setCursor(otherRow);\r\n openOther(index);\r\n } else if ((input.toLowerCase() === 'b' || key.leftArrow) && index > 0) {\r\n setQuestionIndex(index - 1);\r\n setCursor(0);\r\n setNotice(null);\r\n } else if (input.toLowerCase() === 'd') {\r\n resolveOnce({ action: 'decline' });\r\n } else if (key.escape) {\r\n resolveOnce({ action: 'cancel' });\r\n }\r\n });\r\n\r\n const selectedSet = useMemo(() => new Set(selected), [selected]);\r\n const source = truncateDisplay(\r\n sourceLabel(request),\r\n compact ? contentWidth - 9 : contentWidth - 18,\r\n );\r\n const progress = `${questionIndex + 1} of ${request.questions.length}`;\r\n const queueText = queueLength > 1 ? ` · ${queueLength - 1} waiting` : '';\r\n\r\n return (\r\n <Box\r\n width={frame.width}\r\n marginX={frame.marginX}\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n >\r\n <Box justifyContent=\"space-between\">\r\n <Text bold color={theme.brand}>\r\n ? {source}\r\n </Text>\r\n <Text color={theme.subtle}>\r\n {progress}\r\n {queueText}\r\n </Text>\r\n </Box>\r\n\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text bold color={theme.brand}>\r\n {question.header.toUpperCase()}\r\n </Text>\r\n <Text bold color={theme.text}>\r\n {question.question}\r\n </Text>\r\n </Box>\r\n\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {question.options.map((option, index) => {\r\n const active = index === cursor && !otherMode;\r\n const checked = selectedSet.has(option.label);\r\n const marker = question.multiSelect ? (checked ? '■' : '□') : checked ? '●' : '○';\r\n const description = truncateDisplay(\r\n option.description,\r\n compact ? contentWidth - 5 : Math.max(16, contentWidth - option.label.length - 9),\r\n );\r\n return (\r\n <Box\r\n key={option.label}\r\n paddingLeft={1}\r\n flexDirection={compact ? 'column' : 'row'}\r\n backgroundColor={active ? theme.surfaceActive : undefined}\r\n >\r\n <Text\r\n bold={active || checked}\r\n color={active ? theme.selectionText : checked ? theme.success : theme.text}\r\n >\r\n {active ? '›' : ' '} {marker} {index + 1}. {option.label}\r\n </Text>\r\n <Text color={active ? theme.selectionText : theme.subtle}>\r\n {compact ? ` ${description}` : ` — ${description}`}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n\r\n <Box\r\n paddingLeft={1}\r\n backgroundColor={cursor === question.options.length ? theme.surfaceActive : undefined}\r\n >\r\n <Text\r\n bold={cursor === question.options.length || Boolean(customAnswer)}\r\n color={\r\n cursor === question.options.length\r\n ? theme.selectionText\r\n : customAnswer\r\n ? theme.success\r\n : theme.text\r\n }\r\n >\r\n {cursor === question.options.length ? '›' : ' '} {customAnswer ? '■' : '+'} Other\r\n {customAnswer\r\n ? `: ${truncateDisplay(customAnswer, Math.max(8, contentWidth - 14))}`\r\n : '…'}\r\n </Text>\r\n </Box>\r\n </Box>\r\n\r\n {otherMode ? (\r\n <Box\r\n flexDirection=\"column\"\r\n marginTop={1}\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n >\r\n <Text bold color={theme.brand}>\r\n Your answer\r\n </Text>\r\n <Box>\r\n <Text color={theme.brand}>› </Text>\r\n <TextInput\r\n value={otherValue}\r\n onChange={(value) => setOtherValue(value.slice(0, 2000))}\r\n />\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n Enter use answer · Esc return to choices\r\n </Text>\r\n </Box>\r\n ) : null}\r\n\r\n {notice ? <Text color={theme.warning}>! {notice}</Text> : null}\r\n\r\n {!otherMode ? (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color={theme.subtle} dimColor>\r\n {screenReader\r\n ? question.multiSelect\r\n ? 'Use Up and Down to move. Space or number keys toggle choices. Enter confirms. O writes another answer. Escape cancels.'\r\n : 'Use Up and Down to move. Number keys choose. Enter confirms. O writes another answer. Escape cancels.'\r\n : compact\r\n ? question.multiSelect\r\n ? '↑↓ move · Space toggle · Enter next'\r\n : '↑↓ move · Enter choose · O custom'\r\n : question.multiSelect\r\n ? '↑↓ move · Space toggle · Enter continue · 1-4 quick toggle'\r\n : '↑↓ move · Enter choose · 1-4 quick choose · O custom'}\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n {questionIndex > 0 ? '←/B back · ' : ''}D decline · Esc cancel\r\n {!compact ? ' · Keep secrets private' : ''}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport TextInput from './TextInputField.js';\r\nimport { useCallback, useMemo, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport {\r\n coerceElicitationValue,\r\n elicitationDefaults,\r\n validateElicitationField,\r\n} from '../../mcp-elicitation.js';\r\nimport type {\r\n ElicitationField,\r\n ElicitationRequest,\r\n ElicitationResponse,\r\n ElicitationValue,\r\n} from '../../types/tools.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\nimport { floatingFrameMetrics } from './chrome.js';\r\n\r\ninterface McpElicitationFormProps {\r\n request: ElicitationRequest;\r\n queueLength?: number;\r\n terminalWidth?: number;\r\n onResolve: (response: ElicitationResponse) => void;\r\n screenReader?: boolean;\r\n}\r\n\r\n/** Visible option rows for an enum field; longer lists scroll under the cursor. */\r\nconst OPTION_WINDOW = 6;\r\n\r\nfunction displayValue(field: ElicitationField, value: ElicitationValue | undefined): string {\r\n if (value === undefined || value === '') return '—';\r\n if (field.kind === 'boolean') return value ? 'yes' : 'no';\r\n if (field.kind === 'enum') {\r\n const option = field.options.find((entry) => entry.value === value);\r\n return option?.label ?? String(value);\r\n }\r\n return String(value);\r\n}\r\n\r\nfunction matchingOptions(\r\n field: Extract<ElicitationField, { kind: 'enum' }>,\r\n filter: string,\r\n): Array<{ value: string; label: string }> {\r\n const needle = filter.trim().toLowerCase();\r\n if (!needle) return field.options;\r\n return field.options.filter(\r\n (option) =>\r\n option.label.toLowerCase().includes(needle) || option.value.toLowerCase().includes(needle),\r\n );\r\n}\r\n\r\n/** Offset that keeps the cursor inside a fixed-height window over a long list. */\r\nexport function optionWindowStart(cursor: number, total: number, size = OPTION_WINDOW): number {\r\n if (total <= size) return 0;\r\n const half = Math.floor(size / 2);\r\n return Math.min(Math.max(0, cursor - half), total - size);\r\n}\r\n\r\n/**\r\n * Form for an MCP `elicitation/create` request: the server asks, the user\r\n * answers, and the answer travels back inside the still-open tool call.\r\n */\r\nexport function McpElicitationForm({\r\n request,\r\n queueLength = 1,\r\n terminalWidth = 80,\r\n onResolve,\r\n screenReader = false,\r\n}: McpElicitationFormProps) {\r\n const theme = useTheme();\r\n const outerWidth = Math.max(20, Math.floor(terminalWidth));\r\n const frame = floatingFrameMetrics(outerWidth);\r\n const contentWidth = Math.max(14, frame.width - 4);\r\n const compact = outerWidth < 60;\r\n const [values, setValues] = useState<Record<string, ElicitationValue>>(() =>\r\n elicitationDefaults(request.fields),\r\n );\r\n // Read back by the key handler. Ink delivers a whole stdin chunk in one React\r\n // batch, so with plain state a batched arrow+Enter opened the field the cursor\r\n // had left — or submitted the form, when the arrow had moved off the submit\r\n // row.\r\n const [cursor, setCursor, currentCursor] = useKeyState(0);\r\n // `editing` deliberately stays plain render state. The enum row's Enter\r\n // belongs to the filter input's `onSubmit`, and the guard below relies on\r\n // still reading `true` when Ink's handler sees the same keypress. Making it\r\n // batch-safe let the handler fall through and advance a second time, which\r\n // skipped the next field entirely.\r\n const [editing, setEditing] = useState(false);\r\n const [draft, setDraft] = useState('');\r\n const [optionCursor, setOptionCursor, currentOption] = useKeyState(0);\r\n const [notice, setNotice] = useState<string | null>(null);\r\n const [resolved, setResolved] = useState(false);\r\n\r\n const rowCount = request.fields.length + 1;\r\n const submitRow = request.fields.length;\r\n const field = request.fields[cursor];\r\n const options = useMemo(\r\n () => (field?.kind === 'enum' ? matchingOptions(field, editing ? draft : '') : []),\r\n [field, editing, draft],\r\n );\r\n\r\n const resolveOnce = useCallback(\r\n (response: ElicitationResponse) => {\r\n if (resolved) return;\r\n setResolved(true);\r\n onResolve(response);\r\n },\r\n [onResolve, resolved],\r\n );\r\n\r\n const submit = useCallback(() => {\r\n for (const [index, entry] of request.fields.entries()) {\r\n const error = validateElicitationField(entry, values[entry.name]);\r\n if (error) {\r\n setCursor(index);\r\n setNotice(error);\r\n return;\r\n }\r\n }\r\n const content: Record<string, ElicitationValue> = {};\r\n for (const entry of request.fields) {\r\n const value = values[entry.name];\r\n if (value === undefined || value === '') continue;\r\n content[entry.name] = value;\r\n }\r\n resolveOnce({ action: 'accept', content });\r\n }, [request.fields, resolveOnce, values]);\r\n\r\n // Takes the row rather than closing over `field`. The caller is a key handler\r\n // that may have moved the cursor earlier in the same React batch, so the\r\n // field this opens has to be resolved from the batch-safe cursor — otherwise\r\n // an arrow off the send row left `field` undefined and opened nothing.\r\n const beginEdit = useCallback(\r\n (row: number) => {\r\n const target = request.fields[row];\r\n if (!target) return;\r\n setNotice(null);\r\n if (target.kind === 'boolean') {\r\n setValues((current) => ({ ...current, [target.name]: !current[target.name] }));\r\n return;\r\n }\r\n if (target.kind === 'enum') {\r\n const current = values[target.name];\r\n const index = target.options.findIndex((option) => option.value === current);\r\n setOptionCursor(Math.max(0, index));\r\n setDraft('');\r\n setEditing(true);\r\n return;\r\n }\r\n const current = values[target.name];\r\n setDraft(current === undefined ? '' : String(current));\r\n setEditing(true);\r\n },\r\n [request.fields, values, setOptionCursor],\r\n );\r\n\r\n const commitOption = useCallback(() => {\r\n if (field?.kind !== 'enum') return;\r\n const option = options[optionCursor];\r\n if (!option) {\r\n setNotice('No matching choice.');\r\n return;\r\n }\r\n setValues((current) => ({ ...current, [field.name]: option.value }));\r\n setEditing(false);\r\n setDraft('');\r\n setNotice(null);\r\n setCursor(Math.min(currentCursor() + 1, submitRow));\r\n }, [field, options, optionCursor, submitRow]);\r\n\r\n const commitText = useCallback(\r\n (raw: string) => {\r\n if (!field || field.kind === 'boolean' || field.kind === 'enum') return;\r\n const parsed = coerceElicitationValue(field, raw);\r\n if (typeof parsed === 'number' && Number.isNaN(parsed)) {\r\n setNotice(`${field.title} must be a number`);\r\n return;\r\n }\r\n const error = validateElicitationField(field, parsed);\r\n if (error) {\r\n setNotice(error);\r\n return;\r\n }\r\n setValues((current) => {\r\n const next = { ...current };\r\n if (parsed === undefined) delete next[field.name];\r\n else next[field.name] = parsed;\r\n return next;\r\n });\r\n setEditing(false);\r\n setDraft('');\r\n setNotice(null);\r\n setCursor(Math.min(currentCursor() + 1, submitRow));\r\n },\r\n [field, submitRow],\r\n );\r\n\r\n useInput((input, key) => {\r\n if (editing) {\r\n if (key.escape) {\r\n setEditing(false);\r\n setDraft('');\r\n setNotice(null);\r\n return;\r\n }\r\n if (field?.kind === 'enum') {\r\n // Enter belongs to the filter input's onSubmit; handling it here too\r\n // would commit the choice twice and skip a field.\r\n if (key.upArrow) setOptionCursor(Math.max(0, currentOption() - 1));\r\n else if (key.downArrow) {\r\n setOptionCursor(Math.min(Math.max(0, options.length - 1), currentOption() + 1));\r\n }\r\n return;\r\n }\r\n return;\r\n }\r\n\r\n if (key.upArrow || (key.shift && key.tab)) {\r\n setCursor((currentCursor() - 1 + rowCount) % rowCount);\r\n setNotice(null);\r\n } else if (key.downArrow || key.tab) {\r\n setCursor((currentCursor() + 1) % rowCount);\r\n setNotice(null);\r\n } else if (key.return || input === ' ') {\r\n if (currentCursor() === submitRow) submit();\r\n else beginEdit(currentCursor());\r\n } else if (input.toLowerCase() === 'd') {\r\n resolveOnce({ action: 'decline' });\r\n } else if (key.escape) {\r\n resolveOnce({ action: 'cancel' });\r\n }\r\n });\r\n\r\n // `field` is undefined while the cursor rests on the send row — that is a\r\n // normal state, not a reason to stop rendering the form.\r\n const queueText = queueLength > 1 ? ` · ${queueLength - 1} waiting` : '';\r\n const windowStart = optionWindowStart(optionCursor, options.length);\r\n const windowed = options.slice(windowStart, windowStart + OPTION_WINDOW);\r\n\r\n return (\r\n <Box\r\n width={frame.width}\r\n marginX={frame.marginX}\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n >\r\n <Box justifyContent=\"space-between\">\r\n <Text bold color={theme.brand}>\r\n ? {truncateDisplay(request.server, Math.max(8, contentWidth - 18))}\r\n </Text>\r\n <Text color={theme.subtle}>MCP request{queueText}</Text>\r\n </Box>\r\n\r\n <Box marginTop={1}>\r\n <Text bold color={theme.text}>\r\n {request.message}\r\n </Text>\r\n </Box>\r\n\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {request.fields.map((entry, index) => {\r\n const active = index === cursor;\r\n const value = displayValue(entry, values[entry.name]);\r\n const label = `${entry.title}${entry.required ? '*' : ''}`;\r\n return (\r\n <Box\r\n key={entry.name}\r\n paddingLeft={1}\r\n flexDirection={compact ? 'column' : 'row'}\r\n backgroundColor={active && !editing ? theme.surfaceActive : undefined}\r\n >\r\n <Text bold={active} color={active ? theme.selectionText : theme.text}>\r\n {active ? '›' : ' '} {label}\r\n </Text>\r\n <Text color={active ? theme.selectionText : theme.subtle}>\r\n {compact\r\n ? ` ${value}`\r\n : ` — ${truncateDisplay(value, Math.max(8, contentWidth - label.length - 6))}`}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n\r\n <Box\r\n paddingLeft={1}\r\n backgroundColor={cursor === submitRow ? theme.surfaceActive : undefined}\r\n >\r\n <Text\r\n bold={cursor === submitRow}\r\n color={cursor === submitRow ? theme.selectionText : theme.text}\r\n >\r\n {cursor === submitRow ? '›' : ' '} ✓ Send to {request.server}\r\n </Text>\r\n </Box>\r\n </Box>\r\n\r\n {editing && field ? (\r\n <Box\r\n flexDirection=\"column\"\r\n marginTop={1}\r\n borderStyle=\"round\"\r\n borderColor={theme.border}\r\n paddingX={1}\r\n >\r\n <Text bold color={theme.brand}>\r\n {field.title}\r\n </Text>\r\n {field.description ? (\r\n <Text color={theme.subtle} dimColor>\r\n {truncateDisplay(field.description, contentWidth - 2)}\r\n </Text>\r\n ) : null}\r\n {field.kind === 'enum' ? (\r\n <Box flexDirection=\"column\">\r\n <Box>\r\n <Text color={theme.brand}>filter › </Text>\r\n <TextInput\r\n value={draft}\r\n onChange={(value) => {\r\n setDraft(value);\r\n setOptionCursor(0);\r\n }}\r\n onSubmit={commitOption}\r\n />\r\n </Box>\r\n {windowed.map((option, index) => {\r\n const active = windowStart + index === optionCursor;\r\n return (\r\n <Text\r\n key={option.value}\r\n bold={active}\r\n color={active ? theme.selectionText : theme.text}\r\n backgroundColor={active ? theme.surfaceActive : undefined}\r\n >\r\n {active ? '›' : ' '} {truncateDisplay(option.label, contentWidth - 4)}\r\n </Text>\r\n );\r\n })}\r\n {options.length > windowed.length ? (\r\n <Text color={theme.subtle} dimColor>\r\n {options.length} choices · showing {windowStart + 1}-\r\n {windowStart + windowed.length}\r\n </Text>\r\n ) : null}\r\n </Box>\r\n ) : (\r\n <Box>\r\n <Text color={theme.brand}>› </Text>\r\n <TextInput\r\n value={draft}\r\n onChange={(value) => setDraft(value.slice(0, 2000))}\r\n onSubmit={commitText}\r\n />\r\n </Box>\r\n )}\r\n <Text color={theme.subtle} dimColor>\r\n {field.kind === 'enum'\r\n ? '↑↓ move · type to filter · Enter choose · Esc back'\r\n : 'Enter save · Esc back'}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n\r\n {notice ? <Text color={theme.warning}>! {notice}</Text> : null}\r\n\r\n {!editing ? (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color={theme.subtle} dimColor>\r\n {screenReader\r\n ? 'Use Up and Down to move between fields. Enter edits a field or sends the form. D declines. Escape cancels.'\r\n : compact\r\n ? '↑↓ move · Enter edit/send'\r\n : '↑↓ move · Enter edit field or send · * required'}\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n D decline · Esc cancel\r\n {!compact ? ' · Keep secrets private' : ''}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { McpHostServerSnapshot } from '../../mcp-host.js';\r\nimport { SelectionRow, SoftPanel, PanelTitle } from './chrome.js';\r\n\r\ninterface McpServerApprovalPromptProps {\r\n server: McpHostServerSnapshot;\r\n /** Additional servers still waiting after this one. */\r\n remainingCount: number;\r\n onApprove: () => { ok: boolean; error?: string };\r\n onReject: () => { ok: boolean; error?: string };\r\n onDefer: () => void;\r\n}\r\n\r\nconst OPTIONS = [\r\n {\r\n key: 'approve' as const,\r\n label: 'Approve and connect',\r\n hint: 'saved to .book/settings.local.json',\r\n },\r\n { key: 'reject' as const, label: 'Reject', hint: 'saved; will not connect in this project' },\r\n];\r\n\r\n/**\r\n * One-time trust prompt for a server declared in the workspace `.mcp.json`.\r\n * The full non-secret connection target is always shown. Header names are\r\n * listed separately while their values remain redacted.\r\n */\r\nexport function McpServerApprovalPrompt({\r\n server,\r\n remainingCount,\r\n onApprove,\r\n onReject,\r\n onDefer,\r\n}: McpServerApprovalPromptProps) {\r\n const theme = useTheme();\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n const [error, setError] = useState<string>();\r\n\r\n const decide = (key: (typeof OPTIONS)[number]['key']) => {\r\n const result = key === 'approve' ? onApprove() : onReject();\r\n if (!result.ok) setError(result.error ?? 'Could not save the decision.');\r\n };\r\n\r\n useInput((input, key) => {\r\n if (key.escape) return onDefer();\r\n if (key.upArrow || key.downArrow) {\r\n setSelected((currentSelected() + 1) % OPTIONS.length);\r\n setError(undefined);\r\n return;\r\n }\r\n // `currentSelected()`, not `selected`: a batched `↓`+Enter — one paste, one\r\n // fast repeat — used to confirm the option armed before the arrow, which on\r\n // a two-option trust gate means approving the server the user moved off.\r\n if (key.return) return decide(OPTIONS[currentSelected()].key);\r\n if (input === 'y' || input === 'Y') return decide('approve');\r\n if (input === 'n' || input === 'N') return decide('reject');\r\n });\r\n\r\n return (\r\n <SoftPanel tone=\"permission\">\r\n <PanelTitle>Use MCP server “{server.name}” from this project?</PanelTitle>\r\n <Text color={theme.subtle}>\r\n {server.path} declares this server. Approving connects using the configuration below.\r\n </Text>\r\n {server.configChangedSinceApproval ? (\r\n <Text color={theme.warning}>\r\n ! Its connection configuration changed since you last decided, so approval is required\r\n again.\r\n </Text>\r\n ) : null}\r\n <Box marginTop={1} flexDirection=\"column\">\r\n <Text wrap=\"wrap\">\r\n <Text color={theme.subtle}>target </Text>\r\n {server.target}\r\n </Text>\r\n {server.envKeys.length > 0 ? (\r\n <Text color={theme.subtle}>env {server.envKeys.join(', ')}</Text>\r\n ) : null}\r\n {server.headerKeys.length > 0 ? (\r\n <Text color={theme.subtle}>headers {server.headerKeys.join(', ')} (values hidden)</Text>\r\n ) : null}\r\n </Box>\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {OPTIONS.map((option, index) => (\r\n <SelectionRow key={option.key} selected={index === selected}>\r\n {index === selected ? '›' : ' '} {option.label.padEnd(22)}{' '}\r\n <Text color={theme.subtle}>{option.hint}</Text>\r\n </SelectionRow>\r\n ))}\r\n </Box>\r\n <Text color={theme.subtle} dimColor>\r\n ↑↓ select · Enter confirm · y approve · n reject · Esc not now\r\n {remainingCount > 0\r\n ? ` · ${remainingCount} more server${remainingCount === 1 ? '' : 's'} waiting`\r\n : ''}\r\n </Text>\r\n {error ? <Text color={theme.error}>✕ {error}</Text> : null}\r\n </SoftPanel>\r\n );\r\n}\r\n","import { useState, useCallback, useRef, useEffect } from 'react';\r\nimport { planWasLost } from '../../agent/session-state.js';\r\nimport type { Message, Usage, LocalCommandDisplay } from '../../types/messages.js';\r\nimport type {\r\n ElicitationHandler,\r\n ElicitationResponse,\r\n NestedToolInvocation,\r\n ToolDefinition,\r\n ToolResult,\r\n PermissionDecision,\r\n PermissionResult,\r\n PlanApprovalResult,\r\n UserQuestionResponse,\r\n} from '../../types/tools.js';\r\nimport type { PermissionMode, RetryPhase } from '../../types/runtime.js';\r\nimport { createAgentRunContext, type AgentRunContext } from '../../types/runs.js';\r\nimport type { CommandContext } from '../../types/commands.js';\r\nimport type {\r\n SessionMeta,\r\n SessionRecord,\r\n SessionStoreInterface,\r\n CompactResult,\r\n CompactTrigger,\r\n CompactBoundary,\r\n RewindAction,\r\n RewindRecordData,\r\n RewindSnapshotStoreInterface,\r\n RewindTarget,\r\n PlanRecordData,\r\n} from '../../types/sessions.js';\r\nimport { shouldCompact, usagePressureTokens } from '../../agent/compact.js';\r\nimport { resolveContextLimit } from '../../models.js';\r\nimport { applyModelDefaults, resolveModelProviderConfig } from '../../config.js';\r\nimport type { Todo } from '../../tools/todo.js';\r\nimport type { AgentConfig } from '../../types/runtime.js';\r\nimport {\r\n makeMessage,\r\n removeTrailingEmptyAssistantPlaceholder,\r\n resetStreamedContent,\r\n} from './streaming-state.js';\r\nimport { createDebugLoggerWithCounter, createUiDebugLogger } from '../../debug-log.js';\r\nimport { loadMemoryContext } from '../../memory-store.js';\r\nimport {\r\n readSettingsGlobal,\r\n removeProviderGlobal,\r\n persistAgentProfileModel,\r\n persistSettingsGlobal,\r\n persistUserSettingClearingLocal,\r\n persistPermissionRuleLocal,\r\n removePermissionRuleLocal,\r\n persistSkillActivationLocal,\r\n persistSkillExecutionLocal,\r\n persistSkillsEnabledLocal,\r\n clearLocalSettings,\r\n} from '../persist.js';\r\nimport {\r\n DEFAULT_SETTINGS,\r\n providerConfigSchema,\r\n type ResolvedSettings,\r\n type SkillActivation,\r\n type SkillExecution,\r\n} from '../../settings.js';\r\nimport { resolveSettings } from '../../settings-loader.js';\r\nimport { providerConfigFromDraft, type ProviderSaveRequest } from '../model-options.js';\r\nimport type { ProviderRemovalResult } from '../components/ModelPicker.js';\r\nimport { updateEffortLevel } from '../../commands/effort.js';\r\nimport { observationKey } from '../../tools/file-provenance.js';\r\nimport type { SessionBootstrap } from '../../session/resolve.js';\r\nimport { normalizeWorkspace } from '../../session/store.js';\r\nimport {\r\n AgentSession,\r\n type AgentSessionSendControl,\r\n type AgentSessionSendResult,\r\n} from '../../session/agent-session.js';\r\nimport { normalizePersistedTodos } from '../../tools/todo.js';\r\nimport { SessionRuntime } from '../../session/runtime.js';\r\nimport { createInteractiveAgentSession } from '../../session/interactive-session.js';\r\nimport type { AgentCompletionNotification } from '../../agents/types.js';\r\nimport { buildAgentCompletionMessage } from '../../agents/completion-notification.js';\r\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\r\nimport { resolvePermissionMode } from '../../permission-mode.js';\r\n\r\nconst log = createDebugLoggerWithCounter('tui:agent');\r\nconst uiLog = createUiDebugLogger('tui:agent');\r\nimport { createMessageAccumulator } from './message-accumulator.js';\r\nimport type { MessageAccumulator } from './message-accumulator.js';\r\n\r\nexport function didSendMessageComplete(result: AgentSessionSendResult): boolean {\r\n return result.status === 'completed';\r\n}\r\n\r\nexport function shouldDiscardOptimisticMessages(result: AgentSessionSendResult): boolean {\r\n if (result.status === 'cancelled') return !result.messages;\r\n return result.status === 'failed' && result.phase !== 'run';\r\n}\r\n\r\nexport interface UseAgentSessionOptions extends SessionBootstrap {\r\n permissionMode?: PermissionMode;\r\n store?: SessionStoreInterface;\r\n timelineStore?: SessionStoreInterface;\r\n snapshotStore?: RewindSnapshotStoreInterface;\r\n /** Live extra tools (e.g. MCP) merged into each per-send registry. */\r\n additionalTools?: () => ToolDefinition[];\r\n}\r\n\r\nfunction providerIdFromSelection(selection: string): string | undefined {\r\n const slash = selection.indexOf('/');\r\n return slash > 0 ? selection.slice(0, slash) : undefined;\r\n}\r\n\r\n// BYOK providers are persisted to the user-global ~/.book/settings.json so they\r\n// are shared across every project. Only providers present in that file were\r\n// added by the user and are therefore removable; providers inherited from a\r\n// project layer or --settings override are not.\r\nfunction readOwnedProviders(): {\r\n ids: Set<string>;\r\n modelCounts: Map<string, number>;\r\n} {\r\n const global = readSettingsGlobal();\r\n const provider = global.provider;\r\n if (typeof provider !== 'object' || provider === null || Array.isArray(provider)) {\r\n return { ids: new Set(), modelCounts: new Map() };\r\n }\r\n const registry = provider as Record<string, unknown>;\r\n const ids = new Set(Object.keys(registry));\r\n const modelCounts = new Map<string, number>();\r\n for (const providerId of ids) {\r\n const entry = registry[providerId];\r\n const models =\r\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\r\n ? (entry as Record<string, unknown>).models\r\n : undefined;\r\n modelCounts.set(\r\n providerId,\r\n typeof models === 'object' && models !== null && !Array.isArray(models)\r\n ? Object.keys(models).length\r\n : 0,\r\n );\r\n }\r\n return { ids, modelCounts };\r\n}\r\n\r\nexport function resolveConfigAfterProviderRemoval(\r\n current: AgentConfig,\r\n settings: ResolvedSettings,\r\n providerId: string,\r\n): {\r\n config: AgentConfig;\r\n activeModel: string;\r\n switched: boolean;\r\n inheritedProviderRevealed: boolean;\r\n} {\r\n const currentSelection = current.modelSelection ?? current.model;\r\n const configuredDefault = settings.model;\r\n const defaultIsStale =\r\n configuredDefault !== undefined &&\r\n providerIdFromSelection(configuredDefault) === providerId &&\r\n !settings.provider[providerId];\r\n const effectiveDefault = !configuredDefault || defaultIsStale ? 'gpt-4o' : configuredDefault;\r\n const activeProviderRemoved = providerIdFromSelection(currentSelection) === providerId;\r\n const nextSelection = activeProviderRemoved ? effectiveDefault : currentSelection;\r\n const next = applyModelDefaults(\r\n resolveModelProviderConfig({ ...current, settings }, nextSelection),\r\n );\r\n const activeModel = next.modelSelection ?? next.model;\r\n\r\n return {\r\n config: next,\r\n activeModel,\r\n switched: activeProviderRemoved && activeModel !== currentSelection,\r\n inheritedProviderRevealed: Boolean(settings.provider[providerId]),\r\n };\r\n}\r\n\r\n/** UI-only compact status — never appended to provider history. */\r\nexport type CompactUiState = {\r\n phase: 'working' | 'diff' | 'done' | 'error' | 'skipped';\r\n trigger: CompactTrigger;\r\n preMessages?: number;\r\n preContextTokens?: number;\r\n message?: string;\r\n degraded?: boolean;\r\n warning?: string;\r\n strategy?: Extract<CompactResult, { status: 'compacted' }>['strategy'];\r\n modelCalls?: number;\r\n};\r\n\r\nfunction buildObservationLedger(messages: Message[]) {\r\n const ledger = new Map<string, NonNullable<Message['fileObservations']>[number]>();\r\n for (const message of messages) {\r\n for (const observation of message.fileObservations ?? []) {\r\n const key = observationKey(observation.workspaceId, observation.path);\r\n const current = ledger.get(key);\r\n if (!current || current.timestamp <= observation.timestamp) ledger.set(key, observation);\r\n }\r\n }\r\n return ledger;\r\n}\r\n\r\nfunction withoutRuntimeState(config: AgentConfig): AgentConfig {\r\n return { ...config };\r\n}\r\n\r\ninterface SendMessageOptions {\r\n contextMessage?: string;\r\n kind?: Message['kind'];\r\n agentNotifications?: Message['agentNotifications'];\r\n attachments?: Message['attachments'];\r\n /** Managed-continuation linkage back to the originating root and parent run. */\r\n rootRunId?: string;\r\n parentRunId?: string;\r\n}\r\n\r\n/** Short transcript line shown for a fresh-context handoff (the full plan is the context). */\r\nconst HANDOFF_DISPLAY_MESSAGE = 'Implementing the approved plan with a fresh context.';\r\n\r\n/** Frames the approved plan as authoritative task intent for the reseeded implementation turn. */\r\nfunction buildHandoffPrompt(plan: string): string {\r\n return [\r\n 'You are implementing a plan that was just approved in a planning session.',\r\n 'This is a handoff to a fresh context: the plan below is your complete and',\r\n 'authoritative source of task intent. Implement it step by step. If a step is',\r\n 'ambiguous, make the reasonable choice and keep going.',\r\n '',\r\n '<approved-plan>',\r\n plan,\r\n '</approved-plan>',\r\n ].join('\\n');\r\n}\r\n\r\n/**\r\n * Build the session runtime with the plan a resumed session persisted.\r\n *\r\n * Seeded by pushing into the runtime's own arrays: the tools mutate those arrays\r\n * in place, so replacing them here would detach the runtime from what the loop\r\n * reads.\r\n */\r\nfunction createSeededRuntime(\r\n session: UseAgentSessionOptions,\r\n initialTranscript: Message[],\r\n): SessionRuntime {\r\n const runtime = new SessionRuntime({\r\n fileObservationLedger: buildObservationLedger(initialTranscript),\r\n });\r\n runtime.todos.push(...normalizePersistedTodos(session.plan?.todos));\r\n if (session.plan?.tasks?.length) runtime.tasks.push(...session.plan.tasks);\r\n runtime.planUnrestored = planWasLost({\r\n planRecordExisted: session.plan !== undefined,\r\n priorMessages: initialTranscript.length,\r\n todos: runtime.todos.length,\r\n tasks: runtime.tasks.length,\r\n });\r\n return runtime;\r\n}\r\n\r\nexport function useAgent(config: AgentConfig, session: UseAgentSessionOptions) {\r\n const initialTranscript = session.transcript ?? session.history;\r\n const initialContext = session.contextHistory ?? session.history;\r\n const [messages, setMessages] = useState<Message[]>(initialTranscript);\r\n const [compactBoundaries, setCompactBoundaries] = useState<CompactBoundary[]>(\r\n session.compactBoundaries ?? [],\r\n );\r\n const [rewindTargets, setRewindTargets] = useState<RewindTarget[]>(session.rewindTargets ?? []);\r\n const [isThinking, setIsThinking] = useState(false);\r\n /** Local messages produced mid-turn, replayed in order once the turn ends. */\r\n const pendingLocalMessages = useRef<\r\n Array<{ text: string; localCommand?: LocalCommandDisplay; sessionId: string }>\r\n >([]);\r\n const [isCompacting, setIsCompacting] = useState(false);\r\n const [isRewinding, setIsRewinding] = useState(false);\r\n const [compactUi, setCompactUi] = useState<CompactUiState | null>(null);\r\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [currentTurn, setCurrentTurn] = useState(0);\r\n const [usage, setUsage] = useState<Usage | null>(null);\r\n const [mode, setMode] = useState<PermissionMode>(() =>\r\n resolvePermissionMode(config.settings, session.permissionMode),\r\n );\r\n const [agentTodos, setAgentTodos] = useState<Todo[]>([]);\r\n // Set when the user approves a plan with \"fresh context\"; a post-send effect\r\n // starts a new conversation seeded with the approved plan.\r\n const [pendingHandoff, setPendingHandoff] = useState<{\r\n plan: string;\r\n mode: PermissionMode;\r\n generation: number;\r\n } | null>(null);\r\n // Guards single execution of the handoff reseed. State (not a ref) so releasing it\r\n // re-runs the effect to pick up a handoff raised during a prior reseed.\r\n const [handoffInFlight, setHandoffInFlight] = useState(false);\r\n // R1: liveConfig is the mutable config the agent loop reads. `config` (the\r\n // prop) is the startup snapshot; setModel/setEffort/persistPermissionRule\r\n // mutate liveConfig so subsequent runAgentLoop calls pick up the change.\r\n // Without this, /model would silently no-op (send closes over `config`).\r\n const [liveConfig, setLiveConfig] = useState<AgentConfig>(() => withoutRuntimeState(config));\r\n const [ownedProviders, setOwnedProviders] = useState(() => readOwnedProviders());\r\n const [agentSession] = useState(() =>\r\n createInteractiveAgentSession({\r\n runtime: createSeededRuntime(session, initialTranscript),\r\n additionalTools: session.additionalTools,\r\n }),\r\n );\r\n const { interactions, operations } = agentSession;\r\n const [interactionSnapshot, setInteractionSnapshot] = useState(() => interactions.getSnapshot());\r\n const { pendingPermission, pendingPlanApproval, pendingUserQuestions, pendingElicitations } =\r\n interactionSnapshot;\r\n const [turnDurationMs, setTurnDurationMs] = useState<number>(0);\r\n const [sessionId, setSessionId] = useState(session.sessionId);\r\n const [sessionName, setSessionName] = useState(session.sessionName);\r\n\r\n // Retry state for the spinner label.\r\n const [retryPhase, setRetryPhase] = useState<RetryPhase>('none');\r\n const [retryAttempt, setRetryAttempt] = useState(0);\r\n const [retryMax, setRetryMax] = useState(0);\r\n const [retryCountdownMs, setRetryCountdownMs] = useState(0);\r\n\r\n // Mutable id of the assistant message currently being streamed into.\r\n // Callbacks read this ref (not state) so multi-turn updates always target\r\n // the latest in-progress message without stale-closure issues.\r\n const streamingIdRef = useRef<string | null>(null);\r\n const messagesRef = useRef<Message[]>(initialTranscript);\r\n const contextHistoryRef = useRef<Message[]>(initialContext);\r\n const sessionIdRef = useRef(session.sessionId);\r\n const sessionNameRef = useRef(session.sessionName);\r\n const resumedFromRunIdRef = useRef<string | undefined>(undefined);\r\n const sessionGenerationRef = useRef(0);\r\n const modeRef = useRef(mode);\r\n const liveConfigRef = useRef(liveConfig);\r\n const ownedProvidersRef = useRef(ownedProviders);\r\n const turnStartRef = useRef(Date.now());\r\n // Countdown timer ref for retry countdown.\r\n const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n // Message accumulator for batched streaming updates.\r\n const accumulatorRef = useRef<MessageAccumulator | null>(null);\r\n const hostUsageRef = useRef<Usage | null>(null);\r\n const lastHostCompactAttemptRef = useRef<string | null>(null);\r\n // Plan-handoff request captured from the loop's onPlanHandoff callback, consumed\r\n // once the plan-approving send settles.\r\n const pendingHandoffRef = useRef<{ plan: string; mode: PermissionMode } | null>(null);\r\n const timelineStore = session.timelineStore ?? session.store;\r\n\r\n useEffect(() => interactions.subscribe(setInteractionSnapshot), [interactions]);\r\n\r\n useEffect(() => {\r\n messagesRef.current = messages;\r\n }, [messages]);\r\n\r\n useEffect(() => {\r\n liveConfigRef.current = liveConfig;\r\n }, [liveConfig]);\r\n\r\n useEffect(() => {\r\n modeRef.current = mode;\r\n }, [mode]);\r\n\r\n useEffect(() => {\r\n ownedProvidersRef.current = ownedProviders;\r\n }, [ownedProviders]);\r\n\r\n const settlePermission = useCallback(\r\n (decision: PermissionResult | PermissionDecision, via: string) => {\r\n return interactions.settlePermission(decision, via);\r\n },\r\n [interactions],\r\n );\r\n\r\n const settlePlanApproval = useCallback(\r\n (result: PlanApprovalResult, via: string) => {\r\n return interactions.settlePlanApproval(result, via);\r\n },\r\n [interactions],\r\n );\r\n\r\n const settleUserQuestion = useCallback(\r\n (result: UserQuestionResponse, via: string, requestId?: string) =>\r\n interactions.settleUserQuestion(result, via, requestId),\r\n [interactions],\r\n );\r\n\r\n useEffect(() => {\r\n agentSession\r\n .startLifecycle(liveConfigRef.current, session.sessionId, session.source)\r\n .catch((err) => {\r\n log.warn('SessionStart hook failed', {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n });\r\n }, [agentSession, session.sessionId, session.source]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n agentSession\r\n .endLifecycle(liveConfigRef.current, sessionIdRef.current, 'exit')\r\n .catch((err) => {\r\n log.warn('SessionEnd hook failed', {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n });\r\n };\r\n }, [agentSession]);\r\n\r\n // Clean up timers / pending prompts / in-flight work on unmount.\r\n useEffect(() => {\r\n return () => {\r\n if (countdownRef.current) {\r\n clearInterval(countdownRef.current);\r\n countdownRef.current = null;\r\n }\r\n accumulatorRef.current?.stop();\r\n accumulatorRef.current = null;\r\n // Abort work and deny/reject prompts so no session promise survives unmount.\r\n agentSession.dispose('unmount');\r\n };\r\n }, [agentSession]);\r\n\r\n const clearCountdown = useCallback(() => {\r\n if (countdownRef.current) {\r\n clearInterval(countdownRef.current);\r\n countdownRef.current = null;\r\n }\r\n }, []);\r\n\r\n useEffect(\r\n () =>\r\n agentSession.subscribe((snapshot) => {\r\n if (\r\n snapshot.status !== 'completed' &&\r\n snapshot.status !== 'failed' &&\r\n snapshot.status !== 'cancelled' &&\r\n snapshot.status !== 'timed_out' &&\r\n snapshot.status !== 'interrupted'\r\n )\r\n return;\r\n if (snapshot.sessionId !== sessionIdRef.current) return;\r\n setIsThinking(false);\r\n clearCountdown();\r\n setRetryPhase('none');\r\n setRetryCountdownMs(0);\r\n if (\r\n (snapshot.status === 'failed' ||\r\n snapshot.status === 'timed_out' ||\r\n snapshot.status === 'interrupted') &&\r\n snapshot.error\r\n ) {\r\n setError(snapshot.error);\r\n }\r\n }),\r\n [agentSession, clearCountdown],\r\n );\r\n\r\n const finalizeStreamingMessages = useCallback(() => {\r\n setMessages((prev) => {\r\n const next = removeTrailingEmptyAssistantPlaceholder(prev);\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n }, []);\r\n\r\n const prepareConversationProjection = useCallback(() => {\r\n sessionGenerationRef.current++;\r\n accumulatorRef.current?.discard();\r\n accumulatorRef.current = null;\r\n clearCountdown();\r\n }, [clearCountdown]);\r\n\r\n const projectConversationState = useCallback(\r\n (\r\n nextId: string,\r\n nextName: string | undefined,\r\n transcript: Message[],\r\n contextHistory: Message[] = transcript,\r\n boundaries: CompactBoundary[] = [],\r\n targets: RewindTarget[] = [],\r\n plan?: PlanRecordData,\r\n ) => {\r\n sessionIdRef.current = nextId;\r\n sessionNameRef.current = nextName;\r\n messagesRef.current = transcript;\r\n contextHistoryRef.current = contextHistory;\r\n streamingIdRef.current = null;\r\n setSessionId(nextId);\r\n setSessionName(nextName);\r\n setMessages(transcript);\r\n setCompactBoundaries(boundaries);\r\n setRewindTargets(targets);\r\n setIsThinking(false);\r\n setStreamingMessageId(null);\r\n setError(null);\r\n setCurrentTurn(0);\r\n setUsage(null);\r\n hostUsageRef.current = null;\r\n lastHostCompactAttemptRef.current = null;\r\n setAgentTodos([]);\r\n setTurnDurationMs(0);\r\n setRetryPhase('none');\r\n setRetryAttempt(0);\r\n setRetryMax(0);\r\n setRetryCountdownMs(0);\r\n const nextRuntime = agentSession.replaceRuntime(\r\n { fileObservationLedger: buildObservationLedger(transcript) },\r\n 'session_transition',\r\n );\r\n // `replaceRuntime` hands back empty lists, so without this a transition into\r\n // a session drops its persisted plan on the floor — and, because the flag\r\n // stays false too, says nothing about having done so.\r\n nextRuntime.todos.push(...normalizePersistedTodos(plan?.todos));\r\n if (plan?.tasks?.length) nextRuntime.tasks.push(...plan.tasks);\r\n nextRuntime.planUnrestored = planWasLost({\r\n planRecordExisted: plan !== undefined,\r\n priorMessages: transcript.length,\r\n todos: nextRuntime.todos.length,\r\n tasks: nextRuntime.tasks.length,\r\n });\r\n setAgentTodos([...nextRuntime.todos]);\r\n setLiveConfig((current) => ({\r\n ...current,\r\n memoryContext: current.settings.memory.enabled\r\n ? loadMemoryContext(current.workspace)\r\n : undefined,\r\n }));\r\n },\r\n [agentSession],\r\n );\r\n\r\n const resetConversationState = useCallback(\r\n (\r\n nextId: string,\r\n nextName: string | undefined,\r\n transcript: Message[],\r\n contextHistory: Message[] = transcript,\r\n boundaries: CompactBoundary[] = [],\r\n targets: RewindTarget[] = [],\r\n opts: { preserveOperation?: boolean } = {},\r\n ) => {\r\n prepareConversationProjection();\r\n if (opts.preserveOperation) interactions.cancelAll('session-reset');\r\n else agentSession.reset('session-reset');\r\n projectConversationState(nextId, nextName, transcript, contextHistory, boundaries, targets);\r\n },\r\n [agentSession, interactions, prepareConversationProjection, projectConversationState],\r\n );\r\n\r\n const endCurrentSession = useCallback(\r\n (reason: 'clear' | 'resume' | 'exit' | 'completion') =>\r\n agentSession.endLifecycle(liveConfigRef.current, sessionIdRef.current, reason),\r\n [agentSession],\r\n );\r\n\r\n const startNewConversation = useCallback(\r\n async (previousName?: string) => {\r\n await agentSession.clearSession({\r\n config: liveConfigRef.current,\r\n currentSessionId: sessionIdRef.current,\r\n store: session.store,\r\n timelineStore,\r\n previousName,\r\n onTransitionStart: prepareConversationProjection,\r\n onTransition: (bootstrap) => {\r\n resumedFromRunIdRef.current = undefined;\r\n projectConversationState(\r\n bootstrap.sessionId,\r\n bootstrap.sessionName,\r\n bootstrap.transcript ?? bootstrap.history,\r\n bootstrap.contextHistory ?? bootstrap.history,\r\n bootstrap.compactBoundaries,\r\n bootstrap.rewindTargets,\r\n bootstrap.plan,\r\n );\r\n },\r\n });\r\n },\r\n [\r\n agentSession,\r\n prepareConversationProjection,\r\n projectConversationState,\r\n session.store,\r\n timelineStore,\r\n ],\r\n );\r\n\r\n const resumeConversation = useCallback(\r\n async (selector: string) => {\r\n await agentSession.resumeSession({\r\n config: liveConfigRef.current,\r\n currentSessionId: sessionIdRef.current,\r\n store: session.store,\r\n timelineStore,\r\n selector,\r\n onTransitionStart: prepareConversationProjection,\r\n onTransition: (bootstrap) => {\r\n resumedFromRunIdRef.current = [...(bootstrap.transcript ?? bootstrap.history)]\r\n .reverse()\r\n .find((message) => message.role === 'user')?.id;\r\n projectConversationState(\r\n bootstrap.sessionId,\r\n bootstrap.sessionName,\r\n bootstrap.transcript ?? bootstrap.history,\r\n bootstrap.contextHistory ?? bootstrap.history,\r\n bootstrap.compactBoundaries,\r\n bootstrap.rewindTargets,\r\n bootstrap.plan,\r\n );\r\n },\r\n });\r\n },\r\n [\r\n agentSession,\r\n prepareConversationProjection,\r\n projectConversationState,\r\n session.store,\r\n timelineStore,\r\n ],\r\n );\r\n\r\n const listSessions = useCallback((): SessionMeta[] => {\r\n if (!session.store) return [];\r\n const cwd = normalizeWorkspace(liveConfig.workspace);\r\n return session.store.list().filter((meta) => meta.cwd === cwd);\r\n }, [liveConfig.workspace, session.store]);\r\n\r\n const projectCompactResult = useCallback(\r\n (result: Extract<CompactResult, { status: 'compacted' }>, boundary: CompactBoundary) => {\r\n contextHistoryRef.current = result.replacementHistory;\r\n setCompactBoundaries((current) => [...current, boundary]);\r\n setUsage(null);\r\n hostUsageRef.current = null;\r\n },\r\n [],\r\n );\r\n\r\n // Unconditional append, shared by the immediate and the deferred path so a\r\n // replayed message is byte-identical to one that was never blocked.\r\n const appendLocalMessage = useCallback(\r\n (text: string, localCommand?: LocalCommandDisplay) => {\r\n const msg = {\r\n ...makeMessage('assistant', text, undefined, false),\r\n kind: 'local' as const,\r\n localCommand,\r\n };\r\n if (timelineStore) {\r\n timelineStore.append(sessionIdRef.current, {\r\n type: 'local',\r\n eventId: msg.id,\r\n timestamp: msg.timestamp,\r\n data: { id: msg.id, content: msg.content, kind: 'local', includeInContext: false },\r\n });\r\n }\r\n setMessages((prev) => {\r\n const next = [...prev, msg];\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n },\r\n [timelineStore],\r\n );\r\n\r\n const sendMessage = useCallback(\r\n async (\r\n userMessage: string,\r\n commandContext?: CommandContext,\r\n messageOptions?: SendMessageOptions,\r\n ): Promise<AgentSessionSendResult> => {\r\n setCompactUi(null);\r\n\r\n const generation = sessionGenerationRef.current;\r\n const activeSessionId = sessionIdRef.current;\r\n let operationIsCurrent = () => false;\r\n const stillCurrent = () =>\r\n sessionGenerationRef.current === generation && operationIsCurrent();\r\n let activeAccumulator: MessageAccumulator | null = null;\r\n let activeUserMessage: Message | undefined;\r\n let placeholder: Message | undefined;\r\n let activeRunContext: AgentRunContext | undefined;\r\n\r\n log.info('send message', {\r\n len: userMessage.length,\r\n mode: modeRef.current,\r\n hasCommandContext: !!commandContext,\r\n sessionId: activeSessionId,\r\n });\r\n uiLog.event('send:start', {\r\n len: userMessage.length,\r\n mode: modeRef.current,\r\n hasCommandContext: !!commandContext,\r\n });\r\n\r\n const beforePrepare = async (control: AgentSessionSendControl) => {\r\n operationIsCurrent = control.isCurrent;\r\n activeRunContext = control.runContext;\r\n // Cross-turn auto-compact before appending the new user message.\r\n const contextLimit = resolveContextLimit(liveConfig);\r\n const hostCompactAttemptKey = `${usagePressureTokens(hostUsageRef.current)}:${contextHistoryRef.current.length}`;\r\n if (\r\n liveConfig.autoCompactEnabled !== false &&\r\n contextLimit != null &&\r\n shouldCompact(hostUsageRef.current, contextLimit) &&\r\n lastHostCompactAttemptRef.current !== hostCompactAttemptKey\r\n ) {\r\n lastHostCompactAttemptRef.current = hostCompactAttemptKey;\r\n try {\r\n setIsCompacting(true);\r\n setCompactUi({\r\n phase: 'working',\r\n trigger: 'auto',\r\n preMessages: contextHistoryRef.current.length,\r\n preContextTokens: usagePressureTokens(hostUsageRef.current),\r\n });\r\n const autoOutcome = await agentSession.compact({\r\n config: liveConfig,\r\n history: contextHistoryRef.current,\r\n compactBoundaries,\r\n sessionId: activeSessionId,\r\n transcriptOrdinal: messagesRef.current.length,\r\n runContext: control.runContext,\r\n runtime: agentSession.getRuntime(),\r\n timelineStore,\r\n isCurrent: stillCurrent,\r\n onCommitted: projectCompactResult,\r\n options: {\r\n trigger: 'auto',\r\n preContextTokens: usagePressureTokens(hostUsageRef.current),\r\n upcomingUserIntent: messageOptions?.contextMessage ?? userMessage,\r\n },\r\n });\r\n const autoResult = autoOutcome.result;\r\n if (stillCurrent() && autoResult.status === 'compacted' && autoOutcome.boundary) {\r\n setCompactUi({\r\n phase: 'diff',\r\n trigger: 'auto',\r\n preMessages: autoResult.preMessageCount,\r\n preContextTokens: autoResult.preContextTokens,\r\n message: autoResult.degraded\r\n ? 'Conversation compacted with reduced fidelity'\r\n : 'Conversation compacted',\r\n degraded: autoResult.degraded,\r\n warning: autoResult.warning,\r\n strategy: autoResult.strategy,\r\n modelCalls: autoResult.modelCalls,\r\n });\r\n } else if (stillCurrent()) {\r\n setCompactUi(null);\r\n }\r\n } catch (err) {\r\n log.warn('pre-turn auto-compact failed', {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n if (stillCurrent()) setCompactUi(null);\r\n } finally {\r\n if (stillCurrent()) setIsCompacting(false);\r\n }\r\n }\r\n };\r\n\r\n const createUserMessage = () => {\r\n const message = makeMessage('user', userMessage, messageOptions?.contextMessage, true);\r\n message.kind = messageOptions?.kind ?? 'conversation';\r\n // A command context means `userMessage` is a resolved command body -- which for a\r\n // project command is repository-authored text, and for a builtin is Book's own.\r\n message.derivedContent = commandContext ? true : undefined;\r\n message.agentNotifications = messageOptions?.agentNotifications;\r\n message.attachments = messageOptions?.attachments;\r\n activeUserMessage = message;\r\n return message;\r\n };\r\n\r\n const projectPreparingSend = (userMsg: Message, control: AgentSessionSendControl) => {\r\n operationIsCurrent = control.isCurrent;\r\n // Render the user's message immediately and stream into a fresh placeholder.\r\n placeholder = makeMessage('assistant', '', undefined, true);\r\n streamingIdRef.current = placeholder.id;\r\n setStreamingMessageId(placeholder.id);\r\n setIsThinking(true);\r\n setError(null);\r\n setCurrentTurn(0);\r\n setUsage(null);\r\n setRetryPhase('none');\r\n setRetryAttempt(0);\r\n setRetryMax(0);\r\n setRetryCountdownMs(0);\r\n setMessages((prev) => {\r\n const next = [...prev, userMsg, placeholder!];\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n };\r\n\r\n const removeOptimisticMessages = () => {\r\n if (!activeUserMessage || !placeholder) return;\r\n setMessages((prev) => {\r\n const next = prev.filter(\r\n (message) => message.id !== activeUserMessage?.id && message.id !== placeholder?.id,\r\n );\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n };\r\n\r\n const projectPreparedSend = (\r\n prepared: Extract<Awaited<ReturnType<AgentSession['prepareSend']>>, { status: 'prepared' }>,\r\n ) => {\r\n if (prepared.sessionName !== sessionNameRef.current) {\r\n sessionNameRef.current = prepared.sessionName;\r\n setSessionName(prepared.sessionName);\r\n }\r\n setRewindTargets((current) => [prepared.rewindTarget, ...current]);\r\n // Ink layout plus markdown parsing commonly takes longer than a 60fps\r\n // frame on a real transcript. A 32ms cadence keeps streaming responsive\r\n // without making the terminal renderer compete with every token delta.\r\n activeAccumulator = createMessageAccumulator(placeholder!.id, setMessages, messagesRef, 32);\r\n accumulatorRef.current = activeAccumulator;\r\n activeAccumulator.start();\r\n uiLog.event('accumulator:started', { flushIntervalMs: 32 });\r\n };\r\n\r\n const sendResult = await agentSession.send({\r\n config: liveConfig,\r\n displayMessage: userMessage,\r\n contextMessage: messageOptions?.contextMessage,\r\n createUserMessage,\r\n history: () => contextHistoryRef.current,\r\n compactBoundaries,\r\n mode: modeRef.current,\r\n sessionId: activeSessionId,\r\n source: 'tui',\r\n resumedFromRunId:\r\n messageOptions?.kind === 'agent-notification' ? undefined : resumedFromRunIdRef.current,\r\n rootRunId:\r\n messageOptions?.kind === 'agent-notification' ? messageOptions?.rootRunId : undefined,\r\n parentRunId:\r\n messageOptions?.kind === 'agent-notification' ? messageOptions?.parentRunId : undefined,\r\n sessionName: sessionNameRef.current,\r\n snapshotStore: session.snapshotStore,\r\n timelineStore,\r\n registryStore: timelineStore,\r\n isCurrent: () => sessionGenerationRef.current === generation,\r\n runtime: agentSession.getRuntime(),\r\n beforePrepare,\r\n onPreparing: projectPreparingSend,\r\n onPrepared: projectPreparedSend,\r\n callbacks: {\r\n onEvent: (event) => {\r\n if (!stillCurrent()) return;\r\n switch (event.type) {\r\n case 'text':\r\n activeAccumulator?.addText(event.content);\r\n break;\r\n case 'reasoning':\r\n activeAccumulator?.addReasoning(event.content);\r\n break;\r\n case 'tool_use':\r\n activeAccumulator?.addToolCall(event.toolCall);\r\n break;\r\n case 'tool_result':\r\n activeAccumulator?.addToolResult(event.toolResult);\r\n break;\r\n case 'attempt_discarded': {\r\n // Land anything still queued before clearing, or it would flush\r\n // the abandoned attempt back in on top of the reset.\r\n activeAccumulator?.flush();\r\n const streamingId = streamingIdRef.current;\r\n if (streamingId) {\r\n setMessages((prev) => {\r\n const next = resetStreamedContent(prev, streamingId);\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n }\r\n uiLog.event('attempt:discarded', { reason: event.reason });\r\n break;\r\n }\r\n case 'error':\r\n log.warn('agent error', { error: event.error });\r\n break;\r\n }\r\n },\r\n onTodos: (todos) => {\r\n if (stillCurrent()) setAgentTodos(todos as Todo[]);\r\n },\r\n onTurnStart: (turn) => {\r\n if (!stillCurrent()) return;\r\n log.debug('TUI turn start', { turn });\r\n setCurrentTurn(turn);\r\n turnStartRef.current = Date.now();\r\n if (turn > 1) {\r\n activeAccumulator?.stop();\r\n uiLog.event('accumulator:stopped', { reason: 'new-turn', turn });\r\n const next = makeMessage('assistant', '', undefined, true);\r\n streamingIdRef.current = next.id;\r\n setStreamingMessageId(next.id);\r\n setMessages((prev) => {\r\n const updated = [...prev, next];\r\n messagesRef.current = updated;\r\n return updated;\r\n });\r\n activeAccumulator = createMessageAccumulator(next.id, setMessages, messagesRef, 32);\r\n accumulatorRef.current = activeAccumulator;\r\n activeAccumulator.start();\r\n uiLog.event('accumulator:started', { flushIntervalMs: 32, turn });\r\n }\r\n },\r\n onDone: () => {\r\n if (!stillCurrent()) return;\r\n log.info('agent done', { durationMs: Date.now() - turnStartRef.current });\r\n uiLog.event('send:done', { durationMs: Date.now() - turnStartRef.current });\r\n setTurnDurationMs(Date.now() - turnStartRef.current);\r\n },\r\n onUsage: (u: Usage) => {\r\n if (!stillCurrent()) return;\r\n hostUsageRef.current = u;\r\n lastHostCompactAttemptRef.current = null;\r\n setUsage(u);\r\n },\r\n getMode: () => modeRef.current,\r\n onModeChange: (newMode: PermissionMode) => {\r\n if (!stillCurrent()) return;\r\n modeRef.current = newMode;\r\n setMode(newMode);\r\n },\r\n onPlanHandoff: (handoff) => {\r\n if (!stillCurrent()) return;\r\n // Consumed after this send settles (see the pending-handoff effect).\r\n pendingHandoffRef.current = handoff;\r\n },\r\n onCompact: async (history, usage, hints) => {\r\n if (!stillCurrent()) {\r\n return { status: 'skipped', reason: 'disabled', message: 'Session changed.' };\r\n }\r\n const outcome = await agentSession.compact({\r\n config: liveConfigRef.current,\r\n history,\r\n compactBoundaries,\r\n sessionId: activeSessionId,\r\n transcriptOrdinal: messagesRef.current.length,\r\n runContext: activeRunContext,\r\n runtime: agentSession.getRuntime(),\r\n timelineStore,\r\n isCurrent: stillCurrent,\r\n onCommitted: projectCompactResult,\r\n options: {\r\n ...hints,\r\n trigger: 'auto',\r\n preContextTokens: usage ? usagePressureTokens(usage) : undefined,\r\n },\r\n });\r\n const result = outcome.result;\r\n if (!stillCurrent()) return result;\r\n if (result.status === 'compacted' && outcome.boundary) {\r\n setCompactUi({\r\n phase: 'diff',\r\n trigger: 'auto',\r\n preMessages: result.preMessageCount,\r\n preContextTokens: result.preContextTokens,\r\n message: result.degraded\r\n ? 'Conversation compacted with reduced fidelity'\r\n : 'Conversation compacted',\r\n degraded: result.degraded,\r\n warning: result.warning,\r\n strategy: result.strategy,\r\n modelCalls: result.modelCalls,\r\n });\r\n }\r\n return result;\r\n },\r\n onRetry: (phase, attempt, max, delayMs) => {\r\n if (!stillCurrent()) return;\r\n setRetryPhase(phase);\r\n setRetryAttempt(attempt);\r\n setRetryMax(max);\r\n setRetryCountdownMs(delayMs);\r\n\r\n // Start countdown timer.\r\n clearCountdown();\r\n countdownRef.current = setInterval(() => {\r\n setRetryCountdownMs((prev) => {\r\n const next = prev - 1000;\r\n if (next <= 0) {\r\n clearCountdown();\r\n return 0;\r\n }\r\n return next;\r\n });\r\n }, 1000);\r\n },\r\n onStreamStall: (countdownMs) => {\r\n if (!stillCurrent()) return;\r\n setRetryPhase('stalled');\r\n setRetryCountdownMs(countdownMs);\r\n clearCountdown();\r\n countdownRef.current = setInterval(() => {\r\n setRetryCountdownMs((prev) => {\r\n const next = prev - 1000;\r\n if (next <= 0) {\r\n clearCountdown();\r\n return 0;\r\n }\r\n return next;\r\n });\r\n }, 1000);\r\n },\r\n onStreamResume: () => {\r\n if (!stillCurrent()) return;\r\n setRetryPhase('none');\r\n clearCountdown();\r\n },\r\n onPersistPermissionRule: (rule: string) => {\r\n persistPermissionRule(rule);\r\n },\r\n },\r\n options: {\r\n nestedToolObserver: {\r\n onToolCall: (invocation: NestedToolInvocation) => {\r\n if (stillCurrent()) activeAccumulator?.addNestedToolCall(invocation);\r\n },\r\n onToolResult: (traceId: string, result: ToolResult) => {\r\n if (stillCurrent()) activeAccumulator?.addNestedToolResult(traceId, result);\r\n },\r\n },\r\n manageSessionHooks: false,\r\n assistantMessageId: () => streamingIdRef.current ?? undefined,\r\n allowedTools: commandContext?.allowedTools,\r\n modelOverride: commandContext?.modelOverride,\r\n commands: commandContext ? [commandContext.command] : undefined,\r\n parentSessionId: activeSessionId,\r\n },\r\n });\r\n if (messageOptions?.kind !== 'agent-notification' && sendResult.status !== 'rejected') {\r\n resumedFromRunIdRef.current = undefined;\r\n }\r\n\r\n const hostStillCurrent = sessionGenerationRef.current === generation;\r\n if (sendResult.status === 'rejected') {\r\n uiLog.event('send:rejected', {\r\n reason: sendResult.activeKind === 'compact' ? 'compacting' : 'already-in-flight',\r\n len: userMessage.length,\r\n });\r\n return sendResult;\r\n }\r\n if (hostStillCurrent && 'messages' in sendResult && sendResult.messages) {\r\n // Nested tool traces remain display-only; the returned history is provider context.\r\n contextHistoryRef.current = sendResult.messages;\r\n }\r\n // A fresh-context plan approval sets this late in the loop. Always drop it on any\r\n // terminal outcome of this send so it can't leak into a later turn; reseed only\r\n // when this send completed as the current generation.\r\n if (pendingHandoffRef.current) {\r\n const handoff = pendingHandoffRef.current;\r\n pendingHandoffRef.current = null;\r\n if (hostStillCurrent && sendResult.status === 'completed') {\r\n setPendingHandoff({ ...handoff, generation });\r\n }\r\n }\r\n if (hostStillCurrent && shouldDiscardOptimisticMessages(sendResult)) {\r\n if (sendResult.status === 'failed') {\r\n setError(\r\n sendResult.error instanceof Error ? sendResult.error.message : String(sendResult.error),\r\n );\r\n }\r\n setIsThinking(false);\r\n removeOptimisticMessages();\r\n }\r\n if (hostStillCurrent && placeholder) {\r\n accumulatorRef.current?.stop();\r\n uiLog.event('accumulator:stopped', { reason: 'done' });\r\n if (accumulatorRef.current === activeAccumulator) accumulatorRef.current = null;\r\n finalizeStreamingMessages();\r\n streamingIdRef.current = null;\r\n setStreamingMessageId(null);\r\n }\r\n // A run that ended badly used to leave no trace at all: the loop skips\r\n // `onAssistantMessageComplete` on its error path, which is the only writer\r\n // to the session store, and the transient banner is cleared by the next\r\n // send. A run that stopped for a reason the user never saw looks exactly\r\n // like a model that decided it was finished. Record it in the transcript\r\n // instead, after the placeholder cleanup so it is the last row.\r\n //\r\n // Keyed on the settled outcome rather than on `onError`, which also fires\r\n // for problems the run recovers from — a skill that fails to activate is\r\n // reported to the model in the prompt and the turn carries on — so an\r\n // error event would stamp a failure notice onto turns that succeeded.\r\n // `cancelled` is the user's own doing, and the outcomes for a session the\r\n // user left carry no message, so both stay silent.\r\n // A prepare-phase failure carries no outcome; it is already reported by\r\n // the banner, which `shouldDiscardOptimisticMessages` admits for it.\r\n const settled = 'outcome' in sendResult ? sendResult.outcome : undefined;\r\n if (\r\n hostStillCurrent &&\r\n settled?.message &&\r\n settled.status !== 'completed' &&\r\n settled.status !== 'cancelled'\r\n ) {\r\n uiLog.event('run-failure:surfaced', { reason: settled.reason });\r\n appendLocalMessage(`✕ ${settled.message}`);\r\n // The terminal snapshot already put this same text in the transient\r\n // banner above the composer, synchronously, before this teardown ran.\r\n // Two copies of one failure reads as two failures, so the banner gives\r\n // way to the transcript row, which is the copy that survives a resume.\r\n setError(null);\r\n }\r\n uiLog.event('send:finally', { durationMs: Date.now() - turnStartRef.current });\r\n return sendResult;\r\n },\r\n [\r\n liveConfig,\r\n clearCountdown,\r\n compactBoundaries,\r\n finalizeStreamingMessages,\r\n appendLocalMessage,\r\n timelineStore,\r\n projectCompactResult,\r\n session.snapshotStore,\r\n agentSession,\r\n ],\r\n );\r\n\r\n const send = useCallback(\r\n async (\r\n userMessage: string,\r\n commandContext?: CommandContext,\r\n attachments?: Message['attachments'],\r\n ) => {\r\n return sendMessage(userMessage, commandContext, { attachments });\r\n },\r\n [sendMessage],\r\n );\r\n\r\n // Fresh-context plan handoff: once the plan-approving turn settles, start a new\r\n // conversation and reseed it with only the approved plan (like Codex/Claude Code).\r\n useEffect(() => {\r\n if (!pendingHandoff || handoffInFlight) return;\r\n // Abandon if the session moved on (clear/resume/rewind) before we could reseed.\r\n if (sessionGenerationRef.current !== pendingHandoff.generation) {\r\n setPendingHandoff(null);\r\n return;\r\n }\r\n const handoff = pendingHandoff;\r\n setHandoffInFlight(true);\r\n const { plan, mode: handoffMode } = handoff;\r\n void (async () => {\r\n try {\r\n log.info('plan handoff: starting fresh conversation');\r\n await startNewConversation();\r\n modeRef.current = handoffMode;\r\n setMode(handoffMode);\r\n await sendMessage(HANDOFF_DISPLAY_MESSAGE, undefined, {\r\n contextMessage: buildHandoffPrompt(plan),\r\n kind: 'conversation',\r\n });\r\n } catch (err) {\r\n log.warn('plan handoff failed', {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n // Surface the loss: the approved plan was not implemented.\r\n setError('Failed to start fresh-context implementation; the approved plan was not run.');\r\n } finally {\r\n // Clear only this request, so a handoff raised during the reseed above survives\r\n // and is picked up when handoffInFlight is released.\r\n setPendingHandoff((current) => (current === handoff ? null : current));\r\n setHandoffInFlight(false);\r\n }\r\n })();\r\n }, [pendingHandoff, handoffInFlight, startNewConversation, sendMessage]);\r\n\r\n const sendAgentCompletions = useCallback(\r\n async (notifications: AgentCompletionNotification[]): Promise<boolean> => {\r\n if (notifications.length === 0) return false;\r\n const recordedDeliveryIds = new Set(\r\n messagesRef.current.flatMap((message) =>\r\n (message.agentNotifications ?? [])\r\n .map((notification) => notification.deliveryId)\r\n .filter((id): id is string => Boolean(id)),\r\n ),\r\n );\r\n const fresh = notifications.filter(\r\n (notification) => !recordedDeliveryIds.has(notification.deliveryId),\r\n );\r\n if (fresh.length === 0) return true;\r\n const built = fresh.map(buildAgentCompletionMessage);\r\n // Parent linkage is only truthful when every batched completion shares one root.\r\n const sharedRootRunId =\r\n fresh[0]?.rootRunId &&\r\n fresh.every((notification) => notification.rootRunId === fresh[0]?.rootRunId)\r\n ? fresh[0]?.rootRunId\r\n : undefined;\r\n const result = await sendMessage(\r\n built.map((item) => item.displayMessage).join('\\n'),\r\n undefined,\r\n {\r\n contextMessage: built.map((item) => item.contextMessage).join('\\n'),\r\n kind: 'agent-notification',\r\n agentNotifications: built.map((item) => item.display),\r\n rootRunId: sharedRootRunId,\r\n parentRunId: sharedRootRunId ? fresh[0]?.runId : undefined,\r\n },\r\n );\r\n return didSendMessageComplete(result);\r\n },\r\n [sendMessage],\r\n );\r\n\r\n const sendBackgroundShellCompletion = useCallback(\r\n async (shell: BackgroundShellRecord): Promise<boolean> => {\r\n const tail = agentSession.getRuntime().shellManager.readTail(shell.id, 4_000) ?? '';\r\n const exit = shell.exitCode !== undefined ? ` exit=${shell.exitCode ?? 'none'}` : '';\r\n const display = `Background shell ${shell.title || shell.id} ${shell.status}${exit}.`;\r\n const context = [\r\n '<background-shell-completion>',\r\n `id: ${shell.id}`,\r\n `title: ${shell.title || shell.command}`,\r\n `status: ${shell.status}${exit}`,\r\n `elapsed_ms: ${(shell.finishedAt ?? Date.now()) - shell.startedAt}`,\r\n tail ? 'output_tail:' : undefined,\r\n tail || undefined,\r\n '</background-shell-completion>',\r\n ]\r\n .filter((line): line is string => line !== undefined)\r\n .join('\\n');\r\n const result = await sendMessage(display, undefined, {\r\n contextMessage: context,\r\n kind: 'agent-notification',\r\n });\r\n return didSendMessageComplete(result);\r\n },\r\n [agentSession, sendMessage],\r\n );\r\n\r\n const resolvePermission = useCallback(\r\n (decision: PermissionResult | PermissionDecision) => {\r\n settlePermission(decision, 'resolve');\r\n },\r\n [settlePermission],\r\n );\r\n\r\n const cancelPermission = useCallback(() => {\r\n settlePermission('deny', 'cancel-permission');\r\n }, [settlePermission]);\r\n\r\n const resolvePlanApproval = useCallback(\r\n (result: PlanApprovalResult) => {\r\n settlePlanApproval(result, 'resolve');\r\n },\r\n [settlePlanApproval],\r\n );\r\n\r\n const resolveUserQuestion = useCallback(\r\n (result: UserQuestionResponse) => {\r\n settleUserQuestion(result, 'resolve');\r\n },\r\n [settleUserQuestion],\r\n );\r\n\r\n const resolveElicitation = useCallback(\r\n (result: ElicitationResponse) => {\r\n interactions.settleElicitation(result, 'resolve');\r\n },\r\n [interactions],\r\n );\r\n\r\n /** Installed on the MCP host so servers can prompt through this session. */\r\n const elicitationHandler = useCallback<ElicitationHandler>(\r\n (request) => interactions.requestElicitation(request),\r\n [interactions],\r\n );\r\n\r\n // Abort the in-flight agent stream (Esc while thinking) or compact request.\r\n // The active lease stays held until its finally block; only its signal is aborted.\r\n const cancel = useCallback(() => {\r\n const activeKind = operations.activeKind;\r\n const hadAccumulator = accumulatorRef.current !== null;\r\n const cancelled = agentSession.cancel('cancel');\r\n uiLog.event('cancel', {\r\n activeKind,\r\n aborted: cancelled.operation.aborted,\r\n hadAccumulator,\r\n inFlight: activeKind === 'send',\r\n });\r\n // The active lease stays held until its finally block finishes unwinding.\r\n clearCountdown();\r\n setRetryPhase('none');\r\n }, [agentSession, clearCountdown, operations]);\r\n\r\n // Manually compact the conversation (summarize older turns).\r\n const compact = useCallback(\r\n async (focus?: string) => {\r\n const operation = operations.tryStart('compact', true);\r\n if (!operation) {\r\n setCompactUi({\r\n phase: 'skipped',\r\n trigger: 'manual',\r\n message: 'Cannot compact while a turn is in progress.',\r\n });\r\n return;\r\n }\r\n const generation = sessionGenerationRef.current;\r\n const activeSessionId = sessionIdRef.current;\r\n const stillCurrent = () =>\r\n sessionGenerationRef.current === generation && operation.isCurrent();\r\n const preMessages = contextHistoryRef.current.length;\r\n const preContextTokens = usagePressureTokens(hostUsageRef.current);\r\n\r\n setIsCompacting(true);\r\n setCompactUi({\r\n phase: 'working',\r\n trigger: 'manual',\r\n preMessages,\r\n preContextTokens,\r\n });\r\n\r\n try {\r\n const runContext = createAgentRunContext({\r\n sessionId: activeSessionId,\r\n source: 'tui',\r\n });\r\n const outcome = await agentSession.compact({\r\n config: liveConfigRef.current,\r\n history: contextHistoryRef.current,\r\n compactBoundaries,\r\n sessionId: activeSessionId,\r\n transcriptOrdinal: messagesRef.current.length,\r\n runContext,\r\n runtime: agentSession.getRuntime(),\r\n timelineStore,\r\n isCurrent: stillCurrent,\r\n onCommitted: projectCompactResult,\r\n options: {\r\n trigger: 'manual',\r\n focus,\r\n preContextTokens,\r\n signal: operation.signal,\r\n },\r\n });\r\n const result = outcome.result;\r\n\r\n if (!stillCurrent()) return;\r\n\r\n if (result.status === 'skipped') {\r\n setCompactUi({\r\n phase: 'skipped',\r\n trigger: 'manual',\r\n preMessages,\r\n message: result.message ?? 'Not enough messages to compact.',\r\n });\r\n return;\r\n }\r\n if (result.status === 'failed') {\r\n setCompactUi({\r\n phase: 'error',\r\n trigger: 'manual',\r\n preMessages,\r\n message: result.error,\r\n });\r\n return;\r\n }\r\n\r\n if (!outcome.boundary) return;\r\n if (!stillCurrent()) return;\r\n setCompactUi({\r\n phase: 'diff',\r\n trigger: 'manual',\r\n preMessages: result.preMessageCount,\r\n preContextTokens: result.preContextTokens,\r\n message: result.degraded\r\n ? 'Conversation compacted with reduced fidelity'\r\n : 'Conversation compacted',\r\n degraded: result.degraded,\r\n warning: result.warning,\r\n strategy: result.strategy,\r\n modelCalls: result.modelCalls,\r\n });\r\n } catch (e) {\r\n if (stillCurrent()) {\r\n setCompactUi({\r\n phase: 'error',\r\n trigger: 'manual',\r\n preMessages,\r\n message: e instanceof Error ? e.message : String(e),\r\n });\r\n }\r\n } finally {\r\n if (stillCurrent()) setIsCompacting(false);\r\n operation.release();\r\n }\r\n },\r\n [agentSession, compactBoundaries, operations, projectCompactResult, timelineStore],\r\n );\r\n\r\n const getRewindTargets = useCallback((): RewindTarget[] => {\r\n const currentGitHead = session.snapshotStore?.getCurrentGitHead();\r\n return rewindTargets.map((target) => {\r\n if (target.codeUnavailableReason) return { ...target, codeAvailable: false };\r\n const manifest = target.snapshotId\r\n ? session.snapshotStore?.getManifest(target.snapshotId)\r\n : undefined;\r\n const availability = !session.snapshotStore\r\n ? { available: false, reason: 'Filesystem checkpoint storage is unavailable.' }\r\n : !manifest\r\n ? session.snapshotStore.getAvailability(target.snapshotId, target.gitHead)\r\n : currentGitHead !== target.gitHead\r\n ? {\r\n available: false,\r\n reason: 'Git HEAD changed since this prompt; rewind never moves HEAD or the index.',\r\n }\r\n : { available: true };\r\n return {\r\n ...target,\r\n codeAvailable: availability.available,\r\n codeUnavailableReason: availability.available ? undefined : availability.reason,\r\n };\r\n });\r\n }, [rewindTargets, session.snapshotStore]);\r\n\r\n const rewind = useCallback(\r\n async (\r\n targetId: string,\r\n action: RewindAction,\r\n ): Promise<\r\n | { ok: true; restoredPrompt?: string; restoredAttachments?: Message['attachments'] }\r\n | { ok: false; error: string }\r\n > => {\r\n const operation = operations.tryStart('rewind');\r\n if (!operation) {\r\n return { ok: false, error: 'Rewind is unavailable while another operation is active.' };\r\n }\r\n if (!timelineStore) {\r\n operation.release();\r\n return { ok: false, error: 'Rewind timeline storage is unavailable.' };\r\n }\r\n const target = getRewindTargets().find((candidate) => candidate.id === targetId);\r\n if (!target) {\r\n operation.release();\r\n return { ok: false, error: 'The selected rewind target is no longer active.' };\r\n }\r\n if ((action === 'code' || action === 'both') && !target.codeAvailable) {\r\n operation.release();\r\n return {\r\n ok: false,\r\n error: target.codeUnavailableReason ?? 'Code rewind is unavailable for this prompt.',\r\n };\r\n }\r\n\r\n setIsRewinding(true);\r\n const activeSessionId = sessionIdRef.current;\r\n let safetySnapshotId: string | undefined;\r\n try {\r\n if (action === 'code' || action === 'both') {\r\n const restored = session.snapshotStore?.restore(target.snapshotId!);\r\n if (!restored)\r\n return { ok: false, error: 'Filesystem checkpoint storage is unavailable.' };\r\n if (!restored.ok) {\r\n return {\r\n ok: false,\r\n error: restored.rollbackError\r\n ? `${restored.error} Rollback also failed: ${restored.rollbackError}`\r\n : restored.error,\r\n };\r\n }\r\n safetySnapshotId = restored.safetySnapshotId;\r\n }\r\n\r\n timelineStore.append(activeSessionId, {\r\n type: 'rewind',\r\n eventId: crypto.randomUUID(),\r\n timestamp: Date.now(),\r\n data: {\r\n version: 1,\r\n action,\r\n targetId: target.id,\r\n targetUserEventId: target.userEventId,\r\n } satisfies RewindRecordData,\r\n } satisfies SessionRecord);\r\n\r\n if (action === 'conversation' || action === 'both') {\r\n const loaded = timelineStore.load(activeSessionId);\r\n resetConversationState(\r\n activeSessionId,\r\n sessionName,\r\n loaded.transcript,\r\n loaded.contextHistory,\r\n loaded.compactBoundaries,\r\n loaded.rewindTargets,\r\n { preserveOperation: true },\r\n );\r\n }\r\n if (safetySnapshotId) session.snapshotStore?.discardManifest(safetySnapshotId);\r\n return {\r\n ok: true,\r\n ...(action === 'code'\r\n ? {}\r\n : {\r\n restoredPrompt: target.prompt,\r\n ...(target.attachments?.length ? { restoredAttachments: target.attachments } : {}),\r\n }),\r\n };\r\n } catch (rewindError) {\r\n let rollbackMessage = '';\r\n if (safetySnapshotId) {\r\n const rollback = session.snapshotStore?.rollback(safetySnapshotId);\r\n if (rollback && !rollback.ok) rollbackMessage = ` Rollback failed: ${rollback.error}`;\r\n }\r\n return {\r\n ok: false,\r\n error: `${rewindError instanceof Error ? rewindError.message : String(rewindError)}${rollbackMessage}`,\r\n };\r\n } finally {\r\n operation.release();\r\n setIsRewinding(false);\r\n }\r\n },\r\n [\r\n getRewindTargets,\r\n operations,\r\n resetConversationState,\r\n session.snapshotStore,\r\n sessionName,\r\n timelineStore,\r\n ],\r\n );\r\n\r\n const clear = useCallback(() => {\r\n // Abort + stop accumulator BEFORE wiping message state so no late flush\r\n // can resurrect content into a cleared conversation.\r\n accumulatorRef.current?.stop();\r\n accumulatorRef.current = null;\r\n agentSession.cancel('clear');\r\n messagesRef.current = [];\r\n contextHistoryRef.current = [];\r\n setMessages([]);\r\n setCompactBoundaries([]);\r\n setRewindTargets([]);\r\n setError(null);\r\n setCurrentTurn(0);\r\n setUsage(null);\r\n hostUsageRef.current = null;\r\n lastHostCompactAttemptRef.current = null;\r\n setAgentTodos([]);\r\n streamingIdRef.current = null;\r\n setStreamingMessageId(null);\r\n // The send lease is released by send()'s finally after abort.\r\n if (!operations.isRunning('send')) setIsThinking(false);\r\n clearCountdown();\r\n setRetryPhase('none');\r\n setRetryCountdownMs(0);\r\n }, [agentSession, clearCountdown, operations]);\r\n\r\n const cycleMode = useCallback(() => {\r\n const modes: PermissionMode[] = [\r\n 'default',\r\n 'auto',\r\n 'plan',\r\n 'accept-edits',\r\n 'dontAsk',\r\n 'bypassPermissions',\r\n ].filter(\r\n (candidate) =>\r\n candidate !== 'bypassPermissions' ||\r\n liveConfigRef.current.settings.disableBypassPermissionsMode !== true,\r\n ) as PermissionMode[];\r\n const idx = modes.indexOf(modeRef.current);\r\n const nextMode = modes[(idx + 1) % modes.length];\r\n modeRef.current = nextMode;\r\n setMode(nextMode);\r\n }, []);\r\n\r\n // Surface a local-only assistant message WITHOUT an agent round-trip.\r\n // Precedent: compact() mutates messages directly via setMessages. Unlike\r\n // send(), this never invokes runAgentLoop — used by /diff /config /cost\r\n // /init-pre /memory-noop to show output instantly, and by /review to deliver\r\n // a report its agents produced minutes after the command was typed.\r\n const addLocalMessage = useCallback(\r\n (text: string, localCommand?: LocalCommandDisplay) => {\r\n const sendInFlight = operations.isRunning('send');\r\n if (sendInFlight || isThinking) {\r\n // Deferred, not dropped. Callers that finish on their own schedule —\r\n // `/review` runs for minutes in background agents — cannot time their\r\n // output around a turn the user starts meanwhile, and discarding it\r\n // threw away the entire deliverable of that work.\r\n uiLog.event('local-message:deferred', {\r\n reason: sendInFlight ? 'in-flight' : 'is-thinking',\r\n preview: text.slice(0, 40),\r\n });\r\n pendingLocalMessages.current.push({\r\n text,\r\n localCommand,\r\n sessionId: sessionIdRef.current,\r\n });\r\n return; // don't clobber a streaming turn\r\n }\r\n uiLog.event('local-message:added', {\r\n preview: text.slice(0, 40),\r\n presentation: localCommand?.kind ?? 'text',\r\n });\r\n appendLocalMessage(text, localCommand);\r\n },\r\n [appendLocalMessage, isThinking, operations],\r\n );\r\n\r\n // Drain deferred local messages once the turn that blocked them is over.\r\n // Deliberately unconditional: the send lease is a plain object, not reactive\r\n // state, so there is no dependency that reliably changes when it is released\r\n // — and a drain that misses its wake-up is the bug this replaced. The guard\r\n // makes the common (empty) case two boolean reads.\r\n useEffect(() => {\r\n if (pendingLocalMessages.current.length === 0) return;\r\n if (isThinking || operations.isRunning('send')) return;\r\n const queued = pendingLocalMessages.current;\r\n pendingLocalMessages.current = [];\r\n for (const item of queued) {\r\n // Output owed to a conversation the user has since left is dropped on\r\n // purpose: replaying it into an unrelated session is worse than losing it.\r\n if (item.sessionId !== sessionIdRef.current) {\r\n uiLog.event('local-message:discarded', {\r\n reason: 'session-changed',\r\n preview: item.text.slice(0, 40),\r\n });\r\n continue;\r\n }\r\n uiLog.event('local-message:added', {\r\n preview: item.text.slice(0, 40),\r\n presentation: item.localCommand?.kind ?? 'text',\r\n deferred: true,\r\n });\r\n appendLocalMessage(item.text, item.localCommand);\r\n }\r\n });\r\n\r\n // Switch the active model for the rest of the session, optionally persisting\r\n // it to the user-global settings layer (~/.book/settings.json) so the choice\r\n // follows the user across projects. BOOK_MODEL can still override settings on\r\n // the next startup; app.tsx surfaces that warning.\r\n const setModel = useCallback(\r\n (name: string, options: { persist?: boolean } = {}) => {\r\n let next: AgentConfig;\r\n try {\r\n next = applyModelDefaults(resolveModelProviderConfig(liveConfigRef.current, name));\r\n } catch (error) {\r\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n if (options.persist !== false) {\r\n const result = persistUserSettingClearingLocal(config.workspace, 'model', name);\r\n if (!result.ok) return result;\r\n }\r\n setLiveConfig(next);\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const upsertProviderAndSelect = useCallback(\r\n (request: ProviderSaveRequest) => {\r\n const providerId = request.providerId;\r\n let savedProvider;\r\n try {\r\n const existing = liveConfigRef.current.settings.provider[providerId];\r\n savedProvider = providerConfigSchema.parse(\r\n providerConfigFromDraft(request, existing, request.replaceModels),\r\n );\r\n } catch (error) {\r\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n\r\n const selection = `${providerId}/${request.activeModelId}`;\r\n const activate = request.activate !== false;\r\n const result = persistSettingsGlobal({\r\n [`provider.${providerId}`]: savedProvider,\r\n ...(activate ? { model: selection } : {}),\r\n });\r\n if (!result.ok) return result;\r\n // Drop any stale per-project entries for this provider (and the active\r\n // model when we just set it) so this folder inherits the global value\r\n // instead of a local override shadowing it.\r\n clearLocalSettings(config.workspace, [\r\n `provider.${providerId}`,\r\n ...(activate ? ['model'] : []),\r\n ]);\r\n\r\n setLiveConfig((current) => {\r\n const withProvider: AgentConfig = {\r\n ...current,\r\n settings: {\r\n ...current.settings,\r\n ...(activate ? { model: selection } : {}),\r\n provider: {\r\n ...current.settings.provider,\r\n [providerId]: savedProvider,\r\n },\r\n },\r\n };\r\n return activate\r\n ? applyModelDefaults(resolveModelProviderConfig(withProvider, selection))\r\n : withProvider;\r\n });\r\n const nextOwnedProviders = {\r\n ids: new Set(ownedProvidersRef.current.ids).add(providerId),\r\n modelCounts: new Map(ownedProvidersRef.current.modelCounts).set(\r\n providerId,\r\n Object.keys(savedProvider.models).length,\r\n ),\r\n };\r\n ownedProvidersRef.current = nextOwnedProviders;\r\n setOwnedProviders(nextOwnedProviders);\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const removeProvider = useCallback(\r\n (providerId: string): ProviderRemovalResult => {\r\n if (!ownedProvidersRef.current.ids.has(providerId)) {\r\n return { ok: false, error: 'Only BYOK providers you added can be removed.' };\r\n }\r\n\r\n const persisted = removeProviderGlobal(providerId);\r\n if (!persisted.ok) return { ok: false, error: persisted.error };\r\n\r\n let resolvedSettings: ResolvedSettings;\r\n let resolvedRuntime: ReturnType<typeof resolveConfigAfterProviderRemoval>;\r\n try {\r\n resolvedSettings = config.settingsContext?.noSettings\r\n ? structuredClone(DEFAULT_SETTINGS)\r\n : resolveSettings(config.workspace, config.settingsContext?.overridePath);\r\n resolvedRuntime = resolveConfigAfterProviderRemoval(\r\n liveConfigRef.current,\r\n resolvedSettings,\r\n providerId,\r\n );\r\n } catch (error) {\r\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n\r\n liveConfigRef.current = resolvedRuntime.config;\r\n setLiveConfig(resolvedRuntime.config);\r\n const nextOwnedProviderIds = new Set(ownedProvidersRef.current.ids);\r\n const nextOwnedProviderModelCounts = new Map(ownedProvidersRef.current.modelCounts);\r\n nextOwnedProviderIds.delete(providerId);\r\n nextOwnedProviderModelCounts.delete(providerId);\r\n const nextOwnedProviders = {\r\n ids: nextOwnedProviderIds,\r\n modelCounts: nextOwnedProviderModelCounts,\r\n };\r\n ownedProvidersRef.current = nextOwnedProviders;\r\n setOwnedProviders(nextOwnedProviders);\r\n\r\n return {\r\n ok: true,\r\n providerId,\r\n removedModelCount: persisted.removedModelCount,\r\n activeModel: resolvedRuntime.activeModel,\r\n switched: resolvedRuntime.switched,\r\n inheritedProviderRevealed: resolvedRuntime.inheritedProviderRevealed,\r\n };\r\n },\r\n [config.settingsContext?.noSettings, config.settingsContext?.overridePath, config.workspace],\r\n );\r\n\r\n const setEffort = useCallback(\r\n (level: NonNullable<AgentConfig['effort']>) =>\r\n updateEffortLevel(\r\n liveConfigRef.current,\r\n level,\r\n (selected) => persistUserSettingClearingLocal(config.workspace, 'effort', selected),\r\n (selected) =>\r\n setLiveConfig((current) => ({\r\n ...current,\r\n effort: selected,\r\n effortExplicit: true,\r\n })),\r\n ),\r\n [config.workspace],\r\n );\r\n\r\n const setAgentProfileModel = useCallback(\r\n (profile: string, model?: string) => {\r\n const persisted = persistAgentProfileModel(config.workspace, profile, model);\r\n if (!persisted.ok) return persisted;\r\n\r\n setLiveConfig((current) => {\r\n const profiles = { ...current.settings.agents.profiles };\r\n const existing = { ...(profiles[profile] ?? {}) };\r\n existing.model = model ?? 'inherit';\r\n if (Object.keys(existing).length > 0) profiles[profile] = existing;\r\n else delete profiles[profile];\r\n return {\r\n ...current,\r\n settings: {\r\n ...current.settings,\r\n agents: { ...current.settings.agents, profiles },\r\n },\r\n };\r\n });\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setCompactModel = useCallback(\r\n (model: string) => {\r\n const result = persistUserSettingClearingLocal(config.workspace, 'compactModel', model);\r\n if (!result.ok) return result;\r\n setLiveConfig((current) => ({\r\n ...current,\r\n compactModel: model,\r\n settings: { ...current.settings, compactModel: model },\r\n }));\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setSkillActivation = useCallback(\r\n (skillName: string, activation: SkillActivation) => {\r\n const persisted = persistSkillActivationLocal(config.workspace, skillName, activation);\r\n if (!persisted.ok) return persisted;\r\n\r\n setLiveConfig((current) => ({\r\n ...current,\r\n settings: {\r\n ...current.settings,\r\n skills: {\r\n ...current.settings.skills,\r\n overrides: {\r\n ...current.settings.skills.overrides,\r\n [skillName]: activation,\r\n },\r\n },\r\n },\r\n }));\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setSkillExecution = useCallback(\r\n (skillName: string, execution: SkillExecution) => {\r\n const persisted = persistSkillExecutionLocal(config.workspace, skillName, execution);\r\n if (!persisted.ok) return persisted;\r\n\r\n setLiveConfig((current) => ({\r\n ...current,\r\n settings: {\r\n ...current.settings,\r\n skills: {\r\n ...current.settings.skills,\r\n execution: {\r\n ...current.settings.skills.execution,\r\n [skillName]: execution,\r\n },\r\n },\r\n },\r\n }));\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setSkillsEnabled = useCallback(\r\n (enabled: boolean) => {\r\n const persisted = persistSkillsEnabledLocal(config.workspace, enabled);\r\n if (!persisted.ok) return persisted;\r\n setLiveConfig((current) => ({\r\n ...current,\r\n settings: {\r\n ...current.settings,\r\n skills: { ...current.settings.skills, enabled },\r\n },\r\n }));\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setMemoryAutoSave = useCallback(\r\n (enabled: boolean) => {\r\n setLiveConfig((c) => ({\r\n ...c,\r\n settings: {\r\n ...c.settings,\r\n memory: { ...c.settings.memory, autoSave: enabled },\r\n },\r\n }));\r\n persistUserSettingClearingLocal(config.workspace, 'memory.autoSave', enabled);\r\n },\r\n [config.workspace],\r\n );\r\n\r\n /**\r\n * Flip a boolean setting, reading the value that is actually current.\r\n *\r\n * The callers used to compute `!liveConfig.settings…` from the value captured\r\n * at render. Two flips inside one React batch — which is what an accelerator\r\n * that acts on a row followed by Enter on the same row produces — then both\r\n * read the pre-batch value and both persist the same absolute result, so two\r\n * presses moved the setting once and wrote the wrong value to disk.\r\n *\r\n * Reading `liveConfigRef` is not enough on its own: it is mirrored in an\r\n * effect, so inside a batch it is exactly as stale as the render value. The\r\n * ref is therefore written here, synchronously, next to the state update.\r\n */\r\n const toggleSetting = useCallback(\r\n (\r\n read: (config: AgentConfig) => boolean,\r\n write: (config: AgentConfig, value: boolean) => AgentConfig,\r\n persist: (value: boolean) => { ok: boolean; error?: string },\r\n /**\r\n * Target value, for the callers that name one rather than flip. `/config\r\n * ui.showThinking=false` has to land in the same place the menu row does,\r\n * or the typed and pointed halves of one command disagree again.\r\n */\r\n target?: boolean,\r\n ) => {\r\n const next = target ?? !read(liveConfigRef.current);\r\n const result = persist(next);\r\n if (!result.ok) return result;\r\n liveConfigRef.current = write(liveConfigRef.current, next);\r\n setLiveConfig(liveConfigRef.current);\r\n return { ok: true } as const;\r\n },\r\n [],\r\n );\r\n\r\n const toggleShowThinking = useCallback(\r\n (target?: boolean) =>\r\n toggleSetting(\r\n (c) => c.settings.ui.showThinking === true,\r\n (c, value) => ({\r\n ...c,\r\n settings: { ...c.settings, ui: { ...c.settings.ui, showThinking: value } },\r\n }),\r\n (value) => persistUserSettingClearingLocal(config.workspace, 'ui.showThinking', value),\r\n target,\r\n ),\r\n [toggleSetting, config.workspace],\r\n );\r\n\r\n const toggleStartupAnimation = useCallback(\r\n (target?: boolean) =>\r\n toggleSetting(\r\n (c) => c.settings.ui.startupAnimation !== false,\r\n (c, value) => ({\r\n ...c,\r\n settings: { ...c.settings, ui: { ...c.settings.ui, startupAnimation: value } },\r\n }),\r\n (value) => persistUserSettingClearingLocal(config.workspace, 'ui.startupAnimation', value),\r\n target,\r\n ),\r\n [toggleSetting, config.workspace],\r\n );\r\n\r\n const toggleMemoryAutoSave = useCallback(\r\n (target?: boolean) =>\r\n toggleSetting(\r\n (c) => c.settings.memory.autoSave === true,\r\n (c, value) => ({\r\n ...c,\r\n settings: { ...c.settings, memory: { ...c.settings.memory, autoSave: value } },\r\n }),\r\n (value) => persistUserSettingClearingLocal(config.workspace, 'memory.autoSave', value),\r\n target,\r\n ),\r\n [toggleSetting, config.workspace],\r\n );\r\n\r\n // Add an allow rule from the \"Always allow\" approval flow (CC-aligned) and\r\n // surface it live in settings so the next call is auto-allowed.\r\n const persistPermissionRule = useCallback(\r\n (rule: string) => {\r\n setLiveConfig((c) => {\r\n const allow = c.settings.permissions.allow.includes(rule)\r\n ? c.settings.permissions.allow\r\n : [...c.settings.permissions.allow, rule];\r\n return {\r\n ...c,\r\n settings: {\r\n ...c.settings,\r\n permissions: { ...c.settings.permissions, allow },\r\n },\r\n };\r\n });\r\n persistPermissionRuleLocal(config.workspace, 'allow', rule);\r\n },\r\n [config.workspace],\r\n );\r\n\r\n // The counterpart to the above, for the /permissions sheet. Without it a rule\r\n // was one keystroke to add and a hand-edited JSON file to remove.\r\n const removePermissionRule = useCallback(\r\n (entry: { list: 'allow' | 'ask' | 'deny'; rule: string }) => {\r\n const result = removePermissionRuleLocal(config.workspace, entry.list, entry.rule);\r\n if (!result.ok) return result;\r\n setLiveConfig((c) => ({\r\n ...c,\r\n settings: {\r\n ...c.settings,\r\n permissions: {\r\n ...c.settings.permissions,\r\n [entry.list]: c.settings.permissions[entry.list].filter((r) => r !== entry.rule),\r\n },\r\n },\r\n }));\r\n return result;\r\n },\r\n [config.workspace],\r\n );\r\n\r\n const setDefaultPermissionMode = useCallback(\r\n (nextMode: PermissionMode) => {\r\n const storedMode = nextMode === 'accept-edits' ? 'acceptEdits' : nextMode;\r\n const result = persistUserSettingClearingLocal(config.workspace, 'defaultMode', storedMode);\r\n if (!result.ok) return result;\r\n setLiveConfig((current) => ({\r\n ...current,\r\n settings: { ...current.settings, defaultMode: storedMode },\r\n }));\r\n return { ok: true };\r\n },\r\n [config.workspace],\r\n );\r\n\r\n return {\r\n messages,\r\n compactBoundaries,\r\n contextHistory: contextHistoryRef.current,\r\n isThinking,\r\n isCompacting,\r\n isRewinding,\r\n compactUi,\r\n setCompactUi,\r\n streamingMessageId,\r\n error,\r\n currentTurn,\r\n tokenCount: usage?.totalTokens ?? 0,\r\n usage,\r\n mode,\r\n pendingPermission,\r\n pendingPlanApproval,\r\n pendingUserQuestion: pendingUserQuestions[0] ?? null,\r\n pendingUserQuestionCount: pendingUserQuestions.length,\r\n pendingElicitation: pendingElicitations[0] ?? null,\r\n pendingElicitationCount: pendingElicitations.length,\r\n agentTodos,\r\n turnDurationMs,\r\n retryPhase,\r\n retryAttempt,\r\n retryMax,\r\n retryCountdownMs,\r\n liveConfig,\r\n runtime: agentSession.getRuntime(),\r\n removableProviderIds: ownedProviders.ids,\r\n removableProviderModelCounts: ownedProviders.modelCounts,\r\n sessionId,\r\n sessionName,\r\n send,\r\n sendAgentCompletions,\r\n sendBackgroundShellCompletion,\r\n clear,\r\n startNewConversation,\r\n resumeConversation,\r\n listSessions,\r\n endCurrentSession,\r\n resolvePermission,\r\n cancelPermission,\r\n resolvePlanApproval,\r\n resolveUserQuestion,\r\n resolveElicitation,\r\n elicitationHandler,\r\n cancel,\r\n compact,\r\n rewind,\r\n getRewindTargets,\r\n cycleMode,\r\n addLocalMessage,\r\n setModel,\r\n upsertProviderAndSelect,\r\n removeProvider,\r\n setEffort,\r\n setAgentProfileModel,\r\n setCompactModel,\r\n setSkillActivation,\r\n setSkillExecution,\r\n setSkillsEnabled,\r\n setMemoryAutoSave,\r\n toggleMemoryAutoSave,\r\n toggleShowThinking,\r\n toggleStartupAnimation,\r\n\r\n /** Reload the memory snapshot after approve/discard so the next agent turn picks up changes. */\r\n refreshMemoryContext: () => {\r\n setLiveConfig((c) => ({\r\n ...c,\r\n memoryContext: loadMemoryContext(config.workspace),\r\n }));\r\n },\r\n\r\n persistPermissionRule,\r\n removePermissionRule,\r\n setDefaultPermissionMode,\r\n };\r\n}\r\n","import type { Message } from '../../types/messages.js';\r\nimport type { NestedToolInvocation, ToolCall, ToolResult } from '../../types/tools.js';\r\n\r\nexport function makeMessage(\r\n role: 'user' | 'assistant',\r\n content: string,\r\n contextContent?: string,\r\n includeInContext = false,\r\n): Message {\r\n return {\r\n id: crypto.randomUUID(),\r\n role,\r\n content,\r\n contextContent,\r\n includeInContext,\r\n timestamp: Date.now(),\r\n };\r\n}\r\n\r\nfunction findMessageIndex(messages: Message[], id: string): number {\r\n for (let i = messages.length - 1; i >= 0; i -= 1) {\r\n if (messages[i].id === id) return i;\r\n }\r\n return -1;\r\n}\r\n\r\n/** True when an assistant message has no text and no tool activity. */\r\nexport function isTotallyEmptyAssistant(message: Message): boolean {\r\n if (message.role !== 'assistant') return false;\r\n if (message.content !== '') return false;\r\n if (message.reasoningContent) return false;\r\n if ((message.toolCalls?.length ?? 0) > 0) return false;\r\n if ((message.toolResults?.length ?? 0) > 0) return false;\r\n if ((message.nestedToolInvocations?.length ?? 0) > 0) return false;\r\n return true;\r\n}\r\n\r\n/**\r\n * Drop only a trailing totally-empty assistant placeholder.\r\n * Partial content, tools, or non-trailing empties are left untouched.\r\n */\r\nexport function removeTrailingEmptyAssistantPlaceholder(messages: Message[]): Message[] {\r\n if (messages.length === 0) return messages;\r\n const last = messages[messages.length - 1];\r\n if (!isTotallyEmptyAssistant(last)) return messages;\r\n return messages.slice(0, -1);\r\n}\r\n\r\n/**\r\n * Clear the text and reasoning streamed into a message, keeping the message.\r\n *\r\n * Used when the loop abandons an attempt and retries the same turn: the deltas\r\n * are already on screen and cannot be unsent, so the host drops them and lets the\r\n * replacement stream into the same row. Tool activity is left alone — a retry\r\n * only happens when the attempt produced none.\r\n */\r\nexport function resetStreamedContent(messages: Message[], id: string): Message[] {\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const message = messages[index];\r\n if (message.content === '' && !message.reasoningContent) return messages;\r\n const next = messages.slice();\r\n next[index] = { ...message, content: '', reasoningContent: undefined };\r\n return next;\r\n}\r\n\r\nexport function appendContentToMessage(\r\n messages: Message[],\r\n id: string,\r\n content: string,\r\n): Message[] {\r\n if (content === '') return messages;\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const next = messages.slice();\r\n const message = messages[index];\r\n next[index] = { ...message, content: message.content + content };\r\n return next;\r\n}\r\n\r\nexport function appendReasoningToMessage(\r\n messages: Message[],\r\n id: string,\r\n reasoning: string,\r\n): Message[] {\r\n if (reasoning === '') return messages;\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const next = messages.slice();\r\n const message = messages[index];\r\n next[index] = {\r\n ...message,\r\n reasoningContent: (message.reasoningContent ?? '') + reasoning,\r\n };\r\n return next;\r\n}\r\n\r\n/** Upsert a top-level tool call by stable `call.id` (append-only for new ids). */\r\nexport function appendToolCallToMessage(\r\n messages: Message[],\r\n id: string,\r\n call: ToolCall,\r\n): Message[] {\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const message = messages[index];\r\n const existing = message.toolCalls ?? [];\r\n const existingIndex = existing.findIndex((item) => item.id === call.id);\r\n let toolCalls: ToolCall[];\r\n if (existingIndex === -1) {\r\n toolCalls = [...existing, call];\r\n } else if (existing[existingIndex] === call) {\r\n return messages;\r\n } else {\r\n toolCalls = existing.slice();\r\n toolCalls[existingIndex] = call;\r\n }\r\n const next = messages.slice();\r\n next[index] = { ...message, toolCalls };\r\n return next;\r\n}\r\n\r\n/** Upsert a top-level tool result by stable `toolCallId`. */\r\nexport function appendToolResultToMessage(\r\n messages: Message[],\r\n id: string,\r\n result: ToolResult,\r\n): Message[] {\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const message = messages[index];\r\n const existing = message.toolResults ?? [];\r\n const existingIndex = existing.findIndex((item) => item.toolCallId === result.toolCallId);\r\n let toolResults: ToolResult[];\r\n if (existingIndex === -1) {\r\n toolResults = [...existing, result];\r\n } else if (existing[existingIndex] === result) {\r\n return messages;\r\n } else {\r\n toolResults = existing.slice();\r\n toolResults[existingIndex] = result;\r\n }\r\n const next = messages.slice();\r\n next[index] = { ...message, toolResults };\r\n return next;\r\n}\r\n\r\n/** Upsert a nested tool invocation by stable `traceId`. */\r\nexport function appendNestedToolInvocationToMessage(\r\n messages: Message[],\r\n id: string,\r\n invocation: NestedToolInvocation,\r\n): Message[] {\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const message = messages[index];\r\n const existing = message.nestedToolInvocations ?? [];\r\n const existingIndex = existing.findIndex((item) => item.traceId === invocation.traceId);\r\n let nestedToolInvocations: NestedToolInvocation[];\r\n if (existingIndex === -1) {\r\n nestedToolInvocations = [...existing, invocation];\r\n } else {\r\n const prev = existing[existingIndex];\r\n // Preserve an already-attached result unless the upsert carries a newer one.\r\n const merged: NestedToolInvocation = {\r\n ...prev,\r\n ...invocation,\r\n result: invocation.result ?? prev.result,\r\n };\r\n if (\r\n prev.traceId === merged.traceId &&\r\n prev.parentTraceId === merged.parentTraceId &&\r\n prev.call === merged.call &&\r\n prev.result === merged.result\r\n ) {\r\n return messages;\r\n }\r\n nestedToolInvocations = existing.slice();\r\n nestedToolInvocations[existingIndex] = merged;\r\n }\r\n const next = messages.slice();\r\n next[index] = { ...message, nestedToolInvocations };\r\n return next;\r\n}\r\n\r\n/** Attach/replace a nested tool result by stable `traceId`. */\r\nexport function appendNestedToolResultToMessage(\r\n messages: Message[],\r\n id: string,\r\n traceId: string,\r\n result: ToolResult,\r\n): Message[] {\r\n const index = findMessageIndex(messages, id);\r\n if (index === -1) return messages;\r\n const message = messages[index];\r\n const invocations = message.nestedToolInvocations ?? [];\r\n const invocationIndex = invocations.findIndex((invocation) => invocation.traceId === traceId);\r\n if (invocationIndex === -1) return messages;\r\n if (invocations[invocationIndex].result === result) return messages;\r\n\r\n const nestedToolInvocations = invocations.slice();\r\n nestedToolInvocations[invocationIndex] = {\r\n ...nestedToolInvocations[invocationIndex],\r\n result,\r\n };\r\n const next = messages.slice();\r\n next[index] = { ...message, nestedToolInvocations };\r\n return next;\r\n}\r\n","/**\r\n * Persist settings from inside the Ink TUI without killing the app.\r\n *\r\n * Mirrors the write path of cli/config-cmd.ts but returns {ok, error?} instead\r\n * of calling console.log / process.exit(). Settings are layered user (global) →\r\n * project → local. Two write targets are exposed:\r\n * - `*Local` → <workspace>/.book/settings.local.json (per-project, gitignored)\r\n * - `*Global` → ~/.book/settings.json (shared across every project)\r\n * The split is by whose choice it is. A preference about how Book behaves for\r\n * *you* - provider registries, API keys, model, effort, compaction model,\r\n * permission default mode, thinking display, startup animation, memory\r\n * auto-save - is global, so it follows you across folders rather than being\r\n * re-set per project. What stays local is what is genuinely about *this*\r\n * repository: which skills are on, and the permission rules approved for its\r\n * tools.\r\n */\r\nimport { existsSync } from 'fs';\r\nimport { join } from 'path';\r\nimport {\r\n formatSettingsDiagnostics,\r\n readSettingsDocument,\r\n SettingsRepository,\r\n} from '../settings-repository.js';\r\nimport { resolveBookHome } from '../book-home.js';\r\nimport type { SkillActivation, SkillExecution } from '../settings.js';\r\nimport { blockedWorkspaceSettingPath } from '../settings-scope.js';\r\n\r\nconst LOCAL_DIR = '.book';\r\nconst LOCAL_FILE = 'settings.local.json';\r\nconst GLOBAL_FILE = 'settings.json';\r\n\r\n/** Absolute path to the per-project local settings file. */\r\nfunction localSettingsPath(workspace: string): string {\r\n return join(workspace, LOCAL_DIR, LOCAL_FILE);\r\n}\r\n\r\n/** Absolute path to the user-global settings file (~/.book/settings.json). */\r\nfunction globalSettingsPath(): string {\r\n return join(resolveBookHome(), GLOBAL_FILE);\r\n}\r\n\r\n/** Human-readable labels used in provider-removal diagnostics. */\r\nconst LOCAL_LABEL = `${LOCAL_DIR}/${LOCAL_FILE}`;\r\nconst GLOBAL_LABEL = `~/${LOCAL_DIR}/${GLOBAL_FILE}`;\r\n\r\nexport type RemoveLocalProviderResult =\r\n | {\r\n ok: true;\r\n providerId: string;\r\n removedModelCount: number;\r\n localDefaultCleared: boolean;\r\n localProviderExisted: true;\r\n }\r\n | {\r\n ok: false;\r\n providerId: string;\r\n removedModelCount: number;\r\n localDefaultCleared: false;\r\n localProviderExisted: boolean;\r\n error: string;\r\n };\r\n\r\n/** Read a settings document at `path` as a plain object ({} if absent/invalid). */\r\nfunction readSettingsAt(path: string): Record<string, unknown> {\r\n const result = readSettingsDocument(path);\r\n return result.status === 'valid' ? result.document : {};\r\n}\r\n\r\n/** Read the project-local settings.local.json as a plain object. */\r\nexport function readSettingsLocal(workspace: string): Record<string, unknown> {\r\n return readSettingsAt(localSettingsPath(workspace));\r\n}\r\n\r\n/** Read the user-global ~/.book/settings.json as a plain object. */\r\nexport function readSettingsGlobal(): Record<string, unknown> {\r\n return readSettingsAt(globalSettingsPath());\r\n}\r\n\r\n/**\r\n * Set one or more dot-path keys in the settings file at `path` and persist it.\r\n * Returns {ok:false, error} on a filesystem or write failure (never throws).\r\n * Values are stored verbatim — number/bool/object callers should pre-serialize,\r\n * but a non-string is also stored as-is.\r\n */\r\nfunction persistSettingsAt(\r\n path: string,\r\n values: Record<string, unknown>,\r\n): { ok: boolean; error?: string } {\r\n const result = new SettingsRepository(path).set(values);\r\n return result.ok\r\n ? { ok: true }\r\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\r\n}\r\n\r\n/** Persist keys to the project-local layer (.book/settings.local.json). */\r\nexport function persistSettingsLocal(\r\n workspace: string,\r\n values: Record<string, unknown>,\r\n): { ok: boolean; error?: string } {\r\n for (const key of Object.keys(values)) {\r\n const blocked = blockedWorkspaceSettingPath(key);\r\n if (blocked) return { ok: false, error: blocked };\r\n }\r\n return persistSettingsAt(localSettingsPath(workspace), values);\r\n}\r\n\r\n/** Persist keys to the user-global layer (~/.book/settings.json). */\r\nexport function persistSettingsGlobal(values: Record<string, unknown>): {\r\n ok: boolean;\r\n error?: string;\r\n} {\r\n return persistSettingsAt(globalSettingsPath(), values);\r\n}\r\n\r\nexport function persistSettingLocal(\r\n workspace: string,\r\n key: string,\r\n value: unknown,\r\n): { ok: boolean; error?: string } {\r\n return persistSettingsLocal(workspace, { [key]: value });\r\n}\r\n\r\nexport function persistSettingGlobal(key: string, value: unknown): { ok: boolean; error?: string } {\r\n return persistSettingsGlobal({ [key]: value });\r\n}\r\n\r\n/**\r\n * Write a user-global preference and drop the workspace-local value it would\r\n * otherwise lose to.\r\n *\r\n * The local layer resolves last, so a stale override there survives the global\r\n * write and silently decides the *next* session — the setting moves in front of\r\n * the user, then moves back when they restart. `setModel` had carried the\r\n * `clearLocalSettings` call for exactly this reason and the other six user-layer\r\n * writes had not, which is how `compactModel` and `effort` came to revert:\r\n * an earlier version of `/config <key>=<value>` put every typed setting in the\r\n * local file, so the stale value is one those users are especially likely to\r\n * have. One helper rather than seven call sites is what keeps that from being\r\n * true again of the eighth.\r\n */\r\nexport function persistUserSettingClearingLocal(\r\n workspace: string,\r\n key: string,\r\n value: unknown,\r\n): { ok: boolean; error?: string } {\r\n const result = persistSettingsGlobal({ [key]: value });\r\n if (!result.ok) return result;\r\n clearLocalSettings(workspace, [key]);\r\n return { ok: true };\r\n}\r\n\r\n/** Persist a profile model without treating dots in the profile name as path separators. */\r\nexport function persistAgentProfileModel(\r\n workspace: string,\r\n profile: string,\r\n model?: string,\r\n): { ok: boolean; error?: string } {\r\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\r\n const agents =\r\n candidate.agents && typeof candidate.agents === 'object' && !Array.isArray(candidate.agents)\r\n ? (candidate.agents as Record<string, unknown>)\r\n : {};\r\n const profiles =\r\n agents.profiles && typeof agents.profiles === 'object' && !Array.isArray(agents.profiles)\r\n ? (agents.profiles as Record<string, Record<string, unknown>>)\r\n : {};\r\n const existing =\r\n profiles[profile] && typeof profiles[profile] === 'object' ? { ...profiles[profile] } : {};\r\n\r\n // \"inherit\" must be explicit so it can override project/global settings and frontmatter.\r\n existing.model = model ?? 'inherit';\r\n profiles[profile] = existing;\r\n candidate.agents = { ...agents, profiles };\r\n });\r\n return result.ok\r\n ? { ok: true }\r\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\r\n}\r\n\r\n/** Persist a skill override without treating dots in a skill name as path separators. */\r\nexport function persistSkillActivationLocal(\r\n workspace: string,\r\n skillName: string,\r\n activation: SkillActivation,\r\n): { ok: boolean; error?: string } {\r\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\r\n const skills =\r\n candidate.skills && typeof candidate.skills === 'object' && !Array.isArray(candidate.skills)\r\n ? (candidate.skills as Record<string, unknown>)\r\n : {};\r\n const overrides =\r\n skills.overrides && typeof skills.overrides === 'object' && !Array.isArray(skills.overrides)\r\n ? (skills.overrides as Record<string, unknown>)\r\n : {};\r\n overrides[skillName] = activation;\r\n candidate.skills = { ...skills, overrides };\r\n });\r\n return result.ok\r\n ? { ok: true }\r\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\r\n}\r\n\r\n/** Persist a per-skill consent policy without splitting dotted names into paths. */\r\nexport function persistSkillExecutionLocal(\r\n workspace: string,\r\n skillName: string,\r\n execution: SkillExecution,\r\n): { ok: boolean; error?: string } {\r\n const result = new SettingsRepository(localSettingsPath(workspace)).update((candidate) => {\r\n const skills =\r\n candidate.skills && typeof candidate.skills === 'object' && !Array.isArray(candidate.skills)\r\n ? (candidate.skills as Record<string, unknown>)\r\n : {};\r\n const policies =\r\n skills.execution && typeof skills.execution === 'object' && !Array.isArray(skills.execution)\r\n ? (skills.execution as Record<string, unknown>)\r\n : {};\r\n policies[skillName] = execution;\r\n candidate.skills = { ...skills, execution: policies };\r\n });\r\n return result.ok\r\n ? { ok: true }\r\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\r\n}\r\n\r\nexport function persistSkillsEnabledLocal(\r\n workspace: string,\r\n enabled: boolean,\r\n): { ok: boolean; error?: string } {\r\n return persistSettingLocal(workspace, 'skills.enabled', enabled);\r\n}\r\n\r\n/**\r\n * Remove dot-path keys from the project-local layer if present. Used after a\r\n * value has been written to the global layer to clear a stale per-project\r\n * override that would otherwise shadow the new global value (local wins for\r\n * scalars during resolution). A no-op when the local file is absent; never\r\n * throws. Empty parent objects (e.g. an emptied provider registry) are pruned.\r\n */\r\nexport function clearLocalSettings(\r\n workspace: string,\r\n paths: string[],\r\n): { ok: boolean; error?: string } {\r\n const path = localSettingsPath(workspace);\r\n if (!existsSync(path)) return { ok: true };\r\n const result = new SettingsRepository(path).remove(paths);\r\n return result.ok\r\n ? { ok: true }\r\n : { ok: false, error: formatSettingsDiagnostics(result.diagnostics) };\r\n}\r\n\r\n/** Remove one provider from the settings file at `path` and any default targeting it. */\r\nfunction removeProviderAt(\r\n path: string,\r\n label: string,\r\n providerId: string,\r\n): RemoveLocalProviderResult {\r\n if (!existsSync(path)) {\r\n return {\r\n ok: false,\r\n providerId,\r\n removedModelCount: 0,\r\n localDefaultCleared: false,\r\n localProviderExisted: false,\r\n error: `Provider \"${providerId}\" is not configured in ${label}.`,\r\n };\r\n }\r\n const source = readSettingsDocument(path);\r\n if (source.status !== 'valid') {\r\n return {\r\n ok: false,\r\n providerId,\r\n removedModelCount: 0,\r\n localDefaultCleared: false,\r\n localProviderExisted: false,\r\n error: source.status === 'absent' ? `${label} settings are absent.` : source.error,\r\n };\r\n }\r\n const existing = source.document;\r\n\r\n const registry = existing.provider;\r\n const ownsProvider =\r\n typeof registry === 'object' &&\r\n registry !== null &&\r\n !Array.isArray(registry) &&\r\n Object.prototype.hasOwnProperty.call(registry, providerId);\r\n if (!ownsProvider) {\r\n return {\r\n ok: false,\r\n providerId,\r\n removedModelCount: 0,\r\n localDefaultCleared: false,\r\n localProviderExisted: false,\r\n error: `Provider \"${providerId}\" is not configured in ${label}.`,\r\n };\r\n }\r\n\r\n const provider = (registry as Record<string, unknown>)[providerId];\r\n const models =\r\n typeof provider === 'object' && provider !== null && !Array.isArray(provider)\r\n ? (provider as Record<string, unknown>).models\r\n : undefined;\r\n const removedModelCount =\r\n typeof models === 'object' && models !== null && !Array.isArray(models)\r\n ? Object.keys(models).length\r\n : 0;\r\n const localDefaultCleared =\r\n typeof existing.model === 'string' && existing.model.startsWith(`${providerId}/`);\r\n\r\n const result = new SettingsRepository(path).update((candidate) => {\r\n const candidateProviders = candidate.provider as Record<string, unknown>;\r\n delete candidateProviders[providerId];\r\n if (Object.keys(candidateProviders).length === 0) delete candidate.provider;\r\n if (localDefaultCleared) delete candidate.model;\r\n });\r\n if (result.ok) {\r\n return {\r\n ok: true,\r\n providerId,\r\n removedModelCount,\r\n localDefaultCleared,\r\n localProviderExisted: true,\r\n };\r\n }\r\n return {\r\n ok: false,\r\n providerId,\r\n removedModelCount,\r\n localDefaultCleared: false,\r\n localProviderExisted: true,\r\n error: formatSettingsDiagnostics(result.diagnostics),\r\n };\r\n}\r\n\r\n/** Remove one workspace-local provider and any local default that targets it. */\r\nexport function removeProviderLocal(\r\n workspace: string,\r\n providerId: string,\r\n): RemoveLocalProviderResult {\r\n return removeProviderAt(localSettingsPath(workspace), LOCAL_LABEL, providerId);\r\n}\r\n\r\n/** Remove one user-global provider and any global default that targets it. */\r\nexport function removeProviderGlobal(providerId: string): RemoveLocalProviderResult {\r\n return removeProviderAt(globalSettingsPath(), GLOBAL_LABEL, providerId);\r\n}\r\n\r\n/**\r\n * Append a permission rule to settings.permissions.<list> in the local layer.\r\n * Dedupes exact-string matches. Used by the \"Always allow\" approval flow\r\n * (the Claude-Code-aligned way rules get added, rather than a /permissions\r\n * string parser).\r\n */\r\nexport function persistPermissionRuleLocal(\r\n workspace: string,\r\n list: 'allow' | 'ask' | 'deny',\r\n rule: string,\r\n): { ok: boolean; error?: string } {\r\n const existing = readSettingsLocal(workspace);\r\n const perms = (existing.permissions ?? {}) as Record<string, unknown[]>;\r\n const arr = Array.isArray(perms[list]) ? [...(perms[list] as unknown[])] : [];\r\n if (!arr.includes(rule)) arr.push(rule);\r\n perms[list] = arr;\r\n return persistSettingLocal(workspace, 'permissions', perms);\r\n}\r\n\r\n/**\r\n * Remove one permission rule from the local layer.\r\n *\r\n * The counterpart to {@link persistPermissionRuleLocal}, which had none: a rule\r\n * went in on one keystroke at a tool prompt and came out only by hand-editing\r\n * `.book/settings.local.json`, since `book config unset permissions.allow`\r\n * drops the whole list. A rule the user cannot see themselves removing is a\r\n * rule they cannot safely grant.\r\n *\r\n * Only the local layer is writable here, so a rule inherited from the project\r\n * or user-global layer reports `notLocal` rather than silently doing nothing.\r\n */\r\nexport function removePermissionRuleLocal(\r\n workspace: string,\r\n list: 'allow' | 'ask' | 'deny',\r\n rule: string,\r\n): { ok: boolean; error?: string; notLocal?: boolean } {\r\n const existing = readSettingsLocal(workspace);\r\n const perms = (existing.permissions ?? {}) as Record<string, unknown[]>;\r\n const arr = Array.isArray(perms[list]) ? [...(perms[list] as unknown[])] : [];\r\n if (!arr.includes(rule)) return { ok: false, notLocal: true };\r\n perms[list] = arr.filter((entry) => entry !== rule);\r\n return persistSettingLocal(workspace, 'permissions', perms);\r\n}\r\n","import { createDefaultRegistry } from '../tools/registry.js';\r\nimport { AgentSession, type AgentSessionDependencies } from './agent-session.js';\r\nimport type { ToolDefinition } from '../types/tools.js';\r\n\r\nexport interface InteractiveAgentSessionDependencies extends AgentSessionDependencies {\r\n /**\r\n * Extra tool definitions merged into each per-send registry. Evaluated on\r\n * every send so late-arriving surfaces (e.g. MCP servers that finish\r\n * connecting in the background) join the next turn without a restart.\r\n */\r\n additionalTools?: () => ToolDefinition[];\r\n}\r\n\r\n/** Compose the interactive tool surface outside React host code. */\r\nexport function createInteractiveAgentSession(\r\n dependencies: InteractiveAgentSessionDependencies = {},\r\n): AgentSession {\r\n const { additionalTools, ...sessionDependencies } = dependencies;\r\n return new AgentSession({\r\n ...sessionDependencies,\r\n registryFactory:\r\n dependencies.registryFactory ??\r\n ((request) => {\r\n const registry = createDefaultRegistry({\r\n agents: request.config.settings.agents.mode !== 'off',\r\n ...(request.registryStore\r\n ? {\r\n sessionHistory: {\r\n store: request.registryStore,\r\n sessionId: () => request.sessionId,\r\n },\r\n }\r\n : {}),\r\n });\r\n const extra = additionalTools?.() ?? [];\r\n if (extra.length > 0) registry.registerAll(extra);\r\n return registry;\r\n }),\r\n });\r\n}\r\n","import type { NestedToolInvocation, ToolCall, ToolResult } from '../../types/tools.js';\r\nimport {\r\n appendContentToMessage,\r\n appendReasoningToMessage,\r\n appendNestedToolInvocationToMessage,\r\n appendNestedToolResultToMessage,\r\n appendToolCallToMessage,\r\n appendToolResultToMessage,\r\n} from './streaming-state.js';\r\nimport type { Message } from '../../types/messages.js';\r\n\r\n/**\r\n * A single queued streaming operation.\r\n *\r\n * Text ops are coalesced during flush; tool call/result ops are applied\r\n * individually to preserve identity.\r\n */\r\nexport type AccumulatorOp =\r\n | { type: 'text'; content: string }\r\n | { type: 'reasoning'; content: string }\r\n | { type: 'toolCall'; call: ToolCall }\r\n | { type: 'toolResult'; result: ToolResult }\r\n | { type: 'nestedToolCall'; invocation: NestedToolInvocation }\r\n | { type: 'nestedToolResult'; traceId: string; result: ToolResult };\r\n\r\n/**\r\n * Batched message accumulator for streaming events.\r\n *\r\n * Collects text deltas, tool calls, and tool results in a queue and flushes\r\n * them on a bounded cadence. Consecutive text ops are coalesced into a single\r\n * appendContentToMessage call, and no timer stays active while the queue is idle.\r\n *\r\n * The flush callback is a `setMessages`-style state updater so React can\r\n * batch the update with other state changes.\r\n */\r\nexport interface MessageAccumulator {\r\n /** Queue a text delta (appended to the streaming message). */\r\n addText: (content: string) => void;\r\n /** Queue a provider-native reasoning delta. */\r\n addReasoning: (content: string) => void;\r\n /** Queue a tool call. */\r\n addToolCall: (call: ToolCall) => void;\r\n /** Queue a tool result. */\r\n addToolResult: (result: ToolResult) => void;\r\n /** Queue a display-only tool call from a Task subagent. */\r\n addNestedToolCall: (invocation: NestedToolInvocation) => void;\r\n /** Queue a result for a display-only subagent tool call. */\r\n addNestedToolResult: (traceId: string, result: ToolResult) => void;\r\n /** Flush all queued ops immediately (called by timer and stop). */\r\n flush: () => void;\r\n /** Enable scheduled flushing. Queued work starts the timer on demand. */\r\n start: () => void;\r\n /** Stop the timer, flush remaining ops. Idempotent. */\r\n stop: () => void;\r\n /** Stop the timer and drop queued ops without flushing. Idempotent. */\r\n discard: () => void;\r\n}\r\n\r\ninterface AccumulatorState {\r\n queue: AccumulatorOp[];\r\n timerId: ReturnType<typeof setTimeout> | null;\r\n stopped: boolean;\r\n intervalMs: number;\r\n}\r\n\r\n/**\r\n * Create a message accumulator for the given message ID.\r\n *\r\n * @param messageId - ID of the assistant message being streamed into.\r\n * @param setMessages - React state setter (updater form).\r\n * @param messagesRef - Mutable ref mirror of the messages array, kept in sync.\r\n * @param flushIntervalMs - Flush cadence in milliseconds (default 16 ≈ 60fps).\r\n */\r\nexport function createMessageAccumulator(\r\n messageId: string,\r\n setMessages: (updater: (prev: Message[]) => Message[]) => void,\r\n messagesRef: { current: Message[] },\r\n flushIntervalMs = 16,\r\n): MessageAccumulator {\r\n const state: AccumulatorState = {\r\n queue: [],\r\n timerId: null,\r\n stopped: false,\r\n intervalMs: flushIntervalMs,\r\n };\r\n\r\n function scheduleNext(): void {\r\n if (state.stopped || state.timerId !== null || state.queue.length === 0) return;\r\n state.timerId = setTimeout(() => {\r\n state.timerId = null;\r\n flush();\r\n scheduleNext();\r\n }, state.intervalMs);\r\n }\r\n\r\n function flush(): void {\r\n if (state.queue.length === 0) return;\r\n\r\n // Drain the queue so new ops added during setMessages are captured\r\n // in the next flush.\r\n const ops = state.queue;\r\n state.queue = [];\r\n\r\n // Coalesce consecutive text/reasoning ops into a single append operation.\r\n // Tool calls and results are applied individually.\r\n const coalesced: AccumulatorOp[] = [];\r\n for (const op of ops) {\r\n if (\r\n (op.type === 'text' || op.type === 'reasoning') &&\r\n coalesced.length > 0 &&\r\n coalesced[coalesced.length - 1].type === op.type\r\n ) {\r\n (\r\n coalesced[coalesced.length - 1] as { type: 'text' | 'reasoning'; content: string }\r\n ).content += op.content;\r\n } else {\r\n coalesced.push(op);\r\n }\r\n }\r\n\r\n if (coalesced.length === 0) return;\r\n\r\n const startedAt = performance.now();\r\n setMessages((prev: Message[]) => {\r\n let messageIndex = -1;\r\n for (let index = prev.length - 1; index >= 0; index--) {\r\n if (prev[index].id === messageId) {\r\n messageIndex = index;\r\n break;\r\n }\r\n }\r\n if (messageIndex < 0) return prev;\r\n\r\n let active = [prev[messageIndex]];\r\n for (const op of coalesced) {\r\n if (op.type === 'text') {\r\n active = appendContentToMessage(active, messageId, op.content);\r\n } else if (op.type === 'reasoning') {\r\n active = appendReasoningToMessage(active, messageId, op.content);\r\n } else if (op.type === 'toolCall') {\r\n active = appendToolCallToMessage(active, messageId, op.call);\r\n } else if (op.type === 'toolResult') {\r\n active = appendToolResultToMessage(active, messageId, op.result);\r\n } else if (op.type === 'nestedToolCall') {\r\n active = appendNestedToolInvocationToMessage(active, messageId, op.invocation);\r\n } else {\r\n active = appendNestedToolResultToMessage(active, messageId, op.traceId, op.result);\r\n }\r\n }\r\n if (active[0] === prev[messageIndex]) return prev;\r\n const next = prev.slice();\r\n next[messageIndex] = active[0];\r\n messagesRef.current = next;\r\n return next;\r\n });\r\n const transcriptPressure = Math.floor(messagesRef.current.length / 250) * 8;\r\n // React/Ink commits after the state setter returns. Sample on the next\r\n // macrotask so the cadence reflects actual render pressure, not just the\r\n // time spent constructing the next message array.\r\n setImmediate(() => {\r\n if (state.stopped) return;\r\n const renderPressure = performance.now() - startedAt;\r\n state.intervalMs = Math.min(\r\n 48,\r\n Math.max(\r\n flushIntervalMs,\r\n Math.ceil(renderPressure * 1.5),\r\n flushIntervalMs + transcriptPressure,\r\n ),\r\n );\r\n });\r\n }\r\n\r\n function addText(content: string): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'text', content });\r\n scheduleNext();\r\n }\r\n\r\n function addReasoning(content: string): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'reasoning', content });\r\n scheduleNext();\r\n }\r\n\r\n function addToolCall(call: ToolCall): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'toolCall', call });\r\n scheduleNext();\r\n }\r\n\r\n function addToolResult(result: ToolResult): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'toolResult', result });\r\n scheduleNext();\r\n }\r\n\r\n function addNestedToolCall(invocation: NestedToolInvocation): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'nestedToolCall', invocation });\r\n scheduleNext();\r\n }\r\n\r\n function addNestedToolResult(traceId: string, result: ToolResult): void {\r\n if (state.stopped) return;\r\n state.queue.push({ type: 'nestedToolResult', traceId, result });\r\n scheduleNext();\r\n }\r\n\r\n function start(): void {\r\n state.stopped = false;\r\n scheduleNext();\r\n }\r\n\r\n function stop(): void {\r\n if (state.stopped) return;\r\n state.stopped = true;\r\n if (state.timerId !== null) {\r\n clearTimeout(state.timerId);\r\n state.timerId = null;\r\n }\r\n // Final flush of any remaining ops and pending text.\r\n flush();\r\n }\r\n\r\n function discard(): void {\r\n state.stopped = true;\r\n state.queue = [];\r\n if (state.timerId !== null) {\r\n clearTimeout(state.timerId);\r\n state.timerId = null;\r\n }\r\n }\r\n\r\n return {\r\n addText,\r\n addReasoning,\r\n addToolCall,\r\n addToolResult,\r\n addNestedToolCall,\r\n addNestedToolResult,\r\n flush,\r\n start,\r\n stop,\r\n discard,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\n\r\nexport interface Task {\r\n id: string;\r\n subject: string;\r\n status: 'pending' | 'in_progress' | 'completed';\r\n createdAt: number;\r\n}\r\n\r\nexport function useTasks() {\r\n const [tasks, setTasks] = useState<Task[]>([]);\r\n\r\n const addTask = useCallback((data: { subject: string; status: Task['status'] }) => {\r\n const task: Task = {\r\n id: crypto.randomUUID(),\r\n subject: data.subject,\r\n status: data.status,\r\n createdAt: Date.now(),\r\n };\r\n setTasks((prev) => [...prev, task]);\r\n }, []);\r\n\r\n const updateTaskStatus = useCallback((id: string, status: Task['status']) => {\r\n setTasks((prev) => prev.map((t) => (t.id === id ? { ...t, status } : t)));\r\n }, []);\r\n\r\n const removeTask = useCallback((id: string) => {\r\n setTasks((prev) => prev.filter((t) => t.id !== id));\r\n }, []);\r\n\r\n const clearTasks = useCallback(() => {\r\n setTasks([]);\r\n }, []);\r\n\r\n return { tasks, addTask, updateTaskStatus, removeTask, clearTasks };\r\n}\r\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\r\nimport type { AgentManager } from '../../agents/manager.js';\r\nimport type {\r\n AgentActivity,\r\n AgentCompletionNotification,\r\n AgentRecord,\r\n AgentRuntimeEvent,\r\n AgentSummary,\r\n} from '../../agents/types.js';\r\nimport { projectAgentSummary } from '../../agents/projections.js';\r\nimport type { UserQuestionResponse } from '../../types/tools.js';\r\n\r\nexport type ManagedAgentSurface = 'main' | 'tasks' | 'detail';\r\n\r\nexport interface QueuedAgentCompletion {\r\n id: string;\r\n notification: AgentCompletionNotification;\r\n}\r\n\r\nexport interface ManagedAgentState {\r\n summaries: AgentSummary[];\r\n records: Map<string, AgentRecord>;\r\n activities: Map<string, AgentActivity[]>;\r\n liveText: Map<string, string>;\r\n selectedAgentId?: string;\r\n surface: ManagedAgentSurface;\r\n pendingPermissions: AgentRuntimeEvent[];\r\n pendingQuestions: Array<{\r\n agentId: string;\r\n request: NonNullable<AgentRecord['pendingQuestion']>;\r\n }>;\r\n pendingCompletions: QueuedAgentCompletion[];\r\n persistenceEvent?: Extract<AgentRuntimeEvent, { type: 'agent_persistence' }>;\r\n setSurface: (surface: ManagedAgentSurface) => void;\r\n selectAgent: (agentId?: string) => void;\r\n send: (message: string) => Promise<void>;\r\n stopOrDismiss: (agentId?: string) => Promise<void>;\r\n resolvePermission: (requestId: string, response: 'allow' | 'deny' | 'always') => Promise<void>;\r\n resolveQuestion: (agentId: string, response: UserQuestionResponse) => Promise<void>;\r\n acknowledgeCompletions: (ids: string[]) => Promise<void>;\r\n refresh: () => Promise<void>;\r\n}\r\n\r\nfunction upsertSummary(current: AgentSummary[], next: AgentSummary): AgentSummary[] {\r\n const filtered = current.filter((summary) => summary.agentId !== next.agentId);\r\n return [next, ...filtered].sort((left, right) => {\r\n const leftDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(left.status);\r\n const rightDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(right.status);\r\n if (leftDone !== rightDone) return leftDone ? 1 : -1;\r\n return right.updatedAt - left.updatedAt;\r\n });\r\n}\r\n\r\nexport function useManagedAgents(\r\n manager: AgentManager,\r\n parentSessionId?: string,\r\n): ManagedAgentState {\r\n const [summaries, setSummaries] = useState<AgentSummary[]>([]);\r\n const [records, setRecords] = useState<Map<string, AgentRecord>>(() => new Map());\r\n const [activities, setActivities] = useState<Map<string, AgentActivity[]>>(() => new Map());\r\n const [liveText, setLiveText] = useState<Map<string, string>>(() => new Map());\r\n const [selectedAgentId, setSelectedAgentId] = useState<string>();\r\n const [surface, setSurface] = useState<ManagedAgentSurface>('main');\r\n const [pendingCompletions, setPendingCompletions] = useState<QueuedAgentCompletion[]>([]);\r\n const [persistenceEvent, setPersistenceEvent] = useState<\r\n Extract<AgentRuntimeEvent, { type: 'agent_persistence' }> | undefined\r\n >();\r\n const seenCompletions = useRef(new Set<string>());\r\n const deferredDismissals = useRef(new Set<string>());\r\n const visibleAgentIds = useRef(new Set<string>());\r\n\r\n const belongsToCurrentSession = useCallback(\r\n (candidateParentSessionId: string | undefined) =>\r\n parentSessionId === undefined || candidateParentSessionId === parentSessionId,\r\n [parentSessionId],\r\n );\r\n\r\n const enqueueCompletion = useCallback(\r\n (notification: AgentCompletionNotification) => {\r\n if (!belongsToCurrentSession(notification.parentSessionId)) return;\r\n const id = notification.deliveryId;\r\n if (seenCompletions.current.has(id)) return;\r\n seenCompletions.current.add(id);\r\n setPendingCompletions((current) => [...current, { id, notification }]);\r\n },\r\n [belongsToCurrentSession],\r\n );\r\n\r\n const refresh = useCallback(async () => {\r\n const pendingPromise =\r\n typeof manager.listPendingCompletions === 'function'\r\n ? manager.listPendingCompletions()\r\n : Promise.resolve([]);\r\n const [nextRecords, nextCompletions] = await Promise.all([manager.list(), pendingPromise]);\r\n const scopedRecords = nextRecords.filter((record) =>\r\n belongsToCurrentSession(record.parentSessionId),\r\n );\r\n visibleAgentIds.current = new Set(scopedRecords.map((record) => record.id));\r\n setRecords(new Map(scopedRecords.map((record) => [record.id, record])));\r\n setSummaries(\r\n scopedRecords\r\n .filter((record) => {\r\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(\r\n record.status,\r\n );\r\n return (\r\n !terminal ||\r\n deferredDismissals.current.has(record.id) ||\r\n (record.completionSequence ?? 0) > (record.completionDeliveredSequence ?? 0)\r\n );\r\n })\r\n .map(projectAgentSummary)\r\n .sort((left, right) => {\r\n const leftDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(left.status);\r\n const rightDone = ['completed', 'failed', 'stopped', 'interrupted'].includes(\r\n right.status,\r\n );\r\n if (leftDone !== rightDone) return leftDone ? 1 : -1;\r\n return right.updatedAt - left.updatedAt;\r\n }),\r\n );\r\n for (const notification of nextCompletions) enqueueCompletion(notification);\r\n }, [enqueueCompletion, manager]);\r\n\r\n useEffect(() => {\r\n setSummaries([]);\r\n setRecords(new Map());\r\n setActivities(new Map());\r\n setLiveText(new Map());\r\n setSelectedAgentId(undefined);\r\n setSurface('main');\r\n setPendingCompletions([]);\r\n setPersistenceEvent(undefined);\r\n seenCompletions.current.clear();\r\n deferredDismissals.current.clear();\r\n visibleAgentIds.current.clear();\r\n void refresh().catch(() => {});\r\n const unsubscribe = manager.subscribe(\r\n (event) => {\r\n if (event.type === 'agent_persistence') {\r\n setPersistenceEvent(event);\r\n return;\r\n }\r\n if (event.type === 'agent_status') {\r\n if (!belongsToCurrentSession(event.parentSessionId)) return;\r\n visibleAgentIds.current.add(event.agent.agentId);\r\n setSummaries((current) => upsertSummary(current, event.agent));\r\n return;\r\n }\r\n if (event.type === 'agent_activity') {\r\n if (!visibleAgentIds.current.has(event.agentId)) return;\r\n setActivities((current) => {\r\n const next = new Map(current);\r\n const agentActivities = [...(next.get(event.agentId) ?? [])];\r\n const index = agentActivities.findIndex(\r\n (activity) => activity.id === event.activity.id,\r\n );\r\n if (index >= 0) agentActivities[index] = event.activity;\r\n else agentActivities.push(event.activity);\r\n next.set(event.agentId, agentActivities);\r\n return next;\r\n });\r\n setRecords((current) => {\r\n const record = current.get(event.agentId);\r\n if (!record) return current;\r\n return new Map(current).set(event.agentId, {\r\n ...record,\r\n currentActivity: event.activity,\r\n updatedAt: Math.max(\r\n record.updatedAt,\r\n event.activity.finishedAt ?? event.activity.startedAt,\r\n ),\r\n });\r\n });\r\n setSummaries((current) => {\r\n const summary = current.find((candidate) => candidate.agentId === event.agentId);\r\n if (!summary) return current;\r\n return upsertSummary(current, {\r\n ...summary,\r\n currentActivity: event.activity,\r\n updatedAt: Math.max(\r\n summary.updatedAt,\r\n event.activity.finishedAt ?? event.activity.startedAt,\r\n ),\r\n });\r\n });\r\n return;\r\n }\r\n if (event.type === 'agent_update' || event.type === 'agent_start') {\r\n if (!belongsToCurrentSession(event.agent.parentSessionId)) return;\r\n visibleAgentIds.current.add(event.agent.id);\r\n setRecords((current) => new Map(current).set(event.agent.id, event.agent));\r\n setSummaries((current) => upsertSummary(current, projectAgentSummary(event.agent)));\r\n return;\r\n }\r\n if (event.type === 'agent_result') {\r\n if (!belongsToCurrentSession(event.agent.parentSessionId)) return;\r\n visibleAgentIds.current.add(event.agent.id);\r\n setRecords((current) => new Map(current).set(event.agent.id, event.agent));\r\n setSummaries((current) => upsertSummary(current, projectAgentSummary(event.agent)));\r\n return;\r\n }\r\n if (event.type === 'agent_completion') {\r\n enqueueCompletion(event.notification);\r\n return;\r\n }\r\n if (event.type === 'agent_message') {\r\n if (!visibleAgentIds.current.has(event.agentId)) return;\r\n setRecords((current) => {\r\n const record = current.get(event.agentId);\r\n if (!record || record.transcript.some((message) => message.id === event.message.id)) {\r\n return current;\r\n }\r\n return new Map(current).set(event.agentId, {\r\n ...record,\r\n transcript: [...record.transcript, event.message],\r\n });\r\n });\r\n // The deltas that built this message are now in the transcript. Left\r\n // in the live buffer they render a second time under it, and keep\r\n // accumulating across the child's later turns.\r\n setLiveText((current) => {\r\n if (!current.has(event.agentId)) return current;\r\n const next = new Map(current);\r\n next.delete(event.agentId);\r\n return next;\r\n });\r\n return;\r\n }\r\n if (event.type === 'agent_text_delta') {\r\n if (!visibleAgentIds.current.has(event.agentId)) return;\r\n setLiveText((current) => {\r\n const next = new Map(current);\r\n next.set(event.agentId, `${next.get(event.agentId) ?? ''}${event.text}`.slice(-12000));\r\n return next;\r\n });\r\n }\r\n },\r\n { snapshot: true },\r\n );\r\n manager.setInteractivePermissions(true);\r\n return () => {\r\n unsubscribe();\r\n manager.setInteractivePermissions(false);\r\n };\r\n }, [belongsToCurrentSession, enqueueCompletion, manager, refresh]);\r\n\r\n useEffect(() => {\r\n if (persistenceEvent?.state !== 'recovered') return;\r\n const timer = setTimeout(() => setPersistenceEvent(undefined), 3_000);\r\n return () => clearTimeout(timer);\r\n }, [persistenceEvent]);\r\n\r\n const pendingPermissions = useMemo(\r\n () =>\r\n Array.from(records.values())\r\n .filter((record) => record.pendingPermission)\r\n .sort(\r\n (left, right) =>\r\n (left.pendingPermission?.createdAt ?? 0) - (right.pendingPermission?.createdAt ?? 0),\r\n )\r\n .map((record) => ({\r\n type: 'agent_permission' as const,\r\n agentId: record.id,\r\n request: record.pendingPermission!,\r\n })),\r\n [records],\r\n );\r\n const pendingQuestions = useMemo(\r\n () =>\r\n Array.from(records.values())\r\n .filter((record) => record.pendingQuestion)\r\n .sort((left, right) => {\r\n const age =\r\n (left.pendingQuestionCreatedAt ?? left.updatedAt) -\r\n (right.pendingQuestionCreatedAt ?? right.updatedAt);\r\n return age || left.id.localeCompare(right.id);\r\n })\r\n .map((record) => ({ agentId: record.id, request: record.pendingQuestion! })),\r\n [records],\r\n );\r\n\r\n const send = useCallback(\r\n async (message: string) => {\r\n if (!selectedAgentId) return;\r\n deferredDismissals.current.delete(selectedAgentId);\r\n const next = await manager.send(selectedAgentId, message);\r\n setRecords((current) => new Map(current).set(next.id, next));\r\n setSummaries((current) => upsertSummary(current, projectAgentSummary(next)));\r\n },\r\n [manager, selectedAgentId],\r\n );\r\n\r\n const stopOrDismiss = useCallback(\r\n async (agentId?: string) => {\r\n const targetAgentId = agentId ?? selectedAgentId;\r\n if (!targetAgentId) return;\r\n const record = await manager.get(targetAgentId);\r\n if (!record) return;\r\n if (['completed', 'failed', 'stopped', 'interrupted'].includes(record.status)) {\r\n const completionPending =\r\n (record.completionSequence ?? 0) > (record.completionDeliveredSequence ?? 0);\r\n if (!completionPending) await manager.dismiss(targetAgentId);\r\n setRecords((current) => {\r\n const next = new Map(current);\r\n if (!completionPending) next.delete(targetAgentId);\r\n return next;\r\n });\r\n setSummaries((current) => current.filter((summary) => summary.agentId !== targetAgentId));\r\n setSelectedAgentId((current) => (current === targetAgentId ? undefined : current));\r\n return;\r\n }\r\n const next = await manager.stop(targetAgentId);\r\n setRecords((current) => new Map(current).set(next.id, next));\r\n setSummaries((current) => current.filter((summary) => summary.agentId !== targetAgentId));\r\n setSelectedAgentId((current) => (current === targetAgentId ? undefined : current));\r\n },\r\n [manager, selectedAgentId],\r\n );\r\n\r\n const resolvePermission = useCallback(\r\n async (requestId: string, response: 'allow' | 'deny' | 'always') => {\r\n const request = pendingPermissions.find(\r\n (event) => event.type === 'agent_permission' && event.request.id === requestId,\r\n );\r\n if (!request || request.type !== 'agent_permission') return;\r\n const next = await manager.resolvePermission(request.agentId, requestId, response);\r\n setRecords((current) => new Map(current).set(next.id, next));\r\n },\r\n [manager, pendingPermissions],\r\n );\r\n\r\n const resolveQuestion = useCallback(\r\n async (agentId: string, response: UserQuestionResponse) => {\r\n const next = await manager.resolveQuestion(agentId, response);\r\n setRecords((current) => new Map(current).set(next.id, next));\r\n },\r\n [manager],\r\n );\r\n\r\n const acknowledgeCompletions = useCallback(\r\n async (ids: string[]) => {\r\n if (ids.length === 0) return;\r\n const acknowledged = new Set(ids);\r\n const items = pendingCompletions.filter((item) => acknowledged.has(item.id));\r\n if (typeof manager.acknowledgeCompletion === 'function') {\r\n await Promise.all(\r\n items.map((item) => manager.acknowledgeCompletion(item.notification.deliveryId)),\r\n );\r\n }\r\n const completedAgentIds = new Set(items.map((item) => item.notification.completion.agentId));\r\n const heldAgentIds = new Set<string>();\r\n if (\r\n surface === 'detail' &&\r\n selectedAgentId !== undefined &&\r\n completedAgentIds.has(selectedAgentId)\r\n ) {\r\n heldAgentIds.add(selectedAgentId);\r\n deferredDismissals.current.add(selectedAgentId);\r\n }\r\n setSummaries((current) =>\r\n current.filter(\r\n (summary) => !completedAgentIds.has(summary.agentId) || heldAgentIds.has(summary.agentId),\r\n ),\r\n );\r\n setSelectedAgentId((current) =>\r\n current && completedAgentIds.has(current) && !heldAgentIds.has(current)\r\n ? undefined\r\n : current,\r\n );\r\n setPendingCompletions((current) => current.filter((item) => !acknowledged.has(item.id)));\r\n },\r\n [manager, pendingCompletions, selectedAgentId, surface],\r\n );\r\n\r\n const changeSurface = useCallback((nextSurface: ManagedAgentSurface) => {\r\n if (nextSurface === 'main' && deferredDismissals.current.size > 0) {\r\n const dismissed = new Set(deferredDismissals.current);\r\n deferredDismissals.current.clear();\r\n setSummaries((current) => current.filter((summary) => !dismissed.has(summary.agentId)));\r\n setSelectedAgentId((current) => (current && dismissed.has(current) ? undefined : current));\r\n }\r\n setSurface(nextSurface);\r\n }, []);\r\n\r\n return {\r\n summaries,\r\n records,\r\n activities,\r\n liveText,\r\n selectedAgentId,\r\n surface,\r\n pendingPermissions,\r\n pendingQuestions,\r\n pendingCompletions,\r\n persistenceEvent,\r\n setSurface: changeSurface,\r\n selectAgent: setSelectedAgentId,\r\n send,\r\n stopOrDismiss,\r\n resolvePermission,\r\n resolveQuestion,\r\n acknowledgeCompletions,\r\n refresh,\r\n };\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react';\r\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\r\nimport type { ShellJobManager } from '../../jobs/shell-manager.js';\r\n\r\n/**\r\n * Output chunks arrive at raw process frequency (hundreds/s for chatty\r\n * commands); every un-coalesced refresh forces a full App render + Yoga\r\n * layout pass. Consumers read live output via readTail/readOutput, never from\r\n * this list, so output events only need a slow safety-net refresh.\r\n */\r\nconst OUTPUT_REFRESH_COALESCE_MS = 250;\r\n\r\n/**\r\n * Field-wise equality over everything the shell list UI renders. Deliberately\r\n * ignores output, readOffset, and outputRevision: cloneRecord makes every\r\n * list() call referentially fresh, and without this bail each output chunk\r\n * would re-render the whole App with no visible change.\r\n */\r\nfunction shellListEquals(left: BackgroundShellRecord[], right: BackgroundShellRecord[]): boolean {\r\n if (left.length !== right.length) return false;\r\n for (let index = 0; index < left.length; index++) {\r\n const previous = left[index];\r\n const next = right[index];\r\n if (\r\n previous.id !== next.id ||\r\n previous.status !== next.status ||\r\n previous.title !== next.title ||\r\n previous.command !== next.command ||\r\n previous.lifetime !== next.lifetime ||\r\n previous.notify !== next.notify ||\r\n previous.pid !== next.pid ||\r\n previous.startedAt !== next.startedAt ||\r\n previous.finishedAt !== next.finishedAt ||\r\n previous.exitCode !== next.exitCode ||\r\n previous.truncatedBytes !== next.truncatedBytes\r\n ) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface BackgroundShellState {\r\n shells: BackgroundShellRecord[];\r\n lastCompletion?: BackgroundShellRecord;\r\n pendingUiCompletions: BackgroundShellRecord[];\r\n pendingAgentCompletions: BackgroundShellRecord[];\r\n refresh: () => void;\r\n stopOrDismiss: (shellId: string) => Promise<void>;\r\n acknowledge: (shellId: string) => void;\r\n acknowledgeAgentCompletion: (shellId: string, sequence?: number) => void;\r\n}\r\n\r\nexport function useBackgroundShells(\r\n manager: ShellJobManager,\r\n parentSessionId: string,\r\n): BackgroundShellState {\r\n const visible = useCallback(\r\n () =>\r\n manager\r\n .list()\r\n .filter(\r\n (shell) => !['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(shell.status),\r\n ),\r\n [manager],\r\n );\r\n const [shells, setShells] = useState<BackgroundShellRecord[]>(visible);\r\n const [pendingUiCompletions, setPendingUiCompletions] = useState<BackgroundShellRecord[]>(() =>\r\n manager.listPendingUiCompletions(),\r\n );\r\n const [pendingAgentCompletions, setPendingAgentCompletions] = useState<BackgroundShellRecord[]>(\r\n () => manager.listPendingAgentCompletions(parentSessionId),\r\n );\r\n const lastCompletion = pendingUiCompletions[0];\r\n const refresh = useCallback(() => {\r\n setShells((current) => {\r\n const next = visible();\r\n return shellListEquals(current, next) ? current : next;\r\n });\r\n }, [visible]);\r\n const outputRefreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n useEffect(() => {\r\n refresh();\r\n setPendingUiCompletions(manager.listPendingUiCompletions());\r\n setPendingAgentCompletions(manager.listPendingAgentCompletions(parentSessionId));\r\n const scheduleOutputRefresh = () => {\r\n if (outputRefreshTimerRef.current !== null) return;\r\n outputRefreshTimerRef.current = setTimeout(() => {\r\n outputRefreshTimerRef.current = null;\r\n refresh();\r\n }, OUTPUT_REFRESH_COALESCE_MS);\r\n };\r\n const unsubscribe = manager.subscribe((event) => {\r\n if (event.type === 'background_job_output') {\r\n // Refresh on a timer only: the list renders nothing from output, but\r\n // the periodic pass still picks up side effects such as truncation\r\n // counters and persistent-job status reconciliation.\r\n scheduleOutputRefresh();\r\n return;\r\n }\r\n if (event.type === 'background_job_result') {\r\n if (event.job.notify !== 'none') {\r\n setPendingUiCompletions((current) => [\r\n ...current.filter((shell) => shell.id !== event.job.id),\r\n event.job,\r\n ]);\r\n }\r\n if (\r\n event.job.notify === 'agent' &&\r\n event.job.parentSessionId === parentSessionId &&\r\n (event.job.completionSequence ?? 0) > (event.job.completionDeliveredSequence ?? 0)\r\n ) {\r\n setPendingAgentCompletions((current) => [\r\n ...current.filter((shell) => shell.id !== event.job.id),\r\n event.job,\r\n ]);\r\n }\r\n }\r\n refresh();\r\n });\r\n return () => {\r\n unsubscribe();\r\n if (outputRefreshTimerRef.current !== null) {\r\n clearTimeout(outputRefreshTimerRef.current);\r\n outputRefreshTimerRef.current = null;\r\n }\r\n };\r\n }, [manager, parentSessionId, refresh]);\r\n\r\n const stopOrDismiss = useCallback(\r\n async (shellId: string) => {\r\n const shell = manager.get(shellId);\r\n if (!shell) return;\r\n if (['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(shell.status)) {\r\n manager.dismiss(shellId);\r\n } else {\r\n await manager.stop(shellId);\r\n }\r\n refresh();\r\n },\r\n [manager, refresh],\r\n );\r\n\r\n const acknowledge = useCallback(\r\n (shellId: string) => {\r\n manager.acknowledgeCompletion(shellId);\r\n setPendingUiCompletions((current) => current.filter((shell) => shell.id !== shellId));\r\n refresh();\r\n },\r\n [manager, refresh],\r\n );\r\n\r\n const acknowledgeAgentCompletion = useCallback(\r\n (shellId: string, sequence?: number) => {\r\n manager.acknowledgeCompletion(shellId, sequence, 'agent');\r\n setPendingAgentCompletions((current) => current.filter((shell) => shell.id !== shellId));\r\n },\r\n [manager],\r\n );\r\n\r\n return {\r\n shells,\r\n lastCompletion,\r\n pendingUiCompletions,\r\n pendingAgentCompletions,\r\n refresh,\r\n stopOrDismiss,\r\n acknowledge,\r\n acknowledgeAgentCompletion,\r\n };\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport { execFile } from 'node:child_process';\r\nimport { existsSync } from 'node:fs';\r\nimport { dirname, join, resolve } from 'node:path';\r\nimport { isTranscriptScrollActive } from '../scroll-activity.js';\r\n\r\n/**\r\n * Whether `dir` sits anywhere inside a working tree, without spawning anything.\r\n *\r\n * Probing only `<workspace>/.git` succeeds at the repository root alone, so\r\n * launching from a subdirectory reported no branch. Asking `git rev-parse`\r\n * instead fixed that but made every poll spawn children even where there is no\r\n * repository at all: three processes every five seconds, forever, in any plain\r\n * directory. Walking up for the entry costs a handful of `stat` calls and gets\r\n * the subdirectory case right. A worktree or submodule stores `.git` as a file\r\n * rather than a directory, so the entry is what is checked, not its type.\r\n */\r\nexport function isInsideWorkTree(\r\n dir: string,\r\n exists: (path: string) => boolean = existsSync,\r\n): boolean {\r\n let current = resolve(dir);\r\n for (;;) {\r\n if (exists(join(current, '.git'))) return true;\r\n const parent = dirname(current);\r\n if (parent === current) return false;\r\n current = parent;\r\n }\r\n}\r\n\r\nexport interface GitStatus {\r\n branch: string;\r\n status: string; // '\\u2713' clean, '+2 ~1' staged/modified\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Replace state only when the reported status actually changed.\r\n *\r\n * The poll allocates a fresh object every tick, so returning it unconditionally\r\n * made React re-render the whole app twelve times a minute in an idle session\r\n * for no visual change.\r\n */\r\nexport function sameStatus(left: GitStatus, right: GitStatus): boolean {\r\n return left.branch === right.branch && left.status === right.status && left.error === right.error;\r\n}\r\n\r\nexport function useGitStatus(workspace: string): GitStatus {\r\n const [status, setStatus] = useState<GitStatus>({ branch: '?', status: '' });\r\n const update = useCallback((next: GitStatus) => {\r\n setStatus((current) => (sameStatus(current, next) ? current : next));\r\n }, []);\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n let running = false;\r\n let activeController: AbortController | undefined;\r\n\r\n async function check(): Promise<void> {\r\n if (isTranscriptScrollActive()) return;\r\n if (running) return;\r\n running = true;\r\n if (!isInsideWorkTree(workspace)) {\r\n if (!cancelled) update({ branch: '?', status: '' });\r\n running = false;\r\n return;\r\n }\r\n activeController = new AbortController();\r\n\r\n try {\r\n const branch = await runGit(\r\n ['rev-parse', '--abbrev-ref', 'HEAD'],\r\n workspace,\r\n activeController.signal,\r\n );\r\n const short = await runGit(['status', '--short'], workspace, activeController.signal);\r\n\r\n if (!short) {\r\n if (!cancelled) update({ branch, status: '\\u2713' });\r\n return;\r\n }\r\n\r\n const lines = short.split('\\n').filter(Boolean);\r\n let staged = 0;\r\n let modified = 0;\r\n for (const line of lines) {\r\n const stagedChar = line[0];\r\n const modChar = line[1];\r\n if (stagedChar !== ' ' && stagedChar !== '?') staged++;\r\n if (modChar !== ' ') modified++;\r\n }\r\n\r\n const parts: string[] = [];\r\n if (staged > 0) parts.push(`+${staged}`);\r\n if (modified > 0) parts.push(`~${modified}`);\r\n\r\n if (!cancelled) update({ branch, status: parts.join(' ') });\r\n } catch {\r\n // Not a repository, or git is unavailable — both mean \"no branch\".\r\n if (!cancelled) update({ branch: '?', status: '', error: 'git error' });\r\n } finally {\r\n running = false;\r\n activeController = undefined;\r\n }\r\n }\r\n\r\n void check();\r\n const interval = setInterval(() => void check(), 5000);\r\n return () => {\r\n cancelled = true;\r\n activeController?.abort();\r\n clearInterval(interval);\r\n };\r\n }, [update, workspace]);\r\n\r\n return status;\r\n}\r\n\r\nfunction runGit(args: string[], cwd: string, signal: AbortSignal): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n execFile(\r\n 'git',\r\n args,\r\n { cwd, timeout: 5_000, encoding: 'utf8', windowsHide: true, signal },\r\n (error, stdout) => (error ? reject(error) : resolve(stdout.trim())),\r\n );\r\n });\r\n}\r\n","import { useEffect, useRef } from 'react';\r\nimport type { AgentCompletionNotification } from '../../agents/types.js';\r\nimport { takeAgentCompletionBatch } from '../../agents/completion-notification.js';\r\nimport type { QueuedAgentCompletion } from './useManagedAgents.js';\r\n\r\nexport function useAgentCompletionDelivery(options: {\r\n pending: QueuedAgentCompletion[];\r\n parentSessionId: string;\r\n blocked: boolean;\r\n deliver: (notifications: AgentCompletionNotification[]) => Promise<boolean>;\r\n acknowledge: (ids: string[]) => Promise<void>;\r\n}): void {\r\n const deliveryInFlight = useRef(false);\r\n const deliveredIds = useRef(new Set<string>());\r\n const mounted = useRef(true);\r\n const retryAttempts = useRef(0);\r\n const retryTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\r\n const pendingKey = useRef('');\r\n const latest = useRef(options);\r\n const drain = useRef<() => void>(() => {});\r\n latest.current = options;\r\n\r\n const scheduleRetry = () => {\r\n if (!mounted.current || retryTimer.current || retryAttempts.current >= 5) return;\r\n const delayMs = Math.min(1000 * 2 ** retryAttempts.current, 16_000);\r\n retryAttempts.current++;\r\n retryTimer.current = setTimeout(() => {\r\n retryTimer.current = undefined;\r\n drain.current();\r\n }, delayMs);\r\n };\r\n\r\n drain.current = () => {\r\n const current = latest.current;\r\n if (!mounted.current || current.blocked || deliveryInFlight.current || retryTimer.current)\r\n return;\r\n const pending = current.pending.filter(\r\n (item) =>\r\n item.notification.parentSessionId === current.parentSessionId &&\r\n !deliveredIds.current.has(item.id),\r\n );\r\n if (pending.length === 0) return;\r\n\r\n const batchNotifications = takeAgentCompletionBatch(pending.map((item) => item.notification));\r\n const batchIds = new Set(batchNotifications.map((notification) => notification.deliveryId));\r\n const batch = pending.filter((item) => batchIds.has(item.notification.deliveryId));\r\n deliveryInFlight.current = true;\r\n let acknowledged = false;\r\n void current\r\n .deliver(batchNotifications)\r\n .then(async (nextAccepted) => {\r\n if (!nextAccepted || !mounted.current) {\r\n scheduleRetry();\r\n return;\r\n }\r\n const ids = batch.map((item) => item.id);\r\n try {\r\n await current.acknowledge(ids);\r\n } catch {\r\n scheduleRetry();\r\n return;\r\n }\r\n if (!mounted.current) return;\r\n retryAttempts.current = 0;\r\n for (const id of ids) deliveredIds.current.add(id);\r\n acknowledged = true;\r\n })\r\n .catch(() => {\r\n scheduleRetry();\r\n })\r\n .finally(() => {\r\n deliveryInFlight.current = false;\r\n if (acknowledged) queueMicrotask(() => drain.current());\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n const nextKey = options.pending.map((item) => item.id).join('\\0');\r\n if (nextKey !== pendingKey.current) {\r\n pendingKey.current = nextKey;\r\n retryAttempts.current = 0;\r\n if (retryTimer.current) clearTimeout(retryTimer.current);\r\n retryTimer.current = undefined;\r\n }\r\n drain.current();\r\n }, [options.blocked, options.parentSessionId, options.pending]);\r\n\r\n useEffect(() => {\r\n mounted.current = true;\r\n return () => {\r\n mounted.current = false;\r\n if (retryTimer.current) clearTimeout(retryTimer.current);\r\n retryTimer.current = undefined;\r\n };\r\n }, []);\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useEffect, useMemo } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport type { AgentSummary } from '../../agents/types.js';\r\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { CONTENT_COLUMN } from '../layout.js';\r\nimport { SubagentRow } from './SubagentRow.js';\r\nimport { BackgroundShellRow } from './BackgroundShellRow.js';\r\n\r\nexport function SubagentPanel({\r\n agents,\r\n shells = [],\r\n selectedJobId,\r\n selectedAgentId,\r\n isActive = false,\r\n onSelect,\r\n onOpen,\r\n onClose,\r\n onCancel,\r\n onStopOrDismiss,\r\n width = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: {\r\n agents: AgentSummary[];\r\n shells?: BackgroundShellRecord[];\r\n selectedJobId?: string;\r\n selectedAgentId?: string;\r\n isActive?: boolean;\r\n onSelect?: (id?: string) => void;\r\n onOpen?: (id: string) => void;\r\n onClose?: () => void;\r\n onCancel?: () => void;\r\n onStopOrDismiss?: (id: string) => void;\r\n width?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n const [selectedIndex, setSelectedIndex, currentIndex] = useKeyState(0);\r\n const orderedAgents = useMemo(\r\n () =>\r\n [...agents].sort((left, right) => {\r\n const terminal = (status: AgentSummary['status']) =>\r\n ['completed', 'failed', 'stopped', 'interrupted'].includes(status);\r\n const leftTerminal = terminal(left.status);\r\n const rightTerminal = terminal(right.status);\r\n if (leftTerminal !== rightTerminal) return leftTerminal ? 1 : -1;\r\n return right.updatedAt - left.updatedAt;\r\n }),\r\n [agents],\r\n );\r\n const orderedShells = useMemo(\r\n () =>\r\n [...shells].sort((left, right) => {\r\n const terminal = (status: BackgroundShellRecord['status']) =>\r\n ['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(status);\r\n const leftTerminal = terminal(left.status);\r\n const rightTerminal = terminal(right.status);\r\n if (leftTerminal !== rightTerminal) return leftTerminal ? 1 : -1;\r\n return (right.finishedAt ?? right.startedAt) - (left.finishedAt ?? left.startedAt);\r\n }),\r\n [shells],\r\n );\r\n const jobs = useMemo(\r\n () => [\r\n ...orderedAgents.map((agent) => ({ id: agent.agentId, kind: 'agent' as const, agent })),\r\n ...orderedShells.map((shell) => ({ id: shell.id, kind: 'shell' as const, shell })),\r\n ],\r\n [orderedAgents, orderedShells],\r\n );\r\n const rows = useMemo(() => [undefined, ...jobs.map((job) => job.id)], [jobs]);\r\n useEffect(() => {\r\n const selected = selectedJobId ?? selectedAgentId;\r\n const next = selected ? rows.indexOf(selected) : 0;\r\n const resolved = next >= 0 ? next : 0;\r\n setSelectedIndex(resolved);\r\n }, [rows, selectedAgentId, selectedJobId, setSelectedIndex]);\r\n useInput(\r\n (input, key) => {\r\n if (!isActive) return;\r\n if (key.escape) return onCancel?.();\r\n if (key.upArrow) {\r\n const next = (currentIndex() - 1 + rows.length) % rows.length;\r\n setSelectedIndex(next);\r\n onSelect?.(rows[next]);\r\n } else if (key.downArrow || key.tab) {\r\n const next = (currentIndex() + 1) % rows.length;\r\n setSelectedIndex(next);\r\n onSelect?.(rows[next]);\r\n } else if (key.return) {\r\n const id = rows[currentIndex()];\r\n if (id) onOpen?.(id);\r\n else onClose?.();\r\n } else if (input === 'x') {\r\n const id = rows[currentIndex()];\r\n if (id) onStopOrDismiss?.(id);\r\n }\r\n },\r\n { isActive },\r\n );\r\n const tiny = width < 42;\r\n const maxVisible = 5;\r\n // Keep the focused agent inside the window so Tab-cycling never highlights a\r\n // row that has scrolled out of view.\r\n const selected = selectedJobId ?? selectedAgentId;\r\n const focusedAgentIndex = selected ? jobs.findIndex((job) => job.id === selected) : -1;\r\n const windowStart =\r\n focusedAgentIndex < 0\r\n ? 0\r\n : Math.min(\r\n Math.max(0, focusedAgentIndex - (maxVisible - 1)),\r\n Math.max(0, jobs.length - maxVisible),\r\n );\r\n const visible = tiny\r\n ? [jobs.find((job) => job.id === selected) ?? jobs[0]].filter(Boolean)\r\n : jobs.slice(windowStart, windowStart + maxVisible);\r\n const activeRowId = rows[selectedIndex];\r\n const selectedMain = activeRowId === undefined;\r\n if (jobs.length === 0 && !isActive) return null;\r\n return (\r\n <Box flexDirection=\"column\" width={width} marginTop={1}>\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.brand} bold>\r\n Background tasks\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text color={selectedMain ? theme.text : theme.subtle} bold={selectedMain}>\r\n {selectedMain ? '› ' : ' '}● main\r\n </Text>\r\n <Text color={theme.subtle}> current conversation</Text>\r\n </Box>\r\n {jobs.length === 0 ? (\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.subtle}>No background tasks.</Text>\r\n </Box>\r\n ) : null}\r\n {visible.map((job) =>\r\n job.kind === 'agent' ? (\r\n <SubagentRow\r\n key={job.id}\r\n agent={job.agent}\r\n selected={job.id === activeRowId}\r\n width={Math.max(20, width - 2)}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n ) : (\r\n <BackgroundShellRow\r\n key={job.id}\r\n shell={job.shell}\r\n selected={job.id === activeRowId}\r\n width={Math.max(20, width - 2)}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n />\r\n ),\r\n )}\r\n {jobs.length > visible.length ? (\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.subtle}>+{jobs.length - visible.length} more tasks</Text>\r\n </Box>\r\n ) : null}\r\n <Box paddingLeft={CONTENT_COLUMN}>\r\n <Text color={theme.subtle}>\r\n {isActive\r\n ? 'Tab/↑↓ select · Enter open · x stop/dismiss · Esc cancel'\r\n : 'Tab switch job · /jobs manage'}\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import { Text } from 'ink';\r\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport { formatElapsedDuration } from './SubagentRow.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\nfunction glyph(shell: BackgroundShellRecord, reducedMotion: boolean): string {\r\n if (shell.status === 'exited') return '✓';\r\n if (shell.status === 'failed' || shell.status === 'timed_out' || shell.status === 'lost')\r\n return '✕';\r\n if (shell.status === 'killed') return '■';\r\n return reducedMotion ? '*' : '●';\r\n}\r\n\r\nexport function BackgroundShellRow({\r\n shell,\r\n selected = false,\r\n width = 80,\r\n reducedMotion = false,\r\n screenReader = false,\r\n}: {\r\n shell: BackgroundShellRecord;\r\n selected?: boolean;\r\n width?: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n const terminal = ['exited', 'failed', 'killed', 'timed_out', 'lost'].includes(shell.status);\r\n const tick = useUiClock('slow', !terminal);\r\n void tick;\r\n const elapsed = Math.max(\r\n 0,\r\n Math.floor(((shell.finishedAt ?? Date.now()) - shell.startedAt) / 1000),\r\n );\r\n const unread =\r\n (shell.completionSequence ?? 0) > (shell.completionAcknowledgedSequence ?? 0) ? ' !' : '';\r\n const lifetime = shell.lifetime === 'persistent' ? ' | persistent' : '';\r\n const suffix = ` | ${formatElapsedDuration(elapsed)}${lifetime}${unread}`;\r\n const title = shell.title || shell.command;\r\n const color =\r\n shell.status === 'exited'\r\n ? theme.success\r\n : shell.status === 'failed' || shell.status === 'timed_out' || shell.status === 'lost'\r\n ? theme.error\r\n : theme.brand;\r\n\r\n if (screenReader) {\r\n return (\r\n <Text>\r\n {title}. shell. {shell.status}. {formatElapsedDuration(elapsed)}.\r\n </Text>\r\n );\r\n }\r\n\r\n return (\r\n <Text color={selected ? theme.text : color} bold={selected}>\r\n {selected ? '› ' : ' '}\r\n {glyph(shell, reducedMotion)} shell{' '}\r\n {truncateDisplay(title, Math.max(1, width - 11 - suffix.length))}\r\n <Text color={theme.subtle}>{suffix}</Text>\r\n </Text>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useMemo } from 'react';\r\nimport type { AgentRecord } from '../../agents/types.js';\r\nimport type { Message } from '../../types/messages.js';\r\nimport type { TranscriptMode } from '../tool-presentation.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { AgentMessage } from './AgentMessage.js';\r\nimport { ChatPanel } from './ChatPanel.js';\r\n\r\n/**\r\n * The child's in-flight turn, shaped as the assistant message it will become.\r\n *\r\n * A managed child streams its text out of band (`agent_text_delta`) and files\r\n * the finished message afterwards, so while a turn is open there is no\r\n * `Message` for the transcript to render. Printing the raw buffer under the\r\n * panel put the child's private reasoning on screen verbatim — a router that\r\n * inlines thinking as `<think>…</think>` produced a wall of tags — while the\r\n * same text one row up, in the settled transcript, was collapsed to a\r\n * `thought` row. Rendering it as a streaming `AgentMessage` gives the live turn\r\n * the same reasoning split, markdown, and width as every settled one.\r\n */\r\nfunction liveMessage(agentId: string, text: string): Message {\r\n return {\r\n id: `${agentId}:live`,\r\n role: 'assistant',\r\n content: text,\r\n includeInContext: false,\r\n timestamp: 0,\r\n };\r\n}\r\n\r\nexport function SubagentDetail({\r\n record,\r\n liveText,\r\n width,\r\n height,\r\n reducedMotion = false,\r\n screenReader = false,\r\n transcriptMode = 'compact',\r\n automaticToolCallId,\r\n toolExpansionOverrides,\r\n showAllToolOutput = false,\r\n showAllToolOutputIds,\r\n showThinking = true,\r\n}: {\r\n record: AgentRecord;\r\n liveText?: string;\r\n width: number;\r\n height: number;\r\n reducedMotion?: boolean;\r\n screenReader?: boolean;\r\n transcriptMode?: TranscriptMode;\r\n automaticToolCallId?: string | null;\r\n toolExpansionOverrides?: ReadonlyMap<string, boolean>;\r\n showAllToolOutput?: boolean;\r\n showAllToolOutputIds?: ReadonlySet<string>;\r\n showThinking?: boolean;\r\n}) {\r\n const theme = useTheme();\r\n const terminal = ['completed', 'failed', 'stopped', 'interrupted'].includes(record.status);\r\n const hasTranscript = record.transcript.length > 0;\r\n const streaming = Boolean(liveText) && !terminal;\r\n const live = useMemo(\r\n () => (streaming ? liveMessage(record.id, liveText!) : undefined),\r\n [liveText, record.id, streaming],\r\n );\r\n return (\r\n <Box flexDirection=\"column\" width={width}>\r\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1}>\r\n <Text color={theme.brand} bold>\r\n main &gt; {record.displayName ?? record.name}\r\n </Text>\r\n <Text color={theme.subtle}>\r\n {record.profile ?? record.name} | {record.resolvedModel ?? 'unknown'} |{' '}\r\n {record.isolation ?? 'worktree'} | {record.status}\r\n </Text>\r\n {record.referencedEvidenceIds.length > 0 ? (\r\n <Text color={theme.subtle}>Evidence: {record.referencedEvidenceIds.join(', ')}</Text>\r\n ) : null}\r\n <Text color={theme.subtle}>\r\n Type a follow-up to resume this child · Tab switch · Esc main · /tasks list\r\n </Text>\r\n </Box>\r\n {/*\r\n ChatPanel renders nothing for an empty managed transcript, so the\r\n placeholder / live stream below owns the empty state. Ordering: live\r\n stream while the child is producing output, then a status placeholder\r\n only when there is no transcript yet.\r\n */}\r\n <ChatPanel\r\n messages={record.transcript}\r\n terminalWidth={width}\r\n terminalHeight={height}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n model={record.resolvedModel}\r\n mode=\"managed\"\r\n transcriptMode={transcriptMode}\r\n automaticToolCallId={automaticToolCallId}\r\n toolExpansionOverrides={toolExpansionOverrides}\r\n showAllToolOutput={showAllToolOutput}\r\n showAllToolOutputIds={showAllToolOutputIds}\r\n showThinking={showThinking}\r\n />\r\n {live ? (\r\n <Box flexDirection=\"column\" marginTop={hasTranscript ? 1 : 0}>\r\n <AgentMessage\r\n message={live}\r\n isStreaming\r\n hideStreamingSpinner\r\n transcriptMode={transcriptMode}\r\n reducedMotion={reducedMotion}\r\n screenReader={screenReader}\r\n terminalWidth={width}\r\n showThinking={showThinking}\r\n />\r\n </Box>\r\n ) : !hasTranscript ? (\r\n <Box paddingX={1}>\r\n <Text color={theme.subtle}>\r\n {terminal ? 'No transcript recorded.' : 'Waiting for the subagent to produce output…'}\r\n </Text>\r\n </Box>\r\n ) : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from 'ink';\r\nimport { useEffect, useState } from 'react';\r\nimport type { BackgroundShellRecord } from '../../types/runtime.js';\r\nimport { useTheme } from '../theme.js';\r\nimport { useUiClock } from '../ui-clock.js';\r\nimport { formatElapsedDuration } from './SubagentRow.js';\r\n\r\n/** Live-output poll cadence. Reading the tail can hit the filesystem for\r\n * persistent jobs, so it must happen in an effect, never during render. */\r\nconst OUTPUT_POLL_MS = 250;\r\n\r\nfunction sanitizeOutput(value: string): string {\r\n return value.replace(/\\x1b\\[[0-?]*[ -/]*[@-~]/g, '').replace(/\\x1b\\][^\\x07]*(?:\\x07|$)/g, '');\r\n}\r\n\r\nexport function BackgroundShellDetail({\r\n shell,\r\n readTail,\r\n width,\r\n}: {\r\n shell: BackgroundShellRecord;\r\n /** Stable callback returning the current output tail for this shell. */\r\n readTail: () => string;\r\n width: number;\r\n}) {\r\n const theme = useTheme();\r\n const running = shell.finishedAt === undefined;\r\n useUiClock('slow', running);\r\n const [output, setOutput] = useState(readTail);\r\n useEffect(() => {\r\n setOutput(readTail());\r\n if (!running) return;\r\n const timer = setInterval(() => setOutput(readTail()), OUTPUT_POLL_MS);\r\n return () => clearInterval(timer);\r\n }, [readTail, running]);\r\n const elapsed = Math.max(\r\n 0,\r\n Math.floor(((shell.finishedAt ?? Date.now()) - shell.startedAt) / 1000),\r\n );\r\n const exit = shell.exitCode !== undefined ? ` | exit ${shell.exitCode ?? 'none'}` : '';\r\n return (\r\n <Box flexDirection=\"column\" width={width} paddingX={1}>\r\n <Text color={theme.brand} bold>\r\n main &gt; {shell.title || shell.command}\r\n </Text>\r\n <Text color={theme.subtle}>\r\n shell | {shell.status} | {shell.lifetime ?? 'session'} | {formatElapsedDuration(elapsed)}\r\n {exit}\r\n </Text>\r\n <Text color={theme.subtle}>\r\n pid {shell.pid ?? 'unknown'} | {shell.sandboxed ? 'sandboxed' : 'unsandboxed'} | notify{' '}\r\n {shell.notify ?? 'ui'}\r\n </Text>\r\n <Text color={theme.subtle}>cwd {shell.workdir}</Text>\r\n <Text>{shell.command}</Text>\r\n {shell.truncatedBytes > 0 ? (\r\n <Text color={theme.warning}>\r\n {shell.truncatedBytes} older output characters were truncated.\r\n </Text>\r\n ) : null}\r\n <Box marginTop={1} flexDirection=\"column\">\r\n <Text color={theme.subtle}>Output tail</Text>\r\n <Text>{sanitizeOutput(output) || '(no output yet)'}</Text>\r\n </Box>\r\n <Text color={theme.subtle}>Tab switch | x stop/dismiss | Esc main | /jobs list</Text>\r\n </Box>\r\n );\r\n}\r\n","import type { AgentActivity, AgentRecord } from '../agents/types.js';\r\nimport type { Message } from '../types/messages.js';\r\nimport type { ToolCall, ToolResult } from '../types/tools.js';\r\n\r\nexport interface ManagedAgentToolUse {\r\n id: string;\r\n call: ToolCall;\r\n result?: ToolResult;\r\n status: 'running' | 'completed' | 'failed';\r\n startedAt: number;\r\n finishedAt?: number;\r\n}\r\n\r\nexport interface ManagedAgentTrace {\r\n agentId: string;\r\n parentToolCallId: string;\r\n profile: string;\r\n purpose: string;\r\n status: AgentRecord['status'];\r\n startedAt: number;\r\n finishedAt?: number;\r\n toolUses: ManagedAgentToolUse[];\r\n}\r\n\r\nfunction spawnAgentId(result: ToolResult | undefined): string | undefined {\r\n if (!result || typeof result.data !== 'object' || result.data === null) return undefined;\r\n const candidate = (result.data as { agentId?: unknown }).agentId;\r\n return typeof candidate === 'string' ? candidate : undefined;\r\n}\r\n\r\nfunction activityResult(activity: AgentActivity): ToolResult | undefined {\r\n return activity.result;\r\n}\r\n\r\nfunction activityCall(activity: AgentActivity): ToolCall | undefined {\r\n if (activity.kind !== 'tool' || !activity.toolCall) return undefined;\r\n return activity.toolCall;\r\n}\r\n\r\nfunction activityStatus(activity: AgentActivity): ManagedAgentToolUse['status'] {\r\n return activity.status === 'failed'\r\n ? 'failed'\r\n : activity.status === 'completed'\r\n ? 'completed'\r\n : 'running';\r\n}\r\n\r\nfunction resultStatus(result: ToolResult | undefined): ManagedAgentToolUse['status'] | undefined {\r\n if (!result) return undefined;\r\n return result.status === 'success' ? 'completed' : 'failed';\r\n}\r\n\r\nfunction projectChildToolUses(\r\n record: AgentRecord,\r\n activities: AgentActivity[],\r\n): ManagedAgentToolUse[] {\r\n const byId = new Map<string, ManagedAgentToolUse>();\r\n let order = 0;\r\n\r\n const upsert = (use: ManagedAgentToolUse): void => {\r\n const existing = byId.get(use.id);\r\n if (!existing) {\r\n byId.set(use.id, use);\r\n return;\r\n }\r\n byId.set(use.id, {\r\n ...existing,\r\n call: use.call,\r\n result: use.result ?? existing.result,\r\n status:\r\n use.status === 'running' && existing.status !== 'running' ? existing.status : use.status,\r\n startedAt: Math.min(existing.startedAt, use.startedAt),\r\n finishedAt: use.finishedAt ?? existing.finishedAt,\r\n });\r\n };\r\n\r\n for (const activity of activities) {\r\n const call = activityCall(activity);\r\n if (!call) continue;\r\n upsert({\r\n id: call.id,\r\n call,\r\n result: activityResult(activity),\r\n status: activityStatus(activity),\r\n startedAt: activity.startedAt || order++,\r\n finishedAt: activity.finishedAt,\r\n });\r\n order++;\r\n }\r\n\r\n for (const message of record.transcript) {\r\n for (const call of message.toolCalls ?? []) {\r\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\r\n const status = resultStatus(result) ?? byId.get(call.id)?.status ?? 'running';\r\n upsert({\r\n id: call.id,\r\n call,\r\n result,\r\n status,\r\n startedAt: byId.get(call.id)?.startedAt ?? message.timestamp + order,\r\n finishedAt: byId.get(call.id)?.finishedAt ?? (result ? message.timestamp : undefined),\r\n });\r\n order++;\r\n }\r\n }\r\n\r\n return [...byId.values()].sort((left, right) => left.startedAt - right.startedAt);\r\n}\r\n\r\nconst EMPTY_TRACES: ReadonlyMap<string, ManagedAgentTrace> = new Map();\r\n\r\n/**\r\n * Build UI-only traces for managed AgentSpawn calls. Parent Message objects are\r\n * left untouched so child activity never enters provider context or persistence.\r\n */\r\nexport function projectManagedAgentTraces(\r\n messages: Message[],\r\n records: ReadonlyMap<string, AgentRecord>,\r\n activities: ReadonlyMap<string, AgentActivity[]>,\r\n): ReadonlyMap<string, ManagedAgentTrace> {\r\n // Traces require a live agent record; skip the transcript scan entirely (and\r\n // keep a stable identity) while no managed agents exist.\r\n if (records.size === 0) return EMPTY_TRACES;\r\n const traces = new Map<string, ManagedAgentTrace>();\r\n for (const message of messages) {\r\n if (message.role !== 'assistant') continue;\r\n for (const call of message.toolCalls ?? []) {\r\n if (call.name !== 'AgentSpawn') continue;\r\n const result = message.toolResults?.find((candidate) => candidate.toolCallId === call.id);\r\n const agentId = spawnAgentId(result);\r\n const record = agentId ? records.get(agentId) : undefined;\r\n if (!agentId || !record) continue;\r\n traces.set(call.id, {\r\n agentId,\r\n parentToolCallId: call.id,\r\n profile: record.profile ?? record.name,\r\n purpose: record.displayName ?? record.purpose ?? record.prompt,\r\n status: record.status,\r\n startedAt: record.startedAt ?? record.createdAt,\r\n finishedAt: record.finishedAt,\r\n toolUses: projectChildToolUses(record, activities.get(agentId) ?? []),\r\n });\r\n }\r\n }\r\n return traces;\r\n}\r\n","/**\r\n * Wrap arbitrary text so a markdown renderer shows it verbatim.\r\n *\r\n * Local transcript messages (`addLocalMessage`) are prose: they go through\r\n * `MarkdownBlock`, so any text interpolated into one is markdown. A background\r\n * shell command is not — a command carrying a `KILLPROBE` block comment lost\r\n * both of its asterisks to the `em` token, and the completion row disagreed\r\n * with the tool row directly above it about which command had just finished.\r\n * Asterisks are only the visible half of the class: `#`, `[x](y)`, `~~` and `_`\r\n * are all live in prose too.\r\n *\r\n * A code span is the escape hatch, but only if the fence survives the content:\r\n *\r\n * - **Line breaks first.** Block parsing runs before inline parsing, so a `#`\r\n * or a fence line at the start of an embedded line splits the paragraph and\r\n * strands the opening backtick as a literal. Flatten to one line and the\r\n * fence has a single paragraph to live in.\r\n * - **Fence longer than any run inside.** ``echo `date` `` needs a two-backtick\r\n * fence, or the span closes on the command's own backtick.\r\n * - **Pad when the edges collide.** A leading or trailing backtick would fuse\r\n * with the fence; CommonMark strips one space from each end when both are\r\n * present, so the padding does not survive into the rendered text.\r\n */\r\nexport function inlineCode(text: string): string {\r\n const oneLine = text.replace(/\\r\\n|\\r|\\n/g, ' ');\r\n // Nothing to quote. An empty span is not a code span at all, so a fence here\r\n // would leave two stray backticks sitting in the row.\r\n if (!oneLine.trim()) return '';\r\n\r\n const longestRun = [...oneLine.matchAll(/`+/g)].reduce(\r\n (longest, match) => Math.max(longest, match[0].length),\r\n 0,\r\n );\r\n const fence = '`'.repeat(longestRun + 1);\r\n const pad = /^[`\\s]|[`\\s]$/.test(oneLine) ? ' ' : '';\r\n return `${fence}${pad}${oneLine}${pad}${fence}`;\r\n}\r\n","import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs';\r\nimport { basename, extname, join } from 'path';\r\nimport { parseFrontmatter } from '../frontmatter.js';\r\nimport { normalizeAgentTool } from '../subagent-discovery.js';\r\n\r\nconst MUTATION_TOOLS = new Set([\r\n 'ApplyPatch',\r\n 'Write',\r\n 'Edit',\r\n 'MultiEdit',\r\n 'NotebookEdit',\r\n 'Bash',\r\n]);\r\nconst SAFE_AGENT_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\r\n\r\nfunction assertSafeAgentName(name: string): void {\r\n if (!SAFE_AGENT_NAME.test(name) || name === '.' || name === '..') {\r\n throw new Error(\r\n `Unsafe agent name \"${name}\". Names must start with a letter or number and contain only letters, numbers, dots, underscores, or hyphens.`,\r\n );\r\n }\r\n}\r\n\r\nexport interface AgentImportPreview {\r\n sourcePath: string;\r\n name: string;\r\n description: string;\r\n body: string;\r\n tools: string[];\r\n unsupportedTools: string[];\r\n missingTools: boolean;\r\n model?: string;\r\n maxTurns?: number;\r\n warnings: string[];\r\n}\r\n\r\nfunction sourceFiles(path: string): string[] {\r\n if (!existsSync(path)) throw new Error(`Agent import path does not exist: ${path}`);\r\n if (statSync(path).isFile()) return extname(path) === '.md' ? [path] : [];\r\n const files: string[] = [];\r\n const visit = (directory: string) => {\r\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\r\n const fullPath = join(directory, entry.name);\r\n if (entry.isDirectory()) visit(fullPath);\r\n else if (entry.isFile() && extname(entry.name) === '.md') files.push(fullPath);\r\n }\r\n };\r\n visit(path);\r\n return files.sort();\r\n}\r\n\r\nfunction rawTools(value: unknown): string[] {\r\n if (Array.isArray(value))\r\n return value\r\n .map(String)\r\n .map((tool) => tool.trim())\r\n .filter(Boolean);\r\n if (typeof value === 'string')\r\n return value\r\n .split(',')\r\n .map((tool) => tool.trim())\r\n .filter(Boolean);\r\n return [];\r\n}\r\n\r\nexport function previewAgentImport(path: string): AgentImportPreview[] {\r\n return sourceFiles(path).map((sourcePath) => {\r\n const { body, frontmatter } = parseFrontmatter(readFileSync(sourcePath, 'utf8'));\r\n const requestedTools = rawTools(frontmatter.tools ?? frontmatter['allowed-tools']);\r\n const tools = requestedTools\r\n .map(normalizeAgentTool)\r\n .filter((tool): tool is string => Boolean(tool));\r\n const unsupportedTools = requestedTools.filter((tool) => !normalizeAgentTool(tool));\r\n const name = String(frontmatter.name ?? basename(sourcePath, '.md'));\r\n const description = String(frontmatter.description ?? name);\r\n const warnings: string[] = [];\r\n if (!SAFE_AGENT_NAME.test(name) || name === '.' || name === '..') {\r\n warnings.push(`Unsafe agent name: ${name}. Installation will be refused.`);\r\n }\r\n if (requestedTools.length === 0)\r\n warnings.push('No tools were declared; the imported profile denies all tools.');\r\n if (unsupportedTools.length > 0)\r\n warnings.push(`Unsupported tools: ${unsupportedTools.join(', ')}.`);\r\n const readOnlyNominal = /explor|review|research|read.?only/i.test(`${name} ${description}`);\r\n const risky = tools.filter((tool) => MUTATION_TOOLS.has(tool.split('(')[0]));\r\n if (readOnlyNominal && risky.length > 0) {\r\n warnings.push(`Nominally read-only profile includes mutation tools: ${risky.join(', ')}.`);\r\n }\r\n const modelValue = typeof frontmatter.model === 'string' ? frontmatter.model.trim() : undefined;\r\n return {\r\n sourcePath,\r\n name,\r\n description,\r\n body,\r\n tools: Array.from(new Set(tools)),\r\n unsupportedTools,\r\n missingTools: requestedTools.length === 0,\r\n model: modelValue && modelValue !== 'inherit' ? modelValue : undefined,\r\n maxTurns:\r\n typeof frontmatter.maxTurns === 'number'\r\n ? frontmatter.maxTurns\r\n : typeof frontmatter.maxTurns === 'string'\r\n ? Number.parseInt(frontmatter.maxTurns, 10) || undefined\r\n : undefined,\r\n warnings,\r\n };\r\n });\r\n}\r\n\r\nexport function installAgentImports(\r\n previews: AgentImportPreview[],\r\n targetDirectory: string,\r\n): string[] {\r\n const names = new Set<string>();\r\n const targets = previews.map((preview) => {\r\n assertSafeAgentName(preview.name);\r\n if (names.has(preview.name)) {\r\n throw new Error(`Duplicate imported agent name: ${preview.name}.`);\r\n }\r\n names.add(preview.name);\r\n const target = join(targetDirectory, `${preview.name}.md`);\r\n if (existsSync(target)) {\r\n throw new Error(`Agent definition already exists: ${target}. Remove or rename it first.`);\r\n }\r\n return target;\r\n });\r\n mkdirSync(targetDirectory, { recursive: true });\r\n return previews.map((preview, index) => {\r\n const target = targets[index];\r\n const frontmatter = [\r\n '---',\r\n `name: ${preview.name}`,\r\n `description: ${preview.description}`,\r\n 'tools:',\r\n ...preview.tools.map((tool) => `- ${tool}`),\r\n ...(preview.model ? [`model: ${preview.model}`] : []),\r\n ...(preview.maxTurns ? [`maxTurns: ${preview.maxTurns}`] : []),\r\n '---',\r\n preview.body,\r\n '',\r\n ].join('\\n');\r\n writeFileSync(target, frontmatter, { encoding: 'utf8', flag: 'wx' });\r\n return target;\r\n });\r\n}\r\n","import { Box, Text, useInput } from 'ink';\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport { useKeyState } from '../hooks/useKeyState.js';\r\nimport { useTheme } from '../theme.js';\r\nimport type { PermissionMode } from '../../types/runtime.js';\r\nimport { panelContentWidth } from '../layout.js';\r\nimport { SelectionRow } from './chrome.js';\r\nimport { truncateDisplay } from './word-wrap.js';\r\n\r\nexport type PermissionList = 'allow' | 'ask' | 'deny';\r\n\r\nexport interface PermissionRuleEntry {\r\n list: PermissionList;\r\n rule: string;\r\n}\r\n\r\nexport interface RemoveRuleResult {\r\n ok: boolean;\r\n error?: string;\r\n /** The rule is inherited from a layer this panel cannot write. */\r\n notLocal?: boolean;\r\n}\r\n\r\ninterface PermissionsPanelProps {\r\n mode: PermissionMode;\r\n permissions: Record<PermissionList, readonly string[]>;\r\n /** Removes a rule from the local layer. Absent while another surface owns input. */\r\n onRemove?: (entry: PermissionRuleEntry) => RemoveRuleResult;\r\n /** False while a modal or picker owns the keyboard. */\r\n active?: boolean;\r\n terminalWidth?: number;\r\n screenReader?: boolean;\r\n}\r\n\r\nconst LISTS: readonly PermissionList[] = ['allow', 'ask', 'deny'];\r\n\r\n/** Flatten the three lists into the order the panel renders them. */\r\nexport function flattenPermissionRules(\r\n permissions: Record<PermissionList, readonly string[]>,\r\n): PermissionRuleEntry[] {\r\n return LISTS.flatMap((list) => permissions[list].map((rule) => ({ list, rule })));\r\n}\r\n\r\n/**\r\n * The `/permissions` sheet.\r\n *\r\n * It used to be static text captioned \"add via the Always allow option at tool\r\n * prompts\" — accurate, and the whole problem: a rule went in on one keystroke\r\n * and came out only by hand-editing `.book/settings.local.json`. Adding a\r\n * permission was cheap and removing one was not, which is the wrong way round\r\n * for the surface that decides what the agent may do unattended.\r\n */\r\nexport function PermissionsPanel({\r\n mode,\r\n permissions,\r\n onRemove,\r\n active = true,\r\n terminalWidth = 80,\r\n screenReader = false,\r\n}: PermissionsPanelProps) {\r\n const theme = useTheme();\r\n const entries = useMemo(() => flattenPermissionRules(permissions), [permissions]);\r\n const [selected, setSelected, currentSelected] = useKeyState(0);\r\n // The keyed actions read the cursor from a ref: arrows and `x` arriving in\r\n // one React batch would otherwise remove the row the cursor was on before\r\n // the arrows moved it.\r\n const move = (next: (current: number) => number) => {\r\n setSelected(entries.length === 0 ? 0 : next(currentSelected()));\r\n };\r\n const [notice, setNotice] = useState<string | null>(null);\r\n // The interior of the bordered box app.tsx wraps this in, taken from the same\r\n // panel grid that sizes the box -- so the rules stop exactly where it does.\r\n const width = panelContentWidth(terminalWidth);\r\n\r\n // Removing the last rule, or a reload shrinking the list, must not leave the\r\n // cursor pointing past the end.\r\n useEffect(() => {\r\n setSelected(Math.max(0, Math.min(currentSelected(), entries.length - 1)));\r\n }, [entries.length]);\r\n\r\n const canEdit = Boolean(onRemove) && entries.length > 0 && active && !screenReader;\r\n\r\n useInput(\r\n (input, key) => {\r\n if (key.upArrow) {\r\n setNotice(null);\r\n move((s) => (s - 1 + entries.length) % entries.length);\r\n return;\r\n }\r\n if (key.downArrow) {\r\n setNotice(null);\r\n move((s) => (s + 1) % entries.length);\r\n return;\r\n }\r\n if (input === 'x' || input === 'X') {\r\n const entry = entries[currentSelected()];\r\n if (!entry) return;\r\n const result = onRemove!(entry);\r\n if (result.ok) setNotice(`Removed ${entry.rule}`);\r\n else if (result.notLocal)\r\n setNotice(`${entry.rule} comes from a settings file this panel cannot edit.`);\r\n else setNotice(result.error ?? `Could not remove ${entry.rule}`);\r\n }\r\n },\r\n { isActive: canEdit },\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <Box flexDirection=\"column\">\r\n <Text color={theme.subtle} dimColor>\r\n Current mode — {mode}\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Modes — default, auto, plan, accept-edits, dontAsk, bypassPermissions\r\n </Text>\r\n <Text color={theme.subtle} dimColor>\r\n Switch — Alt+M or Shift+Tab\r\n </Text>\r\n </Box>\r\n <Box flexDirection=\"column\">\r\n <Text color={theme.subtle} dimColor>\r\n {entries.length === 0\r\n ? 'No rules yet. \"Always allow\" at a tool prompt adds one.'\r\n : canEdit\r\n ? 'Rules — ↑↓ select, x remove'\r\n : 'Rules'}\r\n </Text>\r\n {LISTS.map((list) => (\r\n <Box key={list} flexDirection=\"column\">\r\n <Text color={theme.subtle} dimColor>\r\n {' '}\r\n {list}:\r\n </Text>\r\n {permissions[list].length === 0 ? (\r\n <Text color={theme.subtle} dimColor>\r\n {' (none)'}\r\n </Text>\r\n ) : (\r\n permissions[list].map((rule) => {\r\n const index = entries.findIndex(\r\n (entry) => entry.list === list && entry.rule === rule,\r\n );\r\n const isSelected = canEdit && index === selected;\r\n return (\r\n <SelectionRow key={`${list}-${rule}`} selected={isSelected} width={width}>\r\n {truncateDisplay(`${isSelected ? ' › ' : ' '}${rule}`, width)}\r\n </SelectionRow>\r\n );\r\n })\r\n )}\r\n </Box>\r\n ))}\r\n {notice ? <Text color={theme.warning}>{truncateDisplay(notice, width)}</Text> : null}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import type { ImageAttachment } from '../types/messages.js';\r\n\r\nexport const MAX_QUEUED_INPUTS = 10;\r\n\r\nexport interface QueuedInput {\r\n id: string;\r\n sessionId: string;\r\n value: string;\r\n attachments?: ImageAttachment[];\r\n createdAt: number;\r\n}\r\n\r\nexport function createQueuedInput(\r\n value: string,\r\n sessionId: string,\r\n attachmentsOrExisting: ImageAttachment[] | Pick<QueuedInput, 'id' | 'createdAt'> = [],\r\n existing?: Pick<QueuedInput, 'id' | 'createdAt'>,\r\n): QueuedInput {\r\n const attachments = Array.isArray(attachmentsOrExisting) ? attachmentsOrExisting : [];\r\n const identity = Array.isArray(attachmentsOrExisting) ? existing : attachmentsOrExisting;\r\n return {\r\n id: identity?.id ?? crypto.randomUUID(),\r\n sessionId,\r\n value,\r\n ...(attachments.length > 0 ? { attachments } : {}),\r\n createdAt: identity?.createdAt ?? Date.now(),\r\n };\r\n}\r\n\r\nexport function enqueueQueuedInput(\r\n queue: readonly QueuedInput[],\r\n input: QueuedInput,\r\n capacity = MAX_QUEUED_INPUTS,\r\n): { accepted: boolean; queue: QueuedInput[] } {\r\n if (queue.length >= capacity) return { accepted: false, queue: [...queue] };\r\n return { accepted: true, queue: [...queue, input] };\r\n}\r\n\r\nexport function recallNewestQueuedInput(\r\n queue: readonly QueuedInput[],\r\n excludedId?: string,\r\n): { queue: QueuedInput[]; recalled?: QueuedInput } {\r\n let index = -1;\r\n for (let candidate = queue.length - 1; candidate >= 0; candidate--) {\r\n if (queue[candidate].id !== excludedId) {\r\n index = candidate;\r\n break;\r\n }\r\n }\r\n if (index < 0) return { queue: [...queue] };\r\n return {\r\n queue: queue.filter((_, itemIndex) => itemIndex !== index),\r\n recalled: queue[index],\r\n };\r\n}\r\n\r\nexport function restoreQueuedInputText(queue: readonly QueuedInput[], draft: string): string {\r\n return [...queue.map((item) => item.value), draft]\r\n .filter((value) => value.trim().length > 0)\r\n .join('\\n\\n');\r\n}\r\n\r\nexport function restoreQueuedInputAttachments(\r\n queue: readonly QueuedInput[],\r\n draft: readonly ImageAttachment[] = [],\r\n): ImageAttachment[] {\r\n return [...queue.flatMap((item) => item.attachments ?? []), ...draft];\r\n}\r\n\r\nexport function shouldRequeueQueuedSend(result: {\r\n status: 'completed' | 'cancelled' | 'failed' | 'rejected';\r\n phase?: 'before-prepare' | 'prepare' | 'run';\r\n userMessagePersisted?: boolean;\r\n}): boolean {\r\n return (\r\n result.status === 'rejected' ||\r\n result.status === 'cancelled' ||\r\n (result.status === 'failed' &&\r\n (result.phase === 'before-prepare' ||\r\n (result.phase === 'prepare' && result.userMessagePersisted === false)))\r\n );\r\n}\r\n","import { spawn } from 'child_process';\r\n\r\nexport const MAX_CLIPBOARD_IMAGE_BYTES = 8 * 1024 * 1024;\r\n\r\nexport interface ClipboardImage {\r\n bytes: Uint8Array;\r\n mediaType: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';\r\n}\r\n\r\ninterface CommandResult {\r\n code: number | null;\r\n stdout: Buffer;\r\n stderr: string;\r\n}\r\n\r\nfunction run(command: string, args: string[], timeoutMs = 5_000): Promise<CommandResult> {\r\n return new Promise((resolve, reject) => {\r\n const child = spawn(command, args, { windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] });\r\n const stdout: Buffer[] = [];\r\n const stderr: Buffer[] = [];\r\n let size = 0;\r\n const timer = setTimeout(() => child.kill(), timeoutMs);\r\n\r\n child.stdout.on('data', (chunk: Buffer) => {\r\n size += chunk.length;\r\n if (size > MAX_CLIPBOARD_IMAGE_BYTES * 2) {\r\n child.kill();\r\n reject(new Error('Clipboard image exceeds the 8 MB limit.'));\r\n return;\r\n }\r\n stdout.push(chunk);\r\n });\r\n child.stderr.on('data', (chunk: Buffer) => stderr.push(chunk));\r\n child.once('error', (error) => {\r\n clearTimeout(timer);\r\n reject(error);\r\n });\r\n child.once('close', (code) => {\r\n clearTimeout(timer);\r\n resolve({ code, stdout: Buffer.concat(stdout), stderr: Buffer.concat(stderr).toString() });\r\n });\r\n });\r\n}\r\n\r\nexport function detectImageMediaType(bytes: Uint8Array): ClipboardImage['mediaType'] | null {\r\n if (\r\n bytes.length >= 8 &&\r\n bytes[0] === 0x89 &&\r\n bytes[1] === 0x50 &&\r\n bytes[2] === 0x4e &&\r\n bytes[3] === 0x47\r\n ) {\r\n return 'image/png';\r\n }\r\n if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff) {\r\n return 'image/jpeg';\r\n }\r\n const header = Buffer.from(bytes.subarray(0, 12)).toString('ascii');\r\n if (header.startsWith('GIF87a') || header.startsWith('GIF89a')) return 'image/gif';\r\n if (header.startsWith('RIFF') && header.slice(8, 12) === 'WEBP') return 'image/webp';\r\n return null;\r\n}\r\n\r\nfunction validated(bytes: Uint8Array): ClipboardImage {\r\n if (bytes.byteLength === 0) throw new Error('No image is available on the clipboard.');\r\n if (bytes.byteLength > MAX_CLIPBOARD_IMAGE_BYTES) {\r\n throw new Error('Clipboard image exceeds the 8 MB limit.');\r\n }\r\n const mediaType = detectImageMediaType(bytes);\r\n if (!mediaType)\r\n throw new Error('Clipboard image format is unsupported. Use PNG, JPEG, GIF, or WebP.');\r\n return { bytes, mediaType };\r\n}\r\n\r\nasync function readWindowsClipboard(): Promise<ClipboardImage> {\r\n const script = [\r\n 'Add-Type -AssemblyName System.Windows.Forms',\r\n 'Add-Type -AssemblyName System.Drawing',\r\n 'if (-not [System.Windows.Forms.Clipboard]::ContainsImage()) { exit 3 }',\r\n '$image = [System.Windows.Forms.Clipboard]::GetImage()',\r\n '$stream = New-Object System.IO.MemoryStream',\r\n '$image.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)',\r\n '[Console]::Out.Write([Convert]::ToBase64String($stream.ToArray()))',\r\n ].join('; ');\r\n let lastError: unknown;\r\n for (const command of ['pwsh.exe', 'powershell.exe']) {\r\n try {\r\n const result = await run(command, [\r\n '-NoProfile',\r\n '-NonInteractive',\r\n '-Sta',\r\n '-Command',\r\n script,\r\n ]);\r\n if (result.code === 3) throw new Error('No image is available on the clipboard.');\r\n if (result.code !== 0) throw new Error(result.stderr.trim() || 'Clipboard helper failed.');\r\n return validated(Buffer.from(result.stdout.toString().trim(), 'base64'));\r\n } catch (error) {\r\n lastError = error;\r\n if (error instanceof Error && /No image is available/.test(error.message)) throw error;\r\n }\r\n }\r\n throw new Error(\r\n `Unable to read the Windows clipboard${lastError instanceof Error ? `: ${lastError.message}` : '.'}`,\r\n );\r\n}\r\n\r\nasync function readUnixClipboard(): Promise<ClipboardImage> {\r\n const candidates: Array<[string, string[]]> =\r\n process.platform === 'darwin'\r\n ? [['pngpaste', ['-']]]\r\n : [\r\n ['wl-paste', ['--no-newline', '--type', 'image/png']],\r\n ['wl-paste', ['--no-newline', '--type', 'image/jpeg']],\r\n ['wl-paste', ['--no-newline', '--type', 'image/webp']],\r\n ['xclip', ['-selection', 'clipboard', '-t', 'image/png', '-o']],\r\n ['xclip', ['-selection', 'clipboard', '-t', 'image/jpeg', '-o']],\r\n ['xclip', ['-selection', 'clipboard', '-t', 'image/webp', '-o']],\r\n ];\r\n let lastError: unknown;\r\n for (const [command, args] of candidates) {\r\n try {\r\n const result = await run(command, args);\r\n if (result.code === 0 && result.stdout.length > 0) return validated(result.stdout);\r\n lastError = new Error(result.stderr.trim() || `${command} found no clipboard image.`);\r\n } catch (error) {\r\n lastError = error;\r\n }\r\n }\r\n const installHint =\r\n process.platform === 'darwin' ? 'Install pngpaste' : 'Install wl-paste or xclip';\r\n throw new Error(\r\n `${installHint} to paste images${lastError instanceof Error ? `: ${lastError.message}` : '.'}`,\r\n );\r\n}\r\n\r\nexport async function readClipboardImage(): Promise<ClipboardImage> {\r\n return process.platform === 'win32' ? readWindowsClipboard() : readUnixClipboard();\r\n}\r\n"],"mappings":"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,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,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,CA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","names":["Box","Text","useInput","useStdout","useApp","useState","useCallback","useEffect","useMemo","useRef","useSyncExternalStore","Box","Text","React","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","Text","Box","React","useMemo","useState","useEffect","useRef","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","join","gutterWidth","lines","jsx","jsxs","useState","useRef","useEffect","run","Text","Box","MarkdownRenderer","useMemo","mutation","lineCount","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","Fragment","jsx","jsxs","formatDuration","Box","Text","useMemo","usage","Box","Text","jsx","jsxs","useCurrentTime","statusGlyph","Box","Text","useRef","useEffect","log","useRef","useEffect","jsx","jsxs","Box","jsx","Box","Text","jsxs","useMemo","React","Box","Text","React","Box","Text","React","jsx","jsxs","Box","Text","React","jsx","jsxs","Box","Text","React","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","Box","React","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","jsx","useRef","useState","useMemo","cache","itemKeys","estimatedRows","measurementKeys","estimatedTotalRows","useEffect","useLayoutEffect","useCallback","React","VirtualTranscriptRow","Box","jsx","jsxs","renderLog","formatTurnTime","Box","Text","useState","useRef","useEffect","useLayoutEffect","useMemo","useCallback","React","cache","Box","Text","useState","useCallback","useEffect","useRef","useMemo","useInput","Text","useMemo","Box","Text","jsx","Box","Text","Fragment","jsx","jsxs","renderLog","useMemo","Text","Text","useMemo","jsx","jsxs","useMemo","Text","Text","useMemo","jsx","jsxs","useMemo","Text","Text","useRef","jsx","jsxs","cursor","jsx","jsxs","uiLog","useState","useRef","useMemo","useEffect","useCallback","nextValue","useInput","action","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","useMemo","jsx","renderLog","useMemo","Box","run","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","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","useInput","useCallback","useState","jsx","useState","useCallback","useState","useCallback","useRef","useEffect","useMemo","useCallback","useRef","useState","resolve","Box","Text","useInput","useCallback","useMemo","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useMemo","useCallback","useInput","Box","Text","jsx","jsxs","useState","useRef","useMemo","useEffect","useCallback","useInput","Box","Text","useMemo","useState","Box","Text","useInput","useEffect","useMemo","jsx","jsxs","useMemo","useEffect","useInput","Text","Box","jsx","useState","useMemo","useMemo","useState","jsx","DESCRIPTIONS","useState","useMemo","useMemo","useState","jsx","useMemo","useState","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","formatAge","useState","useMemo","useInput","Box","Text","Box","Text","measureElement","useInput","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","resolve","graphemeSegmenter","graphemeSegmenter","jsx","jsxs","TranscriptContent","useRef","useState","useMemo","useCallback","measureElement","useLayoutEffect","useEffect","span","focusY","range","useInput","Box","Text","Box","Text","useInput","useCallback","useMemo","useRef","useEffect","useState","stringArg","jsx","jsxs","uiLog","useRef","useMemo","useState","useEffect","uiLog","useCallback","useInput","jsxs","Box","Text","jsx","Box","Text","useInput","useCallback","useRef","useState","jsx","jsxs","uiLog","BUTTONS","Text","Box","useState","useRef","useCallback","useInput","Box","Text","useInput","useCallback","useMemo","useRef","useState","jsx","jsxs","sourceLabel","useState","useRef","useCallback","useInput","useMemo","Box","Text","Box","Text","useInput","useCallback","useMemo","useState","jsx","jsxs","useState","useMemo","useCallback","current","useInput","Box","Text","Box","Text","useInput","useState","jsx","jsxs","useState","useInput","Text","Box","useState","useCallback","useRef","useEffect","uiLog","useState","useRef","usage","useEffect","useCallback","error","useState","useCallback","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useCallback","useEffect","useMemo","next","useCallback","useEffect","useRef","useState","useState","useEffect","useCallback","existsSync","join","existsSync","join","useState","useCallback","useEffect","runGit","resolve","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","Fragment","jsx","jsxs","uiLog","usage","useMemo","useState","useRef","useCallback","useApp","useEffect","useStdout","useSyncExternalStore","useInput","join","Box","Text","result"]}