sisyphi 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ZSIYQB45.js → chunk-CAJEBTUE.js} +6 -2
- package/dist/chunk-CAJEBTUE.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +53 -47
- package/dist/daemon.js.map +1 -1
- package/dist/templates/orchestrator-base.md +9 -7
- package/dist/templates/orchestrator-completion.md +5 -0
- package/dist/templates/orchestrator-impl.md +5 -0
- package/dist/templates/orchestrator-planning.md +5 -0
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/dist/templates/orchestrator-strategy.md +5 -0
- package/dist/templates/orchestrator-validation.md +5 -0
- package/dist/tui.js +577 -125
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/orchestrator-base.md +9 -7
- package/templates/orchestrator-completion.md +5 -0
- package/templates/orchestrator-impl.md +5 -0
- package/templates/orchestrator-planning.md +5 -0
- package/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/templates/orchestrator-strategy.md +5 -0
- package/templates/orchestrator-validation.md +5 -0
- package/dist/chunk-ZSIYQB45.js.map +0 -1
package/dist/tui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tui/terminal.ts","../src/tui/state.ts","../src/tui/app.ts","../src/tui/lib/tree.ts","../src/tui/lib/format.ts","../src/tui/input.ts","../src/tui/render.ts","../src/tui/lib/tree-render.ts","../src/tui/lib/client.ts","../src/tui/lib/tmux.ts","../src/tui/lib/clipboard.ts","../src/tui/panels/tree.ts","../src/tui/panels/detail.ts","../src/tui/panels/nvim-detail.ts","../src/tui/panels/bottom.ts","../src/tui/panels/overlays.ts","../src/tui/lib/nvim-bridge.ts","../src/tui/lib/overview-writer.ts","../src/tui/index.ts"],"sourcesContent":["export interface Key {\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n pageUp: boolean;\n pageDown: boolean;\n return: boolean;\n escape: boolean;\n ctrl: boolean;\n shift: boolean;\n tab: boolean;\n backspace: boolean;\n delete: boolean;\n meta: boolean;\n}\n\nexport type KeypressHandler = (input: string, key: Key) => void;\n\nfunction emptyKey(): Key {\n return {\n upArrow: false,\n downArrow: false,\n leftArrow: false,\n rightArrow: false,\n pageUp: false,\n pageDown: false,\n return: false,\n escape: false,\n ctrl: false,\n shift: false,\n tab: false,\n backspace: false,\n delete: false,\n meta: false,\n };\n}\n\n// ── Terminal Setup/Teardown ──────────────────────────────────────────────────\n\nexport function setupTerminal(): () => void {\n let cleaned = false;\n\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n process.stdout.write('\\x1b[?25h\\x1b[?1049l');\n process.stdin.setRawMode(false);\n process.stdin.pause();\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf-8');\n process.stdout.write('\\x1b[?1049h\\x1b[?25l\\x1b[2J');\n\n process.on('SIGINT', () => { cleanup(); process.exit(0); });\n process.on('SIGTERM', () => { cleanup(); process.exit(0); });\n process.on('exit', cleanup);\n process.on('uncaughtException', (err) => {\n cleanup();\n console.error(err);\n process.exit(1);\n });\n\n return cleanup;\n}\n\n// ── Stdout Write Helper ──────────────────────────────────────────────────────\n\nexport function writeToStdout(data: string): void {\n process.stdout.write(data);\n}\n\n// ── Keypress Parser ──────────────────────────────────────────────────────────\n\n/**\n * Parse all complete key sequences from a buffer string.\n * Returns an array of [input, Key] pairs and the remaining unparsed buffer.\n */\nfunction parseBuffer(buf: string): { events: Array<[string, Key]>; remaining: string } {\n const events: Array<[string, Key]> = [];\n\n let i = 0;\n while (i < buf.length) {\n const ch = buf[i]!;\n\n // ESC prefix sequences\n if (ch === '\\x1b') {\n const rest = buf.slice(i + 1);\n\n // CSI sequences: \\x1b[...\n if (rest.startsWith('[')) {\n const after = rest.slice(1);\n\n // Shift+Arrow: \\x1b[1;2A/B/C/D\n const shiftArrow = after.match(/^1;2([ABCD])/);\n if (shiftArrow) {\n const key = emptyKey();\n key.shift = true;\n const dir = shiftArrow[1]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[1;2${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Arrow keys: \\x1b[A/B/C/D\n if (after.length >= 1 && 'ABCD'.includes(after[0]!)) {\n const key = emptyKey();\n const dir = after[0]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Tilde sequences: \\x1b[N~\n const tildeMatch = after.match(/^(\\d+)~/);\n if (tildeMatch) {\n const num = tildeMatch[1]!;\n const key = emptyKey();\n if (num === '5') key.pageUp = true;\n else if (num === '6') key.pageDown = true;\n else if (num === '3') key.delete = true;\n const seq = `\\x1b[${num}~`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Incomplete CSI — need more data\n return { events, remaining: buf.slice(i) };\n }\n\n // Lone ESC — signal caller to wait (disambiguate vs CSI prefix)\n if (rest.length === 0) {\n return { events, remaining: buf.slice(i) };\n }\n\n // \\x1b + regular char → Meta key\n const metaCh = rest[0]!;\n const key = emptyKey();\n key.meta = true;\n events.push([metaCh, key]);\n i += 2;\n continue;\n }\n\n // Return\n if (ch === '\\r') {\n const key = emptyKey();\n key.return = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Tab\n if (ch === '\\t') {\n const key = emptyKey();\n key.tab = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Backspace (DEL or BS)\n if (ch === '\\x7f' || ch === '\\x08') {\n const key = emptyKey();\n key.backspace = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Ctrl+A–Z (\\x01–\\x1a)\n const code = ch.charCodeAt(0);\n if (code >= 0x01 && code <= 0x1a) {\n const key = emptyKey();\n key.ctrl = true;\n const letter = String.fromCharCode(code + 96);\n events.push([letter, key]);\n i++;\n continue;\n }\n\n // Printable / multibyte char\n events.push([ch, emptyKey()]);\n i++;\n }\n\n return { events, remaining: '' };\n}\n\n// ── Raw Stdin Bypass (for neovim PTY forwarding) ─────────────────────────────\n\nlet rawBypassHandler: ((data: string) => boolean) | null = null;\n\nexport function setRawBypass(handler: ((data: string) => boolean) | null): void {\n rawBypassHandler = handler;\n}\n\nexport function startKeypressListener(handler: KeypressHandler): () => void {\n let buffer = '';\n let escTimer: ReturnType<typeof setTimeout> | null = null;\n\n const onData = (data: string): void => {\n // Raw bypass — forward to neovim PTY if active\n if (rawBypassHandler) {\n const handled = rawBypassHandler(data);\n if (handled) return;\n }\n\n // Cancel pending escape timer — more data arrived\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n\n buffer += data;\n\n const { events, remaining } = parseBuffer(buffer);\n buffer = remaining;\n\n for (const [input, key] of events) {\n handler(input, key);\n }\n\n // If buffer ends with lone ESC, start disambiguation timer\n if (buffer === '\\x1b') {\n escTimer = setTimeout(() => {\n escTimer = null;\n buffer = '';\n const key = emptyKey();\n key.escape = true;\n handler('\\x1b', key);\n }, 50);\n }\n };\n\n process.stdin.on('data', onData);\n\n return (): void => {\n process.stdin.off('data', onData);\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n };\n}\n\n// ── Resize Handler ───────────────────────────────────────────────────────────\n\nexport function onResize(callback: () => void): () => void {\n const onStdoutResize = (): void => callback();\n const onSigwinch = (): void => callback();\n\n process.stdout.on('resize', onStdoutResize);\n process.on('SIGWINCH', onSigwinch);\n\n return (): void => {\n process.stdout.off('resize', onStdoutResize);\n process.off('SIGWINCH', onSigwinch);\n };\n}\n","import type { Session } from '../shared/types.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { ReportBlock } from './lib/reports.js';\n\n// ---------------------------------------------------------------------------\n// Polling data interfaces (moved from usePolling.ts)\n// ---------------------------------------------------------------------------\n\nexport interface SessionSummary {\n id: string;\n name?: string;\n task: string;\n status: string;\n agentCount: number;\n createdAt: string;\n tmuxWindowId?: string;\n /** Cached result of windowExists check — avoids synchronous subprocess in render */\n windowAlive?: boolean;\n}\n\nexport interface CycleLog {\n cycle: number;\n content: string;\n}\n\n// ---------------------------------------------------------------------------\n// InputMode (moved from InputBar.tsx)\n// ---------------------------------------------------------------------------\n\nexport type InputMode =\n | 'navigate'\n | 'report-detail'\n | 'resume'\n | 'continue'\n | 'rollback'\n | 'leader'\n | 'copy-menu'\n | 'delete-confirm'\n | 'spawn-agent'\n | 'search'\n | 'message-agent'\n | 'shell-command'\n | 'help';\n\nexport const INPUT_MODES = new Set<InputMode>([\n 'resume',\n 'continue',\n 'rollback',\n 'delete-confirm',\n 'spawn-agent',\n 'search',\n 'message-agent',\n 'shell-command',\n]);\n\nexport const OPTIONAL_INPUT = new Set<InputMode>(['resume', 'continue', 'search']);\n\nexport const PROMPTS: Partial<Record<InputMode, string>> = {\n resume: 'resume instructions (optional)',\n continue: 'new direction (optional)',\n rollback: 'cycle number',\n 'delete-confirm': \"type 'yes' to confirm delete:\",\n 'spawn-agent': 'agent instruction:',\n search: 'filter:',\n 'message-agent': 'message:',\n 'shell-command': '$ ',\n};\n\n// ---------------------------------------------------------------------------\n// Render scheduling\n// ---------------------------------------------------------------------------\n\nlet renderScheduled = false;\nlet renderFn: (() => void) | null = null;\n\nexport function setRenderFunction(fn: () => void): void {\n renderFn = fn;\n}\n\nexport function requestRender(): void {\n if (renderScheduled) return;\n renderScheduled = true;\n setImmediate(() => {\n renderScheduled = false;\n renderFn?.();\n });\n}\n\n// ---------------------------------------------------------------------------\n// ThrottledScroll\n// ---------------------------------------------------------------------------\n\nconst FRAME_MS = 16; // ~60fps\n\nexport class ThrottledScroll {\n offset: number = 0;\n private target: number = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private onRender: () => void;\n\n constructor(onRender: () => void, initial = 0) {\n this.onRender = onRender;\n this.offset = initial;\n this.target = initial;\n }\n\n private scheduleFlush(): void {\n if (this.timer === null) {\n this.timer = setTimeout(() => {\n this.timer = null;\n this.offset = this.target;\n this.onRender();\n }, FRAME_MS);\n }\n }\n\n scrollBy(delta: number): void {\n this.target = Math.max(0, this.target + delta);\n this.scheduleFlush();\n }\n\n scrollTo(value: number): void {\n this.target = Math.max(0, value);\n this.scheduleFlush();\n }\n\n reset(): void {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.target = 0;\n this.offset = 0;\n }\n\n destroy(): void {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// AppState\n// ---------------------------------------------------------------------------\n\nexport interface AppState {\n // Terminal dimensions\n rows: number;\n cols: number;\n\n // Tree navigation\n cursorIndex: number;\n expanded: Set<string>;\n mode: InputMode;\n focusPane: 'tree' | 'detail' | 'logs';\n\n // Session\n selectedSessionId: string | null;\n searchFilter: string | null;\n targetAgentId: string | null;\n\n // UI\n notification: string | null;\n notificationTimer: ReturnType<typeof setTimeout> | null;\n showCombinedView: boolean;\n\n // Input bar\n inputText: string;\n inputCursorPos: number;\n\n // Scroll\n detailScroll: ThrottledScroll;\n logsScroll: ThrottledScroll;\n\n // Polling data (from daemon)\n sessions: SessionSummary[];\n selectedSession: Session | null;\n planContent: string;\n strategyContent: string;\n goalContent: string;\n logsContent: string;\n logsCycles: CycleLog[];\n paneAlive: boolean;\n contextFiles: string[];\n error: string | null;\n\n // Cursor stabilization\n cursorNodeId: string | null;\n prevNodes: TreeNode[];\n prevCycleCount: number;\n\n // Render caches\n cachedReportBlocks: Map<string, ReportBlock[]>;\n cachedTreeNodes: TreeNode[] | null;\n treeCacheKey: string;\n cachedDetailLines: import('./lib/format.js').DetailLine[] | null;\n detailCacheKey: string;\n detailRenderedCache: import('./render.js').RenderedCache;\n cachedLogsLines: import('./lib/format.js').DetailLine[] | null;\n logsCacheKey: string;\n logsRenderedCache: import('./render.js').RenderedCache;\n\n // Neovim integration\n nvimBridge: import('./lib/nvim-bridge.js').NvimBridge | null;\n nvimEnabled: boolean;\n prevNvimFile: string | null;\n nvimEditable: boolean;\n nvimOpenTabs: Map<string, { path: string; readonly: boolean }>;\n\n // Config\n cwd: string;\n}\n\nexport function createAppState(cwd: string): AppState {\n const cols = process.stdout.columns ?? 80;\n const rows = process.stdout.rows ?? 24;\n\n const detailScroll = new ThrottledScroll(requestRender);\n const logsScroll = new ThrottledScroll(requestRender);\n\n return {\n rows,\n cols,\n cursorIndex: 0,\n expanded: new Set(),\n mode: 'navigate',\n focusPane: 'tree',\n selectedSessionId: null,\n searchFilter: null,\n targetAgentId: null,\n notification: null,\n notificationTimer: null,\n showCombinedView: false,\n inputText: '',\n inputCursorPos: 0,\n detailScroll,\n logsScroll,\n sessions: [],\n selectedSession: null,\n planContent: '',\n strategyContent: '',\n goalContent: '',\n logsContent: '',\n logsCycles: [],\n paneAlive: true,\n contextFiles: [],\n error: null,\n cursorNodeId: null,\n prevNodes: [],\n prevCycleCount: 0,\n cachedReportBlocks: new Map(),\n cachedTreeNodes: null,\n treeCacheKey: '',\n cachedDetailLines: null,\n detailCacheKey: '',\n detailRenderedCache: { lines: [], ansi: [] },\n cachedLogsLines: null,\n logsCacheKey: '',\n logsRenderedCache: { lines: [], ansi: [] },\n nvimBridge: null,\n nvimEnabled: true,\n prevNvimFile: null,\n nvimEditable: false,\n nvimOpenTabs: new Map(),\n cwd,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Notification helper\n// ---------------------------------------------------------------------------\n\nexport function notify(state: AppState, msg: string): void {\n state.notification = msg;\n if (state.notificationTimer !== null) {\n clearTimeout(state.notificationTimer);\n }\n state.notificationTimer = setTimeout(() => {\n state.notification = null;\n state.notificationTimer = null;\n requestRender();\n }, 3000);\n}\n\n// ---------------------------------------------------------------------------\n// Cursor stabilization\n// ---------------------------------------------------------------------------\n\nexport function stabilizeCursor(state: AppState, nodes: TreeNode[]): void {\n if (nodes.length === 0) {\n state.cursorIndex = 0;\n return;\n }\n\n const targetId = state.cursorNodeId;\n if (targetId === null) {\n state.cursorNodeId = nodes[0]?.id ?? null;\n return;\n }\n\n // If current index already points to the right node, no adjustment needed\n if (nodes[state.cursorIndex]?.id === targetId) return;\n\n // Find the tracked node in the new tree\n const newIndex = nodes.findIndex((n) => n.id === targetId);\n if (newIndex !== -1) {\n state.cursorIndex = newIndex;\n } else {\n // Node is gone (parent collapsed, session removed, etc.) — clamp\n const clamped = Math.min(state.cursorIndex, nodes.length - 1);\n state.cursorIndex = clamped;\n state.cursorNodeId = nodes[clamped]?.id ?? null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-expand cycle\n// ---------------------------------------------------------------------------\n\nexport function autoExpandCycle(state: AppState): void {\n const selectedSession = state.selectedSession;\n if (!selectedSession) return;\n\n const sessionNodeId = `session:${selectedSession.id}`;\n const cycles = selectedSession.orchestratorCycles;\n\n // Only auto-manage cycle expansion if the session is already expanded by user\n if (!state.expanded.has(sessionNodeId)) {\n state.prevCycleCount = cycles.length;\n return;\n }\n\n if (cycles.length === 0) {\n state.prevCycleCount = 0;\n return;\n }\n\n const latest = cycles[cycles.length - 1]!;\n const latestId = `cycle:${selectedSession.id}:${latest.cycle}`;\n\n if (cycles.length > state.prevCycleCount && state.prevCycleCount > 0) {\n // New cycle appeared — collapse previous, expand latest\n const prevCycle = cycles[cycles.length - 2];\n if (prevCycle) {\n const prevId = `cycle:${selectedSession.id}:${prevCycle.cycle}`;\n state.expanded.delete(prevId);\n state.expanded.add(latestId);\n }\n } else if (!state.expanded.has(latestId)) {\n // Ensure latest is expanded\n state.expanded.add(latestId);\n }\n\n state.prevCycleCount = cycles.length;\n}\n","import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport {\n type AppState,\n type SessionSummary,\n type CycleLog,\n setRenderFunction,\n requestRender,\n stabilizeCursor,\n autoExpandCycle,\n notify,\n} from './state.js';\nimport { handleKeypress, type InputActions } from './input.js';\nimport { createFrameBuffer, flushFrame, writeCenter, copyRows } from './render.js';\nimport { writeToStdout, startKeypressListener, onResize } from './terminal.js';\nimport { buildTree } from './lib/tree.js';\nimport { precomputePrefixes } from './lib/tree-render.js';\nimport { resolveReports } from './lib/reports.js';\nimport { send } from './lib/client.js';\nimport {\n listAllWindowIds,\n openEditorPopup,\n editInPopup,\n openCompanionPane,\n openClaudeResumePopup,\n selectWindow,\n selectPane,\n switchToSession,\n openLogPopup,\n openShellPopup,\n openInFileManager,\n} from './lib/tmux.js';\nimport { copyToClipboard } from './lib/clipboard.js';\nimport { buildSessionContext } from './lib/context.js';\nimport { renderTreePanel } from './panels/tree.js';\nimport { renderDetailRows, renderLogsRows, type DetailContext } from './panels/detail.js';\nimport { renderNvimDetailRows } from './panels/nvim-detail.js';\nimport { renderNotificationRow, renderInputBar, renderStatusLine } from './panels/bottom.js';\nimport { renderLeaderOverlay, renderCopyMenuOverlay, renderHelpOverlay } from './panels/overlays.js';\nimport { NvimBridge } from './lib/nvim-bridge.js';\nimport { resolveNvimFile } from './lib/overview-writer.js';\nimport { loadConfig } from '../shared/config.js';\nimport { roadmapPath, goalPath, strategyPath, logsDir, contextDir } from '../shared/paths.js';\nimport { statusIndicator, formatDuration, statusColor, agentStatusIcon, agentDisplayName, truncate, ansiColor, ansiDim } from './lib/format.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { Agent, Session } from '../shared/types.js';\n\n// ── Module-level cache for latest rendered nodes (needed by keypress handler) ─\n\nlet latestNodes: TreeNode[] = [];\n\n// ── Module-level cache for context file content ───────────────────────────────\n\nlet cachedContextFilePath: string | null = null;\nlet cachedContextFileContent: string | null = null;\n\n// ── Previous frame for diffing ────────────────────────────────────────────────\n\nlet prevFrame: string[] = [];\n\n// ── Panel dirty tracking ─────────────────────────────────────────────────────\n// Tracks the inputs that affect each panel. When only the scroll offset changes,\n// we can skip re-rendering panels whose inputs haven't changed.\n\nlet prevTreeInputs = '';\nlet prevBottomInputs = '';\nlet prevOverlayMode = '';\nlet cachedTreeRows: string[] = [];\n\n// ── Cycle logs cache (avoids re-reading unchanged files every poll) ───────────\n\nlet cachedLogSessionId: string | null = null;\nlet cachedLogFiles: Map<string, { mtime: number; cycle: number; content: string }> = new Map();\n\n// ── Status header constants ──────────────────────────────────────────────────\n\nconst STATUS_ROW_COUNT = 2; // Fixed height for status header (avoids nvim resize on cursor change)\n\nfunction buildStatusRows(\n cursorNode: TreeNode | undefined,\n session: Session | null,\n state: AppState,\n): string[] {\n if (!cursorNode || !session) {\n return [ansiDim(' No session selected'), ''];\n }\n\n const dur = formatDuration(session.createdAt, session.completedAt);\n const indicator = statusIndicator(session.status);\n const sColor = statusColor(session.status);\n const title = truncate(session.name ?? session.task, 40);\n\n switch (cursorNode.type) {\n case 'session': {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.status} · ${session.orchestratorCycles.length} cycles · ${session.agents.length} agents · ${dur}`),\n ];\n }\n case 'cycle': {\n const cycle = session.orchestratorCycles.find(c => c.cycle === cursorNode.cycleNumber);\n if (!cycle) return [' ' + ansiColor(title, 'white', true), ''];\n const cDur = cycle.completedAt ? formatDuration(cycle.timestamp, cycle.completedAt) : 'running';\n const cStatus = cycle.completedAt ? 'completed' : 'running';\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true) + ansiDim(` · Cycle ${cycle.cycle}`),\n ' ' + ansiDim(`${cStatus} · ${cDur} · ${cycle.agentsSpawned.length} agents`),\n ];\n }\n case 'agent':\n case 'report': {\n const agentId = cursorNode.type === 'agent' ? cursorNode.agentId : cursorNode.agentId;\n const agent = session.agents.find(a => a.id === agentId);\n if (!agent) return [' ' + ansiColor(title, 'white', true), ''];\n const aIcon = agentStatusIcon(agent.status);\n const aDur = formatDuration(agent.spawnedAt, agent.completedAt);\n const aName = agentDisplayName(agent);\n return [\n ' ' + ansiColor(aIcon, statusColor(agent.status === 'running' ? 'active' : agent.status), true) + ' ' + ansiColor(`${agent.id} · ${aName}`, 'white', true),\n ' ' + ansiDim(`${agent.status} · ${agent.agentType || '—'} · ${aDur}`),\n ];\n }\n case 'context-file': {\n const name = cursorNode.filePath.split('/').pop() ?? cursorNode.filePath;\n return [\n ' ' + ansiColor('⊞', 'white') + ' ' + ansiColor(name, 'white', true),\n ' ' + ansiDim(`context file · ${session.status}`),\n ];\n }\n case 'messages':\n case 'message': {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.messages.length} messages`),\n ];\n }\n default: {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.status} · ${dur}`),\n ];\n }\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getAgentForNode(node: TreeNode | undefined, agents: Agent[]): Agent | null {\n if (!node) return null;\n if (node.type === 'agent' || node.type === 'report') {\n return agents.find((a) => a.id === node.agentId) ?? null;\n }\n return null;\n}\n\n// ── startApp ──────────────────────────────────────────────────────────────────\n\nexport function startApp(state: AppState, cleanup: () => void): void {\n const config = loadConfig(state.cwd);\n\n // Initialize NvimBridge\n const treeWidth = 36;\n const initialDetailW = (state.cols - treeWidth) - 4; // detail width minus borders\n const initialDetailH = (state.rows - 3) - 2 - STATUS_ROW_COUNT - 1; // content height minus borders, status, separator\n const bridge = new NvimBridge(\n Math.max(1, initialDetailW),\n Math.max(1, initialDetailH),\n requestRender,\n );\n state.nvimBridge = bridge.available ? bridge : null;\n state.nvimEnabled = bridge.available;\n\n // Track selectedSessionId to detect changes across renders (for immediate poll)\n let prevSelectedSessionId: string | null | undefined = undefined;\n let debouncedPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ── Polling ─────────────────────────────────────────────────────────────────\n\n async function poll(): Promise<void> {\n try {\n let selectedSession: Session | null = null;\n let planContent = '';\n let strategyContent = '';\n let goalContent = '';\n let logsContent = '';\n let logsCycles: CycleLog[] = [];\n let paneAlive = true;\n let contextFiles: string[] = [];\n\n const listPromise = send({ type: 'list', cwd: state.cwd });\n const statusPromise = state.selectedSessionId\n ? send({ type: 'status', sessionId: state.selectedSessionId, cwd: state.cwd })\n : null;\n\n const [listRes, statusRes] = await Promise.all([\n listPromise,\n statusPromise ?? Promise.resolve(null),\n ]);\n\n const sessions: SessionSummary[] = listRes.ok\n ? ((listRes.data?.sessions as SessionSummary[] | undefined) ?? [])\n : [];\n\n // Batch-check window existence in a single tmux call\n const aliveWindows = listAllWindowIds();\n for (const s of sessions) {\n if (s.status !== 'completed' && s.tmuxWindowId) {\n s.windowAlive = aliveWindows.has(s.tmuxWindowId);\n }\n }\n\n if (state.selectedSessionId) {\n if (statusRes?.ok) {\n selectedSession = (statusRes.data?.session as Session | undefined) ?? null;\n }\n\n // Use cached windowAlive from the session list scan above\n if (selectedSession?.tmuxWindowId) {\n const cached = sessions.find((s) => s.id === state.selectedSessionId);\n paneAlive = cached?.windowAlive ?? false;\n }\n\n try {\n const pp = roadmapPath(state.cwd, state.selectedSessionId);\n if (existsSync(pp)) {\n planContent = readFileSync(pp, 'utf-8');\n }\n } catch {\n // roadmap.md may not exist yet\n }\n\n try {\n const gp = goalPath(state.cwd, state.selectedSessionId);\n if (existsSync(gp)) {\n goalContent = readFileSync(gp, 'utf-8');\n }\n } catch {\n // goal.md may not exist yet\n }\n\n try {\n const sp = strategyPath(state.cwd, state.selectedSessionId);\n if (existsSync(sp)) {\n strategyContent = readFileSync(sp, 'utf-8');\n }\n } catch {\n // strategy.md may not exist yet\n }\n\n try {\n const ld = logsDir(state.cwd, state.selectedSessionId);\n if (existsSync(ld)) {\n // Reset cache when session changes\n if (state.selectedSessionId !== cachedLogSessionId) {\n cachedLogFiles = new Map();\n cachedLogSessionId = state.selectedSessionId;\n }\n\n const files = readdirSync(ld)\n .filter((f) => f.startsWith('cycle-'))\n .sort();\n\n // Remove cache entries for deleted files\n const fileSet = new Set(files);\n for (const key of cachedLogFiles.keys()) {\n if (!fileSet.has(key)) cachedLogFiles.delete(key);\n }\n\n // Only re-read files whose mtime changed\n for (const f of files) {\n const filePath = join(ld, f);\n const mtime = statSync(filePath).mtimeMs;\n const cached = cachedLogFiles.get(f);\n if (!cached || cached.mtime !== mtime) {\n const match = f.match(/cycle-(\\d+)\\.md$/);\n const cycle = match ? parseInt(match[1]!, 10) : 0;\n const content = readFileSync(filePath, 'utf-8');\n cachedLogFiles.set(f, { mtime, cycle, content });\n }\n }\n\n logsCycles = files.map((f) => {\n const entry = cachedLogFiles.get(f)!;\n return { cycle: entry.cycle, content: entry.content };\n });\n logsContent = logsCycles.map((c) => c.content).join('\\n');\n }\n } catch {\n // logs may not exist yet\n }\n\n try {\n const cd = contextDir(state.cwd, state.selectedSessionId);\n if (existsSync(cd)) {\n contextFiles = readdirSync(cd)\n .filter((f) => !f.startsWith('.'))\n .sort();\n }\n } catch {\n // context dir may not exist yet\n }\n }\n\n // Resolve report files in poll (not render) to avoid sync disk reads on keypress\n state.cachedReportBlocks.clear();\n if (selectedSession) {\n for (const agent of selectedSession.agents) {\n state.cachedReportBlocks.set(agent.id, resolveReports(agent.reports));\n }\n }\n\n state.sessions = sessions;\n state.selectedSession = selectedSession;\n state.planContent = planContent;\n state.strategyContent = strategyContent;\n state.goalContent = goalContent;\n state.logsContent = logsContent;\n state.logsCycles = logsCycles;\n state.paneAlive = paneAlive;\n state.contextFiles = contextFiles;\n state.error = null;\n\n // Tell nvim to refresh if the same file is still displayed (content may have changed)\n if (state.nvimEnabled && state.nvimBridge?.ready && state.prevNvimFile) {\n state.nvimBridge.checktime();\n }\n\n requestRender();\n } catch (err) {\n state.error = (err as Error).message;\n requestRender();\n }\n }\n\n // ── Render function ──────────────────────────────────────────────────────────\n\n function render(): void {\n const stdoutRows = process.stdout.rows;\n const stdoutCols = process.stdout.columns;\n state.rows = (typeof stdoutRows === 'number' && stdoutRows > 0) ? stdoutRows : 24;\n state.cols = (typeof stdoutCols === 'number' && stdoutCols > 0) ? stdoutCols : 80;\n\n const buf = createFrameBuffer(state.cols, state.rows);\n\n // Terminal too small\n if (state.cols < 60 || state.rows < 12) {\n writeCenter(buf, Math.floor(state.rows / 2), 'Terminal too small — resize to continue');\n const out = flushFrame(buf.lines, prevFrame);\n writeToStdout(out);\n prevFrame = buf.lines;\n return;\n }\n\n // Compute layout\n const treeWidth = 36;\n const remaining = state.cols - treeWidth;\n const detailWidth = state.showCombinedView ? Math.floor(remaining * 0.6) : remaining;\n const logsWidth = state.showCombinedView ? remaining - detailWidth : 0;\n const contentHeight = state.rows - 3;\n\n const treeRect = { x: 0, y: 0, w: treeWidth, h: contentHeight };\n const detailRect = { x: treeWidth, y: 0, w: detailWidth, h: contentHeight };\n const logsRect = state.showCombinedView\n ? { x: treeWidth + detailWidth, y: 0, w: logsWidth, h: contentHeight }\n : null;\n const bottomY = contentHeight;\n\n // Derive data\n const filteredSessions: SessionSummary[] = state.searchFilter\n ? state.sessions.filter((s) => {\n const q = state.searchFilter!.toLowerCase();\n return s.task.toLowerCase().includes(q) || s.id.toLowerCase().includes(q);\n })\n : state.sessions;\n\n const cacheKey = `${state.expanded.size}:${filteredSessions.length}:${state.selectedSession?.id}:${state.contextFiles.length}:${state.searchFilter}`;\n let nodes: TreeNode[];\n if (cacheKey === state.treeCacheKey && state.cachedTreeNodes !== null) {\n nodes = state.cachedTreeNodes;\n } else {\n nodes = buildTree(\n filteredSessions,\n state.selectedSession,\n state.expanded,\n state.cwd,\n state.contextFiles,\n );\n precomputePrefixes(nodes);\n state.cachedTreeNodes = nodes;\n state.treeCacheKey = cacheKey;\n }\n\n // Cursor stabilization\n stabilizeCursor(state, nodes);\n\n // Cache latest nodes for keypress handler\n latestNodes = nodes;\n\n // Track cursor node identity\n const cursorNode = nodes[state.cursorIndex];\n if (cursorNode) state.cursorNodeId = cursorNode.id;\n\n // Derive selectedSessionId from cursor\n const newSessionId = cursorNode?.sessionId ?? null;\n if (newSessionId !== state.selectedSessionId) {\n state.selectedSessionId = newSessionId;\n state.detailScroll.reset();\n state.logsScroll.reset();\n state.cachedDetailLines = null;\n state.detailCacheKey = '';\n state.prevNvimFile = null;\n state.cachedLogsLines = null;\n state.logsCacheKey = '';\n }\n\n // Trigger debounced poll when session changes (avoids poll storm during rapid scrolling)\n if (state.selectedSessionId !== prevSelectedSessionId) {\n prevSelectedSessionId = state.selectedSessionId;\n if (debouncedPollTimer !== null) clearTimeout(debouncedPollTimer);\n if (state.selectedSessionId !== null) {\n debouncedPollTimer = setTimeout(() => {\n debouncedPollTimer = null;\n void poll();\n }, 80);\n }\n }\n\n // Auto-expand cycle\n autoExpandCycle(state);\n\n // Resolve reports for detail panel\n const agents = state.selectedSession?.agents ?? [];\n const reportAgent =\n state.mode === 'report-detail' ? getAgentForNode(cursorNode, agents) : null;\n const reportBlocks = reportAgent ? (state.cachedReportBlocks.get(reportAgent.id) ?? []) : [];\n\n const detailAgent =\n cursorNode?.type === 'agent' || cursorNode?.type === 'report'\n ? getAgentForNode(cursorNode, agents)\n : null;\n const detailReportBlocks = detailAgent\n ? (state.cachedReportBlocks.get(detailAgent.id) ?? [])\n : [];\n\n // Load context file content (cached to avoid re-read on every render)\n let contextFileContent: string | null = null;\n if (cursorNode?.type === 'context-file') {\n if (cursorNode.filePath !== cachedContextFilePath) {\n cachedContextFilePath = cursorNode.filePath;\n try {\n if (existsSync(cursorNode.filePath)) {\n cachedContextFileContent = readFileSync(cursorNode.filePath, 'utf-8');\n } else {\n cachedContextFileContent = null;\n }\n } catch {\n cachedContextFileContent = null;\n }\n }\n contextFileContent = cachedContextFileContent;\n } else {\n // Clear cache when cursor moves away\n cachedContextFilePath = null;\n cachedContextFileContent = null;\n }\n\n // Panel dirty tracking — compute fingerprints for each panel's inputs\n const treeFocused = state.mode === 'navigate' && state.focusPane === 'tree';\n const treeInputs = `${state.treeCacheKey}:${state.cursorIndex}:${treeFocused}`;\n const bottomInputs = `${state.notification}:${state.error}:${state.mode}:${state.inputText}:${state.inputCursorPos}:${cursorNode?.type}`;\n const overlayMode = state.mode === 'leader' || state.mode === 'copy-menu' || state.mode === 'help' ? state.mode : '';\n\n const hasPrev = prevFrame.length === buf.height;\n const treeDirty = !hasPrev || treeInputs !== prevTreeInputs;\n const bottomDirty = !hasPrev || bottomInputs !== prevBottomInputs;\n const overlayDirty = !hasPrev || overlayMode !== prevOverlayMode;\n\n prevTreeInputs = treeInputs;\n prevBottomInputs = bottomInputs;\n prevOverlayMode = overlayMode;\n\n // Render tree into a narrow buffer (treeWidth-wide) so rows are the right size\n // for concatenation. Cached when clean.\n let treeRows: string[];\n if (treeDirty) {\n const treeBlank = ' '.repeat(treeWidth);\n const treeBuf: import('./render.js').FrameBuffer = {\n lines: Array.from({ length: contentHeight }, () => treeBlank),\n width: treeWidth,\n height: contentHeight,\n };\n renderTreePanel(\n treeBuf,\n { x: 0, y: 0, w: treeWidth, h: contentHeight },\n nodes,\n state.cursorIndex,\n treeFocused,\n );\n cachedTreeRows = treeBuf.lines;\n treeRows = treeBuf.lines;\n } else {\n treeRows = cachedTreeRows;\n }\n\n // Render detail + logs as self-contained row strings, then compose by concatenation.\n // This eliminates all sliceDisplayCols calls — the main scroll bottleneck.\n const detailCtx: DetailContext = {\n nodes,\n session: state.selectedSession,\n agents,\n reportBlocks,\n detailReportBlocks,\n contextFileContent,\n };\n\n let detailRows: string[];\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n // Determine which file(s) neovim should display\n const result = resolveNvimFile(state, cursorNode, detailCtx, state.cwd);\n const resultKey = result ? result.files.map(f => f.path).join('|') : null;\n if (resultKey && resultKey !== state.prevNvimFile) {\n state.nvimBridge.openTabFiles(result!.files);\n state.prevNvimFile = resultKey;\n state.nvimEditable = result!.files.some(f => !f.readonly);\n } else if (!resultKey) {\n state.prevNvimFile = null;\n state.nvimEditable = false;\n }\n\n // Build status rows for the header\n const statusRows = buildStatusRows(cursorNode, state.selectedSession, state);\n detailRows = renderNvimDetailRows(detailRect, state.nvimBridge, state.focusPane === 'detail', state.nvimEditable, statusRows);\n } else {\n detailRows = renderDetailRows(detailRect, state, detailCtx);\n }\n const logsRows = logsRect ? renderLogsRows(logsRect, state) : null;\n\n // Compose panel rows into buffer by concatenation (no slicing/splicing)\n for (let i = 0; i < contentHeight; i++) {\n if (logsRows) {\n buf.lines[i] = treeRows[i]! + detailRows[i]! + logsRows[i]!;\n } else {\n buf.lines[i] = treeRows[i]! + detailRows[i]!;\n }\n }\n\n // Bottom rows\n if (bottomDirty || overlayDirty) {\n renderNotificationRow(buf, bottomY, state.notification, state.error);\n renderInputBar(buf, bottomY + 1, state);\n renderStatusLine(buf, bottomY + 2, state, cursorNode?.type);\n } else {\n copyRows(buf, prevFrame, bottomY, 3);\n }\n\n // Overlays (rendered AFTER panels — overwrites panel content)\n if (overlayMode) {\n if (state.mode === 'leader') renderLeaderOverlay(buf, state.rows, state.cols);\n if (state.mode === 'copy-menu') renderCopyMenuOverlay(buf, state.rows, state.cols);\n if (state.mode === 'help') renderHelpOverlay(buf, state.rows, state.cols);\n }\n\n // Build cursor suffix inside synchronized output block to prevent flicker\n let cursorSuffix: string;\n if (state.focusPane === 'detail' && state.nvimBridge?.ready) {\n const cursor = state.nvimBridge.getCursorPos();\n const absX = detailRect.x + 2 + cursor.x;\n // Nvim content starts after: top border (1) + status rows (STATUS_ROW_COUNT) + separator (1)\n const absY = detailRect.y + 1 + STATUS_ROW_COUNT + 1 + cursor.y;\n cursorSuffix = `\\x1b[${state.nvimBridge.cursorStyle} q\\x1b[?25h\\x1b[${absY + 1};${absX + 1}H`;\n } else {\n cursorSuffix = '\\x1b[0 q\\x1b[?25l';\n }\n\n // Flush diff to stdout with cursor positioning inside sync block\n const out = flushFrame(buf.lines, prevFrame, cursorSuffix);\n writeToStdout(out);\n prevFrame = buf.lines;\n }\n\n // ── InputActions ─────────────────────────────────────────────────────────────\n\n const inputActions: InputActions = {\n getNodes: () => latestNodes,\n getCursorNode: () => latestNodes[state.cursorIndex],\n getAgentForNode: (node) => {\n const agents = state.selectedSession?.agents ?? [];\n return getAgentForNode(node, agents);\n },\n sendAndNotify: (request, successMsg) => {\n void send(request)\n .then((res) => {\n if (res.ok) {\n notify(state, successMsg);\n } else {\n const errMsg = res.error ? res.error : 'Unknown error';\n notify(state, `Error: ${errMsg}`);\n }\n })\n .catch((err: Error) => {\n notify(state, `Error: ${err.message}`);\n });\n },\n send,\n openEditorPopup,\n editInPopup,\n openCompanionPane,\n openClaudeResumePopup,\n selectWindow,\n selectPane,\n switchToSession,\n openLogPopup,\n openShellPopup,\n openInFileManager,\n copyToClipboard,\n buildSessionContext,\n resolveEditor: () => {\n if (config.editor) return config.editor;\n if (process.env.EDITOR) return process.env.EDITOR;\n return 'nvim';\n },\n cleanup: () => {\n cleanup();\n process.exit(0);\n },\n };\n\n // ── Wire everything together ─────────────────────────────────────────────────\n\n setRenderFunction(render);\n\n const stopKeypress = startKeypressListener((input, key) => {\n handleKeypress(input, key, state, inputActions);\n });\n\n const stopResize = onResize(() => {\n const stdoutRows = process.stdout.rows;\n const stdoutCols = process.stdout.columns;\n state.rows = (typeof stdoutRows === 'number' && stdoutRows > 0) ? stdoutRows : 24;\n state.cols = (typeof stdoutCols === 'number' && stdoutCols > 0) ? stdoutCols : 80;\n prevFrame = []; // force full redraw\n\n // Resize nvim bridge to match new detail panel dimensions\n // Account for: borders (2), status rows (STATUS_ROW_COUNT), separator (1)\n if (state.nvimBridge) {\n const detailW = state.cols - 36; // treeWidth=36\n const contentH = state.rows - 3; // bottomBar=3\n state.nvimBridge.resize(Math.max(1, detailW - 4), Math.max(1, contentH - 2 - STATUS_ROW_COUNT - 1));\n }\n\n requestRender();\n });\n\n // Initial poll + recurring interval\n void poll();\n const pollInterval = setInterval(() => void poll(), 2500);\n\n // Register teardown so cleanup() releases all resources\n const origCleanup = inputActions.cleanup;\n inputActions.cleanup = () => {\n clearInterval(pollInterval);\n if (debouncedPollTimer !== null) clearTimeout(debouncedPollTimer);\n stopKeypress();\n stopResize();\n state.detailScroll.destroy();\n state.logsScroll.destroy();\n state.nvimBridge?.destroy();\n origCleanup();\n };\n\n // Initial render\n requestRender();\n}\n","import { join } from 'node:path';\nimport { messageSourceLabel } from './format.js';\nimport type {\n TreeNode,\n SessionTreeNode,\n CycleTreeNode,\n AgentTreeNode,\n ReportTreeNode,\n MessagesTreeNode,\n MessageTreeNode,\n ContextTreeNode,\n ContextFileTreeNode,\n} from '../types/tree.js';\nimport type { Session } from '../../shared/types.js';\nimport type { SessionSummary } from '../state.js';\nimport { contextDir } from '../../shared/paths.js';\n\n/** Sort priority: active+open=0, active+closed=1, paused+open=2, paused+closed=3, completed=4 */\nfunction sessionSortKey(s: SessionSummary): number {\n if (s.status === 'completed') return 4;\n // Use cached windowAlive from polling hook (avoids execSync in render path)\n const open = s.windowAlive ?? false;\n if (s.status === 'active') return open ? 0 : 1;\n // paused\n return open ? 2 : 3;\n}\n\nexport function buildTree(\n sessions: SessionSummary[],\n selectedSession: Session | null,\n expanded: Set<string>,\n cwd: string,\n polledContextFiles: string[] = [],\n): TreeNode[] {\n const nodes: TreeNode[] = [];\n\n const sorted = [...sessions].sort((a, b) => {\n const keyDiff = sessionSortKey(a) - sessionSortKey(b);\n if (keyDiff !== 0) return keyDiff;\n // Most recent first within each group\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n for (const s of sorted) {\n const sessionNodeId = `session:${s.id}`;\n const isSelected = selectedSession?.id === s.id;\n const isExpanded = expanded.has(sessionNodeId);\n\n nodes.push({\n id: sessionNodeId,\n type: 'session',\n depth: 0,\n expandable: true,\n expanded: isExpanded && isSelected,\n sessionId: s.id,\n name: s.name,\n task: s.task,\n status: s.status,\n cycleCount: isSelected ? (selectedSession?.orchestratorCycles.length ?? 0) : 0,\n agentCount: s.agentCount,\n createdAt: s.createdAt,\n completedAt: isSelected ? selectedSession?.completedAt : undefined,\n } satisfies SessionTreeNode);\n\n // Only emit children for the selected+expanded session\n if (!isExpanded || !isSelected || !selectedSession) continue;\n\n const cycles = [...selectedSession.orchestratorCycles].reverse();\n const allSpawnedIds = new Set(\n selectedSession.orchestratorCycles.flatMap((c) => c.agentsSpawned),\n );\n\n for (const cycle of cycles) {\n const cycleNodeId = `cycle:${s.id}:${cycle.cycle}`;\n const cycleExpanded = expanded.has(cycleNodeId);\n\n // Agents belonging to this cycle\n const cycleAgents = selectedSession.agents.filter((a) =>\n cycle.agentsSpawned.includes(a.id),\n );\n\n // For the latest cycle, include unassigned agents\n const isLatest = cycle === cycles[0];\n const unassigned = isLatest\n ? selectedSession.agents.filter((a) => !allSpawnedIds.has(a.id))\n : [];\n const allCycleAgents = [...cycleAgents, ...unassigned];\n\n nodes.push({\n id: cycleNodeId,\n type: 'cycle',\n depth: 1,\n expandable: allCycleAgents.length > 0,\n expanded: cycleExpanded,\n sessionId: s.id,\n cycleNumber: cycle.cycle,\n timestamp: cycle.timestamp,\n completedAt: cycle.completedAt,\n activeMs: cycle.activeMs,\n agentCount: allCycleAgents.length,\n mode: cycle.mode,\n } satisfies CycleTreeNode);\n\n if (!cycleExpanded) continue;\n\n for (const agent of allCycleAgents) {\n const agentNodeId = `agent:${s.id}:${agent.id}`;\n const hasReports = agent.reports.length > 0;\n const agentExpanded = expanded.has(agentNodeId);\n\n nodes.push({\n id: agentNodeId,\n type: 'agent',\n depth: 2,\n expandable: hasReports,\n expanded: agentExpanded && hasReports,\n sessionId: s.id,\n agentId: agent.id,\n name: agent.name,\n agentType: agent.agentType,\n status: agent.status,\n spawnedAt: agent.spawnedAt,\n completedAt: agent.completedAt,\n activeMs: agent.activeMs,\n reportCount: agent.reports.length,\n } satisfies AgentTreeNode);\n\n if (!agentExpanded || !hasReports) continue;\n\n for (let ri = 0; ri < agent.reports.length; ri++) {\n const report = agent.reports[ri]!;\n nodes.push({\n id: `report:${s.id}:${agent.id}:${ri}`,\n type: 'report',\n depth: 3,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n reportIndex: ri,\n reportType: report.type,\n timestamp: report.timestamp,\n agentId: agent.id,\n } satisfies ReportTreeNode);\n }\n }\n }\n\n // Messages group\n const messages = selectedSession.messages ?? [];\n if (messages.length > 0) {\n const msgsNodeId = `messages:${s.id}`;\n const msgsExpanded = expanded.has(msgsNodeId);\n\n nodes.push({\n id: msgsNodeId,\n type: 'messages',\n depth: 1,\n expandable: true,\n expanded: msgsExpanded,\n sessionId: s.id,\n count: messages.length,\n } satisfies MessagesTreeNode);\n\n if (msgsExpanded) {\n for (const msg of messages) {\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const sourceLabel = messageSourceLabel(msg.source.type, agentId);\n\n nodes.push({\n id: `message:${s.id}:${msg.id}`,\n type: 'message',\n depth: 2,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n messageId: msg.id,\n source: sourceLabel,\n summary: msg.summary || msg.content,\n timestamp: msg.timestamp,\n } satisfies MessageTreeNode);\n }\n }\n }\n\n // Context group — use polled file list for the selected session (avoids sync I/O in render)\n const contextFiles = isSelected ? polledContextFiles : [];\n\n const ctxNodeId = `context:${s.id}`;\n const ctxExpanded = expanded.has(ctxNodeId);\n\n nodes.push({\n id: ctxNodeId,\n type: 'context',\n depth: 1,\n expandable: contextFiles.length > 0,\n expanded: ctxExpanded && contextFiles.length > 0,\n sessionId: s.id,\n fileCount: contextFiles.length,\n } satisfies ContextTreeNode);\n\n if (ctxExpanded && contextFiles.length > 0) {\n for (const filename of contextFiles) {\n nodes.push({\n id: `context-file:${s.id}:${filename}`,\n type: 'context-file',\n depth: 2,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n label: filename,\n filePath: join(contextDir(cwd, s.id), filename),\n } satisfies ContextFileTreeNode);\n }\n }\n }\n\n return nodes;\n}\n\n/** Find the parent node index for a given node index */\nexport function findParentIndex(nodes: TreeNode[], index: number): number {\n const node = nodes[index];\n if (!node || node.depth === 0) return index;\n const targetDepth = node.depth - 1;\n for (let i = index - 1; i >= 0; i--) {\n if (nodes[i]!.depth === targetDepth) return i;\n if (nodes[i]!.depth < targetDepth) return i;\n }\n return 0;\n}\n","import stringWidth from 'string-width';\n\nexport { formatDuration, statusColor } from '../../shared/format.js';\n\nexport function formatTimeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(minutes / 60);\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'just now';\n}\n\nexport function formatTime(iso: string): string {\n const d = new Date(iso);\n return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;\n}\n\nexport function truncate(text: string, max: number): string {\n // Collapse newlines and normalize wide emoji (see cleanMarkdown for rationale)\n const clean = text.replace(/\\n/g, ' ').replace(/✅/g, '✓').replace(/❌/g, '✗').replace(/\\p{Emoji_Presentation}/gu, '');\n if (max < 4) return clean.slice(0, max);\n const w = stringWidth(clean);\n if (w <= max) return clean;\n // Trim from the end until we fit, respecting display width\n let result = clean;\n while (stringWidth(result) > max - 1 && result.length > 0) {\n // Try to break at a word boundary\n const cut = result.lastIndexOf(' ', result.length - 2);\n if (cut > max * 0.4) {\n result = result.slice(0, cut);\n } else {\n result = result.slice(0, result.length - 1);\n }\n }\n return result + '…';\n}\n\n/** Strip markdown syntax to plain text */\nexport function stripMarkdown(text: string): string {\n return text\n .replace(/^#{1,6}\\s+/gm, '')\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`{1,3}[^`]*`{1,3}/g, '')\n .replace(/^[-*+]\\s+/gm, '')\n .replace(/^\\d+[.)]\\s+/gm, '')\n .replace(/\\[(.+?)\\]\\(.+?\\)/g, '$1')\n .replace(/^>\\s+/gm, '')\n .replace(/---+/g, '')\n .replace(/\\n+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Extract the first meaningful sentence from markdown-heavy text.\n * Much better than blind truncation — finds actual content.\n */\nexport function extractFirstSentence(text: string, maxLen: number): string {\n const lines = text.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('#')) continue;\n if (trimmed.startsWith('---')) continue;\n if (trimmed.startsWith('```')) continue;\n if (trimmed.startsWith('|')) continue;\n if (trimmed.length < 5) continue;\n\n const cleaned = stripMarkdown(trimmed);\n if (cleaned.length < 5) continue;\n\n // Try to end at a sentence boundary\n const periodIdx = cleaned.indexOf('. ');\n if (periodIdx > 10 && periodIdx < maxLen) {\n return cleaned.slice(0, periodIdx + 1);\n }\n return truncate(cleaned, maxLen);\n }\n const fallback = stripMarkdown(text);\n return truncate(fallback, maxLen);\n}\n\nexport function durationColor(startOrMs: string | number, endIso?: string | null): string {\n let totalMs: number;\n if (typeof startOrMs === 'number') {\n totalMs = startOrMs;\n } else {\n const start = new Date(startOrMs).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n totalMs = end - start;\n }\n if (totalMs < 10 * 60 * 1000) return '';\n if (totalMs < 30 * 60 * 1000) return 'yellow';\n return 'red';\n}\n\nexport function statusIndicator(status: string): string {\n switch (status) {\n case 'active':\n return '▶';\n case 'completed':\n return '✓';\n case 'paused':\n return '⏸';\n default:\n return '·';\n }\n}\n\nexport function agentStatusIcon(status: string): string {\n switch (status) {\n case 'running':\n return '▶';\n case 'completed':\n return '✓';\n case 'killed':\n return '✕';\n case 'crashed':\n return '!';\n case 'lost':\n return '?';\n default:\n return '·';\n }\n}\n\nexport function agentTypeColor(agentType: string | undefined): string | undefined {\n if (!agentType) return undefined;\n const t = agentType.toLowerCase();\n if (t.includes('research')) return 'blue';\n if (t.includes('implement') || t.includes('code')) return 'green';\n if (t.includes('review') || t.includes('test')) return 'magenta';\n if (t.includes('plan')) return 'yellow';\n return undefined;\n}\n\nexport function divider(width: number, char: string = '─'): string {\n return char.repeat(Math.max(0, width));\n}\n\n/** Strip YAML frontmatter (--- ... ---) from markdown content */\nexport function stripFrontmatter(content: string): string {\n if (!content.startsWith('---')) return content;\n const end = content.indexOf('\\n---', 3);\n if (end === -1) return content;\n return content.slice(end + 4).trimStart();\n}\n\n/** Clean inline markdown syntax for terminal display */\nexport function cleanMarkdown(line: string): string {\n return line\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`(.+?)`/g, '$1')\n .replace(/\\[(.+?)\\]\\(.+?\\)/g, '$1')\n // Normalize wide emoji → single-width alternatives.\n // Ink's @alcalzone/ansi-tokenize treats emoji as width=1, but terminals\n // render them as width=2. This mismatch causes lines to overflow by 1\n // column, wrapping the right border to the next row (phantom blank lines).\n .replace(/✅/g, '✓')\n .replace(/❌/g, '✗')\n .replace(/\\p{Emoji_Presentation}/gu, '');\n}\n\n// Shared line types for scrollable panels\n\nexport type Seg = {\n text: string;\n color?: string;\n bold?: boolean;\n dim?: boolean;\n italic?: boolean;\n inverse?: boolean;\n};\n\nexport type DetailLine = Seg[];\n\nexport function seg(text: string, opts?: Partial<Omit<Seg, 'text'>>): Seg {\n return { text, ...opts };\n}\n\n/** Create a single-segment DetailLine */\nexport function singleLine(text: string, opts?: Partial<Omit<Seg, 'text'>>): DetailLine {\n return [seg(text, opts)];\n}\n\nexport function messageSourceLabel(source: string, agentId?: string): string {\n if (source === 'user') return 'You';\n if (source === 'agent') {\n if (!agentId) throw new Error('agentId required when source is agent');\n return agentId;\n }\n return 'system';\n}\n\nexport function messageSourceColor(source: string): string {\n if (source === 'user') return 'yellow';\n if (source === 'agent') return 'cyan';\n return 'gray';\n}\n\nexport function reportBadge(type: string): { label: string; color: string } {\n return type === 'final'\n ? { label: 'FINAL', color: 'cyan' }\n : { label: 'UPDATE', color: 'yellow' };\n}\n\nexport function agentDisplayName(agent: { name: string; id: string; agentType: string }): string {\n return agent.name !== agent.id ? agent.name : agent.agentType;\n}\n\nexport function abbreviateMode(mode: string | undefined | null): string {\n if (!mode) return '';\n if (mode === 'implementation') return 'impl';\n if (mode === 'planning') return 'plan';\n if (mode === 'strategy') return 'strat';\n if (mode === 'validation') return 'valid';\n return mode;\n}\n\nexport function ansiBold(text: string): string {\n return `\\x1b[1m${text}\\x1b[0m`;\n}\n\nexport function ansiDim(text: string): string {\n return `\\x1b[2m${text}\\x1b[0m`;\n}\n\nexport function ansiColor(text: string, color: string, bold = false): string {\n const COLOR_MAP: Record<string, number> = { black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, gray: 90 };\n const codes: number[] = [];\n if (bold) codes.push(1);\n const sgr = COLOR_MAP[color];\n if (sgr !== undefined) codes.push(sgr);\n if (codes.length === 0) return text;\n return `\\x1b[${codes.join(';')}m${text}\\x1b[0m`;\n}\n\nexport function modeColor(mode?: string): string {\n if (mode === 'planning') return 'blue';\n if (mode === 'implementation') return 'green';\n if (mode === 'strategy') return 'yellow';\n if (mode === 'validation') return 'magenta';\n return 'cyan';\n}\n\nexport function mergeStatusDisplay(status: string): { icon: string; label: string; color: string } | null {\n switch (status) {\n case 'merged': return { icon: '⊕', label: 'merged', color: 'green' };\n case 'pending': return { icon: '◌', label: 'pending', color: 'yellow' };\n case 'no-changes': return { icon: '∅', label: 'no changes', color: 'gray' };\n case 'conflict': return { icon: '⚠', label: 'conflict', color: 'red' };\n default: return null;\n }\n}\n\nexport function wrapText(text: string, width: number): string[] {\n const cleaned = cleanMarkdown(text);\n if (width <= 0) return cleaned.split('\\n');\n const result: string[] = [];\n for (const rawLine of cleaned.split('\\n')) {\n if (stringWidth(rawLine) <= width) {\n result.push(rawLine);\n continue;\n }\n\n // Single-pass: walk characters tracking cumulative display width\n let lineStart = 0;\n let lastSpace = -1;\n let displayWidth = 0;\n\n for (let i = 0; i < rawLine.length; i++) {\n const charWidth = stringWidth(rawLine[i]!);\n displayWidth += charWidth;\n\n if (rawLine[i] === ' ') lastSpace = i;\n\n if (displayWidth > width) {\n let breakAt: number;\n if (lastSpace > lineStart) {\n // Break at last space that fits\n breakAt = lastSpace;\n result.push(rawLine.slice(lineStart, breakAt));\n // Skip past the space and any leading spaces\n lineStart = breakAt + 1;\n while (lineStart < rawLine.length && rawLine[lineStart] === ' ') lineStart++;\n } else {\n // No space — hard break at previous char\n breakAt = Math.max(lineStart + 1, i);\n result.push(rawLine.slice(lineStart, breakAt));\n lineStart = breakAt;\n }\n\n // Recalculate display width for the carried-over portion\n displayWidth = stringWidth(rawLine.slice(lineStart, i + 1));\n lastSpace = -1;\n }\n }\n\n if (lineStart < rawLine.length) {\n result.push(rawLine.slice(lineStart));\n }\n }\n return result;\n}\n","import type { Key } from './terminal.js';\nimport { setRawBypass } from './terminal.js';\nimport {\n type AppState,\n INPUT_MODES,\n OPTIONAL_INPUT,\n requestRender,\n notify,\n} from './state.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { Agent, Session } from '../shared/types.js';\nimport type { Response } from '../shared/protocol.js';\nimport { sessionDir, goalPath, roadmapPath, strategyPath } from '../shared/paths.js';\nimport type { Request } from '../shared/protocol.js';\nimport { findParentIndex } from './lib/tree.js';\n\n// ── Re-exported types (same definition, no React) ─────────────────────────────\n\nexport type LeaderAction =\n | { type: 'enter-copy-menu' }\n | { type: 'copy-path' }\n | { type: 'copy-context' }\n | { type: 'copy-logs' }\n | { type: 'copy-session-id' }\n | { type: 'delete-session' }\n | { type: 'open-logs' }\n | { type: 'open-session-dir' }\n | { type: 'search' }\n | { type: 'jump-to-session'; index: number }\n | { type: 'spawn-agent' }\n | { type: 'message-agent' }\n | { type: 'help' }\n | { type: 'shell-command' }\n | { type: 'jump-to-pane' }\n | { type: 'kill' }\n | { type: 'quit' }\n | { type: 'dismiss' };\n\nexport interface KeybindingHandlers {\n onMoveUp: () => void;\n onMoveDown: () => void;\n onEnter: () => void;\n onLeft: () => void;\n onRight: () => void;\n onSpace: () => void;\n onTab: () => void;\n onMessage: () => void;\n onGoToWindow: () => void;\n onEditGoal: () => void;\n onNewSession: () => void;\n onClaude: () => void;\n onOpenPlan: () => void;\n onQuit: () => void;\n onReRun: () => void;\n onResume: () => void;\n onContinue: () => void;\n onRestartAgent: () => void;\n onRollback: () => void;\n onToggleLogs: () => void;\n onEdit: () => void;\n}\n\n// ── InputActions interface ─────────────────────────────────────────────────────\n\nexport interface InputActions {\n // Navigation context (computed by caller, passed in)\n getNodes: () => TreeNode[];\n getCursorNode: () => TreeNode | undefined;\n getAgentForNode: (node: TreeNode | undefined) => Agent | null;\n\n // Async daemon operations\n sendAndNotify: (request: Request, successMsg: string) => void;\n send: (request: Request) => Promise<Response>;\n\n // Editor/tmux operations (injected — input.ts must not import these directly)\n openEditorPopup: typeof import('./lib/tmux.js').openEditorPopup;\n editInPopup: typeof import('./lib/tmux.js').editInPopup;\n openCompanionPane: typeof import('./lib/tmux.js').openCompanionPane;\n openClaudeResumePopup: typeof import('./lib/tmux.js').openClaudeResumePopup;\n selectWindow: typeof import('./lib/tmux.js').selectWindow;\n selectPane: typeof import('./lib/tmux.js').selectPane;\n switchToSession: typeof import('./lib/tmux.js').switchToSession;\n openLogPopup: typeof import('./lib/tmux.js').openLogPopup;\n openShellPopup: typeof import('./lib/tmux.js').openShellPopup;\n openInFileManager: typeof import('./lib/tmux.js').openInFileManager;\n copyToClipboard: typeof import('./lib/clipboard.js').copyToClipboard;\n buildSessionContext: typeof import('./lib/context.js').buildSessionContext;\n\n // Config\n resolveEditor: () => string;\n\n // Lifecycle\n cleanup: () => void;\n}\n\n// ── Neovim bypass helpers ─────────────────────────────────────────────────────\n\nfunction activateNvimBypass(state: AppState): void {\n setRawBypass((data: string) => {\n // Tab (0x09) escapes neovim focus\n if (data === '\\t') {\n deactivateNvimBypass();\n state.focusPane = state.showCombinedView ? 'logs' : 'tree';\n requestRender();\n return true; // consumed, not forwarded to nvim\n }\n // Everything else → neovim\n state.nvimBridge!.write(data);\n return true;\n });\n}\n\nfunction deactivateNvimBypass(): void {\n setRawBypass(null);\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\nfunction handleCancel(state: AppState): void {\n state.mode = 'navigate';\n state.targetAgentId = null;\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n}\n\nfunction expandSessionLatestCycle(state: AppState, node: TreeNode): void {\n if (node.type === 'session' && state.selectedSession?.id === node.sessionId) {\n const cycles = state.selectedSession.orchestratorCycles;\n if (cycles.length > 0) {\n const latest = cycles[cycles.length - 1]!;\n state.expanded.add(`cycle:${node.sessionId}:${latest.cycle}`);\n }\n }\n}\n\n// ── handleSubmit ──────────────────────────────────────────────────────────────\n\nasync function handleSubmit(text: string, state: AppState, actions: InputActions): Promise<void> {\n const selectedSessionId = state.selectedSessionId;\n\n switch (state.mode) {\n case 'resume': {\n if (!selectedSessionId) break;\n actions.sendAndNotify(\n { type: 'resume', sessionId: selectedSessionId, cwd: state.cwd, message: text || undefined },\n 'Session resumed',\n );\n break;\n }\n\n case 'continue': {\n if (!selectedSessionId) break;\n try {\n const contRes = await actions.send({ type: 'continue', sessionId: selectedSessionId });\n if (!contRes.ok) { notify(state, `Error: ${contRes.error}`); break; }\n actions.sendAndNotify(\n { type: 'resume', sessionId: selectedSessionId, cwd: state.cwd, message: text || undefined },\n 'Session continued',\n );\n } catch (err) {\n notify(state, `Error: ${(err as Error).message}`);\n }\n break;\n }\n\n case 'rollback': {\n if (!selectedSessionId) break;\n const toCycle = parseInt(text, 10);\n if (isNaN(toCycle) || toCycle < 1) { notify(state, 'Invalid cycle number'); break; }\n actions.sendAndNotify(\n { type: 'rollback', sessionId: selectedSessionId, cwd: state.cwd, toCycle },\n `Rolled back to cycle ${toCycle} — use [R]esume to respawn`,\n );\n break;\n }\n\n case 'delete-confirm': {\n if (!selectedSessionId) break;\n if (text !== 'yes') { notify(state, 'Delete cancelled (type \"yes\" to confirm)'); break; }\n actions.sendAndNotify(\n { type: 'delete', sessionId: selectedSessionId, cwd: state.cwd },\n 'Session deleted',\n );\n break;\n }\n\n case 'spawn-agent': {\n if (!selectedSessionId) break;\n if (!text.trim()) { notify(state, 'Instruction required'); break; }\n actions.sendAndNotify(\n {\n type: 'spawn',\n sessionId: selectedSessionId,\n agentType: 'default',\n name: 'agent',\n instruction: text,\n },\n 'Agent spawned',\n );\n break;\n }\n\n case 'search': {\n state.searchFilter = text.trim() || null;\n break;\n }\n\n case 'message-agent': {\n if (!selectedSessionId || !state.targetAgentId) break;\n actions.sendAndNotify(\n { type: 'message', sessionId: selectedSessionId, content: text, source: { type: 'agent', agentId: state.targetAgentId } },\n `Message sent to ${state.targetAgentId}`,\n );\n state.targetAgentId = null;\n break;\n }\n\n case 'shell-command': {\n if (!text.trim()) break;\n try {\n actions.openShellPopup(state.cwd, text);\n } catch {\n notify(state, 'Failed to run shell command');\n }\n break;\n }\n }\n\n state.mode = 'navigate';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n}\n\n// ── handleInputBarKey ─────────────────────────────────────────────────────────\n\nfunction handleInputBarKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (key.return) {\n if (OPTIONAL_INPUT.has(state.mode) || state.inputText.trim()) {\n void handleSubmit(state.inputText.trim(), state, actions);\n }\n return;\n }\n\n if (key.escape) {\n handleCancel(state);\n return;\n }\n\n if (key.leftArrow) {\n state.inputCursorPos = Math.max(0, state.inputCursorPos - 1);\n requestRender();\n return;\n }\n\n if (key.rightArrow) {\n state.inputCursorPos = Math.min(state.inputText.length, state.inputCursorPos + 1);\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'a') {\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'e') {\n state.inputCursorPos = state.inputText.length;\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'k') {\n state.inputText = state.inputText.slice(0, state.inputCursorPos);\n // cursorPos stays the same (now at end)\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'u') {\n state.inputText = state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n if (key.backspace) {\n if (state.inputCursorPos > 0) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos - 1) +\n state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos -= 1;\n requestRender();\n }\n return;\n }\n\n if (key.delete) {\n if (state.inputCursorPos < state.inputText.length) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos) +\n state.inputText.slice(state.inputCursorPos + 1);\n requestRender();\n }\n return;\n }\n\n if (input && !key.ctrl && !key.meta) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos) +\n input +\n state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos += input.length;\n requestRender();\n }\n}\n\n// ── handleReportDetailKey ─────────────────────────────────────────────────────\n\nfunction handleReportDetailKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (key.escape || key.return) {\n handleCancel(state);\n return;\n }\n if (key.upArrow) {\n state.detailScroll.scrollBy(-1);\n return;\n }\n if (key.downArrow) {\n state.detailScroll.scrollBy(1);\n return;\n }\n}\n\n// ── handleLeaderKey ───────────────────────────────────────────────────────────\n\nfunction handleLeaderAction(action: LeaderAction, state: AppState, actions: InputActions): void {\n const nodes = actions.getNodes();\n const cursorNode = actions.getCursorNode();\n const session = state.selectedSession;\n const selectedSessionId = state.selectedSessionId;\n const agents = session?.agents ?? [];\n\n switch (action.type) {\n case 'enter-copy-menu':\n state.mode = 'copy-menu';\n requestRender();\n return;\n\n case 'copy-path': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n const path = sessionDir(state.cwd, selectedSessionId);\n try {\n actions.copyToClipboard(path);\n notify(state, `Copied path (${path})`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'copy-context': {\n if (!selectedSessionId || !session) { notify(state, 'No session selected'); break; }\n try {\n const xml = actions.buildSessionContext(session, state.cwd);\n actions.copyToClipboard(xml);\n notify(state, `Copied context (${xml.length} chars)`);\n } catch {\n notify(state, 'Failed to copy context');\n }\n break;\n }\n\n case 'copy-logs': {\n if (!state.logsContent) { notify(state, 'No logs content'); break; }\n try {\n actions.copyToClipboard(state.logsContent);\n notify(state, `Copied logs (${state.logsContent.length} chars)`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'copy-session-id': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n try {\n actions.copyToClipboard(selectedSessionId);\n notify(state, `Copied session ID (${selectedSessionId})`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'delete-session': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n state.mode = 'delete-confirm';\n requestRender();\n return;\n }\n\n case 'open-logs': {\n try {\n actions.openLogPopup();\n } catch {\n notify(state, 'Failed to open log popup');\n }\n break;\n }\n\n case 'open-session-dir': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n try {\n actions.openInFileManager(sessionDir(state.cwd, selectedSessionId));\n } catch {\n notify(state, 'Failed to open session directory');\n }\n break;\n }\n\n case 'search':\n state.mode = 'search';\n requestRender();\n return;\n\n case 'jump-to-session': {\n let count = 0;\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i]?.type === 'session') {\n count++;\n if (count === action.index) {\n state.cursorIndex = i;\n state.cursorNodeId = nodes[i]!.id;\n break;\n }\n }\n }\n break;\n }\n\n case 'spawn-agent': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n state.mode = 'spawn-agent';\n requestRender();\n return;\n }\n\n case 'message-agent': {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent) { notify(state, 'Cursor must be on an agent'); break; }\n state.targetAgentId = agent.id;\n state.mode = 'message-agent';\n requestRender();\n return;\n }\n\n case 'help':\n state.mode = 'help';\n requestRender();\n return;\n\n case 'shell-command': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n state.mode = 'shell-command';\n requestRender();\n return;\n }\n\n case 'jump-to-pane': {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent?.paneId) { notify(state, 'Select an agent with an active pane'); break; }\n if (session?.tmuxSessionName) actions.switchToSession(session.tmuxSessionName);\n if (session?.tmuxWindowId) actions.selectWindow(session.tmuxWindowId);\n actions.selectPane(agent.paneId);\n break;\n }\n\n case 'kill': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n const node = nodes[state.cursorIndex];\n if (node && (node.type === 'agent' || node.type === 'report')) {\n const agentId = node.agentId;\n const agent = agents.find((a) => a.id === agentId);\n if (agent?.status !== 'running') { notify(state, `Agent ${agentId} is not running`); break; }\n actions.sendAndNotify({ type: 'kill-agent', sessionId: selectedSessionId, agentId }, `Killed ${agentId}`);\n } else {\n actions.sendAndNotify({ type: 'kill', sessionId: selectedSessionId }, 'Session killed');\n }\n break;\n }\n\n case 'quit':\n actions.cleanup();\n return;\n\n case 'dismiss':\n break;\n }\n\n state.mode = 'navigate';\n requestRender();\n}\n\nfunction handleLeaderKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (state.mode === 'leader') {\n if (key.escape) { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n if (input === 'y') { handleLeaderAction({ type: 'enter-copy-menu' }, state, actions); return; }\n if (input === 'd') { handleLeaderAction({ type: 'delete-session' }, state, actions); return; }\n if (input === 'l') { handleLeaderAction({ type: 'open-logs' }, state, actions); return; }\n if (input === 'o') { handleLeaderAction({ type: 'open-session-dir' }, state, actions); return; }\n if (input === '/') { handleLeaderAction({ type: 'search' }, state, actions); return; }\n if (input === 'a') { handleLeaderAction({ type: 'spawn-agent' }, state, actions); return; }\n if (input === 'm') { handleLeaderAction({ type: 'message-agent' }, state, actions); return; }\n if (input === '?') { handleLeaderAction({ type: 'help' }, state, actions); return; }\n if (input === '!') { handleLeaderAction({ type: 'shell-command' }, state, actions); return; }\n if (input === 'j') { handleLeaderAction({ type: 'jump-to-pane' }, state, actions); return; }\n if (input === 'k') { handleLeaderAction({ type: 'kill' }, state, actions); return; }\n if (input === 'q') { handleLeaderAction({ type: 'quit' }, state, actions); return; }\n const digit = parseInt(input, 10);\n if (!isNaN(digit) && digit >= 1 && digit <= 9) {\n handleLeaderAction({ type: 'jump-to-session', index: digit }, state, actions);\n return;\n }\n handleLeaderAction({ type: 'dismiss' }, state, actions);\n return;\n }\n\n if (state.mode === 'copy-menu') {\n if (key.escape) { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n if (input === 'p') { handleLeaderAction({ type: 'copy-path' }, state, actions); return; }\n if (input === 'C') { handleLeaderAction({ type: 'copy-context' }, state, actions); return; }\n if (input === 'l') { handleLeaderAction({ type: 'copy-logs' }, state, actions); return; }\n if (input === 's') { handleLeaderAction({ type: 'copy-session-id' }, state, actions); return; }\n handleLeaderAction({ type: 'dismiss' }, state, actions);\n return;\n }\n\n if (state.mode === 'help') {\n if (key.escape || input === '?') { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n // any other key: ignore\n }\n}\n\n// ── handleNavigateKey ─────────────────────────────────────────────────────────\n\nfunction handleNavigateKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n const nodes = actions.getNodes();\n const cursorNode = actions.getCursorNode();\n const session = state.selectedSession;\n\n // j / ↑\n if (key.upArrow || input === 'k') {\n if (state.focusPane === 'detail') {\n state.detailScroll.scrollBy(-1);\n } else if (state.focusPane === 'logs') {\n state.logsScroll.scrollBy(-1);\n } else {\n state.cursorIndex = Math.max(0, state.cursorIndex - 1);\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n return;\n }\n\n // j / ↓\n if (key.downArrow || input === 'j') {\n if (state.focusPane === 'detail') {\n state.detailScroll.scrollBy(1);\n } else if (state.focusPane === 'logs') {\n state.logsScroll.scrollBy(1);\n } else {\n state.cursorIndex = Math.min(nodes.length - 1, state.cursorIndex + 1);\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n return;\n }\n\n // h / ←\n if (key.leftArrow || input === 'h') {\n if (state.focusPane === 'logs') {\n state.focusPane = 'detail';\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n activateNvimBypass(state);\n }\n requestRender();\n return;\n }\n if (state.focusPane === 'detail') {\n deactivateNvimBypass();\n state.focusPane = 'tree';\n requestRender();\n return;\n }\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expanded) {\n state.expanded.delete(node.id);\n requestRender();\n } else {\n const parentIdx = findParentIndex(nodes, state.cursorIndex);\n if (parentIdx !== state.cursorIndex) {\n state.cursorIndex = parentIdx;\n state.cursorNodeId = nodes[parentIdx]?.id ?? state.cursorNodeId;\n requestRender();\n }\n }\n return;\n }\n\n // l / →\n if (key.rightArrow || input === 'l') {\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expandable && !node.expanded) {\n state.expanded.add(node.id);\n expandSessionLatestCycle(state, node);\n requestRender();\n } else if (node.expandable && node.expanded) {\n // Move cursor to first child\n if (state.cursorIndex + 1 < nodes.length && nodes[state.cursorIndex + 1]!.depth > node.depth) {\n state.cursorIndex += 1;\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n }\n return;\n }\n\n // tab: cycle focus panes\n if (key.tab) {\n if (state.focusPane === 'tree') {\n state.focusPane = 'detail';\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n activateNvimBypass(state);\n }\n } else if (state.focusPane === 'detail') {\n deactivateNvimBypass();\n state.focusPane = state.showCombinedView ? 'logs' : 'tree';\n } else {\n state.focusPane = 'tree';\n }\n requestRender();\n return;\n }\n\n // space: enter leader mode\n if (input === ' ') {\n state.mode = 'leader';\n requestRender();\n return;\n }\n\n // enter: expand / report-detail / open context file\n if (key.return) {\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expandable && !node.expanded) {\n state.expanded.add(node.id);\n expandSessionLatestCycle(state, node);\n requestRender();\n } else if (node.type === 'report') {\n state.targetAgentId = node.agentId;\n state.mode = 'report-detail';\n requestRender();\n } else if (node.type === 'context-file') {\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, node.filePath);\n } catch {\n notify(state, 'Failed to open file in editor');\n }\n }\n return;\n }\n\n // m: message orchestrator\n if (input === 'm') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const editor = actions.resolveEditor();\n try {\n const content = actions.editInPopup(state.cwd, editor);\n if (content) {\n actions.sendAndNotify(\n { type: 'message', sessionId: state.selectedSessionId, content },\n 'Message queued',\n );\n }\n } catch {\n notify(state, 'Failed to open editor');\n }\n return;\n }\n\n // w: go to tmux window\n if (input === 'w') {\n if (!session || !state.selectedSessionId) { notify(state, 'No session selected'); return; }\n\n if (state.paneAlive && session.tmuxWindowId) {\n if (session.tmuxSessionName) actions.switchToSession(session.tmuxSessionName);\n actions.selectWindow(session.tmuxWindowId);\n return;\n }\n\n // Window is dead — reopen via daemon\n void (async () => {\n try {\n const res = await actions.send({ type: 'reopen-window', sessionId: state.selectedSessionId!, cwd: state.cwd });\n if (!res.ok) { notify(state, `Error: ${res.error}`); return; }\n const data = res.data as { tmuxSessionName: string; tmuxWindowId: string };\n actions.switchToSession(data.tmuxSessionName);\n actions.selectWindow(data.tmuxWindowId);\n } catch (err) {\n notify(state, `Error: ${(err as Error).message}`);\n }\n })();\n return;\n }\n\n // o: open/resume claude session for agent or orchestrator cycle\n if (input === 'o') {\n if (!cursorNode) { notify(state, 'No node selected'); return; }\n let claudeSessionId: string | undefined;\n if (cursorNode.type === 'agent' || cursorNode.type === 'report') {\n const agent = actions.getAgentForNode(cursorNode);\n claudeSessionId = agent?.claudeSessionId ?? undefined;\n } else if (cursorNode.type === 'cycle' && session) {\n const cycle = session.orchestratorCycles.find(c => c.cycle === cursorNode.cycleNumber);\n claudeSessionId = cycle?.claudeSessionId;\n }\n if (!claudeSessionId) { notify(state, 'No Claude session ID available'); return; }\n try {\n actions.openClaudeResumePopup(state.cwd, claudeSessionId);\n } catch {\n notify(state, 'Failed to open Claude session');\n }\n return;\n }\n\n // g: edit goal\n if (input === 'g') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const gp = goalPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, gp, { w: '80', h: '50%' });\n } catch {\n notify(state, `Failed to open goal in ${editor}`);\n }\n return;\n }\n\n // n: new session\n if (input === 'n') {\n const editor = actions.resolveEditor();\n try {\n const content = actions.editInPopup(state.cwd, editor);\n if (content) {\n actions.sendAndNotify(\n { type: 'start', task: content, cwd: state.cwd },\n 'Session created',\n );\n }\n } catch {\n notify(state, 'Failed to open editor');\n }\n return;\n }\n\n // c: open companion pane\n if (input === 'c') {\n try {\n actions.openCompanionPane(state.cwd);\n } catch {\n notify(state, 'Failed to open companion pane');\n }\n return;\n }\n\n // p: open plan/roadmap\n if (input === 'p') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const pp = roadmapPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, pp);\n } catch {\n notify(state, `Failed to open roadmap in ${editor}`);\n }\n return;\n }\n\n // q: quit\n if (input === 'q') {\n actions.cleanup();\n }\n\n // r: re-run agent\n if (input === 'r') {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent || !state.selectedSessionId) { notify(state, 'Select an agent to re-run'); return; }\n actions.sendAndNotify(\n {\n type: 'spawn',\n sessionId: state.selectedSessionId,\n agentType: agent.agentType,\n name: `${agent.name}-retry`,\n instruction: agent.instruction,\n },\n `Re-spawned ${agent.name}`,\n );\n return;\n }\n\n // R: enter resume mode\n if (input === 'R') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n if (session?.status === 'active' && state.paneAlive) { notify(state, 'Session already active'); return; }\n state.mode = 'resume';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n // C: enter continue mode\n if (input === 'C') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n if (session?.status !== 'completed') { notify(state, 'Session not completed'); return; }\n state.mode = 'continue';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n // x: restart agent\n if (input === 'x') {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent || !state.selectedSessionId) { notify(state, 'Select an agent to restart'); return; }\n actions.sendAndNotify(\n { type: 'restart-agent', sessionId: state.selectedSessionId, agentId: agent.id },\n `Restarted ${agent.id}`,\n );\n return;\n }\n\n // b: enter rollback mode — pre-fill with cycle number if cursor is on a cycle node\n if (input === 'b') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const defaultText = cursorNode?.type === 'cycle' ? String(cursorNode.cycleNumber) : undefined;\n state.mode = 'rollback';\n if (defaultText) {\n state.inputText = defaultText;\n state.inputCursorPos = defaultText.length;\n } else {\n state.inputText = '';\n state.inputCursorPos = 0;\n }\n requestRender();\n return;\n }\n\n // e: edit context file\n if (input === 'e') {\n if (!cursorNode || cursorNode.type !== 'context-file') return;\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, cursorNode.filePath);\n } catch {\n notify(state, 'Failed to open file in editor');\n }\n return;\n }\n\n // S: edit strategy\n if (input === 'S') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const sp = strategyPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, sp);\n } catch {\n notify(state, `Failed to open strategy in ${editor}`);\n }\n return;\n }\n\n // t: toggle logs panel\n if (input === 't') {\n if (state.showCombinedView) {\n if (state.focusPane === 'logs') state.focusPane = 'detail';\n state.logsScroll.reset();\n }\n state.showCombinedView = !state.showCombinedView;\n requestRender();\n return;\n }\n}\n\n// ── Main dispatch ─────────────────────────────────────────────────────────────\n\nexport function handleKeypress(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (INPUT_MODES.has(state.mode)) {\n handleInputBarKey(input, key, state, actions);\n } else if (state.mode === 'leader' || state.mode === 'copy-menu' || state.mode === 'help') {\n handleLeaderKey(input, key, state, actions);\n } else if (state.mode === 'report-detail') {\n handleReportDetailKey(input, key, state, actions);\n } else {\n handleNavigateKey(input, key, state, actions);\n }\n}\n","import stringWidth from 'string-width';\nimport type { Seg, DetailLine } from './lib/format.js';\n\nexport type { Seg, DetailLine };\n\n// ─── Color mapping ────────────────────────────────────────────────────────────\n\nexport const COLOR_SGR: Record<string, number> = {\n black: 30,\n red: 31,\n green: 32,\n yellow: 33,\n blue: 34,\n magenta: 35,\n cyan: 36,\n white: 37,\n gray: 90,\n};\n\nexport function colorToSGR(color: string): number {\n const code = COLOR_SGR[color];\n if (code === undefined) throw new Error(`Unknown color: ${color}`);\n return code;\n}\n\n// ─── Seg → ANSI conversion (§1.1) ────────────────────────────────────────────\n\nexport function renderLine(segs: Seg[]): string {\n let out = '';\n for (const s of segs) {\n const codes: number[] = [];\n if (s.bold) codes.push(1);\n if (s.dim) codes.push(2);\n if (s.italic) codes.push(3);\n if (s.inverse) codes.push(7);\n if (s.color) codes.push(colorToSGR(s.color));\n if (codes.length > 0) {\n out += `\\x1b[${codes.join(';')}m${s.text}\\x1b[0m`;\n } else {\n out += s.text;\n }\n }\n return out;\n}\n\n// ─── Frame Buffer (§1.2) ──────────────────────────────────────────────────────\n\nexport interface FrameBuffer {\n lines: string[];\n width: number;\n height: number;\n}\n\nlet cachedBlank = '';\nlet cachedBlankWidth = 0;\n\nexport function createFrameBuffer(width: number, height: number): FrameBuffer {\n if (width !== cachedBlankWidth) {\n cachedBlank = ' '.repeat(width);\n cachedBlankWidth = width;\n }\n const lines = new Array<string>(height);\n for (let i = 0; i < height; i++) lines[i] = cachedBlank;\n return { lines, width, height };\n}\n\n/**\n * Copy rows from a previous frame into the buffer (skip re-render for clean panels).\n */\nexport function copyRows(buf: FrameBuffer, src: string[], startRow: number, count: number): void {\n for (let i = 0; i < count && startRow + i < buf.height; i++) {\n buf.lines[startRow + i] = src[startRow + i]!;\n }\n}\n\n// ─── Frame Diffing (§1.3) ────────────────────────────────────────────────────\n\nexport function flushFrame(frame: string[], prevFrame: string[], suffix?: string): string {\n let out = '\\x1b[?2026h'; // begin synchronized output\n for (let i = 0; i < frame.length; i++) {\n if (frame[i] !== prevFrame[i]) {\n out += `\\x1b[${i + 1};1H`; // cursor to row i+1, col 1\n out += '\\x1b[2K'; // clear entire line\n out += frame[i];\n }\n }\n if (suffix) out += suffix;\n out += '\\x1b[?2026l'; // end synchronized output\n return out;\n}\n\n// ─── ANSI escape sequence regex ───────────────────────────────────────────────\n\nconst ANSI_RE = /\\x1b\\[[0-9;]*[a-zA-Z]/g;\n\n// ─── Clip ANSI string to display width (no buffer interaction) ──────────────\n\n/**\n * Clip an ANSI string to exactly `maxWidth` display columns, padding with spaces.\n * Pure function — no buffer splicing.\n */\nexport function clipAnsi(content: string, maxWidth: number): string {\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n const cp = content.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n if (displayWidth + chWidth > maxWidth) break;\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) out += ' '.repeat(remaining);\n return out;\n}\n\n/**\n * Fast display-width calculation that skips ANSI escapes without regex allocation.\n */\nfunction displayWidthFast(s: string): number {\n let w = 0;\n let i = 0;\n while (i < s.length) {\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const len = ansiLen(s, i);\n if (len > 0) { i += len; continue; }\n }\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n w += cp < 128 ? 1 : stringWidth(ch);\n i += ch.length;\n }\n return w;\n}\n\n/**\n * Parse ANSI escape sequence at position i. Returns length of sequence or 0.\n * Avoids s.slice(i).match(regex) which allocates a new string each call.\n */\nfunction ansiLen(s: string, i: number): number {\n // Caller already verified s[i] === '\\x1b' && s[i+1] === '['\n let j = i + 2;\n const len = s.length;\n // Consume parameter bytes: digits 0-9 and semicolons\n while (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x30 && c <= 0x39) || c === 0x3b) { // '0'-'9' or ';'\n j++;\n } else {\n break;\n }\n }\n // Must end with a letter (final byte)\n if (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)) { // A-Z or a-z\n return j + 1 - i;\n }\n }\n return 0;\n}\n\n// ─── Write functions ──────────────────────────────────────────────────────────\n\n/**\n * Write content into frame buffer at position (x, y).\n *\n * Strategy: rebuild the target line by splitting into display columns,\n * inserting the new content, then reassembling. Since we build the frame\n * fresh each render, we can treat the existing line as plain chars + ANSI.\n *\n * This implementation replaces display columns [x, x+displayWidth(content))\n * in the buffer line with the new content.\n */\nexport function writeAt(buf: FrameBuffer, x: number, y: number, content: string): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n const existing = buf.lines[y]!;\n const contentDisplayWidth = stringWidth(content.replace(ANSI_RE, ''));\n\n // Split the existing line into prefix (0..x) and suffix (x+contentDisplayWidth..)\n // We need to walk the existing line respecting display widths.\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + contentDisplayWidth, buf.width);\n\n // Pad prefix if it's shorter than expected (can happen at end of line)\n const prefixWidth = stringWidth(prefix.replace(ANSI_RE, ''));\n const paddedPrefix = prefix + ' '.repeat(Math.max(0, x - prefixWidth));\n\n buf.lines[y] = paddedPrefix + content + suffix;\n}\n\n/**\n * Write ANSI string into buffer at (x, y), truncating to maxWidth display columns.\n * Pads remaining width with spaces.\n */\nexport function writeClipped(\n buf: FrameBuffer,\n x: number,\n y: number,\n content: string,\n maxWidth: number,\n): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n // Check for ANSI escape sequence — pass through without counting width\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n\n // Get the next character (handle surrogate pairs)\n const cp = content.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (displayWidth + chWidth > maxWidth) break;\n\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n // Ensure any open SGR sequences are reset\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n // Pad to maxWidth\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) {\n out += ' '.repeat(remaining);\n }\n\n // Splice directly into buffer line — we already know exact display width is maxWidth,\n // so skip writeAt's redundant stringWidth + double sliceDisplayCols re-parse.\n const existing = buf.lines[y]!;\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + maxWidth, buf.width);\n const prefixDisplayW = displayWidthFast(prefix);\n const paddedPrefix = prefixDisplayW < x ? prefix + ' '.repeat(x - prefixDisplayW) : prefix;\n buf.lines[y] = paddedPrefix + out + suffix;\n}\n\n/**\n * Write centered text at the given row.\n */\nexport function writeCenter(buf: FrameBuffer, row: number, content: string): void {\n const textWidth = stringWidth(content.replace(ANSI_RE, ''));\n const x = Math.max(0, Math.floor((buf.width - textWidth) / 2));\n writeAt(buf, x, row, content);\n}\n\n// ─── Border Drawing (§1.5) ────────────────────────────────────────────────────\n\nexport function drawBorder(\n buf: FrameBuffer,\n x: number,\n y: number,\n w: number,\n h: number,\n color: string,\n): void {\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n\n // Top: ╭────╮\n writeAt(buf, x, y, sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset);\n // Bottom: ╰────╯\n writeAt(buf, x, y + h - 1, sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset);\n // Sides\n for (let row = y + 1; row < y + h - 1; row++) {\n writeAt(buf, x, row, sgr + '│' + reset);\n writeAt(buf, x + w - 1, row, sgr + '│' + reset);\n }\n}\n\n// ─── Panel Rendering (§4.2) ───────────────────────────────────────────────────\n\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * Cache for pre-rendered ANSI strings. Keyed by the DetailLine[] identity —\n * when the caller provides a `renderedCache`, renderPanel will populate it\n * on first render and reuse on subsequent frames (avoiding renderLine per line).\n */\nexport interface RenderedCache {\n lines: DetailLine[];\n ansi: string[];\n}\n\nexport function renderPanel(\n buf: FrameBuffer,\n rect: Rect,\n lines: DetailLine[],\n scrollOffset: number,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): void {\n const { x, y, w, h } = rect;\n\n // 1. Draw border\n drawBorder(buf, x, y, w, h, focused ? 'blue' : borderColor);\n\n // 2. Inner dimensions (border + 1 padding each side, matching Ink's paddingX={1})\n const innerX = x + 2;\n const innerW = w - 4;\n const innerY = y + 1;\n const innerH = h - 2;\n\n if (innerW <= 0 || innerH <= 0) return;\n\n // 3. Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // 4. Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n const effectiveOffset = Math.min(scrollOffset, maxScroll);\n\n // 5. Render visible lines\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n writeClipped(buf, innerX, innerY + i, ansiLines[effectiveOffset + i]!, innerW);\n }\n\n // 6. Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n writeClipped(buf, innerX, innerY + viewableH, `\\x1b[2m${indicator}\\x1b[0m`, innerW);\n }\n}\n\n/**\n * Build panel as self-contained row strings (w display-columns each, including borders).\n * Returns h strings. No buffer interaction — avoids sliceDisplayCols entirely.\n */\nexport function buildPanelRows(\n rect: Rect,\n lines: DetailLine[],\n scrollOffset: number,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n\n const color = focused ? 'blue' : borderColor;\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const innerH = h - 2;\n const blankInner = ' '.repeat(innerW);\n\n // Top border\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n // Bottom border\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n\n // Pre-fill interior rows with empty content\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + blankInner + borderR;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (innerW <= 0 || innerH <= 0) return rows;\n\n // Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n const effectiveOffset = Math.min(scrollOffset, maxScroll);\n\n // Content rows — clip and compose without buffer splicing\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n const clipped = clipAnsi(ansiLines[effectiveOffset + i]!, innerW);\n rows[1 + i] = borderL + clipped + borderR;\n }\n\n // Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n const clipped = clipAnsi(`\\x1b[2m${indicator}\\x1b[0m`, innerW);\n rows[1 + viewableH] = borderL + clipped + borderR;\n }\n\n return rows;\n}\n\n/**\n * Build empty panel rows (border only, no content).\n */\nexport function buildEmptyPanelRows(\n rect: Rect,\n focused: boolean,\n borderColor: string,\n centerText?: string,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n const color = focused ? 'blue' : borderColor;\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + ' '.repeat(innerW) + borderR;\n\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (centerText) {\n const midRow = Math.floor(h / 2);\n if (midRow > 0 && midRow < h - 1) {\n const clipped = clipAnsi(centerText, innerW);\n // Center within panel\n const textW = displayWidthFast(centerText);\n const pad = Math.max(0, Math.floor((innerW - textW) / 2));\n const centered = ' '.repeat(pad) + clipped;\n rows[midRow] = borderL + clipAnsi(centered, innerW) + borderR;\n }\n }\n\n return rows;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\n/**\n * Slice a string (which may contain ANSI escapes) to display columns [start, end).\n * ANSI sequences are passed through only within the slice range.\n */\nfunction sliceDisplayCols(s: string, start: number, end: number): string {\n let out = '';\n let col = 0;\n let i = 0;\n let inSlice = false;\n let hasOpenSGR = false;\n\n while (i < s.length && col < end) {\n // ANSI escape: pass through if we're in the slice\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const seqLen = ansiLen(s, i);\n if (seqLen > 0) {\n if (col >= start) {\n const seq = s.substring(i, i + seqLen);\n out += seq;\n // Track if we have open SGR (non-reset)\n hasOpenSGR = seq !== '\\x1b[0m' && seq !== '\\x1b[m';\n }\n i += seqLen;\n continue;\n }\n }\n\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (col >= start) {\n inSlice = true;\n // Don't emit char that would overflow end\n if (col + chWidth > end) break;\n out += ch;\n }\n\n col += chWidth;\n i += ch.length;\n }\n\n // Close any open SGR\n if (inSlice && hasOpenSGR) {\n out += '\\x1b[0m';\n }\n\n return out;\n}\n","import type { TreeNode } from '../types/tree.js';\n\n/**\n * Render box-drawing prefix for a tree node.\n * Produces connectors like: │ ├─ ▸ or └─ ▼\n */\nexport function renderTreePrefix(node: TreeNode, nodes: TreeNode[], index: number): string {\n if (node.depth === 0) {\n return node.expandable ? (node.expanded ? '▼ ' : '▸ ') : ' ';\n }\n\n const parts: string[] = [];\n\n // For each ancestor depth level (1..depth-1), draw │ or space\n for (let d = 1; d < node.depth; d++) {\n parts.push(isAncestorLastSibling(nodes, index, d) ? ' ' : '│ ');\n }\n\n // Connector for this node\n parts.push(isLastSibling(nodes, index) ? '└─' : '├─');\n\n // Expand indicator\n if (node.expandable) {\n parts.push(node.expanded ? '▼ ' : '▸ ');\n } else {\n parts.push(' ');\n }\n\n return parts.join('');\n}\n\n/** Check if the node at `index` is the last among its siblings (same depth, same parent) */\nfunction isLastSibling(nodes: TreeNode[], index: number): boolean {\n const depth = nodes[index]!.depth;\n for (let i = index + 1; i < nodes.length; i++) {\n if (nodes[i]!.depth === depth) return false;\n if (nodes[i]!.depth < depth) return true;\n }\n return true;\n}\n\n/** Check if the ancestor at `depth` for the node at `index` is the last among its siblings */\nfunction isAncestorLastSibling(nodes: TreeNode[], index: number, depth: number): boolean {\n // Find the ancestor at this depth by scanning backward\n for (let i = index - 1; i >= 0; i--) {\n if (nodes[i]!.depth === depth) {\n return isLastSibling(nodes, i);\n }\n if (nodes[i]!.depth < depth) return true;\n }\n return true;\n}\n\n/**\n * Pre-compute prefix strings for all tree nodes in O(n).\n * Avoids per-node O(n) scans during rendering.\n */\nexport function precomputePrefixes(nodes: TreeNode[]): void {\n const len = nodes.length;\n if (len === 0) return;\n\n // Step 1: Compute isLastSibling for each node in a single backward pass.\n // A node is \"last sibling\" if no later node at the same depth appears before\n // a node at a shallower depth (or end of array).\n const isLast = new Array<boolean>(len);\n // Track the last-seen index for each depth level\n const lastSeenAtDepth = new Map<number, number>();\n\n for (let i = len - 1; i >= 0; i--) {\n const depth = nodes[i]!.depth;\n // This node is last sibling if no node at same depth was seen after it\n // before a shallower node\n isLast[i] = !lastSeenAtDepth.has(depth);\n lastSeenAtDepth.set(depth, i);\n // Clear deeper depths (they belong to a different parent scope)\n for (const [d] of lastSeenAtDepth) {\n if (d > depth) lastSeenAtDepth.delete(d);\n }\n }\n\n // Step 2: Build prefix strings using pre-computed isLast data.\n // For ancestor connector lines, we need to know if the ancestor at each depth\n // is a last sibling. We maintain a stack of isLast values per depth.\n const ancestorIsLast: boolean[] = [];\n\n for (let i = 0; i < len; i++) {\n const node = nodes[i]!;\n\n if (node.depth === 0) {\n node.prefix = node.expandable ? (node.expanded ? '▼ ' : '▸ ') : ' ';\n ancestorIsLast[0] = isLast[i]!;\n continue;\n }\n\n // Update ancestor tracking\n ancestorIsLast[node.depth] = isLast[i]!;\n\n const parts: string[] = [];\n\n // Ancestor connectors (depth 1 to depth-1)\n for (let d = 1; d < node.depth; d++) {\n parts.push(ancestorIsLast[d] ? ' ' : '│ ');\n }\n\n // This node's connector\n parts.push(isLast[i] ? '└─' : '├─');\n\n // Expand indicator\n if (node.expandable) {\n parts.push(node.expanded ? '▼ ' : '▸ ');\n } else {\n parts.push(' ');\n }\n\n node.prefix = parts.join('');\n }\n}\n","import { rawSend } from '../../shared/client.js';\nimport type { Request, Response } from '../../shared/protocol.js';\n\nexport function send(request: Request): Promise<Response> {\n return rawSend(request, 5_000);\n}\n","import { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { readFileSync, writeFileSync, mkdtempSync, rmSync, cpSync, existsSync, mkdirSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { globalDir } from '../../shared/paths.js';\nimport { augmentedPath } from '../../shared/env.js';\nimport { shellQuote } from '../../shared/shell.js';\nimport { exec, execSafe, EXEC_ENV } from '../../shared/exec.js';\n\n\nexport function getWindowId(): string {\n return exec('tmux display-message -p \"#{window_id}\"');\n}\n\nexport function selectWindow(windowId: string): void {\n execSafe(`tmux select-window -t \"${windowId}\"`);\n}\n\nexport function selectPane(paneId: string): void {\n execSafe(`tmux select-pane -t \"${paneId}\"`);\n}\n\nexport function windowExists(windowId: string): boolean {\n return execSafe(`tmux display-message -t \"${windowId}\" -p \"#{window_id}\"`) !== null;\n}\n\nexport function listAllWindowIds(): Set<string> {\n try {\n const output = execSync('tmux list-windows -a -F \"#{window_id}\"', { encoding: 'utf-8', env: EXEC_ENV });\n return new Set(output.trim().split('\\n').filter(Boolean));\n } catch {\n return new Set();\n }\n}\n\nlet companionPaneId: string | null = null;\n\nfunction setupCompanionPlugin(): string {\n const srcDir = join(import.meta.dirname, 'templates', 'companion-plugin');\n const destDir = join(globalDir(), 'companion-plugin');\n if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });\n cpSync(srcDir, destDir, { recursive: true });\n return destDir;\n}\n\nfunction isPaneAlive(paneId: string): boolean {\n return execSafe(`tmux display-message -t ${shellQuote(paneId)} -p \"#{pane_id}\"`) !== null;\n}\n\nexport function openCompanionPane(cwd: string): void {\n // If companion pane is alive, focus it\n if (companionPaneId && isPaneAlive(companionPaneId)) {\n execSafe(`tmux select-pane -t ${shellQuote(companionPaneId)}`);\n return;\n }\n\n const pluginDir = setupCompanionPlugin();\n\n const templatePath = join(import.meta.dirname, 'templates', 'dashboard-claude.md');\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf-8');\n } catch {\n template = `You are a Sisyphus dashboard companion. Help the user manage multi-agent sessions.\\nProject: ${cwd}\\nRun \\`sisyphus list\\` and \\`sisyphus status\\` to see current state.`;\n }\n\n const rendered = template.replace(/\\{\\{CWD\\}\\}/g, cwd);\n const promptPath = join(globalDir(), 'dashboard-companion-prompt.md');\n writeFileSync(promptPath, rendered, 'utf-8');\n\n const pathEnv = augmentedPath();\n\n const claudeCmd = `SISYPHUS_COMPANION_CWD=${shellQuote(cwd)} PATH=${shellQuote(pathEnv)} claude --dangerously-skip-permissions --plugin-dir ${shellQuote(pluginDir)} --append-system-prompt \"$(cat ${shellQuote(promptPath)})\"`;\n\n const result = exec(\n `tmux split-window -h -d -l 33% -P -F \"#{pane_id}\" -c ${shellQuote(cwd)} ${shellQuote(claudeCmd)}`,\n );\n companionPaneId = result.trim() || null;\n}\n\nconst TERMINAL_EDITORS = new Set(['nvim', 'vim', 'vi', 'nano', 'emacs', 'micro', 'helix', 'hx', 'joe', 'ne', 'kak']);\n\nexport function switchToSession(sessionName: string): void {\n execSafe(`tmux switch-client -t \"${sessionName}\"`);\n}\n\nexport function editInPopup(cwd: string, editor: string, opts?: { content?: string; size?: { w: string; h: string } }): string | null {\n const tmpDir = mkdtempSync(join(tmpdir(), 'sisyphus-'));\n const filePath = join(tmpDir, 'input.md');\n try {\n writeFileSync(filePath, opts?.content ? opts.content : '', 'utf-8');\n openEditorPopup(cwd, editor, filePath, opts?.size);\n const result = readFileSync(filePath, 'utf-8').trim();\n return result || null;\n } finally {\n rmSync(tmpDir, { recursive: true, force: true });\n }\n}\n\nexport function openLogPopup(): void {\n execSync(\n `tmux display-popup -E -w 90% -h 80% ${shellQuote('tail -f ~/.sisyphus/daemon.log')}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openShellPopup(cwd: string, command: string): void {\n execSync(\n `tmux display-popup -E -w 90% -h 80% -d ${shellQuote(cwd)} ${shellQuote(`sh -c '${command.replace(/'/g, \"'\\\\''\")}; echo; echo \"Press enter to close\"; read'`)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openInFileManager(path: string): void {\n execSync(`open ${shellQuote(path)}`, { stdio: 'inherit', env: EXEC_ENV });\n}\n\nexport function openClaudeResumePopup(cwd: string, claudeSessionId: string): void {\n const pathEnv = augmentedPath();\n const cmd = `PATH=${shellQuote(pathEnv)} claude --resume ${shellQuote(claudeSessionId)}`;\n execSync(\n `tmux display-popup -E -w 90% -h 80% -d ${shellQuote(cwd)} ${shellQuote(cmd)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openEditorPopup(cwd: string, editor: string, filePath: string, size?: { w: string; h: string }): void {\n const { w = '90%', h = '90%' } = size ?? {};\n const editorBin = editor.split(/\\s+/)[0]!.split('/').pop()!;\n if (TERMINAL_EDITORS.has(editorBin)) {\n execSync(\n `tmux display-popup -E -w ${w} -h ${h} -d ${shellQuote(cwd)} ${shellQuote(`${editor} ${shellQuote(filePath)}`)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n } else {\n execSync(`${editor} ${shellQuote(filePath)}`, { stdio: 'inherit', cwd, env: EXEC_ENV });\n }\n}\n","import { execSync } from 'node:child_process';\n\nexport function copyToClipboard(text: string): void {\n execSync('pbcopy', { input: text });\n}\n","import type { FrameBuffer, Rect } from '../render.js';\nimport { drawBorder, writeClipped, colorToSGR } from '../render.js';\nimport type { TreeNode } from '../types/tree.js';\nimport { renderTreePrefix } from '../lib/tree-render.js';\nimport {\n statusColor,\n statusIndicator,\n agentStatusIcon,\n truncate,\n formatDuration,\n formatTime,\n formatTimeAgo,\n durationColor,\n agentDisplayName,\n modeColor,\n abbreviateMode,\n} from '../lib/format.js';\n\n// ─── Node content renderer ────────────────────────────────────────────────────\n\ninterface NodeContent {\n icon: string;\n label: string;\n meta: string;\n color: string;\n dim: boolean;\n metaColor?: string;\n suffix?: string;\n suffixColor?: string;\n}\n\nfunction renderNodeContent(node: TreeNode, maxWidth: number): NodeContent {\n switch (node.type) {\n case 'session': {\n const icon = statusIndicator(node.status);\n const color = statusColor(node.status);\n const dim = node.status === 'completed';\n const cyclePart = node.cycleCount > 0 ? `C${node.cycleCount}` : '';\n const dur = formatDuration(node.createdAt, node.completedAt);\n const agopart =\n node.status === 'completed' && node.completedAt ? formatTimeAgo(node.completedAt) : '';\n const meta = [cyclePart, dur, agopart].filter(Boolean).join(' ');\n const displayText = node.name ?? node.task;\n const maxLabel = Math.max(8, maxWidth - meta.length - 4);\n return { icon, label: truncate(displayText, maxLabel), meta, color, dim };\n }\n case 'cycle': {\n const isRunning = !node.completedAt;\n const dur = isRunning ? 'running' : formatDuration(node.activeMs);\n const agents = `${node.agentCount} agent${node.agentCount !== 1 ? 's' : ''}`;\n const modeShort = abbreviateMode(node.mode);\n const mode = modeShort ? ` · ${modeShort}` : '';\n return {\n icon: isRunning ? '●' : '○',\n label: `C${node.cycleNumber}`,\n meta: `${dur} · ${agents}${mode}`,\n color: isRunning ? 'green' : 'gray',\n dim: !isRunning,\n };\n }\n case 'agent': {\n const icon = agentStatusIcon(node.status);\n const color = statusColor(node.status);\n const dur = formatDuration(node.activeMs);\n const durClr = durationColor(node.activeMs) || undefined;\n const dim = node.status === 'completed';\n const displayName = agentDisplayName({\n name: node.name,\n id: node.agentId,\n agentType: node.agentType,\n });\n\n const maxLabel = Math.max(8, maxWidth - dur.length - 4);\n return {\n icon,\n label: truncate(displayName, maxLabel),\n meta: dur,\n color,\n dim,\n metaColor: durClr,\n };\n }\n case 'report': {\n const badge = node.reportType === 'final' ? 'FINAL' : 'UPDATE';\n const time = formatTime(node.timestamp);\n return {\n icon: node.reportType === 'final' ? '◆' : '◇',\n label: `${badge} ${time}`,\n meta: '',\n color: node.reportType === 'final' ? 'cyan' : 'yellow',\n dim: false,\n };\n }\n case 'messages':\n return {\n icon: '✉',\n label: `Messages (${node.count})`,\n meta: '',\n color: 'yellow',\n dim: false,\n };\n case 'message': {\n const maxLabel = Math.max(8, maxWidth - 8);\n return {\n icon: '·',\n label: truncate(`${node.source}: ${node.summary}`, maxLabel),\n meta: formatTime(node.timestamp),\n color: 'gray',\n dim: true,\n };\n }\n case 'context':\n return {\n icon: '⊞',\n label: `Context (${node.fileCount})`,\n meta: '',\n color: 'white',\n dim: node.fileCount === 0,\n };\n case 'context-file': {\n const maxLabel = Math.max(8, maxWidth - 4);\n return {\n icon: '·',\n label: truncate(node.label, maxLabel),\n meta: '',\n color: 'gray',\n dim: false,\n };\n }\n }\n}\n\n// ─── Tree panel renderer ──────────────────────────────────────────────────────\n\nexport function renderTreePanel(\n buf: FrameBuffer,\n rect: Rect,\n nodes: TreeNode[],\n cursorIndex: number,\n focused: boolean,\n): void {\n const { x, y, w, h } = rect;\n\n // 1. Border — yellow when focused\n drawBorder(buf, x, y, w, h, focused ? 'yellow' : 'gray');\n\n // 2. Inner dimensions\n const innerX = x + 2;\n const innerW = w - 4;\n const innerY = y + 1;\n const innerH = h - 2;\n\n if (innerW <= 0 || innerH <= 0) return;\n\n // 3. Empty state\n if (nodes.length === 0) {\n writeClipped(buf, innerX, innerY, '\\x1b[1m Sessions \\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 1, '\\x1b[2mNo sessions found.\\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 2, '\\x1b[2mPress [n] to create one.\\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 3, '\\x1b[2mPress [?] for all keybindings.\\x1b[0m', innerW);\n return;\n }\n\n // 4. Scroll logic\n const maxVisible = Math.max(1, innerH);\n const halfVisible = Math.floor(maxVisible / 2);\n const scrollOffset = Math.max(\n 0,\n Math.min(cursorIndex - halfVisible, nodes.length - maxVisible),\n );\n\n // 5. Scroll indicator adjustments\n const hasTopIndicator = scrollOffset > 0;\n const hasBottomIndicator = scrollOffset + maxVisible < nodes.length;\n\n let rowStart = innerY;\n let availRows = maxVisible;\n\n if (hasTopIndicator) {\n const topMore = scrollOffset;\n writeClipped(buf, innerX, rowStart, `\\x1b[2m↑ ${topMore} more\\x1b[0m`, innerW);\n rowStart++;\n availRows--;\n }\n\n if (hasBottomIndicator) {\n availRows--;\n }\n\n // 6. Render visible nodes\n const visible = nodes.slice(scrollOffset, scrollOffset + availRows + (hasBottomIndicator ? 1 : 0));\n const renderCount = Math.min(visible.length, availRows);\n\n for (let i = 0; i < renderCount; i++) {\n const node = visible[i]!;\n const realIdx = scrollOffset + i;\n const isSelected = realIdx === cursorIndex;\n const prefix = node.prefix ?? renderTreePrefix(node, nodes, realIdx);\n const contentWidth = innerW;\n const { icon, label, meta, color, dim, metaColor, suffix, suffixColor } = renderNodeContent(\n node,\n contentWidth - prefix.length,\n );\n\n // Build ANSI string\n let content = '';\n\n // icon with color\n if (icon) {\n if (dim) content += `\\x1b[2;${colorToSGR(color)}m${icon}\\x1b[0m `;\n else content += `\\x1b[${colorToSGR(color)}m${icon}\\x1b[0m `;\n }\n\n // label\n if (dim) content += `\\x1b[2m${label}\\x1b[0m`;\n else content += label;\n\n // meta\n if (meta) {\n if (metaColor) content += ` \\x1b[${colorToSGR(metaColor)}m${meta}\\x1b[0m`;\n else content += ` \\x1b[2m${meta}\\x1b[0m`;\n }\n\n // suffix\n if (suffix && suffixColor) {\n content += ` \\x1b[${colorToSGR(suffixColor)}m${suffix}\\x1b[0m`;\n }\n\n let line = prefix;\n if (isSelected) {\n const bold = '\\x1b[1m';\n const inverse = focused ? '\\x1b[7m' : '';\n line += `${inverse}${bold}${content}\\x1b[0m`;\n } else {\n line += content;\n }\n\n writeClipped(buf, innerX, rowStart + i, line, innerW);\n }\n\n // 7. Bottom scroll indicator\n if (hasBottomIndicator) {\n const bottomMore = nodes.length - scrollOffset - maxVisible;\n const bottomRow = rowStart + availRows;\n writeClipped(buf, innerX, bottomRow, `\\x1b[2m↓ ${bottomMore} more\\x1b[0m`, innerW);\n }\n}\n","import {\n buildPanelRows,\n buildEmptyPanelRows,\n type Rect,\n} from '../render.js';\nimport type { AppState, CycleLog } from '../state.js';\nimport type {\n TreeNode,\n CycleTreeNode,\n AgentTreeNode,\n ReportTreeNode,\n MessageTreeNode,\n ContextFileTreeNode,\n} from '../types/tree.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\nimport { computeActiveTimeMs } from '../../shared/utils.js';\nimport type { ReportBlock } from '../lib/reports.js';\nimport {\n statusColor,\n formatDuration,\n formatTime,\n truncate,\n wrapText,\n stripFrontmatter,\n cleanMarkdown,\n seg,\n singleLine,\n agentDisplayName,\n reportBadge,\n agentStatusIcon,\n agentTypeColor,\n durationColor,\n modeColor,\n messageSourceLabel,\n messageSourceColor,\n extractFirstSentence,\n divider,\n abbreviateMode,\n type DetailLine,\n} from '../lib/format.js';\n\n// ---------------------------------------------------------------------------\n// Public interface\n// ---------------------------------------------------------------------------\n\nexport interface DetailContext {\n nodes: TreeNode[];\n session: Session | null;\n agents: Agent[];\n reportBlocks: ReportBlock[];\n detailReportBlocks: ReportBlock[];\n contextFileContent: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// PlanLine (copied from PlanView.tsx — no React dependency)\n// ---------------------------------------------------------------------------\n\ninterface PlanLine {\n text: string;\n bold?: boolean;\n dim?: boolean;\n color?: string;\n}\n\nfunction buildPlanLines(content: string, maxLines: number, width: number): PlanLine[] {\n const clean = stripFrontmatter(content);\n if (!clean.trim()) return [];\n\n const contentWidth = width - 4;\n const lines: PlanLine[] = [];\n const rawLines = clean.split('\\n');\n\n for (const rawLine of rawLines) {\n if (lines.length >= maxLines) break;\n\n const trimmed = rawLine.trim();\n\n // Skip frontmatter artifacts\n if (trimmed === '---') continue;\n\n // Headers — bold, with level-based indentation\n const headerMatch = rawLine.match(/^(#{1,6})\\s+(.+)/);\n if (headerMatch) {\n const level = headerMatch[1]!.length;\n const headerText = cleanMarkdown(headerMatch[2]!);\n const indent = ' '.repeat(Math.max(0, level - 1));\n if (lines.length > 0) lines.push({ text: ' ' });\n lines.push({\n text: ` ${indent}${headerText}`,\n bold: true,\n color: level <= 2 ? 'white' : undefined,\n });\n continue;\n }\n\n // Empty lines — pass through (but collapse multiples)\n if (!trimmed) {\n if (lines.length > 0 && lines[lines.length - 1]!.text !== '') {\n lines.push({ text: ' ' });\n }\n continue;\n }\n\n // Numbered list items\n const listMatch = trimmed.match(/^(\\d+)[.)]\\s+(.+)/);\n if (listMatch) {\n const cleaned = `${listMatch[1]}. ${cleanMarkdown(listMatch[2]!)}`;\n const wrapped = wrapText(cleaned, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n continue;\n }\n\n // Checkbox items — must come before bullet match\n const checkboxMatch = trimmed.match(/^- \\[( |x|X)\\] (.+)/);\n if (checkboxMatch) {\n const checked = checkboxMatch[1] !== ' ';\n const checkboxText = cleanMarkdown(checkboxMatch[2]!);\n const icon = checked ? '☑' : '☐';\n const wrapped = wrapText(`${icon} ${checkboxText}`, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true, color: checked ? 'green' : undefined });\n }\n continue;\n }\n\n // Bullet items\n const bulletMatch = trimmed.match(/^[-*+]\\s+(.+)/);\n if (bulletMatch) {\n const cleaned = `· ${cleanMarkdown(bulletMatch[1]!)}`;\n const wrapped = wrapText(cleaned, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n continue;\n }\n\n // Regular content — clean and wrap\n const cleaned = cleanMarkdown(trimmed);\n const wrapped = wrapText(cleaned, contentWidth - 4);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n }\n\n // Truncation indicator\n const totalContentLines = rawLines.filter((l) => l.trim()).length;\n if (lines.length >= maxLines && totalContentLines > maxLines) {\n lines[lines.length - 1] = { text: ' … [p] open in editor', dim: true };\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildSessionLines (ported from SessionDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildSessionLines(\n session: Session,\n planContent: string,\n goalContent: string | undefined,\n width: number,\n paneAlive: boolean,\n strategyContent: string = '',\n): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const agents = session.agents;\n const cycles = session.orchestratorCycles;\n const messages = session.messages;\n const isDead = session.status === 'active' && !paneAlive;\n // Goal text\n const goalText = goalContent\n ? cleanMarkdown(stripFrontmatter(goalContent).trim())\n : session.task;\n goalText\n .split('\\n')\n .flatMap((l) => wrapText(l, contentWidth - 2))\n .forEach((line, i) => {\n lines.push(singleLine(`${i === 0 ? ' ' : ' '}${line}`, { bold: true }));\n });\n\n // Status bar\n const lastCycle = cycles.length > 0 ? cycles[cycles.length - 1]! : null;\n const cycleNum = lastCycle !== null ? lastCycle.cycle : 0;\n const mode = lastCycle !== null && lastCycle.mode !== undefined ? lastCycle.mode : '';\n const runningAgents = agents.filter((a) => a.status === 'running').length;\n const completedAgents = agents.filter((a) => a.status === 'completed').length;\n const elapsed = formatDuration(session.createdAt, session.completedAt);\n const activeMs = computeActiveTimeMs(session);\n const activeTime = formatDuration(activeMs);\n const modeLabelColor = modeColor(mode);\n lines.push([\n seg(' '),\n seg(isDead ? '✕ dead' : session.status, {\n color: statusColor(isDead ? 'crashed' : session.status),\n }),\n seg(` · cycle ${cycleNum}`, { dim: true }),\n ...(mode ? [seg(' (', { dim: true }), seg(mode, { color: modeLabelColor }), seg(')', { dim: true })] : []),\n seg(` · ${elapsed} · `, { dim: true }),\n seg(`${runningAgents} running`, { color: 'green' }),\n seg(' · ', { dim: true }),\n seg(`${completedAgents} done`, { color: 'cyan' }),\n seg(` · ${activeTime} active`, { dim: true }),\n ]);\n\n // Dead session warning\n if (isDead) {\n lines.push([\n seg(' '),\n seg(' ✕ DEAD ', { color: 'red', bold: true }),\n seg(' tmux window closed — [w] reopen [R] resume', { color: 'red' }),\n ]);\n }\n\n // Plan / Strategy section\n lines.push(singleLine(' '));\n if (strategyContent) {\n lines.push([seg(' ▎ ◈ STRATEGY', { color: 'yellow', bold: true })]);\n const stratLines = buildPlanLines(strategyContent, 99999, width);\n if (stratLines.length === 0) {\n lines.push(singleLine(' (empty)', { dim: true, italic: true }));\n } else {\n for (const pl of stratLines) {\n lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));\n }\n }\n } else {\n lines.push([seg(' ▎ ◈ PLAN', { color: 'yellow', bold: true })]);\n const planLines = buildPlanLines(planContent, 99999, width);\n if (planLines.length === 0) {\n lines.push(singleLine(' orchestrator will create one', { dim: true, italic: true }));\n } else {\n for (const pl of planLines) {\n lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));\n }\n }\n }\n\n // Completion report\n if (session.status === 'completed' && session.completionReport) {\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ✓ COMPLETION', { color: 'cyan', bold: true })]);\n wrapText(session.completionReport, contentWidth - 6).forEach((l) => {\n lines.push(singleLine(` ${l}`, { dim: true }));\n });\n }\n\n // Cycles section — newest first\n lines.push(singleLine(' '));\n lines.push([\n seg(' ▎ ⟳ CYCLES', { color: 'blue', bold: true }),\n seg(` (${cycles.length})`, { dim: true }),\n ]);\n\n const pushMsgLine = (msg: (typeof messages)[number], connector: '└▸' | '├▸') => {\n const time = formatTime(msg.timestamp);\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const label = messageSourceLabel(msg.source.type, agentId);\n const labelColor = messageSourceColor(msg.source.type);\n const maxContent = Math.max(10, contentWidth - label.length - 18);\n lines.push([\n seg(` ${connector} `, { dim: true }),\n seg(`[${time}] `, { dim: true }),\n seg(`${label} `, { color: labelColor, bold: true }),\n seg(truncate(msg.summary.length > 0 ? msg.summary : msg.content, maxContent), { dim: true }),\n ]);\n };\n\n if (cycles.length === 0) {\n lines.push(singleLine(' waiting for orchestrator…', { dim: true, italic: true }));\n } else {\n const sortedMsgs = [...messages].sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n );\n const reversedCycles = [...cycles].reverse();\n\n const shortType = (t: string) => {\n const colonIdx = t.indexOf(':');\n return colonIdx >= 0 ? t.slice(colonIdx + 1) : t;\n };\n\n for (let i = 0; i < reversedCycles.length; i++) {\n const cycle = reversedCycles[i]!;\n const olderCycle = reversedCycles[i + 1];\n\n const isRunning = !cycle.completedAt;\n const isNewest = i === 0;\n const isSecond = i === 1;\n const dot = isRunning ? '●' : '○';\n const dotColor = isRunning ? 'green' : isNewest ? 'white' : 'gray';\n const rowDim = !isRunning && !isNewest && !isSecond;\n const duration = isRunning ? 'running' : formatDuration(cycle.activeMs);\n const n = cycle.agentsSpawned.length;\n const startTime = formatTime(cycle.timestamp);\n\n const modeLabel = abbreviateMode(cycle.mode);\n const cycModeColor = modeColor(cycle.mode);\n\n const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n\n const cyclePad = `C${cycle.cycle}`.padEnd(4);\n const durPad = (isRunning ? 'running' : duration).padEnd(9);\n\n const headerRow: DetailLine = [\n seg(` ${dot} `, { color: dotColor }),\n seg(cyclePad, { bold: isRunning || isNewest, dim: rowDim }),\n ...(isRunning\n ? [seg(durPad, { color: 'green', bold: true })]\n : [seg(durPad, { dim: rowDim })]),\n seg(startTime, { dim: true }),\n ...(modeLabel ? [seg(' ', {}), seg(modeLabel, { color: cycModeColor })] : []),\n ];\n lines.push(headerRow);\n\n if (cycleAgents.length > 0) {\n const typeGroups = new Map<string, number>();\n for (const a of cycleAgents) {\n const t = shortType(a.agentType !== '' ? a.agentType : a.name !== '' ? a.name : a.id);\n const prev = typeGroups.get(t);\n typeGroups.set(t, prev !== undefined ? prev + 1 : 1);\n }\n const agentNames = [...typeGroups.entries()]\n .map(([t, count]) => count > 1 ? `${count}× ${t}` : t)\n .join(', ');\n lines.push([\n seg(' ', {}),\n seg(truncate(agentNames, contentWidth - 6), { dim: rowDim }),\n ]);\n } else if (n > 0) {\n lines.push([\n seg(' ', {}),\n seg(`${n} agent${n !== 1 ? 's' : ''}`, { dim: rowDim }),\n ]);\n }\n\n const cycleTime = new Date(cycle.timestamp).getTime();\n const olderCycleTime = olderCycle ? new Date(olderCycle.timestamp).getTime() : 0;\n const cycleMsgs = sortedMsgs.filter((m) => {\n const t = new Date(m.timestamp).getTime();\n return t < cycleTime && t >= olderCycleTime;\n });\n cycleMsgs.forEach((msg, mi) => {\n pushMsgLine(msg, mi < cycleMsgs.length - 1 ? '├▸' : '└▸');\n });\n }\n\n // Messages predating all cycles\n const firstCycleTime = new Date(reversedCycles[reversedCycles.length - 1]!.timestamp).getTime();\n const preMsgs = sortedMsgs.filter((m) => new Date(m.timestamp).getTime() < firstCycleTime);\n preMsgs.forEach((msg, mi) => {\n pushMsgLine(msg, mi < preMsgs.length - 1 ? '├▸' : '└▸');\n });\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildCycleLines (ported from CycleDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildCycleLines(cycle: OrchestratorCycle, agents: Agent[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const isRunning = !cycle.completedAt;\n const dur = isRunning ? 'running' : formatDuration(cycle.activeMs);\n const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n\n lines.push(singleLine(` Cycle ${cycle.cycle}`, { bold: true }));\n lines.push([\n seg(' '),\n seg(isRunning ? 'running' : 'completed', { color: isRunning ? 'green' : 'gray' }),\n seg(` · ${dur} · ${cycleAgents.length} agent${cycleAgents.length !== 1 ? 's' : ''}`, { dim: true }),\n ...(cycle.mode\n ? [seg(' · ', { dim: true }), seg(cycle.mode, { color: modeColor(cycle.mode) })]\n : []),\n ]);\n lines.push(singleLine(\n ` ${formatTime(cycle.timestamp)}${cycle.completedAt ? ` → ${formatTime(cycle.completedAt)}` : ''}`,\n { dim: true },\n ));\n if (cycle.claudeSessionId) {\n lines.push(singleLine(` Session: ${cycle.claudeSessionId}`, { dim: true }));\n }\n\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ⊞ AGENTS', { color: 'green', bold: true })]);\n\n if (cycleAgents.length === 0) {\n lines.push(singleLine(' orchestrator spawning agents…', { dim: true, italic: true }));\n } else {\n for (const agent of cycleAgents) {\n const nameLabel = agentDisplayName(agent);\n const instrPreview = agent.instruction.split('\\n')[0]!;\n const latestReport = agent.reports.length > 0 ? agent.reports[agent.reports.length - 1]! : null;\n const reportSummary = latestReport !== null && agent.status === 'completed'\n ? extractFirstSentence(latestReport.summary, contentWidth - 14)\n : null;\n const agentDur = formatDuration(agent.activeMs);\n const durClrRaw = durationColor(agent.activeMs);\n const durClr = durClrRaw !== '' ? durClrRaw : undefined;\n const typeClrRaw = agentTypeColor(agent.agentType);\n const typeClr = typeClrRaw !== undefined ? typeClrRaw : undefined;\n\n lines.push([\n seg(' '),\n seg(agentStatusIcon(agent.status), { color: statusColor(agent.status) }),\n seg(` ${agent.id}`, { bold: true }),\n seg(` ${truncate(nameLabel, contentWidth - 30)}`, {\n color: typeClr,\n dim: typeClr === undefined,\n }),\n seg(` · ${agent.status} · `, { dim: true }),\n seg(agentDur, { color: durClr, dim: !durClr }),\n ]);\n\n if (instrPreview) {\n lines.push(singleLine(` ${truncate(instrPreview, contentWidth - 10)}`, { dim: true }));\n }\n\n if (reportSummary) {\n lines.push([\n seg(' '),\n seg('↳', { color: 'cyan' }),\n seg(` ${reportSummary}`, { dim: true }),\n ]);\n }\n }\n }\n\n if (cycle.nextPrompt) {\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ▷ NEXT PROMPT', { color: 'yellow', bold: true })]);\n for (const wl of wrapText(cycle.nextPrompt, contentWidth - 6)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildAgentLines (ported from AgentDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildAgentLines(agent: Agent, reportBlocks: ReportBlock[] | undefined, width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const dur = formatDuration(agent.activeMs);\n const icon = agentStatusIcon(agent.status);\n const color = statusColor(agent.status);\n const nameLabel = agentDisplayName(agent);\n lines.push([\n seg(' '),\n seg(icon, { color }),\n seg(` ${agent.id} · ${nameLabel}`, { bold: true }),\n ]);\n\n lines.push([\n seg(' '),\n seg(agent.status, { color }),\n seg(` · ${dur} · ${agent.agentType}`, { dim: true }),\n ]);\n\n if (agent.killedReason) {\n lines.push(singleLine(` ⚠ ${agent.killedReason}`, { color: 'red' }));\n }\n\n lines.push(singleLine(' '));\n lines.push(singleLine(' ▎ ▷ INSTRUCTION', { color: 'white', bold: true }));\n for (const wl of wrapText(agent.instruction, contentWidth - 6)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n\n if (agent.reports.length > 0) {\n const hasResolved = reportBlocks && reportBlocks.length > 0;\n lines.push(singleLine(' '));\n lines.push([seg(` ▎ ◇ REPORTS (${agent.reports.length})`, { color: 'cyan', bold: true })]);\n\n if (hasResolved) {\n for (let i = 0; i < reportBlocks.length; i++) {\n const block = reportBlocks[i]!;\n const { label: badge, color: badgeColor } = reportBadge(block.type);\n\n if (i > 0) lines.push(singleLine(' '));\n lines.push([\n seg(' '),\n seg(badge, { color: badgeColor, bold: block.type === 'final' }),\n seg(` ${formatTime(block.timestamp)}`, { dim: true }),\n ]);\n for (const wl of wrapText(block.content.trim(), contentWidth - 10)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n }\n } else {\n for (const report of agent.reports) {\n const { label: badge, color: badgeColor } = reportBadge(report.type);\n lines.push([\n seg(' '),\n seg(badge, { color: badgeColor, bold: report.type === 'final' }),\n seg(` ${formatTime(report.timestamp)} ${report.summary.split('\\n')[0]}`, { dim: true }),\n ]);\n }\n }\n }\n\n lines.push(singleLine(' '));\n lines.push(singleLine(' ▎ ◦ META', { color: 'gray', bold: true }));\n lines.push(singleLine(` Spawned: ${formatTime(agent.spawnedAt)}`, { dim: true }));\n if (agent.completedAt) {\n lines.push(singleLine(` Completed: ${formatTime(agent.completedAt)}`, { dim: true }));\n }\n if (agent.claudeSessionId) {\n lines.push(singleLine(` Session: ${agent.claudeSessionId}`, { dim: true }));\n }\n if (agent.paneId) {\n lines.push(singleLine(` Pane: ${agent.paneId}`, { dim: true }));\n }\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildReportViewLines (ported from ReportView.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildReportViewLines(agent: Agent, reportBlocks: ReportBlock[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 6;\n const dur = formatDuration(agent.activeMs);\n const icon = agentStatusIcon(agent.status);\n const color = statusColor(agent.status);\n const totalReports = agent.reports.length;\n const nameLabel = agentDisplayName(agent);\n\n lines.push([\n seg(' '),\n seg(icon, { color }),\n seg(' '),\n seg(agent.id, { bold: true }),\n seg(' ', { dim: true }),\n seg('·', { dim: true }),\n seg(' '),\n seg(nameLabel, { bold: true }),\n ]);\n\n lines.push(singleLine(\n ` ${agent.status} · ${dur} · ${agent.agentType} · ${totalReports} report${totalReports !== 1 ? 's' : ''}`,\n { dim: true },\n ));\n\n lines.push(singleLine(' ' + divider(contentWidth - 2), { dim: true }));\n\n if (reportBlocks.length === 0) {\n lines.push(singleLine(''));\n lines.push(singleLine(' No reports submitted yet.', { dim: true }));\n lines.push(singleLine(''));\n return lines;\n }\n\n for (let i = 0; i < reportBlocks.length; i++) {\n const report = reportBlocks[i]!;\n const time = formatTime(report.timestamp);\n\n if (i > 0) {\n lines.push(singleLine(''));\n lines.push(singleLine(` ${divider(contentWidth - 2, '·')}`, { dim: true }));\n lines.push(singleLine(''));\n }\n\n const { label: badge, color: badgeColor } = reportBadge(report.type);\n lines.push([\n seg(` ${badge}`, { color: badgeColor, bold: report.type === 'final' }),\n seg(` ${time}`, { color: badgeColor }),\n ]);\n\n lines.push(singleLine(''));\n\n const wrapped = wrapText(report.content.trim(), contentWidth - 4);\n for (const line of wrapped) {\n lines.push(singleLine(` ${line}`));\n }\n }\n\n lines.push(singleLine(''));\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildLogsLines (ported from LogsPanel.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildLogsLines(cycleLogs: CycleLog[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n\n if (cycleLogs.length === 0) {\n return lines;\n }\n\n const sorted = [...cycleLogs].sort((a, b) => b.cycle - a.cycle);\n\n for (const { cycle, content } of sorted) {\n lines.push([seg(` Cycle ${cycle}`, { color: 'blue', bold: true })]);\n\n const cleaned = cleanMarkdown(stripFrontmatter(content)).trim();\n if (cleaned) {\n for (const rawLine of cleaned.split('\\n')) {\n const wrapped = wrapText(rawLine, contentWidth - 2);\n for (const wl of wrapped) {\n lines.push([seg(` ${wl}`, { dim: true })]);\n }\n }\n }\n\n lines.push([seg(' ')]);\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Main entry points\n// ---------------------------------------------------------------------------\n\nexport function renderDetailRows(\n rect: Rect,\n state: AppState,\n detailCtx: DetailContext,\n): string[] {\n const { session, agents, reportBlocks, detailReportBlocks, contextFileContent } = detailCtx;\n const scrollOffset = state.detailScroll.offset;\n const focused = state.focusPane === 'detail';\n\n // Report detail mode — full panel\n if (state.mode === 'report-detail') {\n const reportAgent = agents.find((a) => a.id === state.targetAgentId);\n if (reportAgent) {\n const lines = buildReportViewLines(reportAgent, reportBlocks, rect.w);\n return buildPanelRows(rect, lines, scrollOffset, focused, 'cyan');\n }\n }\n\n // No cursor / no session → empty state\n const cursorNode: TreeNode | undefined = detailCtx.nodes[state.cursorIndex];\n if (!cursorNode || !session) {\n return buildEmptyPanelRows(rect, false, 'gray', '\\x1b[2mSelect a session to view details\\x1b[0m');\n }\n\n // Session data hasn't arrived yet (poll debounced during rapid scrolling)\n if (cursorNode.sessionId !== session.id) {\n return buildEmptyPanelRows(rect, false, 'gray');\n }\n\n // Compute cache key from all inputs that affect line building\n const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];\n const cacheKey = [\n cursorNode.id,\n cursorNode.type,\n state.mode,\n state.targetAgentId,\n rect.w,\n session.id,\n session.agents.length,\n session.orchestratorCycles.length,\n lastCycle?.completedAt ?? '',\n lastCycle?.agentsSpawned.length ?? 0,\n state.planContent.length,\n state.goalContent.length,\n state.strategyContent.length,\n state.paneAlive,\n detailReportBlocks.length,\n session.messages.length,\n state.contextFiles.length,\n contextFileContent?.length ?? -1,\n ].join(':');\n\n let lines: DetailLine[];\n let borderColor = 'gray';\n\n if (cacheKey === state.detailCacheKey && state.cachedDetailLines !== null) {\n lines = state.cachedDetailLines;\n } else {\n switch (cursorNode.type) {\n case 'session': {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n\n case 'cycle': {\n const cycleNode = cursorNode as CycleTreeNode;\n const cycle = session.orchestratorCycles.find((c) => c.cycle === cycleNode.cycleNumber);\n if (!cycle) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n } else {\n lines = buildCycleLines(cycle, session.agents, rect.w);\n }\n break;\n }\n\n case 'agent': {\n const agentNode = cursorNode as AgentTreeNode;\n const agent = agents.find((a) => a.id === agentNode.agentId);\n if (!agent) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n } else {\n lines = buildAgentLines(agent, detailReportBlocks, rect.w);\n }\n break;\n }\n\n case 'report': {\n const reportNode = cursorNode as ReportTreeNode;\n const agent = agents.find((a) => a.id === reportNode.agentId);\n if (!agent) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n const reportIdx = reportNode.reportIndex;\n const specificBlock = detailReportBlocks.find((_b, i) => {\n const originalIdx = agent.reports.length - 1 - i;\n return originalIdx === reportIdx;\n });\n if (specificBlock) {\n const { label: badge, color: badgeColor } = reportBadge(specificBlock.type);\n lines = [\n [seg(' '), seg(badge, { color: badgeColor }), seg(` ${agent.id} · ${agentDisplayName(agent)}`, { bold: true })],\n singleLine(` ${formatTime(specificBlock.timestamp)}`, { dim: true }),\n singleLine(' '),\n [seg(' ▎ CONTENT', { color: badgeColor, bold: true })],\n ...wrapText(specificBlock.content.trim(), rect.w - 8).map((l) => singleLine(` ${l}`)),\n ];\n borderColor = badgeColor;\n } else {\n lines = buildAgentLines(agent, detailReportBlocks, rect.w);\n }\n break;\n }\n\n case 'messages': {\n lines = [singleLine(` Messages (${session.messages.length})`, { bold: true })];\n if (session.messages.length === 0) {\n lines.push(singleLine(' No messages', { dim: true, italic: true }));\n } else {\n for (const msg of session.messages) {\n const time = formatTime(msg.timestamp);\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const label = messageSourceLabel(msg.source.type, agentId);\n const labelColor = messageSourceColor(msg.source.type);\n const maxContent = Math.max(10, rect.w - label.length - 20);\n lines.push([\n seg(` [${time}] `, { dim: true }),\n seg(`${label}: `, { color: labelColor, bold: true }),\n seg(wrapText(msg.summary.length > 0 ? msg.summary : msg.content, maxContent)[0]!, {}),\n ]);\n }\n }\n break;\n }\n\n case 'message': {\n const msgNode = cursorNode as MessageTreeNode;\n const msg = session.messages.find((m) => m.id === msgNode.messageId);\n lines = [singleLine(' Message', { bold: true })];\n if (msg) {\n lines.push(singleLine(` ${msgNode.source} · ${msgNode.timestamp}`, { dim: true }));\n for (const l of wrapText(msg.content, rect.w - 8)) {\n lines.push(singleLine(` ${l}`));\n }\n } else {\n lines.push(singleLine(' Message not found', { dim: true }));\n }\n break;\n }\n\n case 'context': {\n lines = [\n [seg(' '), seg('⊞', { color: 'white' }), seg(` Context (${state.contextFiles.length})`, { bold: true })],\n ];\n if (state.contextFiles.length === 0) {\n lines.push(singleLine(' No context files found.', { dim: true }));\n } else {\n for (const f of state.contextFiles) {\n lines.push(singleLine(` · ${f}`, { dim: true }));\n }\n }\n break;\n }\n\n case 'context-file': {\n const ctxFileNode = cursorNode as ContextFileTreeNode;\n lines = [\n [seg(' '), seg('⊞', { color: 'white' }), seg(` ${ctxFileNode.label}`, { bold: true })],\n singleLine(' '),\n ];\n if (contextFileContent == null) {\n lines.push(singleLine(' File not found or unreadable.', { dim: true }));\n } else {\n const wrapped = wrapText(stripFrontmatter(contextFileContent), rect.w - 8);\n if (wrapped.length === 0) {\n lines.push(singleLine(' (empty)', { dim: true }));\n } else {\n for (const l of wrapped) {\n lines.push(singleLine(` ${l}`));\n }\n }\n }\n borderColor = 'white';\n break;\n }\n\n default: {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n }\n\n state.cachedDetailLines = lines;\n state.detailCacheKey = cacheKey;\n }\n\n // Compute borderColor from node type (cheap, no need to cache)\n if (cursorNode.type === 'context-file') {\n borderColor = 'white';\n } else if (cursorNode.type === 'report') {\n const reportNode = cursorNode as ReportTreeNode;\n const agent = agents.find((a) => a.id === reportNode.agentId);\n if (agent) {\n const reportIdx = reportNode.reportIndex;\n const specificBlock = detailReportBlocks.find((_b, i) => {\n const originalIdx = agent.reports.length - 1 - i;\n return originalIdx === reportIdx;\n });\n if (specificBlock) borderColor = reportBadge(specificBlock.type).color;\n }\n }\n\n return buildPanelRows(rect, lines, scrollOffset, focused, borderColor, state.detailRenderedCache);\n}\n\nexport function renderLogsRows(\n rect: Rect,\n state: AppState,\n): string[] {\n const focused = state.focusPane === 'logs';\n const scrollOffset = state.logsScroll.offset;\n\n if (state.logsCycles.length === 0) {\n return buildEmptyPanelRows(rect, focused, 'gray', '\\x1b[2mNo logs\\x1b[0m');\n }\n\n const logsCacheKey = `${state.logsCycles.length}:${rect.w}:${state.logsCycles.map((c) => c.cycle).join(',')}`;\n let lines: DetailLine[];\n if (logsCacheKey === state.logsCacheKey && state.cachedLogsLines !== null) {\n lines = state.cachedLogsLines;\n } else {\n lines = buildLogsLines(state.logsCycles, rect.w);\n state.cachedLogsLines = lines;\n state.logsCacheKey = logsCacheKey;\n }\n\n return buildPanelRows(rect, lines, scrollOffset, focused, 'gray', state.logsRenderedCache);\n}\n","import { clipAnsi, colorToSGR, type Rect } from '../render.js';\nimport type { NvimBridge } from '../lib/nvim-bridge.js';\n\n/**\n * Render the neovim detail panel with a status header as self-contained row strings.\n * Produces exactly rect.h strings, each rect.w display columns wide.\n * Compatible with the row-based panel composition in app.ts.\n */\nexport function renderNvimDetailRows(\n rect: Rect,\n bridge: NvimBridge,\n focused: boolean,\n editable: boolean,\n statusRows: string[],\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n\n // Border styling — cyan when focused to distinguish nvim mode, gray otherwise\n const borderColor = focused ? 'cyan' : 'gray';\n const sgr = `\\x1b[${colorToSGR(borderColor)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4; // border + padding on each side\n\n // Top border — insert NVIM/EDIT badge when focused\n if (focused) {\n const badgeText = editable ? ' EDIT ' : ' NVIM ';\n const badgeLen = badgeText.length;\n const dashesLeft = 2;\n const dashesRight = Math.max(0, w - 2 - dashesLeft - badgeLen);\n rows[0] =\n sgr + '╭' + '─'.repeat(dashesLeft) + reset +\n `\\x1b[${colorToSGR('cyan')};1m` + badgeText + reset +\n sgr + '─'.repeat(dashesRight) + '╮' + reset;\n } else {\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n }\n\n // Bottom border\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n\n // Border pieces for interior rows\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const blankInner = ' '.repeat(innerW);\n const emptyRow = borderL + blankInner + borderR;\n\n // Pre-fill interior rows with empty content\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (innerW <= 0 || h <= 2) return rows;\n\n // Render status rows (ANSI, not nvim)\n const statusCount = statusRows.length;\n for (let i = 0; i < statusCount && i < h - 3; i++) {\n const clipped = clipAnsi(statusRows[i]!, innerW);\n rows[1 + i] = borderL + clipped + borderR;\n }\n\n // Separator between status and nvim content\n const separatorRow = 1 + statusCount;\n if (separatorRow < h - 1) {\n rows[separatorRow] = sgr + '├' + '─'.repeat(w - 2) + '┤' + reset;\n }\n\n // Get neovim screen rows and fill the remaining interior\n const nvimStartRow = separatorRow + 1;\n const nvimRows = bridge.getRows();\n for (let i = nvimStartRow; i < h - 1; i++) {\n const nvimIdx = i - nvimStartRow;\n const nvimRow = nvimRows[nvimIdx];\n if (nvimRow !== undefined) {\n const clipped = clipAnsi(nvimRow, innerW);\n rows[i] = borderL + clipped + borderR;\n }\n }\n\n return rows;\n}\n","import { writeClipped, type FrameBuffer } from '../render.js';\nimport { ansiBold, ansiDim } from '../lib/format.js';\nimport type { AppState } from '../state.js';\nimport { INPUT_MODES, PROMPTS } from '../state.js';\nimport type { TreeNodeType } from '../types/tree.js';\n\n// ─── Notification Row ─────────────────────────────────────────────────────────\n\nexport function renderNotificationRow(\n buf: FrameBuffer,\n y: number,\n notification: string | null,\n error: string | null,\n): void {\n if (notification !== null) {\n const icon = /error|failed/i.test(notification)\n ? '✕'\n : /success|created|killed|sent|copied|deleted/i.test(notification)\n ? '✓'\n : 'ℹ';\n const content = `\\x1b[1;33m${icon} ${notification}\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n } else if (error !== null) {\n const content = `\\x1b[31m⚠ ${error}\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n }\n}\n\n// ─── Input Bar ────────────────────────────────────────────────────────────────\n\nexport function renderInputBar(\n buf: FrameBuffer,\n y: number,\n state: AppState,\n): void {\n const { mode, inputText, inputCursorPos } = state;\n\n if (mode === 'navigate') {\n const content = `\\x1b[2mPress [m] to message orchestrator, [n] for new session\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n return;\n }\n\n if (\n mode === 'report-detail' ||\n mode === 'leader' ||\n mode === 'copy-menu' ||\n mode === 'help' ||\n !INPUT_MODES.has(mode)\n ) {\n return;\n }\n\n const prompt = PROMPTS[mode] ?? mode;\n const cursorChar = inputCursorPos < inputText.length ? inputText[inputCursorPos]! : ' ';\n const before = inputText.slice(0, inputCursorPos);\n const after = inputText.slice(inputCursorPos + 1);\n\n const content =\n `\\x1b[33m${prompt} > \\x1b[0m` +\n before +\n `\\x1b[7m${cursorChar}\\x1b[0m` +\n after +\n `\\x1b[2m (enter to send, esc to cancel)\\x1b[0m`;\n\n writeClipped(buf, 1, y, content, buf.width - 2);\n}\n\n// ─── Status Line ──────────────────────────────────────────────────────────────\n\nconst B = ansiBold;\nconst D = ansiDim;\nconst SEP = D('│ ');\n\nexport function renderStatusLine(\n buf: FrameBuffer,\n y: number,\n state: AppState,\n cursorNodeType: TreeNodeType | undefined,\n): void {\n const { mode, focusPane } = state;\n\n if (mode === 'report-detail') return;\n\n let content: string;\n\n if (mode === 'leader') {\n content = `\\x1b[1;35mLEADER\\x1b[0m` + D(' press a command key or [esc] to cancel');\n } else if (mode === 'copy-menu') {\n content = `\\x1b[1;36mCOPY\\x1b[0m` + D(' [p] path [C] context [l] logs [s] session ID [esc] cancel');\n } else if (mode === 'help') {\n content = `\\x1b[1;33mHELP\\x1b[0m` + D(' [esc] or [?] to dismiss');\n } else if (mode === 'delete-confirm') {\n content = `\\x1b[1;31mDELETE\\x1b[0m` + D(\" type 'yes' to confirm, [esc] to cancel\");\n } else if (mode === 'spawn-agent') {\n content = `\\x1b[1;32mSPAWN\\x1b[0m` + D(' enter agent instruction, [esc] to cancel');\n } else if (mode === 'search') {\n content = `\\x1b[1;34mSEARCH\\x1b[0m` + D(' type to filter, enter to apply, [esc] to cancel');\n } else if (mode === 'message-agent') {\n content = `\\x1b[1;36mMESSAGE\\x1b[0m` + D(' enter message for agent, [esc] to cancel');\n } else if (mode === 'shell-command') {\n content = `\\x1b[1;35mSHELL\\x1b[0m` + D(' enter command, [esc] to cancel');\n } else if (mode !== 'navigate') {\n content = D('[enter] send [esc] cancel');\n } else if (focusPane === 'logs' || focusPane === 'detail') {\n content =\n B('[jk/↑↓]') + D(' scroll ') +\n B('[h/←/tab]') + D(' back ') +\n B('[t]') + D('oggle view ') +\n SEP +\n B('[m]') + D('sg ') +\n B('[g]') + D('oal ') +\n B('[n]') + D('ew ') +\n B('[p]') + D('lan ') +\n B('[w]') + D('indow ') +\n B('[R]') + D('esume ') +\n B('[q]') + D('uit');\n } else {\n // tree focused\n let contextFilePart = '';\n if (cursorNodeType === 'context-file') {\n contextFilePart = B('[e]') + D('dit ') + B('[⏎]') + D(' open ');\n }\n content =\n B('[hjkl]') + D(' navigate ') +\n SEP +\n contextFilePart +\n B('[space]') + D(' leader ') +\n B('[tab]') + D(' detail ') +\n B('[t]') + D('oggle view ') +\n SEP +\n B('[m]') + D('sg ') +\n B('[n]') + D('ew ') +\n B('[R]') + D('esume ') +\n B('[q]') + D('uit');\n }\n\n writeClipped(buf, 1, y, content, buf.width - 2);\n}\n","import { drawBorder, writeClipped, type FrameBuffer } from '../render.js';\nimport { ansiColor, ansiDim } from '../lib/format.js';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst LEADER_WIDTH = 26;\nconst LEADER_HEIGHT = 19; // 17 content lines + 2 border lines\nconst COPY_HEIGHT = 9; // 7 content lines + 2 border lines\nconst HELP_WIDTH = 62;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction helpRow(left: string, right: string, innerWidth: number): string {\n const col = Math.floor(innerWidth / 2);\n return (left.padEnd(col) + right).padEnd(innerWidth);\n}\n\n// ─── Overlays ─────────────────────────────────────────────────────────────────\n\nexport function renderLeaderOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const x = cols - LEADER_WIDTH - 1;\n const y = rows - LEADER_HEIGHT - 2;\n const innerWidth = LEADER_WIDTH - 2;\n\n drawBorder(buf, x, y, LEADER_WIDTH, LEADER_HEIGHT, 'magenta');\n\n const lines: string[] = [\n ansiColor(' LEADER'.padEnd(innerWidth), 'magenta', true),\n ' '.padEnd(innerWidth),\n ' y copy menu'.padEnd(innerWidth),\n ' d delete session'.padEnd(innerWidth),\n ' l daemon logs'.padEnd(innerWidth),\n ' o open session dir'.padEnd(innerWidth),\n ' a spawn agent'.padEnd(innerWidth),\n ' m message agent'.padEnd(innerWidth),\n ' / search'.padEnd(innerWidth),\n ' ! shell command'.padEnd(innerWidth),\n ' j jump to pane'.padEnd(innerWidth),\n ' k kill session/agent'.padEnd(innerWidth),\n ' q quit'.padEnd(innerWidth),\n ' ? help'.padEnd(innerWidth),\n ' 1-9 jump to session'.padEnd(innerWidth),\n ' '.padEnd(innerWidth),\n ansiDim(' esc dismiss'.padEnd(innerWidth)),\n ];\n\n for (let i = 0; i < lines.length; i++) {\n writeClipped(buf, x + 1, y + 1 + i, lines[i]!, innerWidth);\n }\n}\n\nexport function renderCopyMenuOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const x = cols - LEADER_WIDTH - 1;\n const y = rows - COPY_HEIGHT - 2;\n const innerWidth = LEADER_WIDTH - 2;\n\n drawBorder(buf, x, y, LEADER_WIDTH, COPY_HEIGHT, 'cyan');\n\n const lines: string[] = [\n ansiColor(' COPY'.padEnd(innerWidth), 'cyan', true),\n ' '.padEnd(innerWidth),\n ' p session path'.padEnd(innerWidth),\n ' C LLM context'.padEnd(innerWidth),\n ' l logs content'.padEnd(innerWidth),\n ' s session ID'.padEnd(innerWidth),\n ansiDim(' esc cancel'.padEnd(innerWidth)),\n ];\n\n for (let i = 0; i < lines.length; i++) {\n writeClipped(buf, x + 1, y + 1 + i, lines[i]!, innerWidth);\n }\n}\n\nexport function renderHelpOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const innerWidth = HELP_WIDTH - 2;\n const x = Math.max(0, Math.floor((cols - HELP_WIDTH) / 2));\n\n const contentLines: string[] = [\n helpRow(' hjkl/↑↓←→ navigate', ' tab switch pane', innerWidth),\n helpRow(' enter expand/open', ' t toggle logs', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' n new session', ' m message orch.', innerWidth),\n helpRow(' R resume session', ' C continue session', innerWidth),\n helpRow(' b rollback cycle', ' x restart agent', innerWidth),\n helpRow(' r re-run agent', ' g edit goal', innerWidth),\n helpRow(' p open roadmap', ' s toggle strategy', innerWidth),\n helpRow(' S edit strategy', ' w go to window', innerWidth),\n helpRow(' o resume claude session', ' c claude companion', innerWidth),\n helpRow(' q quit', '', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' space → y copy submenu', ' space → d delete session', innerWidth),\n helpRow(' space → j jump to pane', ' space → k kill', innerWidth),\n helpRow(' space → q quit', ' space → o open dir', innerWidth),\n helpRow(' space → l tail logs', ' space → / search', innerWidth),\n helpRow(' space → a spawn agent', ' space → m msg agent', innerWidth),\n helpRow(' space → ? help', ' space → 1-9 jump', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' y → p session path', ' y → C LLM context', innerWidth),\n helpRow(' y → l logs content', ' y → s session ID', innerWidth),\n ];\n\n // title + blank + contentLines + blank = contentLines.length + 3 inner rows, + 2 border\n const height = Math.min(contentLines.length + 4, rows - 2);\n const y = Math.max(0, Math.floor((rows - height) / 2));\n\n drawBorder(buf, x, y, HELP_WIDTH, height, 'yellow');\n\n // Title row\n writeClipped(buf, x + 1, y + 1, ansiColor(' KEYBINDINGS (esc or ? to close)'.padEnd(innerWidth), 'yellow', true), innerWidth);\n // Blank row after title\n writeClipped(buf, x + 1, y + 2, ' '.padEnd(innerWidth), innerWidth);\n\n // Content rows (clamp to available height: height - 4 rows for title+blank+trailing_blank+borders)\n const availableContentRows = height - 4;\n for (let i = 0; i < Math.min(contentLines.length, availableContentRows); i++) {\n writeClipped(buf, x + 1, y + 3 + i, contentLines[i]!, innerWidth);\n }\n\n // Trailing blank (only if there's room)\n const trailingBlankRow = y + 3 + Math.min(contentLines.length, availableContentRows);\n if (trailingBlankRow < y + height - 1) {\n writeClipped(buf, x + 1, trailingBlankRow, ' '.padEnd(innerWidth), innerWidth);\n }\n}\n","import { execSync } from 'node:child_process';\nimport { writeFileSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\nexport class NvimBridge {\n private pty: import('node-pty').IPty | null = null;\n private xterm: import('@xterm/headless').Terminal | null = null;\n private _cols: number;\n private _rows: number;\n private onRender: () => void;\n private renderTimer: ReturnType<typeof setTimeout> | null = null;\n\n currentFile: string | null = null;\n ready: boolean = false;\n dirty: boolean = true;\n available: boolean = false;\n /** DECSCUSR cursor style: 0=default, 1=blinking block, 2=steady block, 3=blinking underline, 4=steady underline, 5=blinking bar, 6=steady bar */\n cursorStyle: number = 0;\n private cachedRows: string[] | null = null;\n private nvimPath: string = 'nvim';\n private pendingFiles: { files: { path: string; readonly: boolean }[]; key: string } | null = null;\n private fileDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n private cmdFile: string;\n\n constructor(cols: number, rows: number, onRender: () => void) {\n this._cols = cols;\n this._rows = rows;\n this.onRender = onRender;\n\n // Temp file for passing lua commands to nvim without command-line flash\n const cmdDir = join(tmpdir(), 'sisyphus-nvim');\n mkdirSync(cmdDir, { recursive: true });\n this.cmdFile = join(cmdDir, `cmd-${process.pid}.lua`);\n\n try {\n this.nvimPath = execSync('which nvim', { stdio: 'pipe' }).toString().trim();\n this.available = true;\n } catch {\n this.available = false;\n return;\n }\n\n this.spawn().catch(() => {\n this.available = false;\n this.ready = false;\n });\n }\n\n private async spawn(): Promise<void> {\n const { spawn } = await import('node-pty');\n // @xterm/headless is CJS — Terminal lives on the default export when imported from ESM\n const xtermModule = await import('@xterm/headless');\n const { Terminal } = xtermModule.default as typeof import('@xterm/headless');\n\n this.xterm = new Terminal({\n cols: this._cols,\n rows: this._rows,\n allowProposedApi: true,\n });\n\n const nvimArgs = [\n // Pre-init: only settings needed before user config loads\n '--cmd',\n [\n 'set noswapfile',\n 'set nobackup',\n 'set nowritebackup',\n 'set hidden',\n 'set autoread',\n ].join(' | '),\n // Post-init: cosmetic overrides applied AFTER user config (LazyVim, etc.)\n '-c',\n [\n 'set laststatus=0',\n 'set showtabline=2',\n 'set signcolumn=no',\n 'set nonumber',\n 'set noruler',\n 'set noshowcmd',\n 'set noshowmode',\n 'set shortmess+=F',\n 'set fillchars=eob:\\\\ ',\n 'set scrolloff=3',\n ].join(' | '),\n // Suppress LSP — prevent servers from ever starting (avoids exit warnings)\n '--cmd',\n 'lua vim.lsp.start = function() end',\n // Poll-based command executor: reads lua from temp file — no command-line flash\n '-c',\n `lua local _t = vim.loop.new_timer(); _t:start(100, 50, vim.schedule_wrap(function() local f = io.open('${this.cmdFile.replace(/'/g, \"\\\\'\")}', 'r'); if not f then return end; local c = f:read('*a'); f:close(); os.remove('${this.cmdFile.replace(/'/g, \"\\\\'\")}'); if c and #c > 0 then local fn = loadstring(c); if fn then pcall(fn) end end end))`,\n ];\n\n this.pty = spawn(this.nvimPath, nvimArgs, {\n name: 'xterm-256color',\n cols: this._cols,\n rows: this._rows,\n env: { ...process.env, TERM: 'xterm-256color' } as Record<string, string>,\n });\n\n this.pty.onData((data: string) => {\n // Track DECSCUSR cursor shape sequences (\\x1b[N q) so we can\n // forward them to the real terminal alongside cursor positioning\n const csMatch = data.match(/\\x1b\\[(\\d+) q/);\n if (csMatch) this.cursorStyle = parseInt(csMatch[1], 10);\n\n this.xterm!.write(data);\n this.dirty = true;\n this.cachedRows = null;\n this.debouncedRender();\n });\n\n this.pty.onExit(() => {\n this.ready = false;\n });\n\n // Mark ready after nvim + user config have settled\n setTimeout(() => {\n if (this.pty) {\n this.ready = true;\n this.dirty = true;\n this.cachedRows = null;\n this.onRender();\n }\n }, 500);\n }\n\n private debouncedRender(): void {\n if (this.renderTimer !== null) return;\n this.renderTimer = setTimeout(() => {\n this.renderTimer = null;\n this.onRender();\n }, 16); // ~60fps\n }\n\n /**\n * Execute lua in nvim without flashing the command line.\n * Writes lua to a temp file — a libuv timer in nvim polls and executes it.\n */\n private execLua(lua: string): void {\n writeFileSync(this.cmdFile, lua);\n }\n\n openFile(path: string, readonly: boolean = true): void {\n if (!this.pty || !this.ready) return;\n this.currentFile = path;\n const escapeLua = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const ro = readonly ? 'vim.bo.readonly = true; vim.bo.modifiable = false' : 'vim.bo.readonly = false; vim.bo.modifiable = true';\n this.execLua(`vim.cmd('edit! ${escapeLua(path)}'); ${ro}`);\n }\n\n openTabFiles(files: { path: string; readonly: boolean }[]): void {\n if (!this.pty || !this.ready || files.length === 0) return;\n const key = files.map(f => f.path).join('|');\n // Debounce — only execute after 150ms of no new calls (prevents LSP churn during scroll)\n this.pendingFiles = { files, key };\n if (this.fileDebounceTimer !== null) clearTimeout(this.fileDebounceTimer);\n this.fileDebounceTimer = setTimeout(() => {\n this.fileDebounceTimer = null;\n if (this.pendingFiles) {\n this.executeOpenFiles(this.pendingFiles.files);\n this.currentFile = this.pendingFiles.key;\n this.pendingFiles = null;\n }\n }, 150);\n }\n\n private executeOpenFiles(files: { path: string; readonly: boolean }[]): void {\n if (!this.pty || !this.ready) return;\n const escapeLua = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const stmts: string[] = [\n 'for _, b in ipairs(vim.api.nvim_list_bufs()) do pcall(vim.api.nvim_buf_delete, b, {force=true}) end',\n ];\n for (let i = 0; i < files.length; i++) {\n const path = escapeLua(files[i]!.path);\n stmts.push(i === 0\n ? `vim.cmd('edit! ${path}')`\n : `vim.cmd('edit ${path}')`);\n if (files[i]!.readonly) {\n stmts.push('vim.bo.readonly = true', 'vim.bo.modifiable = false');\n } else {\n stmts.push('vim.bo.readonly = false', 'vim.bo.modifiable = true');\n }\n }\n stmts.push(\"vim.cmd('bfirst')\");\n this.execLua(`(function() ${stmts.join('; ')} end)()`);\n }\n\n openTabFile(path: string, readonly: boolean): void {\n if (!this.pty || !this.ready) return;\n this.pty.write(`:tabedit ${path}\\r`);\n if (readonly) {\n this.pty.write(':setlocal readonly nomodifiable\\r');\n } else {\n this.pty.write(':setlocal noreadonly modifiable\\r');\n }\n }\n\n closeAllTabs(): void {\n if (!this.pty || !this.ready) return;\n this.execLua('for _, b in ipairs(vim.api.nvim_list_bufs()) do pcall(vim.api.nvim_buf_delete, b, {force=true}) end; vim.cmd(\"enew!\")');\n this.currentFile = null;\n }\n\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n this.cachedRows = null;\n this.dirty = true;\n if (this.pty) this.pty.resize(cols, rows);\n if (this.xterm) this.xterm.resize(cols, rows);\n }\n\n write(data: string): void {\n if (this.pty) this.pty.write(data);\n }\n\n getRows(): string[] {\n if (!this.dirty && this.cachedRows) return this.cachedRows;\n if (!this.xterm) return Array.from({ length: this._rows }, () => ' '.repeat(this._cols));\n\n const rows: string[] = [];\n const buffer = this.xterm.buffer.active;\n // Reusable cell to avoid per-cell allocation\n const reusableCell = buffer.getNullCell();\n\n for (let y = 0; y < this._rows; y++) {\n const line = buffer.getLine(y);\n if (!line) {\n rows.push(' '.repeat(this._cols));\n continue;\n }\n\n let row = '';\n let prevFg: number | undefined = undefined;\n let prevBg: number | undefined = undefined;\n let prevFgMode: 'default' | 'palette' | 'rgb' = 'default';\n let prevBgMode: 'default' | 'palette' | 'rgb' = 'default';\n let prevBold = false;\n let prevDim = false;\n let prevItalic = false;\n let prevUnderline = false;\n let prevInverse = false;\n let hasOpenSGR = false;\n\n for (let x = 0; x < this._cols; x++) {\n const cell = line.getCell(x, reusableCell);\n if (!cell) {\n row += ' ';\n continue;\n }\n\n const char = cell.getChars() || ' ';\n\n const fgDefault = cell.isFgDefault();\n const fgPalette = cell.isFgPalette();\n const fgRGB = cell.isFgRGB();\n const fg = fgDefault ? undefined : cell.getFgColor();\n let fgMode: 'default' | 'palette' | 'rgb';\n if (fgDefault) fgMode = 'default';\n else if (fgPalette) fgMode = 'palette';\n else if (fgRGB) fgMode = 'rgb';\n else throw new Error(`Unknown fg color mode at cell (${x}, ${y})`);\n\n const bgDefault = cell.isBgDefault();\n const bgPalette = cell.isBgPalette();\n const bgRGB = cell.isBgRGB();\n const bg = bgDefault ? undefined : cell.getBgColor();\n let bgMode: 'default' | 'palette' | 'rgb';\n if (bgDefault) bgMode = 'default';\n else if (bgPalette) bgMode = 'palette';\n else if (bgRGB) bgMode = 'rgb';\n else throw new Error(`Unknown bg color mode at cell (${x}, ${y})`);\n\n const bold = cell.isBold() !== 0;\n const dim = cell.isDim() !== 0;\n const italic = cell.isItalic() !== 0;\n const underline = cell.isUnderline() !== 0;\n const inverse = cell.isInverse() !== 0;\n\n const attrChanged =\n fg !== prevFg ||\n bg !== prevBg ||\n fgMode !== prevFgMode ||\n bgMode !== prevBgMode ||\n bold !== prevBold ||\n dim !== prevDim ||\n italic !== prevItalic ||\n underline !== prevUnderline ||\n inverse !== prevInverse;\n\n if (attrChanged) {\n if (hasOpenSGR) {\n row += '\\x1b[0m';\n hasOpenSGR = false;\n }\n\n const codes: string[] = [];\n if (bold) codes.push('1');\n if (dim) codes.push('2');\n if (italic) codes.push('3');\n if (underline) codes.push('4');\n if (inverse) codes.push('7');\n\n if (fg !== undefined) {\n if (fgMode === 'palette') {\n codes.push(`38;5;${fg}`);\n } else if (fgMode === 'rgb') {\n const r = (fg >> 16) & 0xff;\n const g = (fg >> 8) & 0xff;\n const b = fg & 0xff;\n codes.push(`38;2;${r};${g};${b}`);\n }\n }\n\n if (bg !== undefined) {\n if (bgMode === 'palette') {\n codes.push(`48;5;${bg}`);\n } else if (bgMode === 'rgb') {\n const r = (bg >> 16) & 0xff;\n const g = (bg >> 8) & 0xff;\n const b = bg & 0xff;\n codes.push(`48;2;${r};${g};${b}`);\n }\n }\n\n if (codes.length > 0) {\n row += `\\x1b[${codes.join(';')}m`;\n hasOpenSGR = true;\n }\n\n prevFg = fg;\n prevBg = bg;\n prevFgMode = fgMode;\n prevBgMode = bgMode;\n prevBold = bold;\n prevDim = dim;\n prevItalic = italic;\n prevUnderline = underline;\n prevInverse = inverse;\n }\n\n row += char;\n }\n\n if (hasOpenSGR) {\n row += '\\x1b[0m';\n }\n\n rows.push(row);\n }\n\n this.cachedRows = rows;\n this.dirty = false;\n return rows;\n }\n\n getCursorPos(): { x: number; y: number } {\n if (!this.xterm) return { x: 0, y: 0 };\n return {\n x: this.xterm.buffer.active.cursorX,\n y: this.xterm.buffer.active.cursorY,\n };\n }\n\n checktime(): void {\n if (this.pty && this.ready) {\n this.execLua('vim.cmd(\"checktime\")');\n }\n }\n\n destroy(): void {\n if (this.renderTimer !== null) {\n clearTimeout(this.renderTimer);\n this.renderTimer = null;\n }\n if (this.fileDebounceTimer !== null) {\n clearTimeout(this.fileDebounceTimer);\n this.fileDebounceTimer = null;\n }\n try {\n if (this.pty) {\n this.pty.kill();\n this.pty = null;\n }\n } catch {\n // ignore kill errors\n }\n if (this.xterm) {\n this.xterm.dispose();\n this.xterm = null;\n }\n this.ready = false;\n try { unlinkSync(this.cmdFile); } catch { /* ignore */ }\n }\n}\n","import { writeFileSync, mkdirSync, renameSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tuiScratchDir, goalPath, roadmapPath, strategyPath } from '../../shared/paths.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\nimport type { TreeNode } from '../types/tree.js';\nimport type { DetailContext } from '../panels/detail.js';\nimport type { AppState } from '../state.js';\nimport type { ReportBlock } from '../lib/reports.js';\n\n// ---------------------------------------------------------------------------\n// Return type\n// ---------------------------------------------------------------------------\n\nexport interface NvimFileResult {\n files: { path: string; readonly: boolean }[];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction atomicWrite(filePath: string, content: string): void {\n const tmp = filePath + '.tmp.' + process.pid;\n writeFileSync(tmp, content, 'utf-8');\n renameSync(tmp, filePath);\n}\n\nfunction ensureTuiDir(cwd: string, sessionId: string): string {\n const dir = tuiScratchDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction formatTimestamp(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n });\n } catch {\n return iso;\n }\n}\n\nfunction formatDurationMs(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n const rem = s % 60;\n if (m < 60) return rem > 0 ? `${m}m ${rem}s` : `${m}m`;\n const h = Math.floor(m / 60);\n const remM = m % 60;\n return remM > 0 ? `${h}h ${remM}m` : `${h}h`;\n}\n\nfunction elapsedSince(start: string, end?: string): string {\n const startMs = new Date(start).getTime();\n const endMs = end ? new Date(end).getTime() : Date.now();\n return formatDurationMs(endMs - startMs);\n}\n\n// ---------------------------------------------------------------------------\n// Compose functions\n// ---------------------------------------------------------------------------\n\nfunction sectionBreak(): string[] {\n return ['', '', '---', '', ''];\n}\n\nfunction composeCycleDetail(session: Session, cycle: OrchestratorCycle): string {\n const isRunning = !cycle.completedAt;\n const dur = isRunning ? 'running' : formatDurationMs(cycle.activeMs);\n const cycleAgents = session.agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n const lines: string[] = [];\n\n lines.push(`# Cycle ${cycle.cycle}`);\n lines.push('');\n lines.push(`**Status:** ${isRunning ? 'running' : 'completed'} | **Duration:** ${dur}`);\n lines.push(`**Started:** ${formatTimestamp(cycle.timestamp)}`);\n if (cycle.completedAt) {\n lines.push(`**Completed:** ${formatTimestamp(cycle.completedAt)}`);\n }\n if (cycle.mode) {\n lines.push(`**Mode:** ${cycle.mode}`);\n }\n if (cycle.claudeSessionId) {\n lines.push(`**Claude Session:** ${cycle.claudeSessionId}`);\n }\n\n // Agents\n lines.push(...sectionBreak());\n lines.push('## Agents');\n lines.push('');\n if (cycleAgents.length === 0) {\n lines.push('_No agents spawned yet._');\n } else {\n for (const agent of cycleAgents) {\n const agentDur = formatDurationMs(agent.activeMs);\n lines.push(`### ${agent.id} — ${agent.name || agent.agentType || agent.id}`);\n lines.push(`- **Status:** ${agent.status} | **Duration:** ${agentDur}`);\n lines.push(`- **Type:** ${agent.agentType || '—'}`);\n if (agent.killedReason) {\n lines.push(`- **Killed reason:** ${agent.killedReason}`);\n }\n lines.push('');\n lines.push('**Instruction:**');\n lines.push('');\n lines.push(agent.instruction);\n const latestReport =\n agent.reports.length > 0 ? agent.reports[agent.reports.length - 1]! : null;\n if (latestReport) {\n lines.push('');\n lines.push(`**Latest report** (${latestReport.type}, ${formatTimestamp(latestReport.timestamp)}):**`);\n lines.push('');\n lines.push(latestReport.summary);\n }\n lines.push('');\n }\n }\n\n // Next prompt\n if (cycle.nextPrompt) {\n lines.push(...sectionBreak());\n lines.push('## Next Prompt');\n lines.push('');\n lines.push(cycle.nextPrompt.trim());\n lines.push('');\n }\n\n return lines.join('\\n') + '\\n';\n}\n\nfunction composeAgentDetail(agent: Agent, reportBlocks: ReportBlock[]): string {\n const dur = formatDurationMs(agent.activeMs);\n const lines: string[] = [];\n\n lines.push(`# ${agent.id} — ${agent.name || agent.agentType || agent.id}`);\n lines.push('');\n lines.push(\n `**Status:** ${agent.status} | **Duration:** ${dur} | **Type:** ${agent.agentType || '—'}`,\n );\n lines.push(`**Spawned:** ${formatTimestamp(agent.spawnedAt)}`);\n if (agent.completedAt) {\n lines.push(`**Completed:** ${formatTimestamp(agent.completedAt)}`);\n }\n if (agent.killedReason) {\n lines.push(`**Killed reason:** ${agent.killedReason}`);\n }\n if (agent.claudeSessionId) {\n lines.push(`**Claude Session:** ${agent.claudeSessionId}`);\n }\n\n lines.push(...sectionBreak());\n lines.push('## Instruction');\n lines.push('');\n lines.push(agent.instruction.trim());\n\n if (reportBlocks.length > 0) {\n lines.push(...sectionBreak());\n lines.push(`## Reports (${reportBlocks.length})`);\n for (const block of reportBlocks) {\n lines.push('');\n const badge = block.type === 'final' ? 'FINAL' : 'UPDATE';\n lines.push(`### ${badge} — ${formatTimestamp(block.timestamp)}`);\n lines.push('');\n lines.push(block.content.trim());\n }\n } else if (agent.reports.length > 0) {\n lines.push(...sectionBreak());\n lines.push(`## Reports (${agent.reports.length})`);\n for (const report of agent.reports) {\n const badge = report.type === 'final' ? 'FINAL' : 'UPDATE';\n lines.push('');\n lines.push(`### ${badge} — ${formatTimestamp(report.timestamp)}`);\n lines.push('');\n lines.push(report.summary);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\nfunction composeMessages(session: Session): string {\n const lines: string[] = [];\n\n lines.push('# Messages');\n lines.push('');\n lines.push(`**Session:** ${session.name ?? session.task.slice(0, 60)}`);\n lines.push(`**Total messages:** ${session.messages.length}`);\n\n if (session.messages.length === 0) {\n lines.push('');\n lines.push('_No messages yet._');\n return lines.join('\\n') + '\\n';\n }\n\n const sorted = [...session.messages].sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n );\n\n for (const msg of sorted) {\n lines.push('');\n lines.push('---');\n lines.push('');\n const src = msg.source;\n let sourceLabel: string;\n if (src.type === 'agent') {\n sourceLabel = src.agentId;\n } else if (src.type === 'user') {\n sourceLabel = 'You';\n } else {\n sourceLabel = src.detail ? `system (${src.detail})` : 'system';\n }\n lines.push(`**From:** ${sourceLabel} | **Time:** ${formatTimestamp(msg.timestamp)}`);\n if (msg.summary && msg.summary !== msg.content) {\n lines.push(`**Summary:** ${msg.summary}`);\n }\n lines.push('');\n lines.push(msg.content.trim());\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Determine which file(s) neovim should display based on the current cursor node.\n * Returns a NvimFileResult with file paths and editability, or null.\n *\n * For session nodes, opens the real files (goal.md, roadmap.md, strategy.md) in splits.\n * For other node types, composes a markdown file in the .tui/ scratch directory.\n */\nexport function resolveNvimFile(\n state: AppState,\n cursorNode: TreeNode | undefined,\n detailCtx: DetailContext,\n cwd: string,\n): NvimFileResult | null {\n if (!cursorNode) return null;\n const sessionId = cursorNode.sessionId;\n if (!sessionId) return null;\n const session = detailCtx.session;\n\n switch (cursorNode.type) {\n case 'session': {\n if (!session) return null;\n const files: { path: string; readonly: boolean }[] = [];\n const gp = goalPath(cwd, sessionId);\n if (existsSync(gp)) files.push({ path: gp, readonly: false });\n const rp = roadmapPath(cwd, sessionId);\n if (existsSync(rp)) files.push({ path: rp, readonly: false });\n const sp = strategyPath(cwd, sessionId);\n if (existsSync(sp)) files.push({ path: sp, readonly: false });\n if (files.length === 0) return null;\n return { files };\n }\n\n case 'cycle': {\n if (!session) return null;\n const cycle = session.orchestratorCycles.find(\n (c) => c.cycle === cursorNode.cycleNumber,\n );\n if (!cycle) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, `cycle-${cursorNode.cycleNumber}.md`);\n atomicWrite(filePath, composeCycleDetail(session, cycle));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'agent': {\n if (!session) return null;\n const agent = session.agents.find((a) => a.id === cursorNode.agentId);\n if (!agent) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, `${agent.id}.md`);\n atomicWrite(filePath, composeAgentDetail(agent, state.cachedReportBlocks.get(agent.id) ?? []));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'report': {\n const agent = session?.agents.find((a) => a.id === cursorNode.agentId);\n if (agent && agent.reports.length > 0) {\n const report = agent.reports[cursorNode.reportIndex];\n if (report?.filePath && existsSync(report.filePath)) {\n return { files: [{ path: report.filePath, readonly: true }] };\n }\n }\n return null;\n }\n\n case 'context-file': {\n if (cursorNode.filePath && existsSync(cursorNode.filePath)) {\n return { files: [{ path: cursorNode.filePath, readonly: false }] };\n }\n return null;\n }\n\n case 'messages':\n case 'message': {\n if (!session || session.messages.length === 0) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, 'messages.md');\n atomicWrite(filePath, composeMessages(session));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'context': {\n return null;\n }\n\n default:\n return null;\n }\n}\n","import { setupTerminal } from './terminal.js';\nimport { createAppState } from './state.js';\nimport { startApp } from './app.js';\n\nconst args = process.argv.slice(2);\n\nfunction getArg(name: string): string | undefined {\n const idx = args.indexOf(`--${name}`);\n if (idx !== -1 && idx + 1 < args.length) {\n return args[idx + 1];\n }\n return undefined;\n}\n\nconst cwd = getArg('cwd') ?? process.cwd();\nconst cleanup = setupTerminal();\nconst state = createAppState(cwd);\nstartApp(state, cleanup);\n"],"mappings":"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","names":["cleanup","key","cwd","state","readFileSync","existsSync","join","cwd","state","stringWidth","prevFrame","stringWidth","join","join","cwd","execSync","cleaned","wrapped","state","lines","state","content","execSync","writeFileSync","mkdirSync","join","tmpdir","writeFileSync","mkdirSync","existsSync","join","writeFileSync","cwd","mkdirSync","state","cwd","existsSync","join","state","cleanup","existsSync","readFileSync","join","out","treeWidth"]}
|
|
1
|
+
{"version":3,"sources":["../src/tui/terminal.ts","../src/tui/state.ts","../src/tui/app.ts","../src/tui/input.ts","../src/tui/lib/tree.ts","../src/tui/lib/format.ts","../src/tui/render.ts","../src/tui/lib/tree-render.ts","../src/tui/lib/client.ts","../src/tui/lib/tmux.ts","../src/tui/lib/clipboard.ts","../src/tui/panels/tree.ts","../src/tui/panels/detail.ts","../src/tui/panels/nvim-detail.ts","../src/tui/panels/bottom.ts","../src/tui/panels/overlays.ts","../src/tui/lib/nvim-bridge.ts","../src/tui/lib/overview-writer.ts","../src/tui/index.ts"],"sourcesContent":["export interface Key {\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n pageUp: boolean;\n pageDown: boolean;\n return: boolean;\n escape: boolean;\n ctrl: boolean;\n shift: boolean;\n tab: boolean;\n backspace: boolean;\n delete: boolean;\n meta: boolean;\n}\n\nexport type KeypressHandler = (input: string, key: Key) => void;\n\nfunction emptyKey(): Key {\n return {\n upArrow: false,\n downArrow: false,\n leftArrow: false,\n rightArrow: false,\n pageUp: false,\n pageDown: false,\n return: false,\n escape: false,\n ctrl: false,\n shift: false,\n tab: false,\n backspace: false,\n delete: false,\n meta: false,\n };\n}\n\n// ── Terminal Setup/Teardown ──────────────────────────────────────────────────\n\nexport function setupTerminal(): () => void {\n let cleaned = false;\n\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n process.stdout.write('\\x1b[?25h\\x1b[?1049l');\n process.stdin.setRawMode(false);\n process.stdin.pause();\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf-8');\n process.stdout.write('\\x1b[?1049h\\x1b[?25l\\x1b[2J');\n\n process.on('SIGINT', () => { cleanup(); process.exit(0); });\n process.on('SIGTERM', () => { cleanup(); process.exit(0); });\n process.on('exit', cleanup);\n process.on('uncaughtException', (err) => {\n cleanup();\n console.error(err);\n process.exit(1);\n });\n\n return cleanup;\n}\n\n// ── Stdout Write Helper ──────────────────────────────────────────────────────\n\nexport function writeToStdout(data: string): void {\n process.stdout.write(data);\n}\n\n// ── Keypress Parser ──────────────────────────────────────────────────────────\n\n/**\n * Parse all complete key sequences from a buffer string.\n * Returns an array of [input, Key] pairs and the remaining unparsed buffer.\n */\nfunction parseBuffer(buf: string): { events: Array<[string, Key]>; remaining: string } {\n const events: Array<[string, Key]> = [];\n\n let i = 0;\n while (i < buf.length) {\n const ch = buf[i]!;\n\n // ESC prefix sequences\n if (ch === '\\x1b') {\n const rest = buf.slice(i + 1);\n\n // CSI sequences: \\x1b[...\n if (rest.startsWith('[')) {\n const after = rest.slice(1);\n\n // Shift+Arrow: \\x1b[1;2A/B/C/D\n const shiftArrow = after.match(/^1;2([ABCD])/);\n if (shiftArrow) {\n const key = emptyKey();\n key.shift = true;\n const dir = shiftArrow[1]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[1;2${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Arrow keys: \\x1b[A/B/C/D\n if (after.length >= 1 && 'ABCD'.includes(after[0]!)) {\n const key = emptyKey();\n const dir = after[0]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Tilde sequences: \\x1b[N~\n const tildeMatch = after.match(/^(\\d+)~/);\n if (tildeMatch) {\n const num = tildeMatch[1]!;\n const key = emptyKey();\n if (num === '5') key.pageUp = true;\n else if (num === '6') key.pageDown = true;\n else if (num === '3') key.delete = true;\n const seq = `\\x1b[${num}~`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Incomplete CSI — need more data\n return { events, remaining: buf.slice(i) };\n }\n\n // Lone ESC — signal caller to wait (disambiguate vs CSI prefix)\n if (rest.length === 0) {\n return { events, remaining: buf.slice(i) };\n }\n\n // \\x1b + regular char → Meta key\n const metaCh = rest[0]!;\n const key = emptyKey();\n key.meta = true;\n events.push([metaCh, key]);\n i += 2;\n continue;\n }\n\n // Return\n if (ch === '\\r') {\n const key = emptyKey();\n key.return = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Tab\n if (ch === '\\t') {\n const key = emptyKey();\n key.tab = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Backspace (DEL or BS)\n if (ch === '\\x7f' || ch === '\\x08') {\n const key = emptyKey();\n key.backspace = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Ctrl+A–Z (\\x01–\\x1a)\n const code = ch.charCodeAt(0);\n if (code >= 0x01 && code <= 0x1a) {\n const key = emptyKey();\n key.ctrl = true;\n const letter = String.fromCharCode(code + 96);\n events.push([letter, key]);\n i++;\n continue;\n }\n\n // Printable / multibyte char\n events.push([ch, emptyKey()]);\n i++;\n }\n\n return { events, remaining: '' };\n}\n\n// ── Raw Stdin Bypass (for neovim PTY forwarding) ─────────────────────────────\n\nlet rawBypassHandler: ((data: string) => boolean) | null = null;\n\nexport function setRawBypass(handler: ((data: string) => boolean) | null): void {\n rawBypassHandler = handler;\n}\n\nexport function startKeypressListener(handler: KeypressHandler): () => void {\n let buffer = '';\n let escTimer: ReturnType<typeof setTimeout> | null = null;\n\n const onData = (data: string): void => {\n // Raw bypass — forward to neovim PTY if active\n if (rawBypassHandler) {\n const handled = rawBypassHandler(data);\n if (handled) return;\n }\n\n // Cancel pending escape timer — more data arrived\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n\n buffer += data;\n\n const { events, remaining } = parseBuffer(buffer);\n buffer = remaining;\n\n for (const [input, key] of events) {\n handler(input, key);\n }\n\n // If buffer ends with lone ESC, start disambiguation timer\n if (buffer === '\\x1b') {\n escTimer = setTimeout(() => {\n escTimer = null;\n buffer = '';\n const key = emptyKey();\n key.escape = true;\n handler('\\x1b', key);\n }, 50);\n }\n };\n\n process.stdin.on('data', onData);\n\n return (): void => {\n process.stdin.off('data', onData);\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n };\n}\n\n// ── Resize Handler ───────────────────────────────────────────────────────────\n\nexport function onResize(callback: () => void): () => void {\n const onStdoutResize = (): void => callback();\n const onSigwinch = (): void => callback();\n\n process.stdout.on('resize', onStdoutResize);\n process.on('SIGWINCH', onSigwinch);\n\n return (): void => {\n process.stdout.off('resize', onStdoutResize);\n process.off('SIGWINCH', onSigwinch);\n };\n}\n","import type { Session } from '../shared/types.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { ReportBlock } from './lib/reports.js';\n\n// ---------------------------------------------------------------------------\n// Polling data interfaces (moved from usePolling.ts)\n// ---------------------------------------------------------------------------\n\nexport interface SessionSummary {\n id: string;\n name?: string;\n task: string;\n status: string;\n agentCount: number;\n createdAt: string;\n tmuxWindowId?: string;\n /** Cached result of windowExists check — avoids synchronous subprocess in render */\n windowAlive?: boolean;\n}\n\nexport interface CycleLog {\n cycle: number;\n content: string;\n}\n\n// ---------------------------------------------------------------------------\n// InputMode (moved from InputBar.tsx)\n// ---------------------------------------------------------------------------\n\nexport type InputMode =\n | 'navigate'\n | 'report-detail'\n | 'resume'\n | 'continue'\n | 'rollback'\n | 'leader'\n | 'copy-menu'\n | 'delete-confirm'\n | 'spawn-agent'\n | 'search'\n | 'message-agent'\n | 'shell-command'\n | 'help'\n | 'compose';\n\n// ---------------------------------------------------------------------------\n// Compose mode types\n// ---------------------------------------------------------------------------\n\nexport type ComposeAction =\n | { kind: 'new-session' }\n | { kind: 'message-orchestrator'; sessionId: string }\n | { kind: 'resume'; sessionId: string }\n | { kind: 'continue'; sessionId: string }\n | { kind: 'spawn-agent'; sessionId: string }\n | { kind: 'message-agent'; sessionId: string; agentId: string };\n\n/** Actions where empty content is allowed (submit without typing) */\nexport const OPTIONAL_COMPOSE = new Set(['resume', 'continue']);\n\n/** Display labels for compose actions */\nexport const COMPOSE_HEADERS: Record<ComposeAction['kind'], string> = {\n 'new-session': 'New Session',\n 'message-orchestrator': 'Message Orchestrator',\n 'resume': 'Resume Session',\n 'continue': 'Continue Session',\n 'spawn-agent': 'Spawn Agent',\n 'message-agent': 'Message Agent',\n};\n\nexport const INPUT_MODES = new Set<InputMode>([\n 'resume',\n 'continue',\n 'rollback',\n 'delete-confirm',\n 'spawn-agent',\n 'search',\n 'message-agent',\n 'shell-command',\n]);\n\nexport const OPTIONAL_INPUT = new Set<InputMode>(['resume', 'continue', 'search']);\n\nexport const PROMPTS: Partial<Record<InputMode, string>> = {\n resume: 'resume instructions (optional)',\n continue: 'new direction (optional)',\n rollback: 'cycle number',\n 'delete-confirm': \"type 'yes' to confirm delete:\",\n 'spawn-agent': 'agent instruction:',\n search: 'filter:',\n 'message-agent': 'message:',\n 'shell-command': '$ ',\n};\n\n// ---------------------------------------------------------------------------\n// Render scheduling\n// ---------------------------------------------------------------------------\n\nlet renderScheduled = false;\nlet renderFn: (() => void) | null = null;\n\nexport function setRenderFunction(fn: () => void): void {\n renderFn = fn;\n}\n\nexport function requestRender(): void {\n if (renderScheduled) return;\n renderScheduled = true;\n setImmediate(() => {\n renderScheduled = false;\n renderFn?.();\n });\n}\n\n// ---------------------------------------------------------------------------\n// ThrottledScroll\n// ---------------------------------------------------------------------------\n\nconst FRAME_MS = 16; // ~60fps\n\nexport class ThrottledScroll {\n offset: number = 0;\n private target: number = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private onRender: () => void;\n\n constructor(onRender: () => void, initial = 0) {\n this.onRender = onRender;\n this.offset = initial;\n this.target = initial;\n }\n\n private scheduleFlush(): void {\n if (this.timer === null) {\n this.timer = setTimeout(() => {\n this.timer = null;\n this.offset = this.target;\n this.onRender();\n }, FRAME_MS);\n }\n }\n\n scrollBy(delta: number): void {\n this.target = Math.max(0, this.target + delta);\n this.scheduleFlush();\n }\n\n scrollTo(value: number): void {\n this.target = Math.max(0, value);\n this.scheduleFlush();\n }\n\n reset(): void {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.target = 0;\n this.offset = 0;\n }\n\n destroy(): void {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// AppState\n// ---------------------------------------------------------------------------\n\nexport interface AppState {\n // Terminal dimensions\n rows: number;\n cols: number;\n\n // Tree navigation\n cursorIndex: number;\n expanded: Set<string>;\n mode: InputMode;\n focusPane: 'tree' | 'detail' | 'logs';\n\n // Session\n selectedSessionId: string | null;\n searchFilter: string | null;\n targetAgentId: string | null;\n\n // UI\n notification: string | null;\n notificationTimer: ReturnType<typeof setTimeout> | null;\n showCombinedView: boolean;\n\n // Input bar\n inputText: string;\n inputCursorPos: number;\n\n // Scroll\n detailScroll: ThrottledScroll;\n logsScroll: ThrottledScroll;\n\n // Polling data (from daemon)\n sessions: SessionSummary[];\n selectedSession: Session | null;\n planContent: string;\n strategyContent: string;\n goalContent: string;\n logsContent: string;\n logsCycles: CycleLog[];\n paneAlive: boolean;\n contextFiles: string[];\n error: string | null;\n\n // Cursor stabilization\n cursorNodeId: string | null;\n prevNodes: TreeNode[];\n prevCycleCount: number;\n\n // Render caches\n cachedReportBlocks: Map<string, ReportBlock[]>;\n cachedTreeNodes: TreeNode[] | null;\n treeCacheKey: string;\n cachedDetailLines: import('./lib/format.js').DetailLine[] | null;\n detailCacheKey: string;\n detailRenderedCache: import('./render.js').RenderedCache;\n cachedLogsLines: import('./lib/format.js').DetailLine[] | null;\n logsCacheKey: string;\n logsRenderedCache: import('./render.js').RenderedCache;\n\n // Neovim integration\n nvimBridge: import('./lib/nvim-bridge.js').NvimBridge | null;\n nvimEnabled: boolean;\n prevNvimFile: string | null;\n nvimEditable: boolean;\n nvimOpenTabs: Map<string, { path: string; readonly: boolean }>;\n\n // Compose mode\n composeAction: ComposeAction | null;\n composeTempFile: string | null;\n composeSignalFile: string | null;\n composePollTimer: ReturnType<typeof setInterval> | null;\n composePrevNvimFile: string | null;\n\n // Config\n cwd: string;\n}\n\nexport function createAppState(cwd: string): AppState {\n const cols = process.stdout.columns ?? 80;\n const rows = process.stdout.rows ?? 24;\n\n const detailScroll = new ThrottledScroll(requestRender);\n const logsScroll = new ThrottledScroll(requestRender);\n\n return {\n rows,\n cols,\n cursorIndex: 0,\n expanded: new Set(),\n mode: 'navigate',\n focusPane: 'tree',\n selectedSessionId: null,\n searchFilter: null,\n targetAgentId: null,\n notification: null,\n notificationTimer: null,\n showCombinedView: false,\n inputText: '',\n inputCursorPos: 0,\n detailScroll,\n logsScroll,\n sessions: [],\n selectedSession: null,\n planContent: '',\n strategyContent: '',\n goalContent: '',\n logsContent: '',\n logsCycles: [],\n paneAlive: true,\n contextFiles: [],\n error: null,\n cursorNodeId: null,\n prevNodes: [],\n prevCycleCount: 0,\n cachedReportBlocks: new Map(),\n cachedTreeNodes: null,\n treeCacheKey: '',\n cachedDetailLines: null,\n detailCacheKey: '',\n detailRenderedCache: { lines: [], ansi: [] },\n cachedLogsLines: null,\n logsCacheKey: '',\n logsRenderedCache: { lines: [], ansi: [] },\n nvimBridge: null,\n nvimEnabled: true,\n prevNvimFile: null,\n nvimEditable: false,\n nvimOpenTabs: new Map(),\n composeAction: null,\n composeTempFile: null,\n composeSignalFile: null,\n composePollTimer: null,\n composePrevNvimFile: null,\n cwd,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Notification helper\n// ---------------------------------------------------------------------------\n\nexport function notify(state: AppState, msg: string): void {\n state.notification = msg;\n if (state.notificationTimer !== null) {\n clearTimeout(state.notificationTimer);\n }\n state.notificationTimer = setTimeout(() => {\n state.notification = null;\n state.notificationTimer = null;\n requestRender();\n }, 3000);\n}\n\n// ---------------------------------------------------------------------------\n// Cursor stabilization\n// ---------------------------------------------------------------------------\n\nexport function stabilizeCursor(state: AppState, nodes: TreeNode[]): void {\n if (nodes.length === 0) {\n state.cursorIndex = 0;\n return;\n }\n\n const targetId = state.cursorNodeId;\n if (targetId === null) {\n state.cursorNodeId = nodes[0]?.id ?? null;\n return;\n }\n\n // If current index already points to the right node, no adjustment needed\n if (nodes[state.cursorIndex]?.id === targetId) return;\n\n // Find the tracked node in the new tree\n const newIndex = nodes.findIndex((n) => n.id === targetId);\n if (newIndex !== -1) {\n state.cursorIndex = newIndex;\n } else {\n // Node is gone (parent collapsed, session removed, etc.) — clamp\n const clamped = Math.min(state.cursorIndex, nodes.length - 1);\n state.cursorIndex = clamped;\n state.cursorNodeId = nodes[clamped]?.id ?? null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-expand cycle\n// ---------------------------------------------------------------------------\n\nexport function autoExpandCycle(state: AppState): void {\n const selectedSession = state.selectedSession;\n if (!selectedSession) return;\n\n const sessionNodeId = `session:${selectedSession.id}`;\n const cycles = selectedSession.orchestratorCycles;\n\n // Only auto-manage cycle expansion if the session is already expanded by user\n if (!state.expanded.has(sessionNodeId)) {\n state.prevCycleCount = cycles.length;\n return;\n }\n\n if (cycles.length === 0) {\n state.prevCycleCount = 0;\n return;\n }\n\n const latest = cycles[cycles.length - 1]!;\n const latestId = `cycle:${selectedSession.id}:${latest.cycle}`;\n\n if (cycles.length > state.prevCycleCount && state.prevCycleCount > 0) {\n // New cycle appeared — collapse previous, expand latest\n const prevCycle = cycles[cycles.length - 2];\n if (prevCycle) {\n const prevId = `cycle:${selectedSession.id}:${prevCycle.cycle}`;\n state.expanded.delete(prevId);\n state.expanded.add(latestId);\n }\n } else if (!state.expanded.has(latestId)) {\n // Ensure latest is expanded\n state.expanded.add(latestId);\n }\n\n state.prevCycleCount = cycles.length;\n}\n","import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport {\n type AppState,\n type SessionSummary,\n type CycleLog,\n setRenderFunction,\n requestRender,\n stabilizeCursor,\n autoExpandCycle,\n notify,\n} from './state.js';\nimport { handleKeypress, type InputActions } from './input.js';\nimport { createFrameBuffer, flushFrame, writeCenter, copyRows } from './render.js';\nimport { writeToStdout, startKeypressListener, onResize } from './terminal.js';\nimport { buildTree } from './lib/tree.js';\nimport { precomputePrefixes } from './lib/tree-render.js';\nimport { resolveReports } from './lib/reports.js';\nimport { send } from './lib/client.js';\nimport {\n listAllWindowIds,\n openEditorPopup,\n editInPopup,\n openCompanionPane,\n openClaudeResumePopup,\n openClaudeResumeSession,\n selectWindow,\n selectPane,\n switchToSession,\n openLogPopup,\n openShellPopup,\n openInFileManager,\n} from './lib/tmux.js';\nimport { copyToClipboard } from './lib/clipboard.js';\nimport { buildSessionContext } from './lib/context.js';\nimport { renderTreePanel } from './panels/tree.js';\nimport { renderDetailRows, renderLogsRows, type DetailContext } from './panels/detail.js';\nimport { renderNvimDetailRows } from './panels/nvim-detail.js';\nimport { renderNotificationRow, renderInputBar, renderStatusLine } from './panels/bottom.js';\nimport { renderLeaderOverlay, renderCopyMenuOverlay, renderHelpOverlay } from './panels/overlays.js';\nimport { NvimBridge } from './lib/nvim-bridge.js';\nimport { resolveNvimFile } from './lib/overview-writer.js';\nimport { loadConfig } from '../shared/config.js';\nimport { roadmapPath, goalPath, strategyPath, logsDir, contextDir } from '../shared/paths.js';\nimport { statusIndicator, formatDuration, statusColor, agentStatusIcon, agentDisplayName, truncate, ansiColor, ansiDim, ansiBold } from './lib/format.js';\nimport { COMPOSE_HEADERS } from './state.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { Agent, Session } from '../shared/types.js';\n\n// ── Module-level cache for latest rendered nodes (needed by keypress handler) ─\n\nlet latestNodes: TreeNode[] = [];\n\n// ── Module-level cache for context file content ───────────────────────────────\n\nlet cachedContextFilePath: string | null = null;\nlet cachedContextFileContent: string | null = null;\n\n// ── Previous frame for diffing ────────────────────────────────────────────────\n\nlet prevFrame: string[] = [];\n\n// ── Panel dirty tracking ─────────────────────────────────────────────────────\n// Tracks the inputs that affect each panel. When only the scroll offset changes,\n// we can skip re-rendering panels whose inputs haven't changed.\n\nlet prevTreeInputs = '';\nlet prevBottomInputs = '';\nlet prevOverlayMode = '';\nlet cachedTreeRows: string[] = [];\n\n// ── Cycle logs cache (avoids re-reading unchanged files every poll) ───────────\n\nlet cachedLogSessionId: string | null = null;\nlet cachedLogFiles: Map<string, { mtime: number; cycle: number; content: string }> = new Map();\n\n// ── Status header constants ──────────────────────────────────────────────────\n\nconst STATUS_ROW_COUNT = 2; // Fixed height for status header (avoids nvim resize on cursor change)\n\nfunction buildStatusRows(\n cursorNode: TreeNode | undefined,\n session: Session | null,\n state: AppState,\n): string[] {\n if (!cursorNode || !session) {\n return [ansiDim(' No session selected'), ''];\n }\n\n const dur = formatDuration(session.createdAt, session.completedAt);\n const indicator = statusIndicator(session.status);\n const sColor = statusColor(session.status);\n const title = truncate(session.name ?? session.task, 40);\n\n switch (cursorNode.type) {\n case 'session': {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.status} · ${session.orchestratorCycles.length} cycles · ${session.agents.length} agents · ${dur}`),\n ];\n }\n case 'cycle': {\n const cycle = session.orchestratorCycles.find(c => c.cycle === cursorNode.cycleNumber);\n if (!cycle) return [' ' + ansiColor(title, 'white', true), ''];\n const cDur = cycle.completedAt ? formatDuration(cycle.timestamp, cycle.completedAt) : 'running';\n const cStatus = cycle.completedAt ? 'completed' : 'running';\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true) + ansiDim(` · Cycle ${cycle.cycle}`),\n ' ' + ansiDim(`${cStatus} · ${cDur} · ${cycle.agentsSpawned.length} agents`),\n ];\n }\n case 'agent':\n case 'report': {\n const agentId = cursorNode.type === 'agent' ? cursorNode.agentId : cursorNode.agentId;\n const agent = session.agents.find(a => a.id === agentId);\n if (!agent) return [' ' + ansiColor(title, 'white', true), ''];\n const aIcon = agentStatusIcon(agent.status);\n const aDur = formatDuration(agent.spawnedAt, agent.completedAt);\n const aName = agentDisplayName(agent);\n return [\n ' ' + ansiColor(aIcon, statusColor(agent.status === 'running' ? 'active' : agent.status), true) + ' ' + ansiColor(`${agent.id} · ${aName}`, 'white', true),\n ' ' + ansiDim(`${agent.status} · ${agent.agentType || '—'} · ${aDur}`),\n ];\n }\n case 'context-file': {\n const name = cursorNode.filePath.split('/').pop() ?? cursorNode.filePath;\n return [\n ' ' + ansiColor('⊞', 'white') + ' ' + ansiColor(name, 'white', true),\n ' ' + ansiDim(`context file · ${session.status}`),\n ];\n }\n case 'messages':\n case 'message': {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.messages.length} messages`),\n ];\n }\n default: {\n return [\n ' ' + ansiColor(indicator, sColor, true) + ' ' + ansiColor(title, 'white', true),\n ' ' + ansiDim(`${session.status} · ${dur}`),\n ];\n }\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getAgentForNode(node: TreeNode | undefined, agents: Agent[]): Agent | null {\n if (!node) return null;\n if (node.type === 'agent' || node.type === 'report') {\n return agents.find((a) => a.id === node.agentId) ?? null;\n }\n return null;\n}\n\n// ── startApp ──────────────────────────────────────────────────────────────────\n\nexport function startApp(state: AppState, cleanup: () => void): void {\n const config = loadConfig(state.cwd);\n\n // Initialize NvimBridge\n const treeWidth = 36;\n const initialDetailW = (state.cols - treeWidth) - 4; // detail width minus borders\n const initialDetailH = (state.rows - 3) - 2 - STATUS_ROW_COUNT - 1; // content height minus borders, status, separator\n const bridge = new NvimBridge(\n Math.max(1, initialDetailW),\n Math.max(1, initialDetailH),\n requestRender,\n );\n state.nvimBridge = bridge.available ? bridge : null;\n state.nvimEnabled = bridge.available;\n\n // Track selectedSessionId to detect changes across renders (for immediate poll)\n let prevSelectedSessionId: string | null | undefined = undefined;\n let debouncedPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ── Polling ─────────────────────────────────────────────────────────────────\n\n async function poll(): Promise<void> {\n try {\n let selectedSession: Session | null = null;\n let planContent = '';\n let strategyContent = '';\n let goalContent = '';\n let logsContent = '';\n let logsCycles: CycleLog[] = [];\n let paneAlive = true;\n let contextFiles: string[] = [];\n\n const listPromise = send({ type: 'list', cwd: state.cwd });\n const statusPromise = state.selectedSessionId\n ? send({ type: 'status', sessionId: state.selectedSessionId, cwd: state.cwd })\n : null;\n\n const [listRes, statusRes] = await Promise.all([\n listPromise,\n statusPromise ?? Promise.resolve(null),\n ]);\n\n const sessions: SessionSummary[] = listRes.ok\n ? ((listRes.data?.sessions as SessionSummary[] | undefined) ?? [])\n : [];\n\n // Batch-check window existence in a single tmux call\n const aliveWindows = listAllWindowIds();\n for (const s of sessions) {\n if (s.status !== 'completed' && s.tmuxWindowId) {\n s.windowAlive = aliveWindows.has(s.tmuxWindowId);\n }\n }\n\n if (state.selectedSessionId) {\n if (statusRes?.ok) {\n selectedSession = (statusRes.data?.session as Session | undefined) ?? null;\n }\n\n // Use cached windowAlive from the session list scan above\n if (selectedSession?.tmuxWindowId) {\n const cached = sessions.find((s) => s.id === state.selectedSessionId);\n paneAlive = cached?.windowAlive ?? false;\n }\n\n try {\n const pp = roadmapPath(state.cwd, state.selectedSessionId);\n if (existsSync(pp)) {\n planContent = readFileSync(pp, 'utf-8');\n }\n } catch {\n // roadmap.md may not exist yet\n }\n\n try {\n const gp = goalPath(state.cwd, state.selectedSessionId);\n if (existsSync(gp)) {\n goalContent = readFileSync(gp, 'utf-8');\n }\n } catch {\n // goal.md may not exist yet\n }\n\n try {\n const sp = strategyPath(state.cwd, state.selectedSessionId);\n if (existsSync(sp)) {\n strategyContent = readFileSync(sp, 'utf-8');\n }\n } catch {\n // strategy.md may not exist yet\n }\n\n try {\n const ld = logsDir(state.cwd, state.selectedSessionId);\n if (existsSync(ld)) {\n // Reset cache when session changes\n if (state.selectedSessionId !== cachedLogSessionId) {\n cachedLogFiles = new Map();\n cachedLogSessionId = state.selectedSessionId;\n }\n\n const files = readdirSync(ld)\n .filter((f) => f.startsWith('cycle-'))\n .sort();\n\n // Remove cache entries for deleted files\n const fileSet = new Set(files);\n for (const key of cachedLogFiles.keys()) {\n if (!fileSet.has(key)) cachedLogFiles.delete(key);\n }\n\n // Only re-read files whose mtime changed\n for (const f of files) {\n const filePath = join(ld, f);\n const mtime = statSync(filePath).mtimeMs;\n const cached = cachedLogFiles.get(f);\n if (!cached || cached.mtime !== mtime) {\n const match = f.match(/cycle-(\\d+)\\.md$/);\n const cycle = match ? parseInt(match[1]!, 10) : 0;\n const content = readFileSync(filePath, 'utf-8');\n cachedLogFiles.set(f, { mtime, cycle, content });\n }\n }\n\n logsCycles = files.map((f) => {\n const entry = cachedLogFiles.get(f)!;\n return { cycle: entry.cycle, content: entry.content };\n });\n logsContent = logsCycles.map((c) => c.content).join('\\n');\n }\n } catch {\n // logs may not exist yet\n }\n\n try {\n const cd = contextDir(state.cwd, state.selectedSessionId);\n if (existsSync(cd)) {\n contextFiles = readdirSync(cd)\n .filter((f) => !f.startsWith('.'))\n .sort();\n }\n } catch {\n // context dir may not exist yet\n }\n }\n\n // Resolve report files in poll (not render) to avoid sync disk reads on keypress\n state.cachedReportBlocks.clear();\n if (selectedSession) {\n for (const agent of selectedSession.agents) {\n state.cachedReportBlocks.set(agent.id, resolveReports(agent.reports));\n }\n }\n\n state.sessions = sessions;\n state.selectedSession = selectedSession;\n state.planContent = planContent;\n state.strategyContent = strategyContent;\n state.goalContent = goalContent;\n state.logsContent = logsContent;\n state.logsCycles = logsCycles;\n state.paneAlive = paneAlive;\n state.contextFiles = contextFiles;\n state.error = null;\n\n // Merge-check editable files; falls back to checktime for readonly buffers\n if (state.nvimEnabled && state.nvimBridge?.ready && state.prevNvimFile) {\n const mergeStatus = state.nvimBridge.mergeCheckOrReload();\n if (mergeStatus === 'clean') {\n notify(state, 'Auto-merged external changes');\n } else if (mergeStatus === 'union') {\n notify(state, 'Auto-merged overlapping edits — review buffer');\n }\n }\n\n requestRender();\n } catch (err) {\n state.error = (err as Error).message;\n requestRender();\n }\n }\n\n // ── Render function ──────────────────────────────────────────────────────────\n\n function render(): void {\n const stdoutRows = process.stdout.rows;\n const stdoutCols = process.stdout.columns;\n state.rows = (typeof stdoutRows === 'number' && stdoutRows > 0) ? stdoutRows : 24;\n state.cols = (typeof stdoutCols === 'number' && stdoutCols > 0) ? stdoutCols : 80;\n\n const buf = createFrameBuffer(state.cols, state.rows);\n\n // Terminal too small\n if (state.cols < 60 || state.rows < 12) {\n writeCenter(buf, Math.floor(state.rows / 2), 'Terminal too small — resize to continue');\n const out = flushFrame(buf.lines, prevFrame);\n writeToStdout(out);\n prevFrame = buf.lines;\n return;\n }\n\n // Compute layout\n const treeWidth = 36;\n const remaining = state.cols - treeWidth;\n const detailWidth = state.showCombinedView ? Math.floor(remaining * 0.6) : remaining;\n const logsWidth = state.showCombinedView ? remaining - detailWidth : 0;\n const contentHeight = state.rows - 3;\n\n const treeRect = { x: 0, y: 0, w: treeWidth, h: contentHeight };\n const detailRect = { x: treeWidth, y: 0, w: detailWidth, h: contentHeight };\n const logsRect = state.showCombinedView\n ? { x: treeWidth + detailWidth, y: 0, w: logsWidth, h: contentHeight }\n : null;\n const bottomY = contentHeight;\n\n // Derive data\n const filteredSessions: SessionSummary[] = state.searchFilter\n ? state.sessions.filter((s) => {\n const q = state.searchFilter!.toLowerCase();\n return s.task.toLowerCase().includes(q) || s.id.toLowerCase().includes(q);\n })\n : state.sessions;\n\n const cacheKey = `${state.expanded.size}:${filteredSessions.length}:${state.selectedSession?.id}:${state.contextFiles.length}:${state.searchFilter}`;\n let nodes: TreeNode[];\n if (cacheKey === state.treeCacheKey && state.cachedTreeNodes !== null) {\n nodes = state.cachedTreeNodes;\n } else {\n nodes = buildTree(\n filteredSessions,\n state.selectedSession,\n state.expanded,\n state.cwd,\n state.contextFiles,\n );\n precomputePrefixes(nodes);\n state.cachedTreeNodes = nodes;\n state.treeCacheKey = cacheKey;\n }\n\n // Cursor stabilization\n stabilizeCursor(state, nodes);\n\n // Cache latest nodes for keypress handler\n latestNodes = nodes;\n\n // Track cursor node identity\n const cursorNode = nodes[state.cursorIndex];\n if (cursorNode) state.cursorNodeId = cursorNode.id;\n\n // Derive selectedSessionId from cursor\n const newSessionId = cursorNode?.sessionId ?? null;\n if (newSessionId !== state.selectedSessionId) {\n state.selectedSessionId = newSessionId;\n state.detailScroll.reset();\n state.logsScroll.reset();\n state.cachedDetailLines = null;\n state.detailCacheKey = '';\n state.prevNvimFile = null;\n state.cachedLogsLines = null;\n state.logsCacheKey = '';\n }\n\n // Trigger debounced poll when session changes (avoids poll storm during rapid scrolling)\n if (state.selectedSessionId !== prevSelectedSessionId) {\n prevSelectedSessionId = state.selectedSessionId;\n if (debouncedPollTimer !== null) clearTimeout(debouncedPollTimer);\n if (state.selectedSessionId !== null) {\n debouncedPollTimer = setTimeout(() => {\n debouncedPollTimer = null;\n void poll();\n }, 80);\n }\n }\n\n // Auto-expand cycle\n autoExpandCycle(state);\n\n // Resolve reports for detail panel\n const agents = state.selectedSession?.agents ?? [];\n const reportAgent =\n state.mode === 'report-detail' ? getAgentForNode(cursorNode, agents) : null;\n const reportBlocks = reportAgent ? (state.cachedReportBlocks.get(reportAgent.id) ?? []) : [];\n\n const detailAgent =\n cursorNode?.type === 'agent' || cursorNode?.type === 'report'\n ? getAgentForNode(cursorNode, agents)\n : null;\n const detailReportBlocks = detailAgent\n ? (state.cachedReportBlocks.get(detailAgent.id) ?? [])\n : [];\n\n // Load context file content (cached to avoid re-read on every render)\n let contextFileContent: string | null = null;\n if (cursorNode?.type === 'context-file') {\n if (cursorNode.filePath !== cachedContextFilePath) {\n cachedContextFilePath = cursorNode.filePath;\n try {\n if (existsSync(cursorNode.filePath)) {\n cachedContextFileContent = readFileSync(cursorNode.filePath, 'utf-8');\n } else {\n cachedContextFileContent = null;\n }\n } catch {\n cachedContextFileContent = null;\n }\n }\n contextFileContent = cachedContextFileContent;\n } else {\n // Clear cache when cursor moves away\n cachedContextFilePath = null;\n cachedContextFileContent = null;\n }\n\n // Panel dirty tracking — compute fingerprints for each panel's inputs\n const treeFocused = state.mode === 'navigate' && state.focusPane === 'tree';\n const treeInputs = `${state.treeCacheKey}:${state.cursorIndex}:${treeFocused}`;\n const bottomInputs = `${state.notification}:${state.error}:${state.mode}:${state.inputText}:${state.inputCursorPos}:${cursorNode?.type}`;\n const overlayMode = state.mode === 'leader' || state.mode === 'copy-menu' || state.mode === 'help' ? state.mode : '';\n\n const hasPrev = prevFrame.length === buf.height;\n const treeDirty = !hasPrev || treeInputs !== prevTreeInputs;\n const bottomDirty = !hasPrev || bottomInputs !== prevBottomInputs;\n const overlayDirty = !hasPrev || overlayMode !== prevOverlayMode;\n\n prevTreeInputs = treeInputs;\n prevBottomInputs = bottomInputs;\n prevOverlayMode = overlayMode;\n\n // Render tree into a narrow buffer (treeWidth-wide) so rows are the right size\n // for concatenation. Cached when clean.\n let treeRows: string[];\n if (treeDirty) {\n const treeBlank = ' '.repeat(treeWidth);\n const treeBuf: import('./render.js').FrameBuffer = {\n lines: Array.from({ length: contentHeight }, () => treeBlank),\n width: treeWidth,\n height: contentHeight,\n };\n renderTreePanel(\n treeBuf,\n { x: 0, y: 0, w: treeWidth, h: contentHeight },\n nodes,\n state.cursorIndex,\n treeFocused,\n );\n cachedTreeRows = treeBuf.lines;\n treeRows = treeBuf.lines;\n } else {\n treeRows = cachedTreeRows;\n }\n\n // Render detail + logs as self-contained row strings, then compose by concatenation.\n // This eliminates all sliceDisplayCols calls — the main scroll bottleneck.\n const detailCtx: DetailContext = {\n nodes,\n session: state.selectedSession,\n agents,\n reportBlocks,\n detailReportBlocks,\n contextFileContent,\n };\n\n let detailRows: string[];\n const composing = state.mode === 'compose';\n\n // Auto-respawn nvim if it died (user quit while viewing goal, roadmap, etc.)\n if (state.nvimEnabled && state.nvimBridge && state.nvimBridge.wasReady && !state.nvimBridge.ready && !state.nvimBridge.respawning) {\n state.nvimBridge.respawning = true;\n state.prevNvimFile = null; // force re-resolve after respawn\n state.nvimBridge.respawn().then(() => {\n state.nvimBridge!.respawning = false;\n requestRender();\n }).catch(() => {\n state.nvimBridge!.respawning = false;\n state.nvimEnabled = false;\n requestRender();\n });\n }\n\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n if (composing) {\n // In compose mode, don't resolve nvim files — nvim is showing the compose temp file\n const action = state.composeAction;\n const label = action ? COMPOSE_HEADERS[action.kind] : 'Compose';\n const statusRows = [\n ' ' + ansiColor(label, 'yellow', true),\n ' ' + ansiDim(':w to submit · Tab to cancel'),\n ];\n detailRows = renderNvimDetailRows(detailRect, state.nvimBridge, true, false, statusRows, true);\n } else {\n // Determine which file(s) neovim should display\n const result = resolveNvimFile(state, cursorNode, detailCtx, state.cwd);\n const resultKey = result ? result.files.map(f => f.path).join('|') : null;\n if (resultKey && resultKey !== state.prevNvimFile) {\n state.nvimBridge.openTabFiles(result!.files);\n state.prevNvimFile = resultKey;\n state.nvimEditable = result!.files.some(f => !f.readonly);\n } else if (!resultKey) {\n state.prevNvimFile = null;\n state.nvimEditable = false;\n }\n\n // Build status rows for the header\n const statusRows = buildStatusRows(cursorNode, state.selectedSession, state);\n detailRows = renderNvimDetailRows(detailRect, state.nvimBridge, state.focusPane === 'detail', state.nvimEditable, statusRows);\n }\n } else {\n detailRows = renderDetailRows(detailRect, state, detailCtx);\n }\n const logsRows = logsRect ? renderLogsRows(logsRect, state) : null;\n\n // Compose panel rows into buffer by concatenation (no slicing/splicing)\n for (let i = 0; i < contentHeight; i++) {\n if (logsRows) {\n buf.lines[i] = treeRows[i]! + detailRows[i]! + logsRows[i]!;\n } else {\n buf.lines[i] = treeRows[i]! + detailRows[i]!;\n }\n }\n\n // Bottom rows\n if (bottomDirty || overlayDirty) {\n renderNotificationRow(buf, bottomY, state.notification, state.error);\n renderInputBar(buf, bottomY + 1, state);\n renderStatusLine(buf, bottomY + 2, state, cursorNode?.type);\n } else {\n copyRows(buf, prevFrame, bottomY, 3);\n }\n\n // Overlays (rendered AFTER panels — overwrites panel content)\n if (overlayMode) {\n if (state.mode === 'leader') renderLeaderOverlay(buf, state.rows, state.cols);\n if (state.mode === 'copy-menu') renderCopyMenuOverlay(buf, state.rows, state.cols);\n if (state.mode === 'help') renderHelpOverlay(buf, state.rows, state.cols);\n }\n\n // Build cursor suffix inside synchronized output block to prevent flicker\n let cursorSuffix: string;\n if (state.focusPane === 'detail' && state.nvimBridge?.ready) {\n const cursor = state.nvimBridge.getCursorPos();\n const absX = detailRect.x + 2 + cursor.x;\n // Nvim content starts after: top border (1) + status rows (STATUS_ROW_COUNT) + separator (1)\n const absY = detailRect.y + 1 + STATUS_ROW_COUNT + 1 + cursor.y;\n cursorSuffix = `\\x1b[${state.nvimBridge.cursorStyle} q\\x1b[?25h\\x1b[${absY + 1};${absX + 1}H`;\n } else {\n cursorSuffix = '\\x1b[0 q\\x1b[?25l';\n }\n\n // Flush diff to stdout with cursor positioning inside sync block\n const out = flushFrame(buf.lines, prevFrame, cursorSuffix);\n writeToStdout(out);\n prevFrame = buf.lines;\n }\n\n // ── InputActions ─────────────────────────────────────────────────────────────\n\n const inputActions: InputActions = {\n getNodes: () => latestNodes,\n getCursorNode: () => latestNodes[state.cursorIndex],\n getAgentForNode: (node) => {\n const agents = state.selectedSession?.agents ?? [];\n return getAgentForNode(node, agents);\n },\n sendAndNotify: (request, successMsg) => {\n void send(request)\n .then((res) => {\n if (res.ok) {\n notify(state, successMsg);\n } else {\n const errMsg = res.error ? res.error : 'Unknown error';\n notify(state, `Error: ${errMsg}`);\n }\n })\n .catch((err: Error) => {\n notify(state, `Error: ${err.message}`);\n });\n },\n send,\n openEditorPopup,\n editInPopup,\n openCompanionPane,\n openClaudeResumePopup,\n openClaudeResumeSession,\n selectWindow,\n selectPane,\n switchToSession,\n openLogPopup,\n openShellPopup,\n openInFileManager,\n copyToClipboard,\n buildSessionContext,\n resolveEditor: () => {\n if (config.editor) return config.editor;\n if (process.env.EDITOR) return process.env.EDITOR;\n return 'nvim';\n },\n cleanup: () => {\n cleanup();\n process.exit(0);\n },\n };\n\n // ── Wire everything together ─────────────────────────────────────────────────\n\n setRenderFunction(render);\n\n const stopKeypress = startKeypressListener((input, key) => {\n handleKeypress(input, key, state, inputActions);\n });\n\n const stopResize = onResize(() => {\n const stdoutRows = process.stdout.rows;\n const stdoutCols = process.stdout.columns;\n state.rows = (typeof stdoutRows === 'number' && stdoutRows > 0) ? stdoutRows : 24;\n state.cols = (typeof stdoutCols === 'number' && stdoutCols > 0) ? stdoutCols : 80;\n prevFrame = []; // force full redraw\n\n // Resize nvim bridge to match new detail panel dimensions\n // Account for: borders (2), status rows (STATUS_ROW_COUNT), separator (1)\n if (state.nvimBridge) {\n const detailW = state.cols - 36; // treeWidth=36\n const contentH = state.rows - 3; // bottomBar=3\n state.nvimBridge.resize(Math.max(1, detailW - 4), Math.max(1, contentH - 2 - STATUS_ROW_COUNT - 1));\n }\n\n requestRender();\n });\n\n // Initial poll + recurring interval\n void poll();\n const pollInterval = setInterval(() => void poll(), 2500);\n\n // Register teardown so cleanup() releases all resources\n const origCleanup = inputActions.cleanup;\n inputActions.cleanup = () => {\n clearInterval(pollInterval);\n if (debouncedPollTimer !== null) clearTimeout(debouncedPollTimer);\n if (state.composePollTimer !== null) clearInterval(state.composePollTimer);\n stopKeypress();\n stopResize();\n state.detailScroll.destroy();\n state.logsScroll.destroy();\n state.nvimBridge?.destroy();\n origCleanup();\n };\n\n // Initial render\n requestRender();\n}\n","import { existsSync, readFileSync, unlinkSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport type { Key } from './terminal.js';\nimport { setRawBypass } from './terminal.js';\nimport {\n type AppState,\n type ComposeAction,\n INPUT_MODES,\n OPTIONAL_INPUT,\n OPTIONAL_COMPOSE,\n requestRender,\n notify,\n} from './state.js';\nimport type { TreeNode } from './types/tree.js';\nimport type { Agent, Session } from '../shared/types.js';\nimport type { Response } from '../shared/protocol.js';\nimport { sessionDir, goalPath, roadmapPath, strategyPath } from '../shared/paths.js';\nimport type { Request } from '../shared/protocol.js';\nimport { findParentIndex } from './lib/tree.js';\n\n// ── Re-exported types (same definition, no React) ─────────────────────────────\n\nexport type LeaderAction =\n | { type: 'enter-copy-menu' }\n | { type: 'copy-path' }\n | { type: 'copy-context' }\n | { type: 'copy-logs' }\n | { type: 'copy-session-id' }\n | { type: 'delete-session' }\n | { type: 'open-logs' }\n | { type: 'open-session-dir' }\n | { type: 'search' }\n | { type: 'jump-to-session'; index: number }\n | { type: 'spawn-agent' }\n | { type: 'message-agent' }\n | { type: 'help' }\n | { type: 'shell-command' }\n | { type: 'jump-to-pane' }\n | { type: 'kill' }\n | { type: 'quit' }\n | { type: 'dismiss' };\n\nexport interface KeybindingHandlers {\n onMoveUp: () => void;\n onMoveDown: () => void;\n onEnter: () => void;\n onLeft: () => void;\n onRight: () => void;\n onSpace: () => void;\n onTab: () => void;\n onMessage: () => void;\n onGoToWindow: () => void;\n onEditGoal: () => void;\n onNewSession: () => void;\n onClaude: () => void;\n onOpenPlan: () => void;\n onQuit: () => void;\n onReRun: () => void;\n onResume: () => void;\n onContinue: () => void;\n onRestartAgent: () => void;\n onRollback: () => void;\n onToggleLogs: () => void;\n onEdit: () => void;\n}\n\n// ── InputActions interface ─────────────────────────────────────────────────────\n\nexport interface InputActions {\n // Navigation context (computed by caller, passed in)\n getNodes: () => TreeNode[];\n getCursorNode: () => TreeNode | undefined;\n getAgentForNode: (node: TreeNode | undefined) => Agent | null;\n\n // Async daemon operations\n sendAndNotify: (request: Request, successMsg: string) => void;\n send: (request: Request) => Promise<Response>;\n\n // Editor/tmux operations (injected — input.ts must not import these directly)\n openEditorPopup: typeof import('./lib/tmux.js').openEditorPopup;\n editInPopup: typeof import('./lib/tmux.js').editInPopup;\n openCompanionPane: typeof import('./lib/tmux.js').openCompanionPane;\n openClaudeResumePopup: typeof import('./lib/tmux.js').openClaudeResumePopup;\n openClaudeResumeSession: typeof import('./lib/tmux.js').openClaudeResumeSession;\n selectWindow: typeof import('./lib/tmux.js').selectWindow;\n selectPane: typeof import('./lib/tmux.js').selectPane;\n switchToSession: typeof import('./lib/tmux.js').switchToSession;\n openLogPopup: typeof import('./lib/tmux.js').openLogPopup;\n openShellPopup: typeof import('./lib/tmux.js').openShellPopup;\n openInFileManager: typeof import('./lib/tmux.js').openInFileManager;\n copyToClipboard: typeof import('./lib/clipboard.js').copyToClipboard;\n buildSessionContext: typeof import('./lib/context.js').buildSessionContext;\n\n // Config\n resolveEditor: () => string;\n\n // Lifecycle\n cleanup: () => void;\n}\n\n// ── Neovim bypass helpers ─────────────────────────────────────────────────────\n\nfunction activateNvimBypass(state: AppState): void {\n setRawBypass((data: string) => {\n // If nvim died, deactivate bypass and let input fall through\n if (!state.nvimBridge?.ready) {\n deactivateNvimBypass();\n state.focusPane = 'tree';\n if (state.mode === 'compose') cancelCompose(state);\n requestRender();\n return false; // not consumed — re-process as normal input\n }\n // Tab (0x09) escapes neovim focus — in compose mode, cancels compose\n if (data === '\\t') {\n if (state.mode === 'compose') {\n cancelCompose(state);\n return true;\n }\n deactivateNvimBypass();\n state.focusPane = state.showCombinedView ? 'logs' : 'tree';\n requestRender();\n return true; // consumed, not forwarded to nvim\n }\n // Everything else → neovim\n state.nvimBridge!.write(data);\n return true;\n });\n}\n\nfunction deactivateNvimBypass(): void {\n setRawBypass(null);\n}\n\n// ── Compose mode helpers ─────────────────────────────────────────────────────\n\nconst COMPOSE_DIR = join(tmpdir(), 'sisyphus-nvim');\n\n/**\n * Enter compose mode: opens a temp file in the nvim detail pane for multi-line input.\n * Returns false if nvim is unavailable (caller should fall back to popup/inline).\n */\nfunction enterComposeMode(state: AppState, action: ComposeAction, actions: InputActions): boolean {\n if (!state.nvimEnabled || !state.nvimBridge?.ready) return false;\n\n mkdirSync(COMPOSE_DIR, { recursive: true });\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const tempFile = join(COMPOSE_DIR, `compose-${id}.md`);\n const signalFile = join(COMPOSE_DIR, `compose-signal-${id}`);\n\n // Create empty temp file\n writeFileSync(tempFile, '', 'utf-8');\n\n // Save current nvim file key so we can force re-resolution on cancel\n state.composePrevNvimFile = state.prevNvimFile;\n state.composeAction = action;\n state.composeTempFile = tempFile;\n state.composeSignalFile = signalFile;\n state.mode = 'compose';\n state.focusPane = 'detail';\n\n // Open in nvim\n state.nvimBridge.openComposeFile(tempFile, signalFile);\n\n // Activate nvim bypass so all input goes to nvim\n activateNvimBypass(state);\n\n // Start polling for signal file\n state.composePollTimer = setInterval(() => {\n checkComposeSignal(state, actions);\n }, 100);\n\n requestRender();\n return true;\n}\n\n/**\n * Cancel compose mode: clean up and restore previous state.\n */\nfunction cancelCompose(state: AppState): void {\n if (state.composePollTimer !== null) {\n clearInterval(state.composePollTimer);\n state.composePollTimer = null;\n }\n\n // Clean up temp files\n if (state.composeTempFile) {\n try { unlinkSync(state.composeTempFile); } catch { /* ignore */ }\n }\n if (state.composeSignalFile) {\n try { unlinkSync(state.composeSignalFile); } catch { /* ignore */ }\n }\n\n // Force nvim to re-resolve files on next render by nulling prevNvimFile\n state.prevNvimFile = null;\n state.composePrevNvimFile = null;\n state.composeAction = null;\n state.composeTempFile = null;\n state.composeSignalFile = null;\n state.mode = 'navigate';\n state.focusPane = 'tree';\n\n deactivateNvimBypass();\n requestRender();\n}\n\n/**\n * Poll for compose signal file. On detection, read content and dispatch action.\n */\nfunction checkComposeSignal(state: AppState, actions: InputActions): void {\n if (!state.composeSignalFile || !state.composeAction) return;\n\n // Auto-cancel if nvim died\n if (!state.nvimBridge?.ready) {\n cancelCompose(state);\n return;\n }\n\n if (!existsSync(state.composeSignalFile)) return;\n\n // Read signal type: \"1\" = submit, \"cancel\" = cancel (from :q / QuitPre)\n let signalContent = '';\n try { signalContent = readFileSync(state.composeSignalFile, 'utf-8').trim(); } catch { /* ignore */ }\n\n if (signalContent === 'cancel') {\n cancelCompose(state);\n return;\n }\n\n // Signal detected — read compose content\n let content = '';\n if (state.composeTempFile) {\n try { content = readFileSync(state.composeTempFile, 'utf-8').trim(); } catch { /* ignore */ }\n }\n\n const action = state.composeAction;\n const required = !OPTIONAL_COMPOSE.has(action.kind);\n\n if (required && !content) {\n // Delete signal file so user can try again\n try { unlinkSync(state.composeSignalFile); } catch { /* ignore */ }\n notify(state, 'Content required');\n return;\n }\n\n // Dispatch the action\n dispatchComposeAction(action, content, state, actions);\n\n // Clean up\n cancelCompose(state);\n}\n\n/**\n * Map compose action kinds to daemon requests.\n */\nfunction dispatchComposeAction(\n action: ComposeAction,\n content: string,\n state: AppState,\n actions: InputActions,\n): void {\n switch (action.kind) {\n case 'new-session':\n actions.sendAndNotify(\n { type: 'start', task: content, cwd: state.cwd },\n 'Session created',\n );\n break;\n\n case 'message-orchestrator':\n actions.sendAndNotify(\n { type: 'message', sessionId: action.sessionId, content },\n 'Message queued',\n );\n break;\n\n case 'resume':\n actions.sendAndNotify(\n { type: 'resume', sessionId: action.sessionId, cwd: state.cwd, message: content || undefined },\n 'Session resumed',\n );\n break;\n\n case 'continue':\n void (async () => {\n try {\n const contRes = await actions.send({ type: 'continue', sessionId: action.sessionId });\n if (!contRes.ok) { notify(state, `Error: ${contRes.error}`); return; }\n actions.sendAndNotify(\n { type: 'resume', sessionId: action.sessionId, cwd: state.cwd, message: content || undefined },\n 'Session continued',\n );\n } catch (err) {\n notify(state, `Error: ${(err as Error).message}`);\n }\n })();\n break;\n\n case 'spawn-agent':\n actions.sendAndNotify(\n {\n type: 'spawn',\n sessionId: action.sessionId,\n agentType: 'default',\n name: 'agent',\n instruction: content,\n },\n 'Agent spawned',\n );\n break;\n\n case 'message-agent':\n actions.sendAndNotify(\n { type: 'message', sessionId: action.sessionId, content, source: { type: 'agent', agentId: action.agentId } },\n `Message sent to ${action.agentId}`,\n );\n break;\n }\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\nfunction handleCancel(state: AppState): void {\n state.mode = 'navigate';\n state.targetAgentId = null;\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n}\n\nfunction expandSessionLatestCycle(state: AppState, node: TreeNode): void {\n if (node.type === 'session' && state.selectedSession?.id === node.sessionId) {\n const cycles = state.selectedSession.orchestratorCycles;\n if (cycles.length > 0) {\n const latest = cycles[cycles.length - 1]!;\n state.expanded.add(`cycle:${node.sessionId}:${latest.cycle}`);\n }\n }\n}\n\n// ── handleSubmit ──────────────────────────────────────────────────────────────\n\nasync function handleSubmit(text: string, state: AppState, actions: InputActions): Promise<void> {\n const selectedSessionId = state.selectedSessionId;\n\n switch (state.mode) {\n case 'resume': {\n if (!selectedSessionId) break;\n actions.sendAndNotify(\n { type: 'resume', sessionId: selectedSessionId, cwd: state.cwd, message: text || undefined },\n 'Session resumed',\n );\n break;\n }\n\n case 'continue': {\n if (!selectedSessionId) break;\n try {\n const contRes = await actions.send({ type: 'continue', sessionId: selectedSessionId });\n if (!contRes.ok) { notify(state, `Error: ${contRes.error}`); break; }\n actions.sendAndNotify(\n { type: 'resume', sessionId: selectedSessionId, cwd: state.cwd, message: text || undefined },\n 'Session continued',\n );\n } catch (err) {\n notify(state, `Error: ${(err as Error).message}`);\n }\n break;\n }\n\n case 'rollback': {\n if (!selectedSessionId) break;\n const toCycle = parseInt(text, 10);\n if (isNaN(toCycle) || toCycle < 1) { notify(state, 'Invalid cycle number'); break; }\n actions.sendAndNotify(\n { type: 'rollback', sessionId: selectedSessionId, cwd: state.cwd, toCycle },\n `Rolled back to cycle ${toCycle} — use [R]esume to respawn`,\n );\n break;\n }\n\n case 'delete-confirm': {\n if (!selectedSessionId) break;\n if (text !== 'yes') { notify(state, 'Delete cancelled (type \"yes\" to confirm)'); break; }\n actions.sendAndNotify(\n { type: 'delete', sessionId: selectedSessionId, cwd: state.cwd },\n 'Session deleted',\n );\n break;\n }\n\n case 'spawn-agent': {\n if (!selectedSessionId) break;\n if (!text.trim()) { notify(state, 'Instruction required'); break; }\n actions.sendAndNotify(\n {\n type: 'spawn',\n sessionId: selectedSessionId,\n agentType: 'default',\n name: 'agent',\n instruction: text,\n },\n 'Agent spawned',\n );\n break;\n }\n\n case 'search': {\n state.searchFilter = text.trim() || null;\n break;\n }\n\n case 'message-agent': {\n if (!selectedSessionId || !state.targetAgentId) break;\n actions.sendAndNotify(\n { type: 'message', sessionId: selectedSessionId, content: text, source: { type: 'agent', agentId: state.targetAgentId } },\n `Message sent to ${state.targetAgentId}`,\n );\n state.targetAgentId = null;\n break;\n }\n\n case 'shell-command': {\n if (!text.trim()) break;\n try {\n actions.openShellPopup(state.cwd, text);\n } catch {\n notify(state, 'Failed to run shell command');\n }\n break;\n }\n }\n\n state.mode = 'navigate';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n}\n\n// ── handleInputBarKey ─────────────────────────────────────────────────────────\n\nfunction handleInputBarKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (key.return) {\n if (OPTIONAL_INPUT.has(state.mode) || state.inputText.trim()) {\n void handleSubmit(state.inputText.trim(), state, actions);\n }\n return;\n }\n\n if (key.escape) {\n handleCancel(state);\n return;\n }\n\n if (key.leftArrow) {\n state.inputCursorPos = Math.max(0, state.inputCursorPos - 1);\n requestRender();\n return;\n }\n\n if (key.rightArrow) {\n state.inputCursorPos = Math.min(state.inputText.length, state.inputCursorPos + 1);\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'a') {\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'e') {\n state.inputCursorPos = state.inputText.length;\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'k') {\n state.inputText = state.inputText.slice(0, state.inputCursorPos);\n // cursorPos stays the same (now at end)\n requestRender();\n return;\n }\n\n if (key.ctrl && input === 'u') {\n state.inputText = state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n if (key.backspace) {\n if (state.inputCursorPos > 0) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos - 1) +\n state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos -= 1;\n requestRender();\n }\n return;\n }\n\n if (key.delete) {\n if (state.inputCursorPos < state.inputText.length) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos) +\n state.inputText.slice(state.inputCursorPos + 1);\n requestRender();\n }\n return;\n }\n\n if (input && !key.ctrl && !key.meta) {\n state.inputText =\n state.inputText.slice(0, state.inputCursorPos) +\n input +\n state.inputText.slice(state.inputCursorPos);\n state.inputCursorPos += input.length;\n requestRender();\n }\n}\n\n// ── handleReportDetailKey ─────────────────────────────────────────────────────\n\nfunction handleReportDetailKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (key.escape || key.return) {\n handleCancel(state);\n return;\n }\n if (key.upArrow) {\n state.detailScroll.scrollBy(-1);\n return;\n }\n if (key.downArrow) {\n state.detailScroll.scrollBy(1);\n return;\n }\n}\n\n// ── handleLeaderKey ───────────────────────────────────────────────────────────\n\nfunction handleLeaderAction(action: LeaderAction, state: AppState, actions: InputActions): void {\n const nodes = actions.getNodes();\n const cursorNode = actions.getCursorNode();\n const session = state.selectedSession;\n const selectedSessionId = state.selectedSessionId;\n const agents = session?.agents ?? [];\n\n switch (action.type) {\n case 'enter-copy-menu':\n state.mode = 'copy-menu';\n requestRender();\n return;\n\n case 'copy-path': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n const path = sessionDir(state.cwd, selectedSessionId);\n try {\n actions.copyToClipboard(path);\n notify(state, `Copied path (${path})`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'copy-context': {\n if (!selectedSessionId || !session) { notify(state, 'No session selected'); break; }\n try {\n const xml = actions.buildSessionContext(session, state.cwd);\n actions.copyToClipboard(xml);\n notify(state, `Copied context (${xml.length} chars)`);\n } catch {\n notify(state, 'Failed to copy context');\n }\n break;\n }\n\n case 'copy-logs': {\n if (!state.logsContent) { notify(state, 'No logs content'); break; }\n try {\n actions.copyToClipboard(state.logsContent);\n notify(state, `Copied logs (${state.logsContent.length} chars)`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'copy-session-id': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n try {\n actions.copyToClipboard(selectedSessionId);\n notify(state, `Copied session ID (${selectedSessionId})`);\n } catch {\n notify(state, 'Failed to copy to clipboard');\n }\n break;\n }\n\n case 'delete-session': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n state.mode = 'delete-confirm';\n requestRender();\n return;\n }\n\n case 'open-logs': {\n try {\n actions.openLogPopup();\n } catch {\n notify(state, 'Failed to open log popup');\n }\n break;\n }\n\n case 'open-session-dir': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n try {\n actions.openInFileManager(sessionDir(state.cwd, selectedSessionId));\n } catch {\n notify(state, 'Failed to open session directory');\n }\n break;\n }\n\n case 'search':\n state.mode = 'search';\n requestRender();\n return;\n\n case 'jump-to-session': {\n let count = 0;\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i]?.type === 'session') {\n count++;\n if (count === action.index) {\n state.cursorIndex = i;\n state.cursorNodeId = nodes[i]!.id;\n break;\n }\n }\n }\n break;\n }\n\n case 'spawn-agent': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n if (enterComposeMode(state, { kind: 'spawn-agent', sessionId: selectedSessionId }, actions)) return;\n // Fallback to inline\n state.mode = 'spawn-agent';\n requestRender();\n return;\n }\n\n case 'message-agent': {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent) { notify(state, 'Cursor must be on an agent'); break; }\n if (enterComposeMode(state, { kind: 'message-agent', sessionId: selectedSessionId!, agentId: agent.id }, actions)) return;\n // Fallback to inline\n state.targetAgentId = agent.id;\n state.mode = 'message-agent';\n requestRender();\n return;\n }\n\n case 'help':\n state.mode = 'help';\n requestRender();\n return;\n\n case 'shell-command': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n state.mode = 'shell-command';\n requestRender();\n return;\n }\n\n case 'jump-to-pane': {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent?.paneId) { notify(state, 'Select an agent with an active pane'); break; }\n if (session?.tmuxSessionName) actions.switchToSession(session.tmuxSessionName);\n if (session?.tmuxWindowId) actions.selectWindow(session.tmuxWindowId);\n actions.selectPane(agent.paneId);\n break;\n }\n\n case 'kill': {\n if (!selectedSessionId) { notify(state, 'No session selected'); break; }\n const node = nodes[state.cursorIndex];\n if (node && (node.type === 'agent' || node.type === 'report')) {\n const agentId = node.agentId;\n const agent = agents.find((a) => a.id === agentId);\n if (agent?.status !== 'running') { notify(state, `Agent ${agentId} is not running`); break; }\n actions.sendAndNotify({ type: 'kill-agent', sessionId: selectedSessionId, agentId }, `Killed ${agentId}`);\n } else {\n actions.sendAndNotify({ type: 'kill', sessionId: selectedSessionId }, 'Session killed');\n }\n break;\n }\n\n case 'quit':\n actions.cleanup();\n return;\n\n case 'dismiss':\n break;\n }\n\n state.mode = 'navigate';\n requestRender();\n}\n\nfunction handleLeaderKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n if (state.mode === 'leader') {\n if (key.escape) { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n if (input === 'y') { handleLeaderAction({ type: 'enter-copy-menu' }, state, actions); return; }\n if (input === 'd') { handleLeaderAction({ type: 'delete-session' }, state, actions); return; }\n if (input === 'l') { handleLeaderAction({ type: 'open-logs' }, state, actions); return; }\n if (input === 'o') { handleLeaderAction({ type: 'open-session-dir' }, state, actions); return; }\n if (input === '/') { handleLeaderAction({ type: 'search' }, state, actions); return; }\n if (input === 'a') { handleLeaderAction({ type: 'spawn-agent' }, state, actions); return; }\n if (input === 'm') { handleLeaderAction({ type: 'message-agent' }, state, actions); return; }\n if (input === '?') { handleLeaderAction({ type: 'help' }, state, actions); return; }\n if (input === '!') { handleLeaderAction({ type: 'shell-command' }, state, actions); return; }\n if (input === 'j') { handleLeaderAction({ type: 'jump-to-pane' }, state, actions); return; }\n if (input === 'k') { handleLeaderAction({ type: 'kill' }, state, actions); return; }\n if (input === 'q') { handleLeaderAction({ type: 'quit' }, state, actions); return; }\n const digit = parseInt(input, 10);\n if (!isNaN(digit) && digit >= 1 && digit <= 9) {\n handleLeaderAction({ type: 'jump-to-session', index: digit }, state, actions);\n return;\n }\n handleLeaderAction({ type: 'dismiss' }, state, actions);\n return;\n }\n\n if (state.mode === 'copy-menu') {\n if (key.escape) { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n if (input === 'p') { handleLeaderAction({ type: 'copy-path' }, state, actions); return; }\n if (input === 'C') { handleLeaderAction({ type: 'copy-context' }, state, actions); return; }\n if (input === 'l') { handleLeaderAction({ type: 'copy-logs' }, state, actions); return; }\n if (input === 's') { handleLeaderAction({ type: 'copy-session-id' }, state, actions); return; }\n handleLeaderAction({ type: 'dismiss' }, state, actions);\n return;\n }\n\n if (state.mode === 'help') {\n if (key.escape || input === '?') { handleLeaderAction({ type: 'dismiss' }, state, actions); return; }\n // any other key: ignore\n }\n}\n\n// ── handleNavigateKey ─────────────────────────────────────────────────────────\n\nfunction handleNavigateKey(input: string, key: Key, state: AppState, actions: InputActions): void {\n const nodes = actions.getNodes();\n const cursorNode = actions.getCursorNode();\n const session = state.selectedSession;\n\n // j / ↑\n if (key.upArrow || input === 'k') {\n if (state.focusPane === 'detail') {\n state.detailScroll.scrollBy(-1);\n } else if (state.focusPane === 'logs') {\n state.logsScroll.scrollBy(-1);\n } else {\n state.cursorIndex = Math.max(0, state.cursorIndex - 1);\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n return;\n }\n\n // j / ↓\n if (key.downArrow || input === 'j') {\n if (state.focusPane === 'detail') {\n state.detailScroll.scrollBy(1);\n } else if (state.focusPane === 'logs') {\n state.logsScroll.scrollBy(1);\n } else {\n state.cursorIndex = Math.min(nodes.length - 1, state.cursorIndex + 1);\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n return;\n }\n\n // h / ←\n if (key.leftArrow || input === 'h') {\n if (state.focusPane === 'logs') {\n state.focusPane = 'detail';\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n activateNvimBypass(state);\n }\n requestRender();\n return;\n }\n if (state.focusPane === 'detail') {\n deactivateNvimBypass();\n state.focusPane = 'tree';\n requestRender();\n return;\n }\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expanded) {\n state.expanded.delete(node.id);\n requestRender();\n } else {\n const parentIdx = findParentIndex(nodes, state.cursorIndex);\n if (parentIdx !== state.cursorIndex) {\n state.cursorIndex = parentIdx;\n state.cursorNodeId = nodes[parentIdx]?.id ?? state.cursorNodeId;\n requestRender();\n }\n }\n return;\n }\n\n // l / →\n if (key.rightArrow || input === 'l') {\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expandable && !node.expanded) {\n state.expanded.add(node.id);\n expandSessionLatestCycle(state, node);\n requestRender();\n } else if (node.expandable && node.expanded) {\n // Move cursor to first child\n if (state.cursorIndex + 1 < nodes.length && nodes[state.cursorIndex + 1]!.depth > node.depth) {\n state.cursorIndex += 1;\n state.cursorNodeId = nodes[state.cursorIndex]?.id ?? state.cursorNodeId;\n requestRender();\n }\n }\n return;\n }\n\n // tab: cycle focus panes\n if (key.tab) {\n if (state.focusPane === 'tree') {\n state.focusPane = 'detail';\n if (state.nvimEnabled && state.nvimBridge?.ready) {\n activateNvimBypass(state);\n }\n } else if (state.focusPane === 'detail') {\n deactivateNvimBypass();\n state.focusPane = state.showCombinedView ? 'logs' : 'tree';\n } else {\n state.focusPane = 'tree';\n }\n requestRender();\n return;\n }\n\n // space: enter leader mode\n if (input === ' ') {\n state.mode = 'leader';\n requestRender();\n return;\n }\n\n // enter: expand / report-detail / open context file\n if (key.return) {\n const node = nodes[state.cursorIndex];\n if (!node) return;\n if (node.expandable && !node.expanded) {\n state.expanded.add(node.id);\n expandSessionLatestCycle(state, node);\n requestRender();\n } else if (node.type === 'report') {\n state.targetAgentId = node.agentId;\n state.mode = 'report-detail';\n requestRender();\n } else if (node.type === 'context-file') {\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, node.filePath);\n } catch {\n notify(state, 'Failed to open file in editor');\n }\n }\n return;\n }\n\n // m: message orchestrator\n if (input === 'm') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n if (enterComposeMode(state, { kind: 'message-orchestrator', sessionId: state.selectedSessionId }, actions)) return;\n // Fallback to popup\n const editor = actions.resolveEditor();\n try {\n const content = actions.editInPopup(state.cwd, editor);\n if (content) {\n actions.sendAndNotify(\n { type: 'message', sessionId: state.selectedSessionId, content },\n 'Message queued',\n );\n }\n } catch {\n notify(state, 'Failed to open editor');\n }\n return;\n }\n\n // w: go to tmux window (or resume orchestrator Claude session if completed)\n if (input === 'w') {\n if (!session || !state.selectedSessionId) { notify(state, 'No session selected'); return; }\n\n if (session.status === 'completed') {\n const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];\n const claudeSessionId = lastCycle?.claudeSessionId;\n if (!claudeSessionId) { notify(state, 'No orchestrator Claude session ID available'); return; }\n try {\n const label = session.name ?? state.selectedSessionId!.slice(0, 8);\n const sessionName = actions.openClaudeResumeSession(state.cwd, claudeSessionId, label);\n actions.switchToSession(sessionName);\n } catch {\n notify(state, 'Failed to open Claude session');\n }\n return;\n }\n\n if (state.paneAlive && session.tmuxWindowId) {\n if (session.tmuxSessionName) actions.switchToSession(session.tmuxSessionName);\n actions.selectWindow(session.tmuxWindowId);\n return;\n }\n\n // Window is dead — reopen via daemon\n void (async () => {\n try {\n const res = await actions.send({ type: 'reopen-window', sessionId: state.selectedSessionId!, cwd: state.cwd });\n if (!res.ok) { notify(state, `Error: ${res.error}`); return; }\n const data = res.data as { tmuxSessionName: string; tmuxWindowId: string };\n actions.switchToSession(data.tmuxSessionName);\n actions.selectWindow(data.tmuxWindowId);\n } catch (err) {\n notify(state, `Error: ${(err as Error).message}`);\n }\n })();\n return;\n }\n\n // o: open/resume claude session for agent or orchestrator cycle\n if (input === 'o') {\n if (!cursorNode) { notify(state, 'No node selected'); return; }\n let claudeSessionId: string | undefined;\n if (cursorNode.type === 'agent' || cursorNode.type === 'report') {\n const agent = actions.getAgentForNode(cursorNode);\n claudeSessionId = agent?.claudeSessionId ?? undefined;\n } else if (cursorNode.type === 'cycle' && session) {\n const cycle = session.orchestratorCycles.find(c => c.cycle === cursorNode.cycleNumber);\n claudeSessionId = cycle?.claudeSessionId;\n }\n if (!claudeSessionId) { notify(state, 'No Claude session ID available'); return; }\n try {\n actions.openClaudeResumePopup(state.cwd, claudeSessionId);\n } catch {\n notify(state, 'Failed to open Claude session');\n }\n return;\n }\n\n // g: edit goal\n if (input === 'g') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const gp = goalPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, gp, { w: '80', h: '50%' });\n } catch {\n notify(state, `Failed to open goal in ${editor}`);\n }\n return;\n }\n\n // n: new session\n if (input === 'n') {\n if (enterComposeMode(state, { kind: 'new-session' }, actions)) return;\n // Fallback to popup\n const editor = actions.resolveEditor();\n try {\n const content = actions.editInPopup(state.cwd, editor);\n if (content) {\n actions.sendAndNotify(\n { type: 'start', task: content, cwd: state.cwd },\n 'Session created',\n );\n }\n } catch {\n notify(state, 'Failed to open editor');\n }\n return;\n }\n\n // c: open companion pane\n if (input === 'c') {\n try {\n actions.openCompanionPane(state.cwd);\n } catch {\n notify(state, 'Failed to open companion pane');\n }\n return;\n }\n\n // p: open plan/roadmap\n if (input === 'p') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const pp = roadmapPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, pp);\n } catch {\n notify(state, `Failed to open roadmap in ${editor}`);\n }\n return;\n }\n\n // q: quit\n if (input === 'q') {\n actions.cleanup();\n }\n\n // r: re-run agent\n if (input === 'r') {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent || !state.selectedSessionId) { notify(state, 'Select an agent to re-run'); return; }\n actions.sendAndNotify(\n {\n type: 'spawn',\n sessionId: state.selectedSessionId,\n agentType: agent.agentType,\n name: `${agent.name}-retry`,\n instruction: agent.instruction,\n },\n `Re-spawned ${agent.name}`,\n );\n return;\n }\n\n // R: enter resume mode\n if (input === 'R') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n if (session?.status === 'active' && state.paneAlive) { notify(state, 'Session already active'); return; }\n if (enterComposeMode(state, { kind: 'resume', sessionId: state.selectedSessionId }, actions)) return;\n // Fallback to inline\n state.mode = 'resume';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n // C: enter continue mode\n if (input === 'C') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n if (session?.status !== 'completed') { notify(state, 'Session not completed'); return; }\n if (enterComposeMode(state, { kind: 'continue', sessionId: state.selectedSessionId }, actions)) return;\n // Fallback to inline\n state.mode = 'continue';\n state.inputText = '';\n state.inputCursorPos = 0;\n requestRender();\n return;\n }\n\n // x: restart agent\n if (input === 'x') {\n const agent = actions.getAgentForNode(cursorNode);\n if (!agent || !state.selectedSessionId) { notify(state, 'Select an agent to restart'); return; }\n actions.sendAndNotify(\n { type: 'restart-agent', sessionId: state.selectedSessionId, agentId: agent.id },\n `Restarted ${agent.id}`,\n );\n return;\n }\n\n // b: enter rollback mode — pre-fill with cycle number if cursor is on a cycle node\n if (input === 'b') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const defaultText = cursorNode?.type === 'cycle' ? String(cursorNode.cycleNumber) : undefined;\n state.mode = 'rollback';\n if (defaultText) {\n state.inputText = defaultText;\n state.inputCursorPos = defaultText.length;\n } else {\n state.inputText = '';\n state.inputCursorPos = 0;\n }\n requestRender();\n return;\n }\n\n // e: edit context file\n if (input === 'e') {\n if (!cursorNode || cursorNode.type !== 'context-file') return;\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, cursorNode.filePath);\n } catch {\n notify(state, 'Failed to open file in editor');\n }\n return;\n }\n\n // S: edit strategy\n if (input === 'S') {\n if (!state.selectedSessionId) { notify(state, 'No session selected'); return; }\n const sp = strategyPath(state.cwd, state.selectedSessionId);\n const editor = actions.resolveEditor();\n try {\n actions.openEditorPopup(state.cwd, editor, sp);\n } catch {\n notify(state, `Failed to open strategy in ${editor}`);\n }\n return;\n }\n\n // t: toggle logs panel\n if (input === 't') {\n if (state.showCombinedView) {\n if (state.focusPane === 'logs') state.focusPane = 'detail';\n state.logsScroll.reset();\n }\n state.showCombinedView = !state.showCombinedView;\n requestRender();\n return;\n }\n}\n\n// ── Main dispatch ─────────────────────────────────────────────────────────────\n\nexport function handleKeypress(input: string, key: Key, state: AppState, actions: InputActions): void {\n // Compose mode: all input goes through nvim bypass — nothing to handle here\n if (state.mode === 'compose') return;\n\n if (INPUT_MODES.has(state.mode)) {\n handleInputBarKey(input, key, state, actions);\n } else if (state.mode === 'leader' || state.mode === 'copy-menu' || state.mode === 'help') {\n handleLeaderKey(input, key, state, actions);\n } else if (state.mode === 'report-detail') {\n handleReportDetailKey(input, key, state, actions);\n } else {\n handleNavigateKey(input, key, state, actions);\n }\n}\n","import { join } from 'node:path';\nimport { messageSourceLabel } from './format.js';\nimport type {\n TreeNode,\n SessionTreeNode,\n CycleTreeNode,\n AgentTreeNode,\n ReportTreeNode,\n MessagesTreeNode,\n MessageTreeNode,\n ContextTreeNode,\n ContextFileTreeNode,\n} from '../types/tree.js';\nimport type { Session } from '../../shared/types.js';\nimport type { SessionSummary } from '../state.js';\nimport { contextDir } from '../../shared/paths.js';\n\n/** Sort priority: active+open=0, active+closed=1, paused+open=2, paused+closed=3, completed=4 */\nfunction sessionSortKey(s: SessionSummary): number {\n if (s.status === 'completed') return 4;\n // Use cached windowAlive from polling hook (avoids execSync in render path)\n const open = s.windowAlive ?? false;\n if (s.status === 'active') return open ? 0 : 1;\n // paused\n return open ? 2 : 3;\n}\n\nexport function buildTree(\n sessions: SessionSummary[],\n selectedSession: Session | null,\n expanded: Set<string>,\n cwd: string,\n polledContextFiles: string[] = [],\n): TreeNode[] {\n const nodes: TreeNode[] = [];\n\n const sorted = [...sessions].sort((a, b) => {\n const keyDiff = sessionSortKey(a) - sessionSortKey(b);\n if (keyDiff !== 0) return keyDiff;\n // Most recent first within each group\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n for (const s of sorted) {\n const sessionNodeId = `session:${s.id}`;\n const isSelected = selectedSession?.id === s.id;\n const isExpanded = expanded.has(sessionNodeId);\n\n nodes.push({\n id: sessionNodeId,\n type: 'session',\n depth: 0,\n expandable: true,\n expanded: isExpanded && isSelected,\n sessionId: s.id,\n name: s.name,\n task: s.task,\n status: s.status,\n cycleCount: isSelected ? (selectedSession?.orchestratorCycles.length ?? 0) : 0,\n agentCount: s.agentCount,\n createdAt: s.createdAt,\n completedAt: isSelected ? selectedSession?.completedAt : undefined,\n } satisfies SessionTreeNode);\n\n // Only emit children for the selected+expanded session\n if (!isExpanded || !isSelected || !selectedSession) continue;\n\n const cycles = [...selectedSession.orchestratorCycles].reverse();\n const allSpawnedIds = new Set(\n selectedSession.orchestratorCycles.flatMap((c) => c.agentsSpawned),\n );\n\n for (const cycle of cycles) {\n const cycleNodeId = `cycle:${s.id}:${cycle.cycle}`;\n const cycleExpanded = expanded.has(cycleNodeId);\n\n // Agents belonging to this cycle\n const cycleAgents = selectedSession.agents.filter((a) =>\n cycle.agentsSpawned.includes(a.id),\n );\n\n // For the latest cycle, include unassigned agents\n const isLatest = cycle === cycles[0];\n const unassigned = isLatest\n ? selectedSession.agents.filter((a) => !allSpawnedIds.has(a.id))\n : [];\n const allCycleAgents = [...cycleAgents, ...unassigned];\n\n nodes.push({\n id: cycleNodeId,\n type: 'cycle',\n depth: 1,\n expandable: allCycleAgents.length > 0,\n expanded: cycleExpanded,\n sessionId: s.id,\n cycleNumber: cycle.cycle,\n timestamp: cycle.timestamp,\n completedAt: cycle.completedAt,\n activeMs: cycle.activeMs,\n agentCount: allCycleAgents.length,\n mode: cycle.mode,\n } satisfies CycleTreeNode);\n\n if (!cycleExpanded) continue;\n\n for (const agent of allCycleAgents) {\n const agentNodeId = `agent:${s.id}:${agent.id}`;\n const hasReports = agent.reports.length > 0;\n const agentExpanded = expanded.has(agentNodeId);\n\n nodes.push({\n id: agentNodeId,\n type: 'agent',\n depth: 2,\n expandable: hasReports,\n expanded: agentExpanded && hasReports,\n sessionId: s.id,\n agentId: agent.id,\n name: agent.name,\n agentType: agent.agentType,\n status: agent.status,\n spawnedAt: agent.spawnedAt,\n completedAt: agent.completedAt,\n activeMs: agent.activeMs,\n reportCount: agent.reports.length,\n } satisfies AgentTreeNode);\n\n if (!agentExpanded || !hasReports) continue;\n\n for (let ri = 0; ri < agent.reports.length; ri++) {\n const report = agent.reports[ri]!;\n nodes.push({\n id: `report:${s.id}:${agent.id}:${ri}`,\n type: 'report',\n depth: 3,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n reportIndex: ri,\n reportType: report.type,\n timestamp: report.timestamp,\n agentId: agent.id,\n } satisfies ReportTreeNode);\n }\n }\n }\n\n // Messages group\n const messages = selectedSession.messages ?? [];\n if (messages.length > 0) {\n const msgsNodeId = `messages:${s.id}`;\n const msgsExpanded = expanded.has(msgsNodeId);\n\n nodes.push({\n id: msgsNodeId,\n type: 'messages',\n depth: 1,\n expandable: true,\n expanded: msgsExpanded,\n sessionId: s.id,\n count: messages.length,\n } satisfies MessagesTreeNode);\n\n if (msgsExpanded) {\n for (const msg of messages) {\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const sourceLabel = messageSourceLabel(msg.source.type, agentId);\n\n nodes.push({\n id: `message:${s.id}:${msg.id}`,\n type: 'message',\n depth: 2,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n messageId: msg.id,\n source: sourceLabel,\n summary: msg.summary || msg.content,\n timestamp: msg.timestamp,\n } satisfies MessageTreeNode);\n }\n }\n }\n\n // Context group — use polled file list for the selected session (avoids sync I/O in render)\n const contextFiles = isSelected ? polledContextFiles : [];\n\n const ctxNodeId = `context:${s.id}`;\n const ctxExpanded = expanded.has(ctxNodeId);\n\n nodes.push({\n id: ctxNodeId,\n type: 'context',\n depth: 1,\n expandable: contextFiles.length > 0,\n expanded: ctxExpanded && contextFiles.length > 0,\n sessionId: s.id,\n fileCount: contextFiles.length,\n } satisfies ContextTreeNode);\n\n if (ctxExpanded && contextFiles.length > 0) {\n for (const filename of contextFiles) {\n nodes.push({\n id: `context-file:${s.id}:${filename}`,\n type: 'context-file',\n depth: 2,\n expandable: false,\n expanded: false,\n sessionId: s.id,\n label: filename,\n filePath: join(contextDir(cwd, s.id), filename),\n } satisfies ContextFileTreeNode);\n }\n }\n }\n\n return nodes;\n}\n\n/** Find the parent node index for a given node index */\nexport function findParentIndex(nodes: TreeNode[], index: number): number {\n const node = nodes[index];\n if (!node || node.depth === 0) return index;\n const targetDepth = node.depth - 1;\n for (let i = index - 1; i >= 0; i--) {\n if (nodes[i]!.depth === targetDepth) return i;\n if (nodes[i]!.depth < targetDepth) return i;\n }\n return 0;\n}\n","import stringWidth from 'string-width';\n\nexport { formatDuration, statusColor } from '../../shared/format.js';\n\nexport function formatTimeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(minutes / 60);\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'just now';\n}\n\nexport function formatTime(iso: string): string {\n const d = new Date(iso);\n return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;\n}\n\nexport function truncate(text: string, max: number): string {\n // Collapse newlines and normalize wide emoji (see cleanMarkdown for rationale)\n const clean = text.replace(/\\n/g, ' ').replace(/✅/g, '✓').replace(/❌/g, '✗').replace(/\\p{Emoji_Presentation}/gu, '');\n if (max < 4) return clean.slice(0, max);\n const w = stringWidth(clean);\n if (w <= max) return clean;\n // Trim from the end until we fit, respecting display width\n let result = clean;\n while (stringWidth(result) > max - 1 && result.length > 0) {\n // Try to break at a word boundary\n const cut = result.lastIndexOf(' ', result.length - 2);\n if (cut > max * 0.4) {\n result = result.slice(0, cut);\n } else {\n result = result.slice(0, result.length - 1);\n }\n }\n return result + '…';\n}\n\n/** Strip markdown syntax to plain text */\nexport function stripMarkdown(text: string): string {\n return text\n .replace(/^#{1,6}\\s+/gm, '')\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`{1,3}[^`]*`{1,3}/g, '')\n .replace(/^[-*+]\\s+/gm, '')\n .replace(/^\\d+[.)]\\s+/gm, '')\n .replace(/\\[(.+?)\\]\\(.+?\\)/g, '$1')\n .replace(/^>\\s+/gm, '')\n .replace(/---+/g, '')\n .replace(/\\n+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Extract the first meaningful sentence from markdown-heavy text.\n * Much better than blind truncation — finds actual content.\n */\nexport function extractFirstSentence(text: string, maxLen: number): string {\n const lines = text.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('#')) continue;\n if (trimmed.startsWith('---')) continue;\n if (trimmed.startsWith('```')) continue;\n if (trimmed.startsWith('|')) continue;\n if (trimmed.length < 5) continue;\n\n const cleaned = stripMarkdown(trimmed);\n if (cleaned.length < 5) continue;\n\n // Try to end at a sentence boundary\n const periodIdx = cleaned.indexOf('. ');\n if (periodIdx > 10 && periodIdx < maxLen) {\n return cleaned.slice(0, periodIdx + 1);\n }\n return truncate(cleaned, maxLen);\n }\n const fallback = stripMarkdown(text);\n return truncate(fallback, maxLen);\n}\n\nexport function durationColor(startOrMs: string | number, endIso?: string | null): string {\n let totalMs: number;\n if (typeof startOrMs === 'number') {\n totalMs = startOrMs;\n } else {\n const start = new Date(startOrMs).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n totalMs = end - start;\n }\n if (totalMs < 10 * 60 * 1000) return '';\n if (totalMs < 30 * 60 * 1000) return 'yellow';\n return 'red';\n}\n\nexport function statusIndicator(status: string): string {\n switch (status) {\n case 'active':\n return '▶';\n case 'completed':\n return '✓';\n case 'paused':\n return '⏸';\n default:\n return '·';\n }\n}\n\nexport function agentStatusIcon(status: string): string {\n switch (status) {\n case 'running':\n return '▶';\n case 'completed':\n return '✓';\n case 'killed':\n return '✕';\n case 'crashed':\n return '!';\n case 'lost':\n return '?';\n default:\n return '·';\n }\n}\n\nexport function agentTypeColor(agentType: string | undefined): string | undefined {\n if (!agentType) return undefined;\n const t = agentType.toLowerCase();\n if (t.includes('research')) return 'blue';\n if (t.includes('implement') || t.includes('code')) return 'green';\n if (t.includes('review') || t.includes('test')) return 'magenta';\n if (t.includes('plan')) return 'yellow';\n return undefined;\n}\n\nexport function divider(width: number, char: string = '─'): string {\n return char.repeat(Math.max(0, width));\n}\n\n/** Strip YAML frontmatter (--- ... ---) from markdown content */\nexport function stripFrontmatter(content: string): string {\n if (!content.startsWith('---')) return content;\n const end = content.indexOf('\\n---', 3);\n if (end === -1) return content;\n return content.slice(end + 4).trimStart();\n}\n\n/** Clean inline markdown syntax for terminal display */\nexport function cleanMarkdown(line: string): string {\n return line\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`(.+?)`/g, '$1')\n .replace(/\\[(.+?)\\]\\(.+?\\)/g, '$1')\n // Normalize wide emoji → single-width alternatives.\n // Ink's @alcalzone/ansi-tokenize treats emoji as width=1, but terminals\n // render them as width=2. This mismatch causes lines to overflow by 1\n // column, wrapping the right border to the next row (phantom blank lines).\n .replace(/✅/g, '✓')\n .replace(/❌/g, '✗')\n .replace(/\\p{Emoji_Presentation}/gu, '');\n}\n\n// Shared line types for scrollable panels\n\nexport type Seg = {\n text: string;\n color?: string;\n bold?: boolean;\n dim?: boolean;\n italic?: boolean;\n inverse?: boolean;\n};\n\nexport type DetailLine = Seg[];\n\nexport function seg(text: string, opts?: Partial<Omit<Seg, 'text'>>): Seg {\n return { text, ...opts };\n}\n\n/** Create a single-segment DetailLine */\nexport function singleLine(text: string, opts?: Partial<Omit<Seg, 'text'>>): DetailLine {\n return [seg(text, opts)];\n}\n\nexport function messageSourceLabel(source: string, agentId?: string): string {\n if (source === 'user') return 'You';\n if (source === 'agent') {\n if (!agentId) throw new Error('agentId required when source is agent');\n return agentId;\n }\n return 'system';\n}\n\nexport function messageSourceColor(source: string): string {\n if (source === 'user') return 'yellow';\n if (source === 'agent') return 'cyan';\n return 'gray';\n}\n\nexport function reportBadge(type: string): { label: string; color: string } {\n return type === 'final'\n ? { label: 'FINAL', color: 'cyan' }\n : { label: 'UPDATE', color: 'yellow' };\n}\n\nexport function agentDisplayName(agent: { name: string; id: string; agentType: string }): string {\n return agent.name !== agent.id ? agent.name : agent.agentType;\n}\n\nexport function abbreviateMode(mode: string | undefined | null): string {\n if (!mode) return '';\n if (mode === 'implementation') return 'impl';\n if (mode === 'planning') return 'plan';\n if (mode === 'strategy') return 'strat';\n if (mode === 'validation') return 'valid';\n return mode;\n}\n\nexport function ansiBold(text: string): string {\n return `\\x1b[1m${text}\\x1b[0m`;\n}\n\nexport function ansiDim(text: string): string {\n return `\\x1b[2m${text}\\x1b[0m`;\n}\n\nexport function ansiColor(text: string, color: string, bold = false): string {\n const COLOR_MAP: Record<string, number> = { black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, gray: 90 };\n const codes: number[] = [];\n if (bold) codes.push(1);\n const sgr = COLOR_MAP[color];\n if (sgr !== undefined) codes.push(sgr);\n if (codes.length === 0) return text;\n return `\\x1b[${codes.join(';')}m${text}\\x1b[0m`;\n}\n\nexport function modeColor(mode?: string): string {\n if (mode === 'planning') return 'blue';\n if (mode === 'implementation') return 'green';\n if (mode === 'strategy') return 'yellow';\n if (mode === 'validation') return 'magenta';\n return 'cyan';\n}\n\nexport function mergeStatusDisplay(status: string): { icon: string; label: string; color: string } | null {\n switch (status) {\n case 'merged': return { icon: '⊕', label: 'merged', color: 'green' };\n case 'pending': return { icon: '◌', label: 'pending', color: 'yellow' };\n case 'no-changes': return { icon: '∅', label: 'no changes', color: 'gray' };\n case 'conflict': return { icon: '⚠', label: 'conflict', color: 'red' };\n default: return null;\n }\n}\n\nexport function wrapText(text: string, width: number): string[] {\n const cleaned = cleanMarkdown(text);\n if (width <= 0) return cleaned.split('\\n');\n const result: string[] = [];\n for (const rawLine of cleaned.split('\\n')) {\n if (stringWidth(rawLine) <= width) {\n result.push(rawLine);\n continue;\n }\n\n // Single-pass: walk characters tracking cumulative display width\n let lineStart = 0;\n let lastSpace = -1;\n let displayWidth = 0;\n\n for (let i = 0; i < rawLine.length; i++) {\n const charWidth = stringWidth(rawLine[i]!);\n displayWidth += charWidth;\n\n if (rawLine[i] === ' ') lastSpace = i;\n\n if (displayWidth > width) {\n let breakAt: number;\n if (lastSpace > lineStart) {\n // Break at last space that fits\n breakAt = lastSpace;\n result.push(rawLine.slice(lineStart, breakAt));\n // Skip past the space and any leading spaces\n lineStart = breakAt + 1;\n while (lineStart < rawLine.length && rawLine[lineStart] === ' ') lineStart++;\n } else {\n // No space — hard break at previous char\n breakAt = Math.max(lineStart + 1, i);\n result.push(rawLine.slice(lineStart, breakAt));\n lineStart = breakAt;\n }\n\n // Recalculate display width for the carried-over portion\n displayWidth = stringWidth(rawLine.slice(lineStart, i + 1));\n lastSpace = -1;\n }\n }\n\n if (lineStart < rawLine.length) {\n result.push(rawLine.slice(lineStart));\n }\n }\n return result;\n}\n","import stringWidth from 'string-width';\nimport type { Seg, DetailLine } from './lib/format.js';\n\nexport type { Seg, DetailLine };\n\n// ─── Color mapping ────────────────────────────────────────────────────────────\n\nexport const COLOR_SGR: Record<string, number> = {\n black: 30,\n red: 31,\n green: 32,\n yellow: 33,\n blue: 34,\n magenta: 35,\n cyan: 36,\n white: 37,\n gray: 90,\n};\n\nexport function colorToSGR(color: string): number {\n const code = COLOR_SGR[color];\n if (code === undefined) throw new Error(`Unknown color: ${color}`);\n return code;\n}\n\n// ─── Seg → ANSI conversion (§1.1) ────────────────────────────────────────────\n\nexport function renderLine(segs: Seg[]): string {\n let out = '';\n for (const s of segs) {\n const codes: number[] = [];\n if (s.bold) codes.push(1);\n if (s.dim) codes.push(2);\n if (s.italic) codes.push(3);\n if (s.inverse) codes.push(7);\n if (s.color) codes.push(colorToSGR(s.color));\n if (codes.length > 0) {\n out += `\\x1b[${codes.join(';')}m${s.text}\\x1b[0m`;\n } else {\n out += s.text;\n }\n }\n return out;\n}\n\n// ─── Frame Buffer (§1.2) ──────────────────────────────────────────────────────\n\nexport interface FrameBuffer {\n lines: string[];\n width: number;\n height: number;\n}\n\nlet cachedBlank = '';\nlet cachedBlankWidth = 0;\n\nexport function createFrameBuffer(width: number, height: number): FrameBuffer {\n if (width !== cachedBlankWidth) {\n cachedBlank = ' '.repeat(width);\n cachedBlankWidth = width;\n }\n const lines = new Array<string>(height);\n for (let i = 0; i < height; i++) lines[i] = cachedBlank;\n return { lines, width, height };\n}\n\n/**\n * Copy rows from a previous frame into the buffer (skip re-render for clean panels).\n */\nexport function copyRows(buf: FrameBuffer, src: string[], startRow: number, count: number): void {\n for (let i = 0; i < count && startRow + i < buf.height; i++) {\n buf.lines[startRow + i] = src[startRow + i]!;\n }\n}\n\n// ─── Frame Diffing (§1.3) ────────────────────────────────────────────────────\n\nexport function flushFrame(frame: string[], prevFrame: string[], suffix?: string): string {\n let out = '\\x1b[?2026h'; // begin synchronized output\n for (let i = 0; i < frame.length; i++) {\n if (frame[i] !== prevFrame[i]) {\n out += `\\x1b[${i + 1};1H`; // cursor to row i+1, col 1\n out += '\\x1b[2K'; // clear entire line\n out += frame[i];\n }\n }\n if (suffix) out += suffix;\n out += '\\x1b[?2026l'; // end synchronized output\n return out;\n}\n\n// ─── ANSI escape sequence regex ───────────────────────────────────────────────\n\nconst ANSI_RE = /\\x1b\\[[0-9;]*[a-zA-Z]/g;\n\n// ─── Clip ANSI string to display width (no buffer interaction) ──────────────\n\n/**\n * Clip an ANSI string to exactly `maxWidth` display columns, padding with spaces.\n * Pure function — no buffer splicing.\n */\nexport function clipAnsi(content: string, maxWidth: number): string {\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n const cp = content.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n if (displayWidth + chWidth > maxWidth) break;\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) out += ' '.repeat(remaining);\n return out;\n}\n\n/**\n * Fast display-width calculation that skips ANSI escapes without regex allocation.\n */\nfunction displayWidthFast(s: string): number {\n let w = 0;\n let i = 0;\n while (i < s.length) {\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const len = ansiLen(s, i);\n if (len > 0) { i += len; continue; }\n }\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n w += cp < 128 ? 1 : stringWidth(ch);\n i += ch.length;\n }\n return w;\n}\n\n/**\n * Parse ANSI escape sequence at position i. Returns length of sequence or 0.\n * Avoids s.slice(i).match(regex) which allocates a new string each call.\n */\nfunction ansiLen(s: string, i: number): number {\n // Caller already verified s[i] === '\\x1b' && s[i+1] === '['\n let j = i + 2;\n const len = s.length;\n // Consume parameter bytes: digits 0-9 and semicolons\n while (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x30 && c <= 0x39) || c === 0x3b) { // '0'-'9' or ';'\n j++;\n } else {\n break;\n }\n }\n // Must end with a letter (final byte)\n if (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)) { // A-Z or a-z\n return j + 1 - i;\n }\n }\n return 0;\n}\n\n// ─── Write functions ──────────────────────────────────────────────────────────\n\n/**\n * Write content into frame buffer at position (x, y).\n *\n * Strategy: rebuild the target line by splitting into display columns,\n * inserting the new content, then reassembling. Since we build the frame\n * fresh each render, we can treat the existing line as plain chars + ANSI.\n *\n * This implementation replaces display columns [x, x+displayWidth(content))\n * in the buffer line with the new content.\n */\nexport function writeAt(buf: FrameBuffer, x: number, y: number, content: string): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n const existing = buf.lines[y]!;\n const contentDisplayWidth = stringWidth(content.replace(ANSI_RE, ''));\n\n // Split the existing line into prefix (0..x) and suffix (x+contentDisplayWidth..)\n // We need to walk the existing line respecting display widths.\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + contentDisplayWidth, buf.width);\n\n // Pad prefix if it's shorter than expected (can happen at end of line)\n const prefixWidth = stringWidth(prefix.replace(ANSI_RE, ''));\n const paddedPrefix = prefix + ' '.repeat(Math.max(0, x - prefixWidth));\n\n buf.lines[y] = paddedPrefix + content + suffix;\n}\n\n/**\n * Write ANSI string into buffer at (x, y), truncating to maxWidth display columns.\n * Pads remaining width with spaces.\n */\nexport function writeClipped(\n buf: FrameBuffer,\n x: number,\n y: number,\n content: string,\n maxWidth: number,\n): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n // Check for ANSI escape sequence — pass through without counting width\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n\n // Get the next character (handle surrogate pairs)\n const cp = content.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (displayWidth + chWidth > maxWidth) break;\n\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n // Ensure any open SGR sequences are reset\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n // Pad to maxWidth\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) {\n out += ' '.repeat(remaining);\n }\n\n // Splice directly into buffer line — we already know exact display width is maxWidth,\n // so skip writeAt's redundant stringWidth + double sliceDisplayCols re-parse.\n const existing = buf.lines[y]!;\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + maxWidth, buf.width);\n const prefixDisplayW = displayWidthFast(prefix);\n const paddedPrefix = prefixDisplayW < x ? prefix + ' '.repeat(x - prefixDisplayW) : prefix;\n buf.lines[y] = paddedPrefix + out + suffix;\n}\n\n/**\n * Write centered text at the given row.\n */\nexport function writeCenter(buf: FrameBuffer, row: number, content: string): void {\n const textWidth = stringWidth(content.replace(ANSI_RE, ''));\n const x = Math.max(0, Math.floor((buf.width - textWidth) / 2));\n writeAt(buf, x, row, content);\n}\n\n// ─── Border Drawing (§1.5) ────────────────────────────────────────────────────\n\nexport function drawBorder(\n buf: FrameBuffer,\n x: number,\n y: number,\n w: number,\n h: number,\n color: string,\n): void {\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n\n // Top: ╭────╮\n writeAt(buf, x, y, sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset);\n // Bottom: ╰────╯\n writeAt(buf, x, y + h - 1, sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset);\n // Sides\n for (let row = y + 1; row < y + h - 1; row++) {\n writeAt(buf, x, row, sgr + '│' + reset);\n writeAt(buf, x + w - 1, row, sgr + '│' + reset);\n }\n}\n\n// ─── Panel Rendering (§4.2) ───────────────────────────────────────────────────\n\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * Cache for pre-rendered ANSI strings. Keyed by the DetailLine[] identity —\n * when the caller provides a `renderedCache`, renderPanel will populate it\n * on first render and reuse on subsequent frames (avoiding renderLine per line).\n */\nexport interface RenderedCache {\n lines: DetailLine[];\n ansi: string[];\n}\n\nexport function renderPanel(\n buf: FrameBuffer,\n rect: Rect,\n lines: DetailLine[],\n scrollOffset: number,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): void {\n const { x, y, w, h } = rect;\n\n // 1. Draw border\n drawBorder(buf, x, y, w, h, focused ? 'blue' : borderColor);\n\n // 2. Inner dimensions (border + 1 padding each side, matching Ink's paddingX={1})\n const innerX = x + 2;\n const innerW = w - 4;\n const innerY = y + 1;\n const innerH = h - 2;\n\n if (innerW <= 0 || innerH <= 0) return;\n\n // 3. Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // 4. Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n const effectiveOffset = Math.min(scrollOffset, maxScroll);\n\n // 5. Render visible lines\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n writeClipped(buf, innerX, innerY + i, ansiLines[effectiveOffset + i]!, innerW);\n }\n\n // 6. Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n writeClipped(buf, innerX, innerY + viewableH, `\\x1b[2m${indicator}\\x1b[0m`, innerW);\n }\n}\n\n/**\n * Build panel as self-contained row strings (w display-columns each, including borders).\n * Returns h strings. No buffer interaction — avoids sliceDisplayCols entirely.\n */\nexport function buildPanelRows(\n rect: Rect,\n lines: DetailLine[],\n scrollOffset: number,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n\n const color = focused ? 'blue' : borderColor;\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const innerH = h - 2;\n const blankInner = ' '.repeat(innerW);\n\n // Top border\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n // Bottom border\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n\n // Pre-fill interior rows with empty content\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + blankInner + borderR;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (innerW <= 0 || innerH <= 0) return rows;\n\n // Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n const effectiveOffset = Math.min(scrollOffset, maxScroll);\n\n // Content rows — clip and compose without buffer splicing\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n const clipped = clipAnsi(ansiLines[effectiveOffset + i]!, innerW);\n rows[1 + i] = borderL + clipped + borderR;\n }\n\n // Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n const clipped = clipAnsi(`\\x1b[2m${indicator}\\x1b[0m`, innerW);\n rows[1 + viewableH] = borderL + clipped + borderR;\n }\n\n return rows;\n}\n\n/**\n * Build empty panel rows (border only, no content).\n */\nexport function buildEmptyPanelRows(\n rect: Rect,\n focused: boolean,\n borderColor: string,\n centerText?: string,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n const color = focused ? 'blue' : borderColor;\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + ' '.repeat(innerW) + borderR;\n\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (centerText) {\n const midRow = Math.floor(h / 2);\n if (midRow > 0 && midRow < h - 1) {\n const clipped = clipAnsi(centerText, innerW);\n // Center within panel\n const textW = displayWidthFast(centerText);\n const pad = Math.max(0, Math.floor((innerW - textW) / 2));\n const centered = ' '.repeat(pad) + clipped;\n rows[midRow] = borderL + clipAnsi(centered, innerW) + borderR;\n }\n }\n\n return rows;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\n/**\n * Slice a string (which may contain ANSI escapes) to display columns [start, end).\n * ANSI sequences are passed through only within the slice range.\n */\nfunction sliceDisplayCols(s: string, start: number, end: number): string {\n let out = '';\n let col = 0;\n let i = 0;\n let inSlice = false;\n let hasOpenSGR = false;\n\n while (i < s.length && col < end) {\n // ANSI escape: pass through if we're in the slice\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const seqLen = ansiLen(s, i);\n if (seqLen > 0) {\n if (col >= start) {\n const seq = s.substring(i, i + seqLen);\n out += seq;\n // Track if we have open SGR (non-reset)\n hasOpenSGR = seq !== '\\x1b[0m' && seq !== '\\x1b[m';\n }\n i += seqLen;\n continue;\n }\n }\n\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (col >= start) {\n inSlice = true;\n // Don't emit char that would overflow end\n if (col + chWidth > end) break;\n out += ch;\n }\n\n col += chWidth;\n i += ch.length;\n }\n\n // Close any open SGR\n if (inSlice && hasOpenSGR) {\n out += '\\x1b[0m';\n }\n\n return out;\n}\n","import type { TreeNode } from '../types/tree.js';\n\n/**\n * Render box-drawing prefix for a tree node.\n * Produces connectors like: │ ├─ ▸ or └─ ▼\n */\nexport function renderTreePrefix(node: TreeNode, nodes: TreeNode[], index: number): string {\n if (node.depth === 0) {\n return node.expandable ? (node.expanded ? '▼ ' : '▸ ') : ' ';\n }\n\n const parts: string[] = [];\n\n // For each ancestor depth level (1..depth-1), draw │ or space\n for (let d = 1; d < node.depth; d++) {\n parts.push(isAncestorLastSibling(nodes, index, d) ? ' ' : '│ ');\n }\n\n // Connector for this node\n parts.push(isLastSibling(nodes, index) ? '└─' : '├─');\n\n // Expand indicator\n if (node.expandable) {\n parts.push(node.expanded ? '▼ ' : '▸ ');\n } else {\n parts.push(' ');\n }\n\n return parts.join('');\n}\n\n/** Check if the node at `index` is the last among its siblings (same depth, same parent) */\nfunction isLastSibling(nodes: TreeNode[], index: number): boolean {\n const depth = nodes[index]!.depth;\n for (let i = index + 1; i < nodes.length; i++) {\n if (nodes[i]!.depth === depth) return false;\n if (nodes[i]!.depth < depth) return true;\n }\n return true;\n}\n\n/** Check if the ancestor at `depth` for the node at `index` is the last among its siblings */\nfunction isAncestorLastSibling(nodes: TreeNode[], index: number, depth: number): boolean {\n // Find the ancestor at this depth by scanning backward\n for (let i = index - 1; i >= 0; i--) {\n if (nodes[i]!.depth === depth) {\n return isLastSibling(nodes, i);\n }\n if (nodes[i]!.depth < depth) return true;\n }\n return true;\n}\n\n/**\n * Pre-compute prefix strings for all tree nodes in O(n).\n * Avoids per-node O(n) scans during rendering.\n */\nexport function precomputePrefixes(nodes: TreeNode[]): void {\n const len = nodes.length;\n if (len === 0) return;\n\n // Step 1: Compute isLastSibling for each node in a single backward pass.\n // A node is \"last sibling\" if no later node at the same depth appears before\n // a node at a shallower depth (or end of array).\n const isLast = new Array<boolean>(len);\n // Track the last-seen index for each depth level\n const lastSeenAtDepth = new Map<number, number>();\n\n for (let i = len - 1; i >= 0; i--) {\n const depth = nodes[i]!.depth;\n // This node is last sibling if no node at same depth was seen after it\n // before a shallower node\n isLast[i] = !lastSeenAtDepth.has(depth);\n lastSeenAtDepth.set(depth, i);\n // Clear deeper depths (they belong to a different parent scope)\n for (const [d] of lastSeenAtDepth) {\n if (d > depth) lastSeenAtDepth.delete(d);\n }\n }\n\n // Step 2: Build prefix strings using pre-computed isLast data.\n // For ancestor connector lines, we need to know if the ancestor at each depth\n // is a last sibling. We maintain a stack of isLast values per depth.\n const ancestorIsLast: boolean[] = [];\n\n for (let i = 0; i < len; i++) {\n const node = nodes[i]!;\n\n if (node.depth === 0) {\n node.prefix = node.expandable ? (node.expanded ? '▼ ' : '▸ ') : ' ';\n ancestorIsLast[0] = isLast[i]!;\n continue;\n }\n\n // Update ancestor tracking\n ancestorIsLast[node.depth] = isLast[i]!;\n\n const parts: string[] = [];\n\n // Ancestor connectors (depth 1 to depth-1)\n for (let d = 1; d < node.depth; d++) {\n parts.push(ancestorIsLast[d] ? ' ' : '│ ');\n }\n\n // This node's connector\n parts.push(isLast[i] ? '└─' : '├─');\n\n // Expand indicator\n if (node.expandable) {\n parts.push(node.expanded ? '▼ ' : '▸ ');\n } else {\n parts.push(' ');\n }\n\n node.prefix = parts.join('');\n }\n}\n","import { rawSend } from '../../shared/client.js';\nimport type { Request, Response } from '../../shared/protocol.js';\n\nexport function send(request: Request): Promise<Response> {\n return rawSend(request, 5_000);\n}\n","import { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { readFileSync, writeFileSync, mkdtempSync, rmSync, cpSync, existsSync, mkdirSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { globalDir } from '../../shared/paths.js';\nimport { augmentedPath } from '../../shared/env.js';\nimport { shellQuote } from '../../shared/shell.js';\nimport { exec, execSafe, EXEC_ENV } from '../../shared/exec.js';\n\n\nexport function getWindowId(): string {\n return exec('tmux display-message -p \"#{window_id}\"');\n}\n\nexport function selectWindow(windowId: string): void {\n execSafe(`tmux select-window -t \"${windowId}\"`);\n}\n\nexport function selectPane(paneId: string): void {\n execSafe(`tmux select-pane -t \"${paneId}\"`);\n}\n\nexport function windowExists(windowId: string): boolean {\n return execSafe(`tmux display-message -t \"${windowId}\" -p \"#{window_id}\"`) !== null;\n}\n\nexport function listAllWindowIds(): Set<string> {\n try {\n const output = execSync('tmux list-windows -a -F \"#{window_id}\"', { encoding: 'utf-8', env: EXEC_ENV });\n return new Set(output.trim().split('\\n').filter(Boolean));\n } catch {\n return new Set();\n }\n}\n\nlet companionPaneId: string | null = null;\n\nfunction setupCompanionPlugin(): string {\n const srcDir = join(import.meta.dirname, 'templates', 'companion-plugin');\n const destDir = join(globalDir(), 'companion-plugin');\n if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });\n cpSync(srcDir, destDir, { recursive: true });\n return destDir;\n}\n\nfunction isPaneAlive(paneId: string): boolean {\n return execSafe(`tmux display-message -t ${shellQuote(paneId)} -p \"#{pane_id}\"`) !== null;\n}\n\nexport function openCompanionPane(cwd: string): void {\n // If companion pane is alive, focus it\n if (companionPaneId && isPaneAlive(companionPaneId)) {\n execSafe(`tmux select-pane -t ${shellQuote(companionPaneId)}`);\n return;\n }\n\n const pluginDir = setupCompanionPlugin();\n\n const templatePath = join(import.meta.dirname, 'templates', 'dashboard-claude.md');\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf-8');\n } catch {\n template = `You are a Sisyphus dashboard companion. Help the user manage multi-agent sessions.\\nProject: ${cwd}\\nRun \\`sisyphus list\\` and \\`sisyphus status\\` to see current state.`;\n }\n\n const rendered = template.replace(/\\{\\{CWD\\}\\}/g, cwd);\n const promptPath = join(globalDir(), 'dashboard-companion-prompt.md');\n writeFileSync(promptPath, rendered, 'utf-8');\n\n const pathEnv = augmentedPath();\n\n const claudeCmd = `SISYPHUS_COMPANION_CWD=${shellQuote(cwd)} PATH=${shellQuote(pathEnv)} claude --dangerously-skip-permissions --plugin-dir ${shellQuote(pluginDir)} --append-system-prompt \"$(cat ${shellQuote(promptPath)})\"`;\n\n const result = exec(\n `tmux split-window -h -d -l 33% -P -F \"#{pane_id}\" -c ${shellQuote(cwd)} ${shellQuote(claudeCmd)}`,\n );\n companionPaneId = result.trim() || null;\n}\n\nconst TERMINAL_EDITORS = new Set(['nvim', 'vim', 'vi', 'nano', 'emacs', 'micro', 'helix', 'hx', 'joe', 'ne', 'kak']);\n\nexport function switchToSession(sessionName: string): void {\n execSafe(`tmux switch-client -t \"${sessionName}\"`);\n}\n\nexport function editInPopup(cwd: string, editor: string, opts?: { content?: string; size?: { w: string; h: string } }): string | null {\n const tmpDir = mkdtempSync(join(tmpdir(), 'sisyphus-'));\n const filePath = join(tmpDir, 'input.md');\n try {\n writeFileSync(filePath, opts?.content ? opts.content : '', 'utf-8');\n openEditorPopup(cwd, editor, filePath, opts?.size);\n const result = readFileSync(filePath, 'utf-8').trim();\n return result || null;\n } finally {\n rmSync(tmpDir, { recursive: true, force: true });\n }\n}\n\nexport function openLogPopup(): void {\n execSync(\n `tmux display-popup -E -w 90% -h 80% ${shellQuote('tail -f ~/.sisyphus/daemon.log')}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openShellPopup(cwd: string, command: string): void {\n execSync(\n `tmux display-popup -E -w 90% -h 80% -d ${shellQuote(cwd)} ${shellQuote(`sh -c '${command.replace(/'/g, \"'\\\\''\")}; echo; echo \"Press enter to close\"; read'`)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openInFileManager(path: string): void {\n execSync(`open ${shellQuote(path)}`, { stdio: 'inherit', env: EXEC_ENV });\n}\n\nexport function openClaudeResumePopup(cwd: string, claudeSessionId: string): void {\n const pathEnv = augmentedPath();\n const cmd = `PATH=${shellQuote(pathEnv)} claude --resume ${shellQuote(claudeSessionId)}`;\n execSync(\n `tmux display-popup -E -w 90% -h 80% -d ${shellQuote(cwd)} ${shellQuote(cmd)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n}\n\nexport function openClaudeResumeSession(cwd: string, claudeSessionId: string, sessionLabel: string): string {\n const pathEnv = augmentedPath();\n const cmd = `PATH=${shellQuote(pathEnv)} claude --resume ${shellQuote(claudeSessionId)}`;\n const sessionName = `sisyphus-${sessionLabel}-resume`;\n exec(`tmux new-session -d -s ${shellQuote(sessionName)} -c ${shellQuote(cwd)} ${shellQuote(cmd)}`);\n execSafe(`tmux set-option -t ${shellQuote(sessionName)} @sisyphus_cwd ${shellQuote(cwd.replace(/\\/+$/, ''))}`);\n // Match session defaults from daemon tmux.ts configureSessionDefaults\n const paneTarget = `${sessionName}:`;\n execSafe(`tmux set -w -t ${shellQuote(paneTarget)} pane-border-status top`);\n execSafe(`tmux set -w -t ${shellQuote(paneTarget)} allow-rename off`);\n execSafe(`tmux set -w -t ${shellQuote(paneTarget)} automatic-rename off`);\n execSafe(`tmux select-pane -t ${shellQuote(paneTarget)} -T ${shellQuote(`ssph:resume ${sessionLabel}`)}`);\n return sessionName;\n}\n\nexport function openEditorPopup(cwd: string, editor: string, filePath: string, size?: { w: string; h: string }): void {\n const { w = '90%', h = '90%' } = size ?? {};\n const editorBin = editor.split(/\\s+/)[0]!.split('/').pop()!;\n if (TERMINAL_EDITORS.has(editorBin)) {\n execSync(\n `tmux display-popup -E -w ${w} -h ${h} -d ${shellQuote(cwd)} ${shellQuote(`${editor} ${shellQuote(filePath)}`)}`,\n { stdio: 'inherit', env: EXEC_ENV },\n );\n } else {\n execSync(`${editor} ${shellQuote(filePath)}`, { stdio: 'inherit', cwd, env: EXEC_ENV });\n }\n}\n","import { execSync } from 'node:child_process';\n\nexport function copyToClipboard(text: string): void {\n execSync('pbcopy', { input: text });\n}\n","import type { FrameBuffer, Rect } from '../render.js';\nimport { drawBorder, writeClipped, colorToSGR } from '../render.js';\nimport type { TreeNode } from '../types/tree.js';\nimport { renderTreePrefix } from '../lib/tree-render.js';\nimport {\n statusColor,\n statusIndicator,\n agentStatusIcon,\n truncate,\n formatDuration,\n formatTime,\n formatTimeAgo,\n durationColor,\n agentDisplayName,\n modeColor,\n abbreviateMode,\n} from '../lib/format.js';\n\n// ─── Node content renderer ────────────────────────────────────────────────────\n\ninterface NodeContent {\n icon: string;\n label: string;\n meta: string;\n color: string;\n dim: boolean;\n metaColor?: string;\n suffix?: string;\n suffixColor?: string;\n}\n\nfunction renderNodeContent(node: TreeNode, maxWidth: number): NodeContent {\n switch (node.type) {\n case 'session': {\n const icon = statusIndicator(node.status);\n const color = statusColor(node.status);\n const dim = node.status === 'completed';\n const cyclePart = node.cycleCount > 0 ? `C${node.cycleCount}` : '';\n const dur = formatDuration(node.createdAt, node.completedAt);\n const agopart =\n node.status === 'completed' && node.completedAt ? formatTimeAgo(node.completedAt) : '';\n const meta = [cyclePart, dur, agopart].filter(Boolean).join(' ');\n const displayText = node.name ?? node.task;\n const maxLabel = Math.max(8, maxWidth - meta.length - 4);\n return { icon, label: truncate(displayText, maxLabel), meta, color, dim };\n }\n case 'cycle': {\n const isRunning = !node.completedAt;\n const dur = isRunning ? 'running' : formatDuration(node.activeMs);\n const agents = `${node.agentCount} agent${node.agentCount !== 1 ? 's' : ''}`;\n const modeShort = abbreviateMode(node.mode);\n const mode = modeShort ? ` · ${modeShort}` : '';\n return {\n icon: isRunning ? '●' : '○',\n label: `C${node.cycleNumber}`,\n meta: `${dur} · ${agents}${mode}`,\n color: isRunning ? 'green' : 'gray',\n dim: !isRunning,\n };\n }\n case 'agent': {\n const icon = agentStatusIcon(node.status);\n const color = statusColor(node.status);\n const dur = formatDuration(node.activeMs);\n const durClr = durationColor(node.activeMs) || undefined;\n const dim = node.status === 'completed';\n const displayName = agentDisplayName({\n name: node.name,\n id: node.agentId,\n agentType: node.agentType,\n });\n\n const maxLabel = Math.max(8, maxWidth - dur.length - 4);\n return {\n icon,\n label: truncate(displayName, maxLabel),\n meta: dur,\n color,\n dim,\n metaColor: durClr,\n };\n }\n case 'report': {\n const badge = node.reportType === 'final' ? 'FINAL' : 'UPDATE';\n const time = formatTime(node.timestamp);\n return {\n icon: node.reportType === 'final' ? '◆' : '◇',\n label: `${badge} ${time}`,\n meta: '',\n color: node.reportType === 'final' ? 'cyan' : 'yellow',\n dim: false,\n };\n }\n case 'messages':\n return {\n icon: '✉',\n label: `Messages (${node.count})`,\n meta: '',\n color: 'yellow',\n dim: false,\n };\n case 'message': {\n const maxLabel = Math.max(8, maxWidth - 8);\n return {\n icon: '·',\n label: truncate(`${node.source}: ${node.summary}`, maxLabel),\n meta: formatTime(node.timestamp),\n color: 'gray',\n dim: true,\n };\n }\n case 'context':\n return {\n icon: '⊞',\n label: `Context (${node.fileCount})`,\n meta: '',\n color: 'white',\n dim: node.fileCount === 0,\n };\n case 'context-file': {\n const maxLabel = Math.max(8, maxWidth - 4);\n return {\n icon: '·',\n label: truncate(node.label, maxLabel),\n meta: '',\n color: 'gray',\n dim: false,\n };\n }\n }\n}\n\n// ─── Tree panel renderer ──────────────────────────────────────────────────────\n\nexport function renderTreePanel(\n buf: FrameBuffer,\n rect: Rect,\n nodes: TreeNode[],\n cursorIndex: number,\n focused: boolean,\n): void {\n const { x, y, w, h } = rect;\n\n // 1. Border — yellow when focused\n drawBorder(buf, x, y, w, h, focused ? 'yellow' : 'gray');\n\n // 2. Inner dimensions\n const innerX = x + 2;\n const innerW = w - 4;\n const innerY = y + 1;\n const innerH = h - 2;\n\n if (innerW <= 0 || innerH <= 0) return;\n\n // 3. Empty state\n if (nodes.length === 0) {\n writeClipped(buf, innerX, innerY, '\\x1b[1m Sessions \\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 1, '\\x1b[2mNo sessions found.\\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 2, '\\x1b[2mPress [n] to create one.\\x1b[0m', innerW);\n writeClipped(buf, innerX, innerY + 3, '\\x1b[2mPress [?] for all keybindings.\\x1b[0m', innerW);\n return;\n }\n\n // 4. Scroll logic\n const maxVisible = Math.max(1, innerH);\n const halfVisible = Math.floor(maxVisible / 2);\n const scrollOffset = Math.max(\n 0,\n Math.min(cursorIndex - halfVisible, nodes.length - maxVisible),\n );\n\n // 5. Scroll indicator adjustments\n const hasTopIndicator = scrollOffset > 0;\n const hasBottomIndicator = scrollOffset + maxVisible < nodes.length;\n\n let rowStart = innerY;\n let availRows = maxVisible;\n\n if (hasTopIndicator) {\n const topMore = scrollOffset;\n writeClipped(buf, innerX, rowStart, `\\x1b[2m↑ ${topMore} more\\x1b[0m`, innerW);\n rowStart++;\n availRows--;\n }\n\n if (hasBottomIndicator) {\n availRows--;\n }\n\n // 6. Render visible nodes\n const visible = nodes.slice(scrollOffset, scrollOffset + availRows + (hasBottomIndicator ? 1 : 0));\n const renderCount = Math.min(visible.length, availRows);\n\n for (let i = 0; i < renderCount; i++) {\n const node = visible[i]!;\n const realIdx = scrollOffset + i;\n const isSelected = realIdx === cursorIndex;\n const prefix = node.prefix ?? renderTreePrefix(node, nodes, realIdx);\n const contentWidth = innerW;\n const { icon, label, meta, color, dim, metaColor, suffix, suffixColor } = renderNodeContent(\n node,\n contentWidth - prefix.length,\n );\n\n // Build ANSI string\n let content = '';\n\n // icon with color\n if (icon) {\n if (dim) content += `\\x1b[2;${colorToSGR(color)}m${icon}\\x1b[0m `;\n else content += `\\x1b[${colorToSGR(color)}m${icon}\\x1b[0m `;\n }\n\n // label\n if (dim) content += `\\x1b[2m${label}\\x1b[0m`;\n else content += label;\n\n // meta\n if (meta) {\n if (metaColor) content += ` \\x1b[${colorToSGR(metaColor)}m${meta}\\x1b[0m`;\n else content += ` \\x1b[2m${meta}\\x1b[0m`;\n }\n\n // suffix\n if (suffix && suffixColor) {\n content += ` \\x1b[${colorToSGR(suffixColor)}m${suffix}\\x1b[0m`;\n }\n\n let line = prefix;\n if (isSelected) {\n const bold = '\\x1b[1m';\n const inverse = focused ? '\\x1b[7m' : '';\n line += `${inverse}${bold}${content}\\x1b[0m`;\n } else {\n line += content;\n }\n\n writeClipped(buf, innerX, rowStart + i, line, innerW);\n }\n\n // 7. Bottom scroll indicator\n if (hasBottomIndicator) {\n const bottomMore = nodes.length - scrollOffset - maxVisible;\n const bottomRow = rowStart + availRows;\n writeClipped(buf, innerX, bottomRow, `\\x1b[2m↓ ${bottomMore} more\\x1b[0m`, innerW);\n }\n}\n","import {\n buildPanelRows,\n buildEmptyPanelRows,\n type Rect,\n} from '../render.js';\nimport type { AppState, CycleLog } from '../state.js';\nimport type {\n TreeNode,\n CycleTreeNode,\n AgentTreeNode,\n ReportTreeNode,\n MessageTreeNode,\n ContextFileTreeNode,\n} from '../types/tree.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\nimport { computeActiveTimeMs } from '../../shared/utils.js';\nimport type { ReportBlock } from '../lib/reports.js';\nimport {\n statusColor,\n formatDuration,\n formatTime,\n truncate,\n wrapText,\n stripFrontmatter,\n cleanMarkdown,\n seg,\n singleLine,\n agentDisplayName,\n reportBadge,\n agentStatusIcon,\n agentTypeColor,\n durationColor,\n modeColor,\n messageSourceLabel,\n messageSourceColor,\n extractFirstSentence,\n divider,\n abbreviateMode,\n type DetailLine,\n} from '../lib/format.js';\n\n// ---------------------------------------------------------------------------\n// Public interface\n// ---------------------------------------------------------------------------\n\nexport interface DetailContext {\n nodes: TreeNode[];\n session: Session | null;\n agents: Agent[];\n reportBlocks: ReportBlock[];\n detailReportBlocks: ReportBlock[];\n contextFileContent: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// PlanLine (copied from PlanView.tsx — no React dependency)\n// ---------------------------------------------------------------------------\n\ninterface PlanLine {\n text: string;\n bold?: boolean;\n dim?: boolean;\n color?: string;\n}\n\nfunction buildPlanLines(content: string, maxLines: number, width: number): PlanLine[] {\n const clean = stripFrontmatter(content);\n if (!clean.trim()) return [];\n\n const contentWidth = width - 4;\n const lines: PlanLine[] = [];\n const rawLines = clean.split('\\n');\n\n for (const rawLine of rawLines) {\n if (lines.length >= maxLines) break;\n\n const trimmed = rawLine.trim();\n\n // Skip frontmatter artifacts\n if (trimmed === '---') continue;\n\n // Headers — bold, with level-based indentation\n const headerMatch = rawLine.match(/^(#{1,6})\\s+(.+)/);\n if (headerMatch) {\n const level = headerMatch[1]!.length;\n const headerText = cleanMarkdown(headerMatch[2]!);\n const indent = ' '.repeat(Math.max(0, level - 1));\n if (lines.length > 0) lines.push({ text: ' ' });\n lines.push({\n text: ` ${indent}${headerText}`,\n bold: true,\n color: level <= 2 ? 'white' : undefined,\n });\n continue;\n }\n\n // Empty lines — pass through (but collapse multiples)\n if (!trimmed) {\n if (lines.length > 0 && lines[lines.length - 1]!.text !== '') {\n lines.push({ text: ' ' });\n }\n continue;\n }\n\n // Numbered list items\n const listMatch = trimmed.match(/^(\\d+)[.)]\\s+(.+)/);\n if (listMatch) {\n const cleaned = `${listMatch[1]}. ${cleanMarkdown(listMatch[2]!)}`;\n const wrapped = wrapText(cleaned, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n continue;\n }\n\n // Checkbox items — must come before bullet match\n const checkboxMatch = trimmed.match(/^- \\[( |x|X)\\] (.+)/);\n if (checkboxMatch) {\n const checked = checkboxMatch[1] !== ' ';\n const checkboxText = cleanMarkdown(checkboxMatch[2]!);\n const icon = checked ? '☑' : '☐';\n const wrapped = wrapText(`${icon} ${checkboxText}`, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true, color: checked ? 'green' : undefined });\n }\n continue;\n }\n\n // Bullet items\n const bulletMatch = trimmed.match(/^[-*+]\\s+(.+)/);\n if (bulletMatch) {\n const cleaned = `· ${cleanMarkdown(bulletMatch[1]!)}`;\n const wrapped = wrapText(cleaned, contentWidth - 6);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n continue;\n }\n\n // Regular content — clean and wrap\n const cleaned = cleanMarkdown(trimmed);\n const wrapped = wrapText(cleaned, contentWidth - 4);\n for (const wl of wrapped) {\n if (lines.length >= maxLines) break;\n lines.push({ text: ` ${wl}`, dim: true });\n }\n }\n\n // Truncation indicator\n const totalContentLines = rawLines.filter((l) => l.trim()).length;\n if (lines.length >= maxLines && totalContentLines > maxLines) {\n lines[lines.length - 1] = { text: ' … [p] open in editor', dim: true };\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildSessionLines (ported from SessionDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildSessionLines(\n session: Session,\n planContent: string,\n goalContent: string | undefined,\n width: number,\n paneAlive: boolean,\n strategyContent: string = '',\n): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const agents = session.agents;\n const cycles = session.orchestratorCycles;\n const messages = session.messages;\n const isDead = session.status === 'active' && !paneAlive;\n // Goal text\n const goalText = goalContent\n ? cleanMarkdown(stripFrontmatter(goalContent).trim())\n : session.task;\n goalText\n .split('\\n')\n .flatMap((l) => wrapText(l, contentWidth - 2))\n .forEach((line, i) => {\n lines.push(singleLine(`${i === 0 ? ' ' : ' '}${line}`, { bold: true }));\n });\n\n // Status bar\n const lastCycle = cycles.length > 0 ? cycles[cycles.length - 1]! : null;\n const cycleNum = lastCycle !== null ? lastCycle.cycle : 0;\n const mode = lastCycle !== null && lastCycle.mode !== undefined ? lastCycle.mode : '';\n const runningAgents = agents.filter((a) => a.status === 'running').length;\n const completedAgents = agents.filter((a) => a.status === 'completed').length;\n const elapsed = formatDuration(session.createdAt, session.completedAt);\n const activeMs = computeActiveTimeMs(session);\n const activeTime = formatDuration(activeMs);\n const modeLabelColor = modeColor(mode);\n lines.push([\n seg(' '),\n seg(isDead ? '✕ dead' : session.status, {\n color: statusColor(isDead ? 'crashed' : session.status),\n }),\n seg(` · cycle ${cycleNum}`, { dim: true }),\n ...(mode ? [seg(' (', { dim: true }), seg(mode, { color: modeLabelColor }), seg(')', { dim: true })] : []),\n seg(` · ${elapsed} · `, { dim: true }),\n seg(`${runningAgents} running`, { color: 'green' }),\n seg(' · ', { dim: true }),\n seg(`${completedAgents} done`, { color: 'cyan' }),\n seg(` · ${activeTime} active`, { dim: true }),\n ]);\n\n // Dead session warning\n if (isDead) {\n lines.push([\n seg(' '),\n seg(' ✕ DEAD ', { color: 'red', bold: true }),\n seg(' tmux window closed — [w] reopen [R] resume', { color: 'red' }),\n ]);\n }\n\n // Plan / Strategy section\n lines.push(singleLine(' '));\n if (strategyContent) {\n lines.push([seg(' ▎ ◈ STRATEGY', { color: 'yellow', bold: true })]);\n const stratLines = buildPlanLines(strategyContent, 99999, width);\n if (stratLines.length === 0) {\n lines.push(singleLine(' (empty)', { dim: true, italic: true }));\n } else {\n for (const pl of stratLines) {\n lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));\n }\n }\n } else {\n lines.push([seg(' ▎ ◈ PLAN', { color: 'yellow', bold: true })]);\n const planLines = buildPlanLines(planContent, 99999, width);\n if (planLines.length === 0) {\n lines.push(singleLine(' orchestrator will create one', { dim: true, italic: true }));\n } else {\n for (const pl of planLines) {\n lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));\n }\n }\n }\n\n // Completion report\n if (session.status === 'completed' && session.completionReport) {\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ✓ COMPLETION', { color: 'cyan', bold: true })]);\n wrapText(session.completionReport, contentWidth - 6).forEach((l) => {\n lines.push(singleLine(` ${l}`, { dim: true }));\n });\n }\n\n // Cycles section — newest first\n lines.push(singleLine(' '));\n lines.push([\n seg(' ▎ ⟳ CYCLES', { color: 'blue', bold: true }),\n seg(` (${cycles.length})`, { dim: true }),\n ]);\n\n const pushMsgLine = (msg: (typeof messages)[number], connector: '└▸' | '├▸') => {\n const time = formatTime(msg.timestamp);\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const label = messageSourceLabel(msg.source.type, agentId);\n const labelColor = messageSourceColor(msg.source.type);\n const maxContent = Math.max(10, contentWidth - label.length - 18);\n lines.push([\n seg(` ${connector} `, { dim: true }),\n seg(`[${time}] `, { dim: true }),\n seg(`${label} `, { color: labelColor, bold: true }),\n seg(truncate(msg.summary.length > 0 ? msg.summary : msg.content, maxContent), { dim: true }),\n ]);\n };\n\n if (cycles.length === 0) {\n lines.push(singleLine(' waiting for orchestrator…', { dim: true, italic: true }));\n } else {\n const sortedMsgs = [...messages].sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n );\n const reversedCycles = [...cycles].reverse();\n\n const shortType = (t: string) => {\n const colonIdx = t.indexOf(':');\n return colonIdx >= 0 ? t.slice(colonIdx + 1) : t;\n };\n\n for (let i = 0; i < reversedCycles.length; i++) {\n const cycle = reversedCycles[i]!;\n const olderCycle = reversedCycles[i + 1];\n\n const isRunning = !cycle.completedAt;\n const isNewest = i === 0;\n const isSecond = i === 1;\n const dot = isRunning ? '●' : '○';\n const dotColor = isRunning ? 'green' : isNewest ? 'white' : 'gray';\n const rowDim = !isRunning && !isNewest && !isSecond;\n const duration = isRunning ? 'running' : formatDuration(cycle.activeMs);\n const n = cycle.agentsSpawned.length;\n const startTime = formatTime(cycle.timestamp);\n\n const modeLabel = abbreviateMode(cycle.mode);\n const cycModeColor = modeColor(cycle.mode);\n\n const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n\n const cyclePad = `C${cycle.cycle}`.padEnd(4);\n const durPad = (isRunning ? 'running' : duration).padEnd(9);\n\n const headerRow: DetailLine = [\n seg(` ${dot} `, { color: dotColor }),\n seg(cyclePad, { bold: isRunning || isNewest, dim: rowDim }),\n ...(isRunning\n ? [seg(durPad, { color: 'green', bold: true })]\n : [seg(durPad, { dim: rowDim })]),\n seg(startTime, { dim: true }),\n ...(modeLabel ? [seg(' ', {}), seg(modeLabel, { color: cycModeColor })] : []),\n ];\n lines.push(headerRow);\n\n if (cycleAgents.length > 0) {\n const typeGroups = new Map<string, number>();\n for (const a of cycleAgents) {\n const t = shortType(a.agentType !== '' ? a.agentType : a.name !== '' ? a.name : a.id);\n const prev = typeGroups.get(t);\n typeGroups.set(t, prev !== undefined ? prev + 1 : 1);\n }\n const agentNames = [...typeGroups.entries()]\n .map(([t, count]) => count > 1 ? `${count}× ${t}` : t)\n .join(', ');\n lines.push([\n seg(' ', {}),\n seg(truncate(agentNames, contentWidth - 6), { dim: rowDim }),\n ]);\n } else if (n > 0) {\n lines.push([\n seg(' ', {}),\n seg(`${n} agent${n !== 1 ? 's' : ''}`, { dim: rowDim }),\n ]);\n }\n\n const cycleTime = new Date(cycle.timestamp).getTime();\n const olderCycleTime = olderCycle ? new Date(olderCycle.timestamp).getTime() : 0;\n const cycleMsgs = sortedMsgs.filter((m) => {\n const t = new Date(m.timestamp).getTime();\n return t < cycleTime && t >= olderCycleTime;\n });\n cycleMsgs.forEach((msg, mi) => {\n pushMsgLine(msg, mi < cycleMsgs.length - 1 ? '├▸' : '└▸');\n });\n }\n\n // Messages predating all cycles\n const firstCycleTime = new Date(reversedCycles[reversedCycles.length - 1]!.timestamp).getTime();\n const preMsgs = sortedMsgs.filter((m) => new Date(m.timestamp).getTime() < firstCycleTime);\n preMsgs.forEach((msg, mi) => {\n pushMsgLine(msg, mi < preMsgs.length - 1 ? '├▸' : '└▸');\n });\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildCycleLines (ported from CycleDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildCycleLines(cycle: OrchestratorCycle, agents: Agent[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const isRunning = !cycle.completedAt;\n const dur = isRunning ? 'running' : formatDuration(cycle.activeMs);\n const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n\n lines.push(singleLine(` Cycle ${cycle.cycle}`, { bold: true }));\n lines.push([\n seg(' '),\n seg(isRunning ? 'running' : 'completed', { color: isRunning ? 'green' : 'gray' }),\n seg(` · ${dur} · ${cycleAgents.length} agent${cycleAgents.length !== 1 ? 's' : ''}`, { dim: true }),\n ...(cycle.mode\n ? [seg(' · ', { dim: true }), seg(cycle.mode, { color: modeColor(cycle.mode) })]\n : []),\n ]);\n lines.push(singleLine(\n ` ${formatTime(cycle.timestamp)}${cycle.completedAt ? ` → ${formatTime(cycle.completedAt)}` : ''}`,\n { dim: true },\n ));\n if (cycle.claudeSessionId) {\n lines.push(singleLine(` Session: ${cycle.claudeSessionId}`, { dim: true }));\n }\n\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ⊞ AGENTS', { color: 'green', bold: true })]);\n\n if (cycleAgents.length === 0) {\n lines.push(singleLine(' orchestrator spawning agents…', { dim: true, italic: true }));\n } else {\n for (const agent of cycleAgents) {\n const nameLabel = agentDisplayName(agent);\n const instrPreview = agent.instruction.split('\\n')[0]!;\n const latestReport = agent.reports.length > 0 ? agent.reports[agent.reports.length - 1]! : null;\n const reportSummary = latestReport !== null && agent.status === 'completed'\n ? extractFirstSentence(latestReport.summary, contentWidth - 14)\n : null;\n const agentDur = formatDuration(agent.activeMs);\n const durClrRaw = durationColor(agent.activeMs);\n const durClr = durClrRaw !== '' ? durClrRaw : undefined;\n const typeClrRaw = agentTypeColor(agent.agentType);\n const typeClr = typeClrRaw !== undefined ? typeClrRaw : undefined;\n\n lines.push([\n seg(' '),\n seg(agentStatusIcon(agent.status), { color: statusColor(agent.status) }),\n seg(` ${agent.id}`, { bold: true }),\n seg(` ${truncate(nameLabel, contentWidth - 30)}`, {\n color: typeClr,\n dim: typeClr === undefined,\n }),\n seg(` · ${agent.status} · `, { dim: true }),\n seg(agentDur, { color: durClr, dim: !durClr }),\n ]);\n\n if (instrPreview) {\n lines.push(singleLine(` ${truncate(instrPreview, contentWidth - 10)}`, { dim: true }));\n }\n\n if (reportSummary) {\n lines.push([\n seg(' '),\n seg('↳', { color: 'cyan' }),\n seg(` ${reportSummary}`, { dim: true }),\n ]);\n }\n }\n }\n\n if (cycle.nextPrompt) {\n lines.push(singleLine(' '));\n lines.push([seg(' ▎ ▷ NEXT PROMPT', { color: 'yellow', bold: true })]);\n for (const wl of wrapText(cycle.nextPrompt, contentWidth - 6)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildAgentLines (ported from AgentDetail.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildAgentLines(agent: Agent, reportBlocks: ReportBlock[] | undefined, width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n const dur = formatDuration(agent.activeMs);\n const icon = agentStatusIcon(agent.status);\n const color = statusColor(agent.status);\n const nameLabel = agentDisplayName(agent);\n lines.push([\n seg(' '),\n seg(icon, { color }),\n seg(` ${agent.id} · ${nameLabel}`, { bold: true }),\n ]);\n\n lines.push([\n seg(' '),\n seg(agent.status, { color }),\n seg(` · ${dur} · ${agent.agentType}`, { dim: true }),\n ]);\n\n if (agent.killedReason) {\n lines.push(singleLine(` ⚠ ${agent.killedReason}`, { color: 'red' }));\n }\n\n lines.push(singleLine(' '));\n lines.push(singleLine(' ▎ ▷ INSTRUCTION', { color: 'white', bold: true }));\n for (const wl of wrapText(agent.instruction, contentWidth - 6)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n\n if (agent.reports.length > 0) {\n const hasResolved = reportBlocks && reportBlocks.length > 0;\n lines.push(singleLine(' '));\n lines.push([seg(` ▎ ◇ REPORTS (${agent.reports.length})`, { color: 'cyan', bold: true })]);\n\n if (hasResolved) {\n for (let i = 0; i < reportBlocks.length; i++) {\n const block = reportBlocks[i]!;\n const { label: badge, color: badgeColor } = reportBadge(block.type);\n\n if (i > 0) lines.push(singleLine(' '));\n lines.push([\n seg(' '),\n seg(badge, { color: badgeColor, bold: block.type === 'final' }),\n seg(` ${formatTime(block.timestamp)}`, { dim: true }),\n ]);\n for (const wl of wrapText(block.content.trim(), contentWidth - 10)) {\n lines.push(singleLine(` ${wl}`, { dim: true }));\n }\n }\n } else {\n for (const report of agent.reports) {\n const { label: badge, color: badgeColor } = reportBadge(report.type);\n lines.push([\n seg(' '),\n seg(badge, { color: badgeColor, bold: report.type === 'final' }),\n seg(` ${formatTime(report.timestamp)} ${report.summary.split('\\n')[0]}`, { dim: true }),\n ]);\n }\n }\n }\n\n lines.push(singleLine(' '));\n lines.push(singleLine(' ▎ ◦ META', { color: 'gray', bold: true }));\n lines.push(singleLine(` Spawned: ${formatTime(agent.spawnedAt)}`, { dim: true }));\n if (agent.completedAt) {\n lines.push(singleLine(` Completed: ${formatTime(agent.completedAt)}`, { dim: true }));\n }\n if (agent.claudeSessionId) {\n lines.push(singleLine(` Session: ${agent.claudeSessionId}`, { dim: true }));\n }\n if (agent.paneId) {\n lines.push(singleLine(` Pane: ${agent.paneId}`, { dim: true }));\n }\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildReportViewLines (ported from ReportView.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildReportViewLines(agent: Agent, reportBlocks: ReportBlock[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 6;\n const dur = formatDuration(agent.activeMs);\n const icon = agentStatusIcon(agent.status);\n const color = statusColor(agent.status);\n const totalReports = agent.reports.length;\n const nameLabel = agentDisplayName(agent);\n\n lines.push([\n seg(' '),\n seg(icon, { color }),\n seg(' '),\n seg(agent.id, { bold: true }),\n seg(' ', { dim: true }),\n seg('·', { dim: true }),\n seg(' '),\n seg(nameLabel, { bold: true }),\n ]);\n\n lines.push(singleLine(\n ` ${agent.status} · ${dur} · ${agent.agentType} · ${totalReports} report${totalReports !== 1 ? 's' : ''}`,\n { dim: true },\n ));\n\n lines.push(singleLine(' ' + divider(contentWidth - 2), { dim: true }));\n\n if (reportBlocks.length === 0) {\n lines.push(singleLine(''));\n lines.push(singleLine(' No reports submitted yet.', { dim: true }));\n lines.push(singleLine(''));\n return lines;\n }\n\n for (let i = 0; i < reportBlocks.length; i++) {\n const report = reportBlocks[i]!;\n const time = formatTime(report.timestamp);\n\n if (i > 0) {\n lines.push(singleLine(''));\n lines.push(singleLine(` ${divider(contentWidth - 2, '·')}`, { dim: true }));\n lines.push(singleLine(''));\n }\n\n const { label: badge, color: badgeColor } = reportBadge(report.type);\n lines.push([\n seg(` ${badge}`, { color: badgeColor, bold: report.type === 'final' }),\n seg(` ${time}`, { color: badgeColor }),\n ]);\n\n lines.push(singleLine(''));\n\n const wrapped = wrapText(report.content.trim(), contentWidth - 4);\n for (const line of wrapped) {\n lines.push(singleLine(` ${line}`));\n }\n }\n\n lines.push(singleLine(''));\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// buildLogsLines (ported from LogsPanel.tsx buildLines)\n// ---------------------------------------------------------------------------\n\nfunction buildLogsLines(cycleLogs: CycleLog[], width: number): DetailLine[] {\n const lines: DetailLine[] = [];\n const contentWidth = width - 4;\n\n if (cycleLogs.length === 0) {\n return lines;\n }\n\n const sorted = [...cycleLogs].sort((a, b) => b.cycle - a.cycle);\n\n for (const { cycle, content } of sorted) {\n lines.push([seg(` Cycle ${cycle}`, { color: 'blue', bold: true })]);\n\n const cleaned = cleanMarkdown(stripFrontmatter(content)).trim();\n if (cleaned) {\n for (const rawLine of cleaned.split('\\n')) {\n const wrapped = wrapText(rawLine, contentWidth - 2);\n for (const wl of wrapped) {\n lines.push([seg(` ${wl}`, { dim: true })]);\n }\n }\n }\n\n lines.push([seg(' ')]);\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Main entry points\n// ---------------------------------------------------------------------------\n\nexport function renderDetailRows(\n rect: Rect,\n state: AppState,\n detailCtx: DetailContext,\n): string[] {\n const { session, agents, reportBlocks, detailReportBlocks, contextFileContent } = detailCtx;\n const scrollOffset = state.detailScroll.offset;\n const focused = state.focusPane === 'detail';\n\n // Report detail mode — full panel\n if (state.mode === 'report-detail') {\n const reportAgent = agents.find((a) => a.id === state.targetAgentId);\n if (reportAgent) {\n const lines = buildReportViewLines(reportAgent, reportBlocks, rect.w);\n return buildPanelRows(rect, lines, scrollOffset, focused, 'cyan');\n }\n }\n\n // No cursor / no session → empty state\n const cursorNode: TreeNode | undefined = detailCtx.nodes[state.cursorIndex];\n if (!cursorNode || !session) {\n return buildEmptyPanelRows(rect, false, 'gray', '\\x1b[2mSelect a session to view details\\x1b[0m');\n }\n\n // Session data hasn't arrived yet (poll debounced during rapid scrolling)\n if (cursorNode.sessionId !== session.id) {\n return buildEmptyPanelRows(rect, false, 'gray');\n }\n\n // Compute cache key from all inputs that affect line building\n const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];\n const cacheKey = [\n cursorNode.id,\n cursorNode.type,\n state.mode,\n state.targetAgentId,\n rect.w,\n session.id,\n session.agents.length,\n session.orchestratorCycles.length,\n lastCycle?.completedAt ?? '',\n lastCycle?.agentsSpawned.length ?? 0,\n state.planContent.length,\n state.goalContent.length,\n state.strategyContent.length,\n state.paneAlive,\n detailReportBlocks.length,\n session.messages.length,\n state.contextFiles.length,\n contextFileContent?.length ?? -1,\n ].join(':');\n\n let lines: DetailLine[];\n let borderColor = 'gray';\n\n if (cacheKey === state.detailCacheKey && state.cachedDetailLines !== null) {\n lines = state.cachedDetailLines;\n } else {\n switch (cursorNode.type) {\n case 'session': {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n\n case 'cycle': {\n const cycleNode = cursorNode as CycleTreeNode;\n const cycle = session.orchestratorCycles.find((c) => c.cycle === cycleNode.cycleNumber);\n if (!cycle) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n } else {\n lines = buildCycleLines(cycle, session.agents, rect.w);\n }\n break;\n }\n\n case 'agent': {\n const agentNode = cursorNode as AgentTreeNode;\n const agent = agents.find((a) => a.id === agentNode.agentId);\n if (!agent) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n } else {\n lines = buildAgentLines(agent, detailReportBlocks, rect.w);\n }\n break;\n }\n\n case 'report': {\n const reportNode = cursorNode as ReportTreeNode;\n const agent = agents.find((a) => a.id === reportNode.agentId);\n if (!agent) {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n const reportIdx = reportNode.reportIndex;\n const specificBlock = detailReportBlocks.find((_b, i) => {\n const originalIdx = agent.reports.length - 1 - i;\n return originalIdx === reportIdx;\n });\n if (specificBlock) {\n const { label: badge, color: badgeColor } = reportBadge(specificBlock.type);\n lines = [\n [seg(' '), seg(badge, { color: badgeColor }), seg(` ${agent.id} · ${agentDisplayName(agent)}`, { bold: true })],\n singleLine(` ${formatTime(specificBlock.timestamp)}`, { dim: true }),\n singleLine(' '),\n [seg(' ▎ CONTENT', { color: badgeColor, bold: true })],\n ...wrapText(specificBlock.content.trim(), rect.w - 8).map((l) => singleLine(` ${l}`)),\n ];\n borderColor = badgeColor;\n } else {\n lines = buildAgentLines(agent, detailReportBlocks, rect.w);\n }\n break;\n }\n\n case 'messages': {\n lines = [singleLine(` Messages (${session.messages.length})`, { bold: true })];\n if (session.messages.length === 0) {\n lines.push(singleLine(' No messages', { dim: true, italic: true }));\n } else {\n for (const msg of session.messages) {\n const time = formatTime(msg.timestamp);\n const agentId = msg.source.type === 'agent' ? msg.source.agentId : undefined;\n const label = messageSourceLabel(msg.source.type, agentId);\n const labelColor = messageSourceColor(msg.source.type);\n const maxContent = Math.max(10, rect.w - label.length - 20);\n lines.push([\n seg(` [${time}] `, { dim: true }),\n seg(`${label}: `, { color: labelColor, bold: true }),\n seg(wrapText(msg.summary.length > 0 ? msg.summary : msg.content, maxContent)[0]!, {}),\n ]);\n }\n }\n break;\n }\n\n case 'message': {\n const msgNode = cursorNode as MessageTreeNode;\n const msg = session.messages.find((m) => m.id === msgNode.messageId);\n lines = [singleLine(' Message', { bold: true })];\n if (msg) {\n lines.push(singleLine(` ${msgNode.source} · ${msgNode.timestamp}`, { dim: true }));\n for (const l of wrapText(msg.content, rect.w - 8)) {\n lines.push(singleLine(` ${l}`));\n }\n } else {\n lines.push(singleLine(' Message not found', { dim: true }));\n }\n break;\n }\n\n case 'context': {\n lines = [\n [seg(' '), seg('⊞', { color: 'white' }), seg(` Context (${state.contextFiles.length})`, { bold: true })],\n ];\n if (state.contextFiles.length === 0) {\n lines.push(singleLine(' No context files found.', { dim: true }));\n } else {\n for (const f of state.contextFiles) {\n lines.push(singleLine(` · ${f}`, { dim: true }));\n }\n }\n break;\n }\n\n case 'context-file': {\n const ctxFileNode = cursorNode as ContextFileTreeNode;\n lines = [\n [seg(' '), seg('⊞', { color: 'white' }), seg(` ${ctxFileNode.label}`, { bold: true })],\n singleLine(' '),\n ];\n if (contextFileContent == null) {\n lines.push(singleLine(' File not found or unreadable.', { dim: true }));\n } else {\n const wrapped = wrapText(stripFrontmatter(contextFileContent), rect.w - 8);\n if (wrapped.length === 0) {\n lines.push(singleLine(' (empty)', { dim: true }));\n } else {\n for (const l of wrapped) {\n lines.push(singleLine(` ${l}`));\n }\n }\n }\n borderColor = 'white';\n break;\n }\n\n default: {\n lines = buildSessionLines(session, state.planContent, state.goalContent, rect.w, state.paneAlive, state.strategyContent);\n break;\n }\n }\n\n state.cachedDetailLines = lines;\n state.detailCacheKey = cacheKey;\n }\n\n // Compute borderColor from node type (cheap, no need to cache)\n if (cursorNode.type === 'context-file') {\n borderColor = 'white';\n } else if (cursorNode.type === 'report') {\n const reportNode = cursorNode as ReportTreeNode;\n const agent = agents.find((a) => a.id === reportNode.agentId);\n if (agent) {\n const reportIdx = reportNode.reportIndex;\n const specificBlock = detailReportBlocks.find((_b, i) => {\n const originalIdx = agent.reports.length - 1 - i;\n return originalIdx === reportIdx;\n });\n if (specificBlock) borderColor = reportBadge(specificBlock.type).color;\n }\n }\n\n return buildPanelRows(rect, lines, scrollOffset, focused, borderColor, state.detailRenderedCache);\n}\n\nexport function renderLogsRows(\n rect: Rect,\n state: AppState,\n): string[] {\n const focused = state.focusPane === 'logs';\n const scrollOffset = state.logsScroll.offset;\n\n if (state.logsCycles.length === 0) {\n return buildEmptyPanelRows(rect, focused, 'gray', '\\x1b[2mNo logs\\x1b[0m');\n }\n\n const logsCacheKey = `${state.logsCycles.length}:${rect.w}:${state.logsCycles.map((c) => c.cycle).join(',')}`;\n let lines: DetailLine[];\n if (logsCacheKey === state.logsCacheKey && state.cachedLogsLines !== null) {\n lines = state.cachedLogsLines;\n } else {\n lines = buildLogsLines(state.logsCycles, rect.w);\n state.cachedLogsLines = lines;\n state.logsCacheKey = logsCacheKey;\n }\n\n return buildPanelRows(rect, lines, scrollOffset, focused, 'gray', state.logsRenderedCache);\n}\n","import { clipAnsi, colorToSGR, type Rect } from '../render.js';\nimport type { NvimBridge } from '../lib/nvim-bridge.js';\n\n/**\n * Render the neovim detail panel with a status header as self-contained row strings.\n * Produces exactly rect.h strings, each rect.w display columns wide.\n * Compatible with the row-based panel composition in app.ts.\n */\nexport function renderNvimDetailRows(\n rect: Rect,\n bridge: NvimBridge,\n focused: boolean,\n editable: boolean,\n statusRows: string[],\n composing: boolean = false,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n\n // Border styling — cyan when focused to distinguish nvim mode, gray otherwise\n const borderColor = focused ? 'cyan' : 'gray';\n const sgr = `\\x1b[${colorToSGR(borderColor)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4; // border + padding on each side\n\n // Top border — insert badge when focused\n if (focused) {\n const badgeText = composing ? ' COMPOSE ' : editable ? ' EDIT ' : ' NVIM ';\n const badgeLen = badgeText.length;\n const dashesLeft = 2;\n const dashesRight = Math.max(0, w - 2 - dashesLeft - badgeLen);\n rows[0] =\n sgr + '╭' + '─'.repeat(dashesLeft) + reset +\n `\\x1b[${colorToSGR('cyan')};1m` + badgeText + reset +\n sgr + '─'.repeat(dashesRight) + '╮' + reset;\n } else {\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n }\n\n // Bottom border\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n\n // Border pieces for interior rows\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const blankInner = ' '.repeat(innerW);\n const emptyRow = borderL + blankInner + borderR;\n\n // Pre-fill interior rows with empty content\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (innerW <= 0 || h <= 2) return rows;\n\n // Render status rows (ANSI, not nvim)\n const statusCount = statusRows.length;\n for (let i = 0; i < statusCount && i < h - 3; i++) {\n const clipped = clipAnsi(statusRows[i]!, innerW);\n rows[1 + i] = borderL + clipped + borderR;\n }\n\n // Separator between status and nvim content\n const separatorRow = 1 + statusCount;\n if (separatorRow < h - 1) {\n rows[separatorRow] = sgr + '├' + '─'.repeat(w - 2) + '┤' + reset;\n }\n\n // Get neovim screen rows and fill the remaining interior\n const nvimStartRow = separatorRow + 1;\n const nvimRows = bridge.getRows();\n for (let i = nvimStartRow; i < h - 1; i++) {\n const nvimIdx = i - nvimStartRow;\n const nvimRow = nvimRows[nvimIdx];\n if (nvimRow !== undefined) {\n const clipped = clipAnsi(nvimRow, innerW);\n rows[i] = borderL + clipped + borderR;\n }\n }\n\n return rows;\n}\n","import { writeClipped, type FrameBuffer } from '../render.js';\nimport { ansiBold, ansiDim } from '../lib/format.js';\nimport type { AppState } from '../state.js';\nimport { INPUT_MODES, PROMPTS, COMPOSE_HEADERS } from '../state.js';\nimport type { TreeNodeType } from '../types/tree.js';\n\n// ─── Notification Row ─────────────────────────────────────────────────────────\n\nexport function renderNotificationRow(\n buf: FrameBuffer,\n y: number,\n notification: string | null,\n error: string | null,\n): void {\n if (notification !== null) {\n const icon = /error|failed/i.test(notification)\n ? '✕'\n : /success|created|killed|sent|copied|deleted/i.test(notification)\n ? '✓'\n : 'ℹ';\n const content = `\\x1b[1;33m${icon} ${notification}\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n } else if (error !== null) {\n const content = `\\x1b[31m⚠ ${error}\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n }\n}\n\n// ─── Input Bar ────────────────────────────────────────────────────────────────\n\nexport function renderInputBar(\n buf: FrameBuffer,\n y: number,\n state: AppState,\n): void {\n const { mode, inputText, inputCursorPos } = state;\n\n if (mode === 'compose') {\n const action = state.composeAction;\n const label = action ? COMPOSE_HEADERS[action.kind] : 'Compose';\n const content = `\\x1b[1;33mCOMPOSE\\x1b[0m\\x1b[2m ${label} · :w to submit · Tab to cancel\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n return;\n }\n\n if (mode === 'navigate') {\n const content = `\\x1b[2mPress [m] to message orchestrator, [n] for new session\\x1b[0m`;\n writeClipped(buf, 1, y, content, buf.width - 2);\n return;\n }\n\n if (\n mode === 'report-detail' ||\n mode === 'leader' ||\n mode === 'copy-menu' ||\n mode === 'help' ||\n !INPUT_MODES.has(mode)\n ) {\n return;\n }\n\n const prompt = PROMPTS[mode] ?? mode;\n const cursorChar = inputCursorPos < inputText.length ? inputText[inputCursorPos]! : ' ';\n const before = inputText.slice(0, inputCursorPos);\n const after = inputText.slice(inputCursorPos + 1);\n\n const content =\n `\\x1b[33m${prompt} > \\x1b[0m` +\n before +\n `\\x1b[7m${cursorChar}\\x1b[0m` +\n after +\n `\\x1b[2m (enter to send, esc to cancel)\\x1b[0m`;\n\n writeClipped(buf, 1, y, content, buf.width - 2);\n}\n\n// ─── Status Line ──────────────────────────────────────────────────────────────\n\nconst B = ansiBold;\nconst D = ansiDim;\nconst SEP = D('│ ');\n\nexport function renderStatusLine(\n buf: FrameBuffer,\n y: number,\n state: AppState,\n cursorNodeType: TreeNodeType | undefined,\n): void {\n const { mode, focusPane } = state;\n\n if (mode === 'report-detail') return;\n if (mode === 'compose') return; // compose status shown in input bar\n\n let content: string;\n\n if (mode === 'leader') {\n content = `\\x1b[1;35mLEADER\\x1b[0m` + D(' press a command key or [esc] to cancel');\n } else if (mode === 'copy-menu') {\n content = `\\x1b[1;36mCOPY\\x1b[0m` + D(' [p] path [C] context [l] logs [s] session ID [esc] cancel');\n } else if (mode === 'help') {\n content = `\\x1b[1;33mHELP\\x1b[0m` + D(' [esc] or [?] to dismiss');\n } else if (mode === 'delete-confirm') {\n content = `\\x1b[1;31mDELETE\\x1b[0m` + D(\" type 'yes' to confirm, [esc] to cancel\");\n } else if (mode === 'spawn-agent') {\n content = `\\x1b[1;32mSPAWN\\x1b[0m` + D(' enter agent instruction, [esc] to cancel');\n } else if (mode === 'search') {\n content = `\\x1b[1;34mSEARCH\\x1b[0m` + D(' type to filter, enter to apply, [esc] to cancel');\n } else if (mode === 'message-agent') {\n content = `\\x1b[1;36mMESSAGE\\x1b[0m` + D(' enter message for agent, [esc] to cancel');\n } else if (mode === 'shell-command') {\n content = `\\x1b[1;35mSHELL\\x1b[0m` + D(' enter command, [esc] to cancel');\n } else if (mode !== 'navigate') {\n content = D('[enter] send [esc] cancel');\n } else if (focusPane === 'logs' || focusPane === 'detail') {\n content =\n B('[jk/↑↓]') + D(' scroll ') +\n B('[h/←/tab]') + D(' back ') +\n B('[t]') + D('oggle view ') +\n SEP +\n B('[m]') + D('sg ') +\n B('[g]') + D('oal ') +\n B('[n]') + D('ew ') +\n B('[p]') + D('lan ') +\n B('[w]') + D('indow ') +\n B('[R]') + D('esume ') +\n B('[q]') + D('uit');\n } else {\n // tree focused\n let contextFilePart = '';\n if (cursorNodeType === 'context-file') {\n contextFilePart = B('[e]') + D('dit ') + B('[⏎]') + D(' open ');\n }\n content =\n B('[hjkl]') + D(' navigate ') +\n SEP +\n contextFilePart +\n B('[space]') + D(' leader ') +\n B('[tab]') + D(' detail ') +\n B('[t]') + D('oggle view ') +\n SEP +\n B('[m]') + D('sg ') +\n B('[n]') + D('ew ') +\n B('[R]') + D('esume ') +\n B('[q]') + D('uit');\n }\n\n writeClipped(buf, 1, y, content, buf.width - 2);\n}\n","import { drawBorder, writeClipped, type FrameBuffer } from '../render.js';\nimport { ansiColor, ansiDim } from '../lib/format.js';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst LEADER_WIDTH = 26;\nconst LEADER_HEIGHT = 19; // 17 content lines + 2 border lines\nconst COPY_HEIGHT = 9; // 7 content lines + 2 border lines\nconst HELP_WIDTH = 62;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction helpRow(left: string, right: string, innerWidth: number): string {\n const col = Math.floor(innerWidth / 2);\n return (left.padEnd(col) + right).padEnd(innerWidth);\n}\n\n// ─── Overlays ─────────────────────────────────────────────────────────────────\n\nexport function renderLeaderOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const x = cols - LEADER_WIDTH - 1;\n const y = rows - LEADER_HEIGHT - 2;\n const innerWidth = LEADER_WIDTH - 2;\n\n drawBorder(buf, x, y, LEADER_WIDTH, LEADER_HEIGHT, 'magenta');\n\n const lines: string[] = [\n ansiColor(' LEADER'.padEnd(innerWidth), 'magenta', true),\n ' '.padEnd(innerWidth),\n ' y copy menu'.padEnd(innerWidth),\n ' d delete session'.padEnd(innerWidth),\n ' l daemon logs'.padEnd(innerWidth),\n ' o open session dir'.padEnd(innerWidth),\n ' a spawn agent'.padEnd(innerWidth),\n ' m message agent'.padEnd(innerWidth),\n ' / search'.padEnd(innerWidth),\n ' ! shell command'.padEnd(innerWidth),\n ' j jump to pane'.padEnd(innerWidth),\n ' k kill session/agent'.padEnd(innerWidth),\n ' q quit'.padEnd(innerWidth),\n ' ? help'.padEnd(innerWidth),\n ' 1-9 jump to session'.padEnd(innerWidth),\n ' '.padEnd(innerWidth),\n ansiDim(' esc dismiss'.padEnd(innerWidth)),\n ];\n\n for (let i = 0; i < lines.length; i++) {\n writeClipped(buf, x + 1, y + 1 + i, lines[i]!, innerWidth);\n }\n}\n\nexport function renderCopyMenuOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const x = cols - LEADER_WIDTH - 1;\n const y = rows - COPY_HEIGHT - 2;\n const innerWidth = LEADER_WIDTH - 2;\n\n drawBorder(buf, x, y, LEADER_WIDTH, COPY_HEIGHT, 'cyan');\n\n const lines: string[] = [\n ansiColor(' COPY'.padEnd(innerWidth), 'cyan', true),\n ' '.padEnd(innerWidth),\n ' p session path'.padEnd(innerWidth),\n ' C LLM context'.padEnd(innerWidth),\n ' l logs content'.padEnd(innerWidth),\n ' s session ID'.padEnd(innerWidth),\n ansiDim(' esc cancel'.padEnd(innerWidth)),\n ];\n\n for (let i = 0; i < lines.length; i++) {\n writeClipped(buf, x + 1, y + 1 + i, lines[i]!, innerWidth);\n }\n}\n\nexport function renderHelpOverlay(buf: FrameBuffer, rows: number, cols: number): void {\n const innerWidth = HELP_WIDTH - 2;\n const x = Math.max(0, Math.floor((cols - HELP_WIDTH) / 2));\n\n const contentLines: string[] = [\n helpRow(' hjkl/↑↓←→ navigate', ' tab switch pane', innerWidth),\n helpRow(' enter expand/open', ' t toggle logs', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' n new session', ' m message orch.', innerWidth),\n helpRow(' R resume session', ' C continue session', innerWidth),\n helpRow(' b rollback cycle', ' x restart agent', innerWidth),\n helpRow(' r re-run agent', ' g edit goal', innerWidth),\n helpRow(' p open roadmap', ' s toggle strategy', innerWidth),\n helpRow(' S edit strategy', ' w go to window', innerWidth),\n helpRow(' o resume claude session', ' c claude companion', innerWidth),\n helpRow(' q quit', '', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' space → y copy submenu', ' space → d delete session', innerWidth),\n helpRow(' space → j jump to pane', ' space → k kill', innerWidth),\n helpRow(' space → q quit', ' space → o open dir', innerWidth),\n helpRow(' space → l tail logs', ' space → / search', innerWidth),\n helpRow(' space → a spawn agent', ' space → m msg agent', innerWidth),\n helpRow(' space → ? help', ' space → 1-9 jump', innerWidth),\n ' '.padEnd(innerWidth),\n helpRow(' y → p session path', ' y → C LLM context', innerWidth),\n helpRow(' y → l logs content', ' y → s session ID', innerWidth),\n ];\n\n // title + blank + contentLines + blank = contentLines.length + 3 inner rows, + 2 border\n const height = Math.min(contentLines.length + 4, rows - 2);\n const y = Math.max(0, Math.floor((rows - height) / 2));\n\n drawBorder(buf, x, y, HELP_WIDTH, height, 'yellow');\n\n // Title row\n writeClipped(buf, x + 1, y + 1, ansiColor(' KEYBINDINGS (esc or ? to close)'.padEnd(innerWidth), 'yellow', true), innerWidth);\n // Blank row after title\n writeClipped(buf, x + 1, y + 2, ' '.padEnd(innerWidth), innerWidth);\n\n // Content rows (clamp to available height: height - 4 rows for title+blank+trailing_blank+borders)\n const availableContentRows = height - 4;\n for (let i = 0; i < Math.min(contentLines.length, availableContentRows); i++) {\n writeClipped(buf, x + 1, y + 3 + i, contentLines[i]!, innerWidth);\n }\n\n // Trailing blank (only if there's room)\n const trailingBlankRow = y + 3 + Math.min(contentLines.length, availableContentRows);\n if (trailingBlankRow < y + height - 1) {\n writeClipped(buf, x + 1, trailingBlankRow, ' '.padEnd(innerWidth), innerWidth);\n }\n}\n","import { execSync } from 'node:child_process';\nimport { writeFileSync, mkdirSync, unlinkSync, readFileSync, statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\nfunction simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash |= 0;\n }\n return Math.abs(hash).toString(36);\n}\n\nexport class NvimBridge {\n private pty: import('node-pty').IPty | null = null;\n private xterm: import('@xterm/headless').Terminal | null = null;\n private _cols: number;\n private _rows: number;\n private onRender: () => void;\n private renderTimer: ReturnType<typeof setTimeout> | null = null;\n\n currentFile: string | null = null;\n ready: boolean = false;\n dirty: boolean = true;\n available: boolean = false;\n respawning: boolean = false;\n /** Set true once nvim has been ready at least once — prevents respawn during initial startup */\n wasReady: boolean = false;\n /** DECSCUSR cursor style: 0=default, 1=blinking block, 2=steady block, 3=blinking underline, 4=steady underline, 5=blinking bar, 6=steady bar */\n cursorStyle: number = 0;\n private cachedRows: string[] | null = null;\n private nvimPath: string = 'nvim';\n private pendingFiles: { files: { path: string; readonly: boolean }[]; key: string } | null = null;\n private fileDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n private cmdDir: string;\n private cmdFile: string;\n /** Tracked editable files: path → { basePath (snapshot), mtimeMs } */\n private editableFiles: Map<string, { basePath: string; mtimeMs: number }> = new Map();\n private mergeStatusFile: string;\n\n constructor(cols: number, rows: number, onRender: () => void) {\n this._cols = cols;\n this._rows = rows;\n this.onRender = onRender;\n\n // Temp file for passing lua commands to nvim without command-line flash\n this.cmdDir = join(tmpdir(), 'sisyphus-nvim');\n mkdirSync(this.cmdDir, { recursive: true });\n this.cmdFile = join(this.cmdDir, `cmd-${process.pid}.lua`);\n this.mergeStatusFile = join(this.cmdDir, `merge-status-${process.pid}.txt`);\n\n try {\n this.nvimPath = execSync('which nvim', { stdio: 'pipe' }).toString().trim();\n this.available = true;\n } catch {\n this.available = false;\n return;\n }\n\n this.spawn().catch(() => {\n this.available = false;\n this.ready = false;\n });\n }\n\n private spawn(): Promise<void> {\n return Promise.all([\n import('node-pty'),\n import('@xterm/headless'),\n ]).then(([nodePty, xtermModule]) => new Promise<void>((resolve) => {\n const { spawn } = nodePty;\n // @xterm/headless is CJS — Terminal lives on the default export when imported from ESM\n const { Terminal } = xtermModule.default as typeof import('@xterm/headless');\n\n this.xterm = new Terminal({\n cols: this._cols,\n rows: this._rows,\n allowProposedApi: true,\n });\n\n const nvimArgs = [\n // Pre-init: only settings needed before user config loads\n '--cmd',\n [\n 'set noswapfile',\n 'set nobackup',\n 'set nowritebackup',\n 'set hidden',\n 'set autoread',\n ].join(' | '),\n // Post-init: cosmetic overrides applied AFTER user config (LazyVim, etc.)\n '-c',\n [\n 'set laststatus=0',\n 'set showtabline=2',\n 'set signcolumn=no',\n 'set nonumber',\n 'set noruler',\n 'set noshowcmd',\n 'set noshowmode',\n 'set shortmess+=F',\n 'set fillchars=eob:\\\\ ',\n 'set scrolloff=3',\n ].join(' | '),\n // Suppress LSP — prevent servers from ever starting (avoids exit warnings)\n '--cmd',\n 'lua vim.lsp.start = function() end',\n // Poll-based command executor: reads lua from temp file — no command-line flash\n '-c',\n `lua local _t = vim.loop.new_timer(); _t:start(100, 50, vim.schedule_wrap(function() local f = io.open('${this.cmdFile.replace(/'/g, \"\\\\'\")}', 'r'); if not f then return end; local c = f:read('*a'); f:close(); os.remove('${this.cmdFile.replace(/'/g, \"\\\\'\")}'); if c and #c > 0 then local fn = loadstring(c); if fn then pcall(fn) end end end))`,\n ];\n\n this.pty = spawn(this.nvimPath, nvimArgs, {\n name: 'xterm-256color',\n cols: this._cols,\n rows: this._rows,\n env: { ...process.env, TERM: 'xterm-256color' } as Record<string, string>,\n });\n\n let settled = false;\n\n this.pty.onData((data: string) => {\n // Track DECSCUSR cursor shape sequences (\\x1b[N q) so we can\n // forward them to the real terminal alongside cursor positioning\n const csMatch = data.match(/\\x1b\\[(\\d+) q/);\n if (csMatch) this.cursorStyle = parseInt(csMatch[1], 10);\n\n this.xterm!.write(data);\n this.dirty = true;\n this.cachedRows = null;\n this.debouncedRender();\n });\n\n this.pty.onExit(() => {\n this.ready = false;\n this.dirty = true;\n this.cachedRows = null;\n this.onRender();\n // Resolve if nvim dies before settling (prevents hanging promise)\n if (!settled) { settled = true; resolve(); }\n });\n\n // Mark ready after nvim + user config have settled\n setTimeout(() => {\n if (this.pty) {\n this.ready = true;\n this.wasReady = true;\n this.dirty = true;\n this.cachedRows = null;\n this.onRender();\n }\n if (!settled) { settled = true; resolve(); }\n }, 500);\n }));\n }\n\n /**\n * Respawn nvim after it exited (e.g. user quit during compose).\n * Cleans up dead instances and re-runs spawn().\n */\n async respawn(): Promise<void> {\n if (!this.available) return;\n if (this.xterm) { this.xterm.dispose(); this.xterm = null; }\n if (this.pty) { try { this.pty.kill(); } catch { /* already dead */ } this.pty = null; }\n this.ready = false;\n this.dirty = true;\n this.cachedRows = null;\n this.currentFile = null;\n await this.spawn();\n }\n\n private debouncedRender(): void {\n if (this.renderTimer !== null) return;\n this.renderTimer = setTimeout(() => {\n this.renderTimer = null;\n this.onRender();\n }, 16); // ~60fps\n }\n\n /**\n * Execute lua in nvim without flashing the command line.\n * Writes lua to a temp file — a libuv timer in nvim polls and executes it.\n */\n private execLua(lua: string): void {\n writeFileSync(this.cmdFile, lua);\n }\n\n openFile(path: string, readonly: boolean = true): void {\n if (!this.pty || !this.ready) return;\n this.currentFile = path;\n const escapeLua = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const ro = readonly ? 'vim.bo.readonly = true; vim.bo.modifiable = false' : 'vim.bo.readonly = false; vim.bo.modifiable = true';\n this.execLua(`vim.cmd('edit! ${escapeLua(path)}'); ${ro}`);\n }\n\n openTabFiles(files: { path: string; readonly: boolean }[]): void {\n if (!this.pty || !this.ready || files.length === 0) return;\n const key = files.map(f => f.path).join('|');\n // Debounce — only execute after 150ms of no new calls (prevents LSP churn during scroll)\n this.pendingFiles = { files, key };\n if (this.fileDebounceTimer !== null) clearTimeout(this.fileDebounceTimer);\n this.fileDebounceTimer = setTimeout(() => {\n this.fileDebounceTimer = null;\n if (this.pendingFiles) {\n this.executeOpenFiles(this.pendingFiles.files);\n this.currentFile = this.pendingFiles.key;\n this.pendingFiles = null;\n }\n }, 150);\n }\n\n private executeOpenFiles(files: { path: string; readonly: boolean }[]): void {\n if (!this.pty || !this.ready) return;\n\n // Snapshot editable files for 3-way merge tracking\n this.trackEditableFiles(files);\n\n const escapeLua = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const stmts: string[] = [\n 'for _, b in ipairs(vim.api.nvim_list_bufs()) do pcall(vim.api.nvim_buf_delete, b, {force=true}) end',\n ];\n for (let i = 0; i < files.length; i++) {\n const path = escapeLua(files[i]!.path);\n stmts.push(i === 0\n ? `vim.cmd('edit! ${path}')`\n : `vim.cmd('edit ${path}')`);\n if (files[i]!.readonly) {\n stmts.push('vim.bo.readonly = true', 'vim.bo.modifiable = false');\n } else {\n stmts.push('vim.bo.readonly = false', 'vim.bo.modifiable = true');\n }\n }\n stmts.push(\"vim.cmd('bfirst')\");\n this.execLua(`(function() ${stmts.join('; ')} end)()`);\n }\n\n openTabFile(path: string, readonly: boolean): void {\n if (!this.pty || !this.ready) return;\n this.pty.write(`:tabedit ${path}\\r`);\n if (readonly) {\n this.pty.write(':setlocal readonly nomodifiable\\r');\n } else {\n this.pty.write(':setlocal noreadonly modifiable\\r');\n }\n }\n\n /**\n * Open a temp file for compose mode: clears buffers, opens writable,\n * installs BufWritePost autocmd that writes a signal file on :w,\n * and enters insert mode.\n */\n openComposeFile(tempPath: string, signalPath: string): void {\n if (!this.pty || !this.ready) return;\n\n // Cancel any pending file debounce (prevents queued openTabFiles from overwriting)\n if (this.fileDebounceTimer !== null) {\n clearTimeout(this.fileDebounceTimer);\n this.fileDebounceTimer = null;\n this.pendingFiles = null;\n }\n\n const escapeLua = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const eSig = escapeLua(signalPath);\n const lua = [\n // Clear all existing buffers\n 'for _, b in ipairs(vim.api.nvim_list_bufs()) do pcall(vim.api.nvim_buf_delete, b, {force=true}) end',\n // Open temp file as writable\n `vim.cmd('edit! ${escapeLua(tempPath)}')`,\n 'vim.bo.readonly = false',\n 'vim.bo.modifiable = true',\n // Install BufWritePost autocmd — writes submit signal on :w\n `vim.api.nvim_create_autocmd('BufWritePost', { buffer = 0, callback = function() local f = io.open('${eSig}', 'w'); if f then f:write('1'); f:close() end end })`,\n // Install QuitPre autocmd — writes cancel signal if no submit signal exists (quit proceeds, nvim may exit)\n `vim.api.nvim_create_autocmd('QuitPre', { buffer = 0, callback = function() local sf = io.open('${eSig}', 'r'); if sf then sf:close() else local f = io.open('${eSig}', 'w'); if f then f:write('cancel'); f:close() end end end })`,\n // Enter insert mode\n \"vim.cmd('startinsert')\",\n ].join('; ');\n this.execLua(`(function() ${lua} end)()`);\n this.currentFile = tempPath;\n }\n\n closeAllTabs(): void {\n if (!this.pty || !this.ready) return;\n this.execLua('for _, b in ipairs(vim.api.nvim_list_bufs()) do pcall(vim.api.nvim_buf_delete, b, {force=true}) end; vim.cmd(\"enew!\")');\n this.currentFile = null;\n }\n\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n this.cachedRows = null;\n this.dirty = true;\n if (this.pty) this.pty.resize(cols, rows);\n if (this.xterm) this.xterm.resize(cols, rows);\n }\n\n write(data: string): void {\n if (this.pty) this.pty.write(data);\n }\n\n getRows(): string[] {\n if (!this.dirty && this.cachedRows) return this.cachedRows;\n if (!this.xterm) return Array.from({ length: this._rows }, () => ' '.repeat(this._cols));\n\n const rows: string[] = [];\n const buffer = this.xterm.buffer.active;\n // Reusable cell to avoid per-cell allocation\n const reusableCell = buffer.getNullCell();\n\n for (let y = 0; y < this._rows; y++) {\n const line = buffer.getLine(y);\n if (!line) {\n rows.push(' '.repeat(this._cols));\n continue;\n }\n\n let row = '';\n let prevFg: number | undefined = undefined;\n let prevBg: number | undefined = undefined;\n let prevFgMode: 'default' | 'palette' | 'rgb' = 'default';\n let prevBgMode: 'default' | 'palette' | 'rgb' = 'default';\n let prevBold = false;\n let prevDim = false;\n let prevItalic = false;\n let prevUnderline = false;\n let prevInverse = false;\n let hasOpenSGR = false;\n\n for (let x = 0; x < this._cols; x++) {\n const cell = line.getCell(x, reusableCell);\n if (!cell) {\n row += ' ';\n continue;\n }\n\n const char = cell.getChars() || ' ';\n\n const fgDefault = cell.isFgDefault();\n const fgPalette = cell.isFgPalette();\n const fgRGB = cell.isFgRGB();\n const fg = fgDefault ? undefined : cell.getFgColor();\n let fgMode: 'default' | 'palette' | 'rgb';\n if (fgDefault) fgMode = 'default';\n else if (fgPalette) fgMode = 'palette';\n else if (fgRGB) fgMode = 'rgb';\n else throw new Error(`Unknown fg color mode at cell (${x}, ${y})`);\n\n const bgDefault = cell.isBgDefault();\n const bgPalette = cell.isBgPalette();\n const bgRGB = cell.isBgRGB();\n const bg = bgDefault ? undefined : cell.getBgColor();\n let bgMode: 'default' | 'palette' | 'rgb';\n if (bgDefault) bgMode = 'default';\n else if (bgPalette) bgMode = 'palette';\n else if (bgRGB) bgMode = 'rgb';\n else throw new Error(`Unknown bg color mode at cell (${x}, ${y})`);\n\n const bold = cell.isBold() !== 0;\n const dim = cell.isDim() !== 0;\n const italic = cell.isItalic() !== 0;\n const underline = cell.isUnderline() !== 0;\n const inverse = cell.isInverse() !== 0;\n\n const attrChanged =\n fg !== prevFg ||\n bg !== prevBg ||\n fgMode !== prevFgMode ||\n bgMode !== prevBgMode ||\n bold !== prevBold ||\n dim !== prevDim ||\n italic !== prevItalic ||\n underline !== prevUnderline ||\n inverse !== prevInverse;\n\n if (attrChanged) {\n if (hasOpenSGR) {\n row += '\\x1b[0m';\n hasOpenSGR = false;\n }\n\n const codes: string[] = [];\n if (bold) codes.push('1');\n if (dim) codes.push('2');\n if (italic) codes.push('3');\n if (underline) codes.push('4');\n if (inverse) codes.push('7');\n\n if (fg !== undefined) {\n if (fgMode === 'palette') {\n codes.push(`38;5;${fg}`);\n } else if (fgMode === 'rgb') {\n const r = (fg >> 16) & 0xff;\n const g = (fg >> 8) & 0xff;\n const b = fg & 0xff;\n codes.push(`38;2;${r};${g};${b}`);\n }\n }\n\n if (bg !== undefined) {\n if (bgMode === 'palette') {\n codes.push(`48;5;${bg}`);\n } else if (bgMode === 'rgb') {\n const r = (bg >> 16) & 0xff;\n const g = (bg >> 8) & 0xff;\n const b = bg & 0xff;\n codes.push(`48;2;${r};${g};${b}`);\n }\n }\n\n if (codes.length > 0) {\n row += `\\x1b[${codes.join(';')}m`;\n hasOpenSGR = true;\n }\n\n prevFg = fg;\n prevBg = bg;\n prevFgMode = fgMode;\n prevBgMode = bgMode;\n prevBold = bold;\n prevDim = dim;\n prevItalic = italic;\n prevUnderline = underline;\n prevInverse = inverse;\n }\n\n row += char;\n }\n\n if (hasOpenSGR) {\n row += '\\x1b[0m';\n }\n\n rows.push(row);\n }\n\n this.cachedRows = rows;\n this.dirty = false;\n return rows;\n }\n\n getCursorPos(): { x: number; y: number } {\n if (!this.xterm) return { x: 0, y: 0 };\n return {\n x: this.xterm.buffer.active.cursorX,\n y: this.xterm.buffer.active.cursorY,\n };\n }\n\n /**\n * Snapshot editable files on disk so we have a base for 3-way merge.\n * Called when files are opened in nvim tabs.\n */\n private trackEditableFiles(files: { path: string; readonly: boolean }[]): void {\n // Clean up old snapshots\n for (const [, info] of this.editableFiles) {\n try { unlinkSync(info.basePath); } catch { /* ignore */ }\n }\n this.editableFiles.clear();\n\n for (const file of files) {\n if (file.readonly) continue;\n try {\n const content = readFileSync(file.path, 'utf-8');\n const mtime = statSync(file.path).mtimeMs;\n const basePath = join(this.cmdDir, `base-${simpleHash(file.path)}.md`);\n writeFileSync(basePath, content, 'utf-8');\n this.editableFiles.set(file.path, { basePath, mtimeMs: mtime });\n } catch { /* file may not exist yet */ }\n }\n }\n\n /**\n * Check editable files for external changes and 3-way merge if the buffer\n * is dirty. Falls back to regular checktime for clean/readonly buffers.\n *\n * Returns a merge status string from the *previous* cycle ('clean' or 'union')\n * if a merge completed, or null.\n */\n mergeCheckOrReload(): string | null {\n if (!this.pty || !this.ready) return null;\n\n // Read merge status from previous cycle\n let mergeResult: string | null = null;\n try {\n if (existsSync(this.mergeStatusFile)) {\n const content = readFileSync(this.mergeStatusFile, 'utf-8').trim();\n unlinkSync(this.mergeStatusFile);\n if (content) {\n const lines = content.split('\\n');\n mergeResult = lines.some(l => l === 'union') ? 'union' : 'clean';\n }\n }\n } catch { /* ignore */ }\n\n // If a merge just completed, refresh stored mtimes (merge wrote to disk)\n if (mergeResult) {\n for (const [filePath, info] of this.editableFiles) {\n try { info.mtimeMs = statSync(filePath).mtimeMs; } catch { /* ignore */ }\n }\n this.execLua('vim.cmd(\"checktime\")');\n return mergeResult;\n }\n\n // Check which editable files changed on disk\n const changedFiles: { filePath: string; basePath: string }[] = [];\n for (const [filePath, info] of this.editableFiles) {\n try {\n const currentMtime = statSync(filePath).mtimeMs;\n if (currentMtime !== info.mtimeMs) {\n changedFiles.push({ filePath, basePath: info.basePath });\n info.mtimeMs = currentMtime;\n }\n } catch { /* file gone */ }\n }\n\n // No editable files changed — regular checktime handles readonly buffers\n if (changedFiles.length === 0) {\n this.execLua('vim.cmd(\"checktime\")');\n return null;\n }\n\n // Generate Lua: run checktime first (reloads clean buffers), then merge dirty ones\n const esc = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n\n const mergeBlocks = changedFiles.map(({ filePath, basePath }) => `\n do\n local bufnr = vim.fn.bufnr('${esc(filePath)}')\n if bufnr ~= -1 and vim.api.nvim_buf_is_loaded(bufnr) then\n if vim.bo[bufnr].modified then\n local buf_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)\n local buf_content = table.concat(buf_lines, '\\\\n') .. '\\\\n'\n local tmp = '${esc(this.cmdDir)}/merge-current-${process.pid}.md'\n local f = io.open(tmp, 'w')\n if f then f:write(buf_content); f:close() end\n local result = vim.fn.system({'git', 'merge-file', '-p', '--union', tmp, '${esc(basePath)}', '${esc(filePath)}'})\n local merged_lines = vim.split(result, '\\\\n', {trimempty = false})\n if #merged_lines > 0 and merged_lines[#merged_lines] == '' then\n table.remove(merged_lines)\n end\n vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, merged_lines)\n local out = io.open('${esc(filePath)}', 'w')\n if out then out:write(result); out:close() end\n vim.bo[bufnr].modified = false\n local bf = io.open('${esc(basePath)}', 'w')\n if bf then bf:write(result); bf:close() end\n local sf = io.open('${esc(this.mergeStatusFile)}', 'a')\n if sf then sf:write(vim.v.shell_error == 0 and 'clean' or 'union'); sf:write('\\\\n'); sf:close() end\n else\n local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)\n local bf = io.open('${esc(basePath)}', 'w')\n if bf then bf:write(table.concat(lines, '\\\\n') .. '\\\\n'); bf:close() end\n end\n end\n end`).join('\\n');\n\n this.execLua(`(function()\n pcall(function() vim.cmd('checktime') end)\n ${mergeBlocks}\n end)()`);\n\n return null;\n }\n\n checktime(): void {\n if (this.pty && this.ready) {\n this.execLua('vim.cmd(\"checktime\")');\n }\n }\n\n destroy(): void {\n if (this.renderTimer !== null) {\n clearTimeout(this.renderTimer);\n this.renderTimer = null;\n }\n if (this.fileDebounceTimer !== null) {\n clearTimeout(this.fileDebounceTimer);\n this.fileDebounceTimer = null;\n }\n try {\n if (this.pty) {\n this.pty.kill();\n this.pty = null;\n }\n } catch {\n // ignore kill errors\n }\n if (this.xterm) {\n this.xterm.dispose();\n this.xterm = null;\n }\n this.ready = false;\n try { unlinkSync(this.cmdFile); } catch { /* ignore */ }\n try { unlinkSync(this.mergeStatusFile); } catch { /* ignore */ }\n for (const [, info] of this.editableFiles) {\n try { unlinkSync(info.basePath); } catch { /* ignore */ }\n }\n this.editableFiles.clear();\n }\n}\n","import { writeFileSync, mkdirSync, renameSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tuiScratchDir, goalPath, roadmapPath, strategyPath } from '../../shared/paths.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\nimport type { TreeNode } from '../types/tree.js';\nimport type { DetailContext } from '../panels/detail.js';\nimport type { AppState } from '../state.js';\nimport type { ReportBlock } from '../lib/reports.js';\n\n// ---------------------------------------------------------------------------\n// Return type\n// ---------------------------------------------------------------------------\n\nexport interface NvimFileResult {\n files: { path: string; readonly: boolean }[];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction atomicWrite(filePath: string, content: string): void {\n const tmp = filePath + '.tmp.' + process.pid;\n writeFileSync(tmp, content, 'utf-8');\n renameSync(tmp, filePath);\n}\n\nfunction ensureTuiDir(cwd: string, sessionId: string): string {\n const dir = tuiScratchDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction formatTimestamp(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n });\n } catch {\n return iso;\n }\n}\n\nfunction formatDurationMs(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n const rem = s % 60;\n if (m < 60) return rem > 0 ? `${m}m ${rem}s` : `${m}m`;\n const h = Math.floor(m / 60);\n const remM = m % 60;\n return remM > 0 ? `${h}h ${remM}m` : `${h}h`;\n}\n\nfunction elapsedSince(start: string, end?: string): string {\n const startMs = new Date(start).getTime();\n const endMs = end ? new Date(end).getTime() : Date.now();\n return formatDurationMs(endMs - startMs);\n}\n\n// ---------------------------------------------------------------------------\n// Compose functions\n// ---------------------------------------------------------------------------\n\nfunction sectionBreak(): string[] {\n return ['', '', '---', '', ''];\n}\n\nfunction composeCycleDetail(session: Session, cycle: OrchestratorCycle): string {\n const isRunning = !cycle.completedAt;\n const dur = isRunning ? 'running' : formatDurationMs(cycle.activeMs);\n const cycleAgents = session.agents.filter((a) => cycle.agentsSpawned.includes(a.id));\n const lines: string[] = [];\n\n lines.push(`# Cycle ${cycle.cycle}`);\n lines.push('');\n lines.push(`**Status:** ${isRunning ? 'running' : 'completed'} | **Duration:** ${dur}`);\n lines.push(`**Started:** ${formatTimestamp(cycle.timestamp)}`);\n if (cycle.completedAt) {\n lines.push(`**Completed:** ${formatTimestamp(cycle.completedAt)}`);\n }\n if (cycle.mode) {\n lines.push(`**Mode:** ${cycle.mode}`);\n }\n if (cycle.claudeSessionId) {\n lines.push(`**Claude Session:** ${cycle.claudeSessionId}`);\n }\n\n // Agents\n lines.push(...sectionBreak());\n lines.push('## Agents');\n lines.push('');\n if (cycleAgents.length === 0) {\n lines.push('_No agents spawned yet._');\n } else {\n for (const agent of cycleAgents) {\n const agentDur = formatDurationMs(agent.activeMs);\n lines.push(`### ${agent.id} — ${agent.name || agent.agentType || agent.id}`);\n lines.push(`- **Status:** ${agent.status} | **Duration:** ${agentDur}`);\n lines.push(`- **Type:** ${agent.agentType || '—'}`);\n if (agent.killedReason) {\n lines.push(`- **Killed reason:** ${agent.killedReason}`);\n }\n lines.push('');\n lines.push('**Instruction:**');\n lines.push('');\n lines.push(agent.instruction);\n const latestReport =\n agent.reports.length > 0 ? agent.reports[agent.reports.length - 1]! : null;\n if (latestReport) {\n lines.push('');\n lines.push(`**Latest report** (${latestReport.type}, ${formatTimestamp(latestReport.timestamp)}):**`);\n lines.push('');\n lines.push(latestReport.summary);\n }\n lines.push('');\n }\n }\n\n // Next prompt\n if (cycle.nextPrompt) {\n lines.push(...sectionBreak());\n lines.push('## Next Prompt');\n lines.push('');\n lines.push(cycle.nextPrompt.trim());\n lines.push('');\n }\n\n return lines.join('\\n') + '\\n';\n}\n\nfunction composeAgentDetail(agent: Agent, reportBlocks: ReportBlock[]): string {\n const dur = formatDurationMs(agent.activeMs);\n const lines: string[] = [];\n\n lines.push(`# ${agent.id} — ${agent.name || agent.agentType || agent.id}`);\n lines.push('');\n lines.push(\n `**Status:** ${agent.status} | **Duration:** ${dur} | **Type:** ${agent.agentType || '—'}`,\n );\n lines.push(`**Spawned:** ${formatTimestamp(agent.spawnedAt)}`);\n if (agent.completedAt) {\n lines.push(`**Completed:** ${formatTimestamp(agent.completedAt)}`);\n }\n if (agent.killedReason) {\n lines.push(`**Killed reason:** ${agent.killedReason}`);\n }\n if (agent.claudeSessionId) {\n lines.push(`**Claude Session:** ${agent.claudeSessionId}`);\n }\n\n lines.push(...sectionBreak());\n lines.push('## Instruction');\n lines.push('');\n lines.push(agent.instruction.trim());\n\n if (reportBlocks.length > 0) {\n lines.push(...sectionBreak());\n lines.push(`## Reports (${reportBlocks.length})`);\n for (const block of reportBlocks) {\n lines.push('');\n const badge = block.type === 'final' ? 'FINAL' : 'UPDATE';\n lines.push(`### ${badge} — ${formatTimestamp(block.timestamp)}`);\n lines.push('');\n lines.push(block.content.trim());\n }\n } else if (agent.reports.length > 0) {\n lines.push(...sectionBreak());\n lines.push(`## Reports (${agent.reports.length})`);\n for (const report of agent.reports) {\n const badge = report.type === 'final' ? 'FINAL' : 'UPDATE';\n lines.push('');\n lines.push(`### ${badge} — ${formatTimestamp(report.timestamp)}`);\n lines.push('');\n lines.push(report.summary);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\nfunction composeMessages(session: Session): string {\n const lines: string[] = [];\n\n lines.push('# Messages');\n lines.push('');\n lines.push(`**Session:** ${session.name ?? session.task.slice(0, 60)}`);\n lines.push(`**Total messages:** ${session.messages.length}`);\n\n if (session.messages.length === 0) {\n lines.push('');\n lines.push('_No messages yet._');\n return lines.join('\\n') + '\\n';\n }\n\n const sorted = [...session.messages].sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n );\n\n for (const msg of sorted) {\n lines.push('');\n lines.push('---');\n lines.push('');\n const src = msg.source;\n let sourceLabel: string;\n if (src.type === 'agent') {\n sourceLabel = src.agentId;\n } else if (src.type === 'user') {\n sourceLabel = 'You';\n } else {\n sourceLabel = src.detail ? `system (${src.detail})` : 'system';\n }\n lines.push(`**From:** ${sourceLabel} | **Time:** ${formatTimestamp(msg.timestamp)}`);\n if (msg.summary && msg.summary !== msg.content) {\n lines.push(`**Summary:** ${msg.summary}`);\n }\n lines.push('');\n lines.push(msg.content.trim());\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Determine which file(s) neovim should display based on the current cursor node.\n * Returns a NvimFileResult with file paths and editability, or null.\n *\n * For session nodes, opens the real files (goal.md, roadmap.md, strategy.md) in splits.\n * For other node types, composes a markdown file in the .tui/ scratch directory.\n */\nexport function resolveNvimFile(\n state: AppState,\n cursorNode: TreeNode | undefined,\n detailCtx: DetailContext,\n cwd: string,\n): NvimFileResult | null {\n if (!cursorNode) return null;\n const sessionId = cursorNode.sessionId;\n if (!sessionId) return null;\n const session = detailCtx.session;\n\n switch (cursorNode.type) {\n case 'session': {\n if (!session) return null;\n const files: { path: string; readonly: boolean }[] = [];\n const gp = goalPath(cwd, sessionId);\n if (existsSync(gp)) files.push({ path: gp, readonly: false });\n const rp = roadmapPath(cwd, sessionId);\n if (existsSync(rp)) files.push({ path: rp, readonly: false });\n const sp = strategyPath(cwd, sessionId);\n if (existsSync(sp)) files.push({ path: sp, readonly: false });\n if (files.length === 0) return null;\n return { files };\n }\n\n case 'cycle': {\n if (!session) return null;\n const cycle = session.orchestratorCycles.find(\n (c) => c.cycle === cursorNode.cycleNumber,\n );\n if (!cycle) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, `cycle-${cursorNode.cycleNumber}.md`);\n atomicWrite(filePath, composeCycleDetail(session, cycle));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'agent': {\n if (!session) return null;\n const agent = session.agents.find((a) => a.id === cursorNode.agentId);\n if (!agent) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, `${agent.id}.md`);\n atomicWrite(filePath, composeAgentDetail(agent, state.cachedReportBlocks.get(agent.id) ?? []));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'report': {\n const agent = session?.agents.find((a) => a.id === cursorNode.agentId);\n if (agent && agent.reports.length > 0) {\n const report = agent.reports[cursorNode.reportIndex];\n if (report?.filePath && existsSync(report.filePath)) {\n return { files: [{ path: report.filePath, readonly: true }] };\n }\n }\n return null;\n }\n\n case 'context-file': {\n if (cursorNode.filePath && existsSync(cursorNode.filePath)) {\n return { files: [{ path: cursorNode.filePath, readonly: false }] };\n }\n return null;\n }\n\n case 'messages':\n case 'message': {\n if (!session || session.messages.length === 0) return null;\n const dir = ensureTuiDir(cwd, sessionId);\n const filePath = join(dir, 'messages.md');\n atomicWrite(filePath, composeMessages(session));\n return { files: [{ path: filePath, readonly: true }] };\n }\n\n case 'context': {\n return null;\n }\n\n default:\n return null;\n }\n}\n","import { setupTerminal } from './terminal.js';\nimport { createAppState } from './state.js';\nimport { startApp } from './app.js';\n\nconst args = process.argv.slice(2);\n\nfunction getArg(name: string): string | undefined {\n const idx = args.indexOf(`--${name}`);\n if (idx !== -1 && idx + 1 < args.length) {\n return args[idx + 1];\n }\n return undefined;\n}\n\nconst cwd = getArg('cwd') ?? process.cwd();\nconst cleanup = setupTerminal();\nconst state = createAppState(cwd);\nstartApp(state, cleanup);\n"],"mappings":"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","names":["cleanup","key","cwd","state","readFileSync","existsSync","statSync","join","join","cwd","state","join","stringWidth","prevFrame","stringWidth","join","readFileSync","writeFileSync","existsSync","mkdirSync","tmpdir","join","existsSync","mkdirSync","cwd","readFileSync","writeFileSync","tmpdir","execSync","cleaned","wrapped","state","lines","state","content","execSync","writeFileSync","mkdirSync","unlinkSync","readFileSync","existsSync","join","tmpdir","writeFileSync","mkdirSync","existsSync","join","writeFileSync","cwd","mkdirSync","state","cwd","existsSync","join","state","cleanup","existsSync","readFileSync","join","statSync","out","treeWidth"]}
|