mastracode 0.32.3 → 0.32.4-alpha.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-DQZ5eq1o.js","names":["parseHex","participant","ANSI_STRIP_RE","showStatus","MAX_COLLAPSED_LINES","padLine","formatTokens","formatDuration","getObserverColor","getReflectorColor","COLLAPSED_LINES","formatTokens","truncateAnsi","COLLAPSED_LINES","formatDuration","stripAnsi","process","stripAnsi","maxAllowedContent","getCurrentModeColor","#closed","#waiting","#chunks","parseJsonRiver","getCurrentModeColor","MINUTE_MS","getAvailableModePacks","askText","askSelect","getCurrentModeColor","commandExists","askText","getOAuthProviders","handleSandboxCmd","handleReviewCmd","handleReportIssueCmd","loadSettings"],"sources":["../src/tui/theme.ts","../src/tui/detect-theme.ts","../src/tui/components/chat-boundary-spacer.ts","../src/tui/components/chat-spacing.ts","../src/tui/chat-boundary-reconciliation.ts","../src/tui/components/goal-cycles-dialog.ts","../src/tui/components/model-selector.ts","../src/tui/overlay.ts","../src/tui/components/masked-input.ts","../src/tui/components/api-key-dialog.ts","../src/tui/prompt-api-key.ts","../src/tui/commands/goal.ts","../src/tui/components/help-overlay.ts","../src/tui/shell-config.ts","../src/tui/commands/help.ts","../src/tui/commands/cost.ts","../src/tui/commands/yolo.ts","../src/tui/components/multiline-input.ts","../src/tui/components/wrapping-select-list.ts","../src/tui/components/ask-question-dialog.ts","../src/tui/modal-question.ts","../src/tui/voice/native/open-settings.ts","../src/tui/voice/transcribe.ts","../src/tui/commands/voice.ts","../src/tui/components/thinking-settings.ts","../src/tui/commands/think.ts","../src/tui/commands/permissions.ts","../src/tui/commands/name.ts","../src/tui/commands/exit.ts","../src/tui/commands/hooks.ts","../src/tui/key-input.ts","../src/tui/components/mcp-selector.ts","../src/tui/notify.ts","../src/tui/display.ts","../src/tui/open-url.ts","../src/tui/commands/mcp.ts","../src/tui/commands/mode.ts","../src/tui/components/width-aware-container.ts","../src/tui/components/slash-command.ts","../src/tui/components/ask-question-inline.ts","../src/tui/db-message-parts.ts","../src/tui/sanitize-ansi.ts","../src/tui/components/assistant-message.ts","../src/tui/components/judge-display.ts","../src/tui/components/notification-summary.ts","../src/tui/components/notification.ts","../src/tui/components/om-marker.ts","../src/tui/components/om-output.ts","../src/tui/components/plan-approval-inline.ts","../src/tui/components/reactive-signal.ts","../src/tui/components/state-signal.ts","../src/tui/components/subagent-execution.ts","../src/tui/components/system-reminder.ts","../src/tui/components/ansi.ts","../src/tui/components/task-progress.ts","../src/tui/components/temporal-gap.ts","../src/tui/components/collapsible.ts","../src/tui/components/error-display.ts","../src/tui/components/tool-validation-error.ts","../src/tui/components/tool-execution-enhanced.ts","../src/tui/components/user-message.ts","../src/tui/components/tool-approval-dialog.ts","../src/tui/render-scheduler.ts","../src/tui/handlers/tool.ts","../src/tui/render-messages.ts","../src/tui/commands/send-slash-command-message.ts","../src/tui/commands/skill-filters.ts","../src/tui/commands/skills.ts","../src/tui/commands/new.ts","../src/tui/commands/clone.ts","../src/tui/commands/resource.ts","../src/tui/components/diff-output.ts","../src/tui/commands/diff.ts","../src/tui/components/thread-selector.ts","../src/tui/commands/threads.ts","../src/tui/commands/thread.ts","../src/tui/commands/thread-tag-dir.ts","../src/tui/commands/sandbox.ts","../src/tui/components/obi-loader.ts","../src/tui/components/om-progress.ts","../src/tui/status-duration.ts","../src/tui/status-line.ts","../src/tui/commands/models-pack.ts","../src/tui/commands/custom-providers.ts","../src/tui/commands/subagents.ts","../src/tui/components/om-settings.ts","../src/tui/commands/om.ts","../src/tui/components/settings.ts","../src/tui/commands/api-keys.ts","../src/tui/commands/settings.ts","../src/tui/commands/browser.ts","../src/tui/components/login-dialog.ts","../src/tui/components/login-mode-selector.ts","../src/tui/components/login-selector.ts","../src/tui/om-defaults.ts","../src/tui/commands/login.ts","../src/tui/commands/review.ts","../src/tui/commands/report-issue.ts","../src/tui/commands/setup.ts","../src/tui/commands/theme.ts","../src/tui/commands/update.ts","../src/tui/commands/mastra-gateway.ts","../src/tui/commands/plugins.ts","../src/tui/commands/feedback.ts","../src/tui/commands/observability.ts","../src/tui/commands/github.ts","../src/tui/commands/prune.ts","../src/tui/goal-input-lock.ts","../src/tui/command-dispatch.ts","../src/tui/prune-chat.ts","../src/tui/handlers/agent-lifecycle.ts","../src/tui/handlers/message.ts","../src/tui/handlers/om.ts","../src/tui/handlers/prompts.ts","../src/tui/handlers/subagent.ts","../src/tui/components/wrapping-autocomplete-list.ts","../src/tui/components/custom-editor.ts","../src/tui/voice/mic-capture.ts","../src/tui/voice/engines/cloud-engine.ts","../src/tui/voice/native/compile.ts","../src/tui/voice/engines/macos-native-engine.ts","../src/tui/voice/engines/index.ts","../src/tui/voice/voice-controller.ts","../src/tui/state.ts","../src/tui/event-dispatch.ts","../src/tui/onboarding-inline.ts","../src/tui/components/banner.ts","../src/tui/components/idle-counter.ts","../src/tui/components/simple-progress.ts","../src/tui/setup.ts","../src/tui/components/shell-output.ts","../src/tui/shell-result.ts","../src/tui/shell-runner.ts","../src/tui/shell.ts","../src/tui/mastra-tui.ts"],"sourcesContent":["/**\n * Theme system for the Mastra Code TUI.\n * Simplified from pi-mono's theme system.\n */\n\nimport type { MarkdownTheme, EditorTheme, SettingsListTheme, SelectListTheme } from '@earendil-works/pi-tui';\nimport { mastraBrand } from '@mastra/code-sdk/theme-palette';\nimport chalk from 'chalk';\n\n// =============================================================================\n// Theme Mode\n// =============================================================================\n\nexport type ThemeMode = 'dark' | 'light';\n\nlet currentThemeMode: ThemeMode = 'dark';\n\nexport function getThemeMode(): ThemeMode {\n return currentThemeMode;\n}\n\n// =============================================================================\n// Mastra Brand Palette (immutable — stays constant regardless of theme)\n// =============================================================================\n\nexport { mastraBrand };\n\n// =============================================================================\n// Extended Color Palette (additional colors for future use)\n// =============================================================================\n\nexport const extendedColors = {\n // Teals / Cyans\n teal: '#14b8a6',\n cyan: '#06b6d4',\n lightCyan: '#22d3ee',\n // Blues\n skyBlue: '#38bdf8',\n indigo: '#6366f1',\n // Purples / Violets\n violet: '#a855f7',\n lavender: '#c084fc',\n fuchsia: '#d946ef',\n // Pinks / Roses\n rose: '#f472b6',\n coral: '#fb7185',\n // Warm Tones\n amber: '#fb923c',\n lime: '#a3e635',\n gold: '#facc15',\n // Earthy / Muted\n stone: '#a8a29e',\n warmGray: '#78716c',\n copper: '#b45309',\n} as const;\n\nexport const greens = {\n // Bright / Vivid\n emerald: '#4ade80',\n seafoam: '#34d399',\n jade: '#10b981',\n springGreen: '#00ff7f',\n neonGreen: '#50fa7b',\n // Warm Greens\n chartreuse: '#84cc16',\n lightLime: '#bef264',\n electricLime: '#caff33',\n // Cool / Deep\n aquamarine: '#2dd4bf',\n mint: '#5eead4',\n pastelMint: '#6ee7b7',\n // Forest / Muted\n forest: '#16a34a',\n deepForest: '#15803d',\n sage: '#059669',\n pine: '#047857',\n evergreen: '#065f46',\n // Neon / Electric\n neonLime: '#39ff14',\n pureGreen: '#00ff00',\n hacker: '#00ff41',\n lawnGreen: '#66ff00',\n} as const;\n\n// =============================================================================\n// Mastra Surface Palette (theme-dependent)\n// =============================================================================\n\ninterface MastraSurface {\n bg: string;\n antiGrid: string;\n elevationSm: string;\n elevationLg: string;\n hover: string;\n white: string;\n specialGray: string;\n mainGray: string;\n darkGray: string;\n borderAntiGrid: string;\n borderElevation: string;\n}\n\nconst darkSurface: MastraSurface = {\n bg: '#020202',\n antiGrid: '#0d0d0d',\n elevationSm: '#1a1a1a',\n elevationLg: '#141414',\n hover: '#262626',\n white: '#f0f0f0',\n specialGray: '#cccccc',\n mainGray: '#939393',\n darkGray: '#848484',\n borderAntiGrid: '#141414',\n borderElevation: '#1a1a1a',\n};\n\nconst lightSurface: MastraSurface = {\n bg: '#ffffff',\n antiGrid: '#eaeaea',\n elevationSm: '#ebebeb',\n elevationLg: '#f0f0f0',\n hover: '#e0e0e0',\n white: '#1a1a1a',\n specialGray: '#444444',\n mainGray: '#636363',\n darkGray: '#666666',\n borderAntiGrid: '#e5e5e5',\n borderElevation: '#e0e0e0',\n};\n\ntype MastraPalette = typeof mastraBrand & MastraSurface;\n\nfunction getSurface(): MastraSurface {\n return currentThemeMode === 'dark' ? darkSurface : lightSurface;\n}\n\n// The actual terminal background color detected via OSC 11.\n// Falls back to the surface palette bg if not detected.\nlet detectedTerminalBg: string | undefined;\n\n/** The effective background color used for contrast calculations. */\nfunction getContrastBg(): string {\n return detectedTerminalBg ?? getSurface().bg;\n}\n\n// Theme-adapted brand colors — precomputed for contrast against the actual terminal bg.\nlet adaptedBrand: Record<string, string> = {};\n\n// Theme-adapted surface colors — precomputed for contrast against the actual terminal bg.\nlet adaptedSurface: Partial<Record<string, string>> = {};\n\n// Surface keys that represent text colors (not backgrounds/borders)\nconst textSurfaceKeys: (keyof MastraSurface)[] = ['white', 'specialGray', 'mainGray', 'darkGray'];\n\n// Theme keys that are used as foreground text colors (not backgrounds/borders)\nconst textThemeKeys: (keyof ThemeColors)[] = [\n 'accent',\n 'success',\n 'error',\n 'warning',\n 'muted',\n 'dim',\n 'text',\n 'thinkingText',\n 'userMessageText',\n 'toolTitle',\n 'toolOutput',\n 'textHighlight',\n 'path',\n 'number',\n 'function',\n];\n\n// Comfortable minimum contrast for TUI body text — above WCAG AA (4.5:1) for better readability\nexport const TUI_MIN_CONTRAST = 5.5;\n\n/** Terminal width buffer applied at the framework level to prevent wrapping in nested terminals */\nexport const TERM_WIDTH_BUFFER = 3;\n/** Get the effective terminal width (matching the framework's reduced width) */\nexport const getTermWidth = () => (process.stdout.columns || 80) - TERM_WIDTH_BUFFER;\n\n/** Left indent (in spaces) applied to assistant text (Markdown body) */\nexport const CHAT_INDENT = 2;\n/** Precomputed indent string for assistant text */\nexport const CHAT_INDENT_STR = ' '.repeat(2);\n/** Left indent (in spaces) applied to user messages and tool call boxes */\nexport const BOX_INDENT = 0;\n/** Precomputed indent string for boxes */\nexport const BOX_INDENT_STR = '';\n\n// Brand accent colors (purple, blue, etc.) use standard WCAG AA to preserve vibrancy\nconst BRAND_MIN_CONTRAST = 4.5;\n\nfunction computeAdaptedColors(): void {\n const bg = getContrastBg();\n\n adaptedBrand = {};\n for (const [key, value] of Object.entries(mastraBrand)) {\n adaptedBrand[key] = ensureContrast(value, bg, BRAND_MIN_CONTRAST);\n }\n adaptedSurface = {};\n const surface = getSurface();\n for (const key of textSurfaceKeys) {\n adaptedSurface[key] = ensureContrast(surface[key], bg, TUI_MIN_CONTRAST);\n }\n\n // Adapt theme foreground colors against actual terminal bg\n const baseTheme = currentThemeMode === 'light' ? lightTheme : darkTheme;\n const adapted = { ...baseTheme };\n for (const key of textThemeKeys) {\n adapted[key] = ensureContrast(baseTheme[key], bg, TUI_MIN_CONTRAST);\n }\n currentTheme = adapted;\n}\n\n// Note: computeAdaptedColors() is called after darkTheme/lightTheme are defined (see below)\n\n/** Mastra palette — brand + text surface colors are contrast-adapted, other surface colors adapt to theme mode. */\nexport const mastra: MastraPalette = new Proxy({} as MastraPalette, {\n get(_target, prop: string) {\n if (prop in mastraBrand) {\n return adaptedBrand[prop] ?? mastraBrand[prop as keyof typeof mastraBrand];\n }\n // For text surface colors, return the contrast-adapted version\n if (prop in adaptedSurface) {\n return adaptedSurface[prop];\n }\n const surface = getSurface();\n if (prop in surface) {\n return surface[prop as keyof MastraSurface];\n }\n return undefined;\n },\n});\n\n/** Tint a hex color by a brightness factor (0–1). e.g. tintHex(\"#ff8800\", 0.15) → near-black orange */\nexport function tintHex(hex: string, factor: number): string {\n const r = Math.floor(parseInt(hex.slice(1, 3), 16) * factor);\n const g = Math.floor(parseInt(hex.slice(3, 5), 16) * factor);\n const b = Math.floor(parseInt(hex.slice(5, 7), 16) * factor);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n// =============================================================================\n// Theme Colors\n// =============================================================================\n\nexport type ThemeColor =\n | 'accent'\n | 'border'\n | 'borderAccent'\n | 'borderMuted'\n | 'success'\n | 'error'\n | 'warning'\n | 'muted'\n | 'dim'\n | 'text'\n | 'thinkingText'\n | 'userMessageText'\n | 'toolTitle'\n | 'toolArgs'\n | 'toolOutput'\n | 'textHighlight'\n | 'toolBorderPending'\n | 'toolBorderSuccess'\n | 'toolBorderError'\n | 'function'\n | 'path'\n | 'number';\n\nexport type ThemeBg =\n | 'selectedBg'\n | 'userMessageBg'\n | 'systemReminderBg'\n | 'toolPendingBg'\n | 'toolSuccessBg'\n | 'toolErrorBg'\n | 'overlayBg'\n | 'errorBg';\n\nexport interface ThemeColors {\n // Core UI\n accent: string;\n border: string;\n borderAccent: string;\n borderMuted: string;\n success: string;\n error: string;\n warning: string;\n muted: string;\n dim: string;\n text: string;\n thinkingText: string;\n // User messages\n userMessageBg: string;\n userMessageText: string;\n // System reminders\n systemReminderBg: string;\n // Tool execution\n toolPendingBg: string;\n toolSuccessBg: string;\n toolErrorBg: string;\n toolBorderPending: string;\n toolBorderSuccess: string;\n toolBorderError: string;\n toolTitle: string;\n toolArgs: string;\n toolOutput: string;\n textHighlight: string;\n // Selection\n selectedBg: string;\n // Overlays\n overlayBg: string;\n // Error display\n errorBg: string;\n path: string;\n number: string;\n function: string;\n}\n\n// =============================================================================\n// Dark Theme\n// =============================================================================\n\nexport const darkTheme: ThemeColors = {\n // Core UI\n accent: '#16c858', // Brand green\n border: '#3f3f46',\n borderAccent: '#16c858',\n borderMuted: '#27272a',\n success: '#22c55e',\n error: '#ef4444',\n warning: '#f59e0b',\n muted: '#8c8c94',\n dim: '#84848c',\n text: '#fafafa',\n thinkingText: '#a1a1aa',\n // User messages\n userMessageBg: '#0f172a', // Slate blue\n userMessageText: '#fafafa',\n // System reminders\n systemReminderBg: '#1a1400', // Dark orange tint\n // Tool execution\n toolPendingBg: darkSurface.antiGrid,\n toolSuccessBg: darkSurface.antiGrid,\n toolErrorBg: '#1f0a0a', // Dark red tint\n toolBorderPending: '#52525b', // Zinc-600 dim grey for pending\n toolBorderSuccess: '#52525b', // Zinc-600 dim grey for success\n toolBorderError: '#ef4444', // Red for error\n toolTitle: '#fb923c', // Amber for tool names\n toolArgs: '#ffe4c4', // Bisque (warm cream) for tool arguments\n toolOutput: '#d4d4d8',\n textHighlight: '#c084fc', // Lavender for inline code, headings, links\n // Error display\n errorBg: '#291415', // Slightly lighter than toolErrorBg for contrast\n path: '#9ca3af', // Gray for file paths\n number: '#fbbf24', // Yellow for line numbers\n function: '#60a5fa', // Light blue for function names\n // Selection\n selectedBg: darkSurface.hover,\n // Overlays\n overlayBg: darkSurface.antiGrid,\n};\n\n// =============================================================================\n// Light Theme\n// =============================================================================\n\nexport const lightTheme: ThemeColors = {\n // Core UI\n accent: '#0d8020', // Brand green (light mode)\n border: '#d4d4d8',\n borderAccent: '#0d8020',\n borderMuted: '#e4e4e7',\n success: '#15803d',\n error: '#dc2626',\n warning: '#d97706',\n muted: '#595961',\n dim: '#67676f',\n text: '#18181b',\n thinkingText: '#595961',\n // User messages\n userMessageBg: '#f0fdf4', // Light green tint\n userMessageText: '#18181b',\n // System reminders\n systemReminderBg: '#fefce8', // Light yellow\n // Tool execution\n toolPendingBg: lightSurface.antiGrid,\n toolSuccessBg: lightSurface.antiGrid,\n toolErrorBg: '#fef2f2', // Light red\n toolBorderPending: '#a1a1aa', // Zinc-400 dim grey for pending\n toolBorderSuccess: '#a1a1aa', // Zinc-400 dim grey for success\n toolBorderError: '#dc2626', // Red for error\n toolTitle: '#c2410c', // Deep amber for light backgrounds\n toolArgs: '#92400e', // Deep amber-brown for light backgrounds\n toolOutput: '#3f3f46',\n textHighlight: '#7c3aed', // Deep violet for light backgrounds\n // Error display\n errorBg: '#fef2f2', // Light red\n path: '#6b7280', // Gray for file paths\n number: '#b45309', // Amber for line numbers\n function: '#2563eb', // Blue for function names\n // Selection\n selectedBg: lightSurface.hover,\n // Overlays\n overlayBg: lightSurface.antiGrid,\n};\n\n// =============================================================================\n// Theme Instance\n// =============================================================================\n\nlet currentTheme: ThemeColors = darkTheme;\n\n// Initialize adapted colors now that darkTheme/lightTheme are defined\ncomputeAdaptedColors();\n\n/**\n * Get the current theme colors.\n */\nfunction getTheme(): ThemeColors {\n return currentTheme;\n}\n\n/**\n * Set the current theme.\n */\nfunction setTheme(colors: ThemeColors): void {\n currentTheme = colors;\n}\n\n/**\n * Apply a theme mode, updating both the surface palette and the theme colors.\n */\nexport function applyThemeMode(mode: ThemeMode, terminalBgHex?: string): void {\n currentThemeMode = mode;\n currentTheme = mode === 'light' ? lightTheme : darkTheme;\n detectedTerminalBg = terminalBgHex;\n computeAdaptedColors();\n // Set terminal default foreground via OSC 10 so unstyled text (e.g. editor input)\n // adapts to the theme. Convert hex to rgb/ format for OSC.\n if (process.stdout.isTTY) {\n const textHex = currentTheme.text;\n const r = parseInt(textHex.slice(1, 3), 16);\n const g = parseInt(textHex.slice(3, 5), 16);\n const b = parseInt(textHex.slice(5, 7), 16);\n process.stdout.write(\n `\\x1b]10;rgb:${r.toString(16).padStart(2, '0')}/${g.toString(16).padStart(2, '0')}/${b.toString(16).padStart(2, '0')}\\x07`,\n );\n }\n}\n\n/**\n * Restore terminal foreground to default. Call on exit to undo OSC 10 changes.\n */\nexport function restoreTerminalForeground(): void {\n if (process.stdout.isTTY) {\n // OSC 110 resets the terminal's default foreground to its original value.\n process.stdout.write('\\x1b]110\\x07');\n }\n}\n\n// =============================================================================\n// Theme Helper Functions\n// =============================================================================\n\n/**\n * Apply foreground color from theme.\n */\nfunction fg(color: ThemeColor, text: string): string {\n const hex = currentTheme[color];\n if (!hex) return text;\n return chalk.hex(hex)(text);\n}\n\n/**\n * Apply background color from theme.\n */\nfunction bg(color: ThemeBg, text: string): string {\n const hex = currentTheme[color];\n if (!hex) return text;\n return chalk.bgHex(hex)(text);\n}\n\n/**\n * Apply bold styling.\n */\nfunction bold(text: string): string {\n return chalk.bold(text);\n}\n\n/**\n * Apply italic styling.\n */\nfunction italic(text: string): string {\n return chalk.italic(text);\n}\n\n/**\n * Apply dim styling.\n */\nfunction dim(text: string): string {\n return chalk.dim(text);\n}\n\n// =============================================================================\n// Contrast Utilities (WCAG 2.1)\n// =============================================================================\n\n/** Convert a single sRGB channel (0–1) to linear light. */\nfunction linearize(c: number): number {\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\n/** Parse a hex color string into [r, g, b] in 0–1 range. */\nfunction parseHex(hex: string): [number, number, number] {\n const h = hex.replace('#', '');\n return [parseInt(h.slice(0, 2), 16) / 255, parseInt(h.slice(2, 4), 16) / 255, parseInt(h.slice(4, 6), 16) / 255];\n}\n\n/** Convert [r, g, b] (0–255) to a hex color string. */\nfunction toHex(r: number, g: number, b: number): string {\n const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v)));\n return `#${clamp(r).toString(16).padStart(2, '0')}${clamp(g).toString(16).padStart(2, '0')}${clamp(b).toString(16).padStart(2, '0')}`;\n}\n\n/** WCAG relative luminance of a hex color. Returns 0 (black) to 1 (white). */\nexport function luminance(hex: string): number {\n const [r, g, b] = parseHex(hex);\n return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);\n}\n\n/** WCAG contrast ratio between two hex colors. Returns 1 (identical) to 21 (black/white). */\nexport function contrastRatio(hex1: string, hex2: string): number {\n const l1 = luminance(hex1);\n const l2 = luminance(hex2);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/** Convert RGB (0–1) to HSL. Returns [h (0–360), s (0–1), l (0–1)]. */\nfunction rgbToHsl(r: number, g: number, b: number): [number, number, number] {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n if (max === min) return [0, 0, l];\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h = 0;\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n else if (max === g) h = ((b - r) / d + 2) / 6;\n else h = ((r - g) / d + 4) / 6;\n return [h * 360, s, l];\n}\n\n/** Convert HSL to RGB (0–1). */\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n h = h / 360;\n if (s === 0) return [l, l, l];\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n return [hue2rgb(p, q, h + 1 / 3), hue2rgb(p, q, h), hue2rgb(p, q, h - 1 / 3)];\n}\n\n/**\n * Adjust a foreground color to ensure sufficient contrast against a background.\n * Adjusts lightness in HSL space to preserve hue and saturation.\n * Returns the original color if it already has sufficient contrast.\n */\nexport function ensureContrast(fgHex: string, bgHex: string, minRatio = 4.5): string {\n if (contrastRatio(fgHex, bgHex) >= minRatio) return fgHex;\n\n const [r, g, b] = parseHex(fgHex);\n const [h, s, origL] = rgbToHsl(r, g, b);\n const origCR = contrastRatio(fgHex, bgHex);\n\n function searchDirection(lighten: boolean): { hex: string; contrast: number } {\n const targetL = lighten ? 1 : 0;\n const extreme = lighten ? '#ffffff' : '#000000';\n const extremeCR = contrastRatio(extreme, bgHex);\n if (extremeCR <= origCR) return { hex: fgHex, contrast: origCR };\n\n let lo = 0;\n let hi = 1;\n let best = fgHex;\n let bestCR = origCR;\n\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n const newL = origL + (targetL - origL) * mid;\n const [nr, ng, nb] = hslToRgb(h, s, newL);\n const candidate = toHex(nr * 255, ng * 255, nb * 255);\n const cr = contrastRatio(candidate, bgHex);\n if (cr >= minRatio) {\n best = candidate;\n bestCR = cr;\n hi = mid;\n } else {\n lo = mid;\n }\n }\n\n if (bestCR < minRatio && extremeCR > bestCR) {\n // If the best hue-preserving result is reasonably close to the target,\n // keep it to preserve color identity rather than collapsing to black/white.\n if (bestCR >= minRatio * 0.65) {\n return { hex: best, contrast: bestCR };\n }\n return { hex: extreme, contrast: extremeCR };\n }\n\n return { hex: best, contrast: bestCR };\n }\n\n const whiteContrast = contrastRatio('#ffffff', bgHex);\n const blackContrast = contrastRatio('#000000', bgHex);\n const primaryLighten = whiteContrast >= blackContrast;\n\n const primaryResult = searchDirection(primaryLighten);\n if (primaryResult.contrast >= minRatio) return primaryResult.hex;\n\n const altResult = searchDirection(!primaryLighten);\n if (altResult.contrast >= minRatio) return altResult.hex;\n\n return primaryResult.contrast >= altResult.contrast ? primaryResult.hex : altResult.hex;\n}\n\n/**\n * Returns \"#ffffff\" or \"#000000\" depending on which has better contrast\n * against the given hex background color (WCAG relative luminance).\n */\nexport function getContrastText(hexBg: string): string {\n return luminance(hexBg) > 0.179 ? '#000000' : '#ffffff';\n}\n\nconst NEAR_BLACK_LUMINANCE = luminance('#111111');\nconst NEAR_BLACK_GLYPH_MIN_CONTRAST = 3;\n\n/**\n * Keep deliberately subdued glyph colors on black/nearly-black backgrounds,\n * but contrast-adapt them on brighter terminal backgrounds.\n */\nexport function ensureContrastUnlessNearBlack(fgHex: string, minRatio = TUI_MIN_CONTRAST): string {\n const bgHex = getContrastBg();\n if (luminance(bgHex) <= NEAR_BLACK_LUMINANCE) return fgHex;\n return ensureContrast(fgHex, bgHex, minRatio);\n}\n\n/**\n * Terminal glyphs need a little extra visibility even on black backgrounds.\n * Keep them subdued on near-black terminals, but do not let them get too faint.\n */\nexport function ensureTerminalGlyphContrast(fgHex: string, minRatio = TUI_MIN_CONTRAST): string {\n const bgHex = getContrastBg();\n const targetRatio = luminance(bgHex) <= NEAR_BLACK_LUMINANCE ? NEAR_BLACK_GLYPH_MIN_CONTRAST : minRatio;\n return ensureContrast(fgHex, bgHex, targetRatio);\n}\n\n// =============================================================================\n// Theme Object\n// =============================================================================\n\nexport const theme = {\n fg,\n bg,\n bold,\n italic,\n dim,\n getTheme,\n setTheme,\n};\n\n// =============================================================================\n// Markdown Theme (for pi-tui Markdown component)\n// =============================================================================\n\nexport function getMarkdownTheme(): MarkdownTheme {\n const t = getTheme();\n return {\n heading: (text: string) => chalk.hex(t.textHighlight).bold(text),\n link: (text: string) => chalk.hex(t.textHighlight)(text),\n linkUrl: (text: string) => chalk.hex(t.muted)(text),\n code: (text: string) => chalk.hex(t.textHighlight).bold(text),\n codeBlock: (text: string) => chalk.hex(t.text)(text),\n codeBlockBorder: (text: string) => chalk.hex(t.dim)(text),\n quote: (text: string) => chalk.hex(t.muted).italic(text),\n quoteBorder: (text: string) => chalk.hex(t.borderMuted)(text),\n hr: (text: string) => chalk.hex(t.borderMuted)(text),\n listBullet: (text: string) => chalk.hex(t.textHighlight)(text),\n // Required by MarkdownTheme interface\n bold: (text: string) => chalk.bold(text),\n italic: (text: string) => chalk.italic(text),\n strikethrough: (text: string) => chalk.strikethrough(text),\n underline: (text: string) => chalk.underline(text),\n };\n}\n\n// =============================================================================\n// Editor Theme (for pi-tui Editor component)\n// =============================================================================\n\nexport function getEditorTheme(): EditorTheme {\n const t = getTheme();\n return {\n borderColor: (text: string) => chalk.hex(getContrastBg())(text),\n selectList: {\n selectedPrefix: (text: string) => chalk.hex(t.accent)(text),\n selectedText: (text: string) => chalk.bgHex(t.selectedBg)(text),\n description: (text: string) => chalk.hex(t.muted)(text),\n scrollInfo: (text: string) => chalk.hex(t.dim)(text),\n noMatch: (text: string) => chalk.hex(t.muted)(text),\n },\n };\n}\n\n// =============================================================================\n// Settings List Theme (for pi-tui SettingsList component)\n// =============================================================================\n\nexport function getSettingsListTheme(): SettingsListTheme {\n const t = getTheme();\n return {\n label: (text: string, selected: boolean) => (selected ? chalk.hex(t.text).bold(text) : chalk.hex(t.muted)(text)),\n value: (text: string, selected: boolean) => (selected ? chalk.hex(t.accent)(text) : chalk.hex(t.dim)(text)),\n description: (text: string) => chalk.hex(t.muted).italic(text),\n cursor: chalk.hex(t.accent)('→ '),\n hint: (text: string) => chalk.hex(t.dim)(text),\n };\n}\n\nexport function getSelectListTheme(): SelectListTheme {\n const t = getTheme();\n return {\n selectedPrefix: (text: string) => chalk.hex(t.accent)(text),\n selectedText: (text: string) => chalk.bgHex(t.selectedBg)(text),\n description: (text: string) => chalk.hex(t.muted)(text),\n scrollInfo: (text: string) => chalk.hex(t.dim)(text),\n noMatch: (text: string) => chalk.hex(t.muted)(text),\n };\n}\n","/**\n * Terminal theme detection for Mastra Code TUI.\n *\n * Detection priority:\n * 1. MASTRA_THEME env var (explicit override)\n * 2. OSC 11 query — asks the terminal for its actual background color\n * 3. COLORFGBG env var (set by some terminal emulators)\n * 4. Default: 'dark'\n */\n\nimport { luminance } from './theme.js';\nimport type { ThemeMode } from './theme.js';\n\n/**\n * Query the terminal's background color via OSC 11 and compute luminance.\n * Returns 'dark' or 'light', or null if the terminal doesn't respond.\n *\n * The query sends `\\x1b]11;?\\x07` to stdout. Terminals that support\n * xterm-style OSC queries reply on stdin with something like:\n * \\x1b]11;rgb:0000/0000/0000\\x07 (black background → dark)\n * \\x1b]11;rgb:ffff/ffff/ffff\\x07 (white background → light)\n *\n * We parse the rgb components, compute relative luminance (WCAG),\n * and classify as dark (luma < 0.5) or light (luma >= 0.5).\n */\nfunction queryTerminalBackground(timeoutMs = 200): Promise<ThemeDetectionResult | null> {\n return new Promise(resolve => {\n // Can't query if stdin isn't a TTY\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n resolve(null);\n return;\n }\n\n let settled = false;\n let buffer = '';\n let wasRaw: boolean;\n let wasResumed = false;\n let timer: NodeJS.Timeout | undefined;\n\n const cleanup = () => {\n if (settled) return;\n settled = true;\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n process.stdin.removeListener('data', onData);\n // Restore original raw mode state\n try {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(wasRaw);\n }\n } catch {\n // ignore\n }\n // Only pause stdin if we were the ones who resumed it\n if (wasResumed) {\n process.stdin.pause();\n }\n };\n\n const onData = (data: Buffer) => {\n buffer += data.toString();\n\n // Look for the OSC 11 response: \\x1b]11;rgb:RRRR/GGGG/BBBB\\x07 or \\x1b]11;rgb:RRRR/GGGG/BBBB\\x1b\\\\\n const match = buffer.match(/\\x1b\\]11;rgb:([0-9a-fA-F]+)\\/([0-9a-fA-F]+)\\/([0-9a-fA-F]+)/);\n if (match) {\n cleanup();\n\n // Parse RGB components — terminals may respond with 2 or 4 hex digits per component\n const rHex = match[1]!;\n const gHex = match[2]!;\n const bHex = match[3]!;\n\n // Normalize to 0–1 range. If 4 digits: max is 0xFFFF. If 2 digits: max is 0xFF.\n const normalize = (hex: string) => {\n const val = parseInt(hex, 16);\n return hex.length <= 2 ? val / 0xff : val / 0xffff;\n };\n\n const r = normalize(rHex);\n const g = normalize(gHex);\n const b = normalize(bHex);\n\n // Convert to hex and compute WCAG relative luminance\n const toHexByte = (v: number) =>\n Math.round(v * 255)\n .toString(16)\n .padStart(2, '0');\n const detectedBgHex = `#${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}`;\n const luma = luminance(detectedBgHex);\n\n resolve({ mode: luma >= 0.5 ? 'light' : 'dark', detectedBgHex });\n return;\n }\n };\n\n // Timeout — terminal didn't respond (or doesn't support OSC 11)\n timer = setTimeout(() => {\n cleanup();\n resolve(null);\n }, timeoutMs);\n\n // Ensure the timeout doesn't keep the process alive\n if (timer.unref) timer.unref();\n\n try {\n // Save current state and switch to raw mode for reading the response\n wasRaw = process.stdin.isRaw ?? false;\n process.stdin.setRawMode(true);\n if (process.stdin.isPaused()) {\n process.stdin.resume();\n wasResumed = true;\n }\n process.stdin.on('data', onData);\n\n // Send OSC 11 query — use BEL (\\x07) terminator for broadest compatibility\n process.stdout.write('\\x1b]11;?\\x07');\n } catch {\n // If we can't set raw mode, give up on this method\n cleanup();\n resolve(null);\n }\n });\n}\n\n/**\n * Detect COLORFGBG env var.\n * Format: \"fg;bg\" where bg is an ANSI color index.\n * Color indices 0-6 are dark, 7+ are light.\n */\nfunction detectFromColorFgBg(): ThemeMode | null {\n const colorFgBg = process.env.COLORFGBG;\n if (!colorFgBg) return null;\n\n const parts = colorFgBg.split(';');\n const bgPart = parts[parts.length - 1];\n if (bgPart === undefined) return null;\n\n const bgIndex = parseInt(bgPart, 10);\n if (isNaN(bgIndex)) return null;\n\n // Standard ANSI: 0-6 are dark colors, 7+ are light (7 = white/light gray, 15 = bright white)\n return bgIndex >= 7 ? 'light' : 'dark';\n}\n\n/**\n * Detect the terminal's color scheme.\n * Returns 'dark' or 'light'. Does not check persisted settings —\n * the caller should check settings first and only call this for 'auto' mode.\n */\nexport interface ThemeDetectionResult {\n mode: ThemeMode;\n /** The actual terminal background hex color, if detected via OSC 11. */\n detectedBgHex?: string;\n}\n\nexport async function detectTerminalTheme(): Promise<ThemeDetectionResult> {\n // 1. Explicit env var override\n const envTheme = process.env.MASTRA_THEME?.toLowerCase();\n if (envTheme === 'light') return { mode: 'light' };\n if (envTheme === 'dark') return { mode: 'dark' };\n\n // 2. OSC 11 query — ask the terminal for its actual background color\n const oscResult = await queryTerminalBackground(200);\n if (oscResult) return oscResult;\n\n // 3. COLORFGBG env var fallback\n const fgbgResult = detectFromColorFgBg();\n if (fgbgResult) return { mode: fgbgResult };\n\n // 4. Default to dark\n return { mode: 'dark' };\n}\n","import { Spacer } from '@earendil-works/pi-tui';\n\n/**\n * Static spacer placed above a chat component.\n *\n * Height is set once during reconciliation via `setLines()` and stays\n * fixed until the next reconciliation pass — no per-frame recomputation.\n */\nexport class ChatBoundarySpacer extends Spacer {\n readonly isChatBoundarySpacer = true;\n\n constructor(lines = 1) {\n super(lines);\n }\n}\n\nexport function isChatBoundarySpacer(component: unknown): component is ChatBoundarySpacer {\n return !!component && (component as { isChatBoundarySpacer?: boolean }).isChatBoundarySpacer === true;\n}\n","import type { Component } from '@earendil-works/pi-tui';\n\nexport type ChatSpacingKind =\n | 'quiet-compact-tool'\n | 'quiet-shell-tool'\n | 'normal-tool'\n | 'assistant-message'\n | 'user-message'\n | 'plan'\n | 'task'\n | 'system'\n | 'other';\n\nexport interface ChatSpacingParticipant {\n getChatSpacingKind(): ChatSpacingKind | undefined;\n}\n\ninterface CompactToolSpacingParticipant {\n getCompactToolGroupKey?(): string | undefined;\n hasQuietStreamingPreview?(): boolean;\n}\n\nexport function getChatSpacingKind(component: Component | undefined): ChatSpacingKind | undefined {\n const participant = component as Partial<ChatSpacingParticipant> | undefined;\n return participant?.getChatSpacingKind?.();\n}\n\nexport function getSpacingBetweenComponents(\n prev: Component | undefined,\n next: Component | undefined,\n _prevPrev?: Component | undefined,\n _nextNext?: Component | undefined,\n): number {\n const prevKind = getChatSpacingKind(prev);\n const nextKind = getChatSpacingKind(next);\n\n if (prevKind === 'quiet-compact-tool' && nextKind === 'quiet-compact-tool') {\n const prevKey = getCompactToolGroupKey(prev);\n const nextKey = getCompactToolGroupKey(next);\n if (prevKey && nextKey && prevKey === nextKey) return 0;\n return 1;\n }\n if (hasQuietStreamingPreview(prev) || hasQuietStreamingPreview(next)) return 1;\n return getSpacingBetween(prevKind, nextKind);\n}\n\nfunction getCompactToolGroupKey(component: Component | undefined): string | undefined {\n return (component as CompactToolSpacingParticipant | undefined)?.getCompactToolGroupKey?.();\n}\n\nfunction hasQuietStreamingPreview(component: Component | undefined): boolean {\n return (component as CompactToolSpacingParticipant | undefined)?.hasQuietStreamingPreview?.() ?? false;\n}\n\nexport function getSpacingBetween(prev: ChatSpacingKind | undefined, next: ChatSpacingKind | undefined): number {\n if (!prev || !next) return 0;\n if (prev === 'quiet-compact-tool' && next === 'quiet-compact-tool') return 0;\n if (isToolSpacingKind(prev) && next === 'assistant-message') return 1;\n if (prev === 'assistant-message' && isToolSpacingKind(next)) return 1;\n return 1;\n}\n\nfunction isToolSpacingKind(kind: ChatSpacingKind | undefined): boolean {\n return kind === 'quiet-compact-tool' || kind === 'quiet-shell-tool' || kind === 'normal-tool';\n}\n","import type { Component, Container } from '@earendil-works/pi-tui';\nimport { ChatBoundarySpacer, isChatBoundarySpacer } from './components/chat-boundary-spacer.js';\nimport { getChatSpacingKind, getSpacingBetweenComponents } from './components/chat-spacing.js';\nimport type { CompactToolLabelColor } from './components/tool-execution-interface.js';\n\ninterface CompactToolGroupingParticipant {\n getCompactToolGroupKey?(): string | undefined;\n getCompactToolGroupSummary?(): string | undefined;\n getOwnCompactToolLabelColor?(): CompactToolLabelColor | undefined;\n setCompactToolGroupLabelColor?(color: CompactToolLabelColor | undefined): void;\n setCompactToolContinuation?(continuation: boolean, previousSummary?: string): void;\n setCompactToolHasFollowingContinuation?(hasFollowingContinuation: boolean): void;\n}\n\n/**\n * Insert a chat component into the container and reconcile spacing.\n *\n * The component is spliced at `index` and then a single reconciliation\n * pass places static spacers above each component that needs one.\n */\nexport function insertChatComponentWithBoundarySpacing(\n chatContainer: Container,\n child: Component,\n index = chatContainer.children.length,\n): void {\n const children = chatContainer.children as Component[];\n const boundedIndex = Math.max(0, Math.min(index, children.length));\n children.splice(boundedIndex, 0, child);\n reconcileChatBoundarySpacers(chatContainer);\n}\n\n/**\n * Rebuild the spacing layout for a chat container.\n *\n * Places one static {@link ChatBoundarySpacer} above each component that\n * participates in spacing (has a `getChatSpacingKind`) and has a preceding\n * spacing participant. Spacer heights are computed once via\n * `getSpacingBetweenComponents` — no per-frame recomputation.\n *\n * Existing spacer instances are reused (via `setLines`) to minimise\n * object churn and avoid identity-change flicker.\n */\nexport function reconcileChatBoundarySpacers(chatContainer: Container): void {\n const children = chatContainer.children as Component[];\n const components = children.filter(child => !isChatBoundarySpacer(child));\n\n // Pool existing spacers for reuse so we keep the same object identity\n // where possible, reducing object churn.\n const spacerPool = children.filter(isChatBoundarySpacer);\n let poolIndex = 0;\n\n const nextCompactToolGroupKeys = new Array<string | undefined>(components.length);\n let nextSpacingComponentGroupKey: string | undefined;\n for (let i = components.length - 1; i >= 0; i--) {\n nextCompactToolGroupKeys[i] = nextSpacingComponentGroupKey;\n const component = components[i];\n if (component && getChatSpacingKind(component)) {\n nextSpacingComponentGroupKey = (component as CompactToolGroupingParticipant).getCompactToolGroupKey?.();\n }\n }\n\n const nextChildren: Component[] = [];\n let previousCompactToolGroupKey: string | undefined;\n let previousCompactToolSummary: string | undefined;\n let currentCompactRun: CompactToolGroupingParticipant[] = [];\n let previousSpacingComponent: Component | undefined;\n\n const flushCompactRunColor = () => {\n const color = getCompactRunLabelColor(currentCompactRun);\n for (const participant of currentCompactRun) {\n participant.setCompactToolGroupLabelColor?.(color);\n }\n currentCompactRun = [];\n };\n\n for (let i = 0; i < components.length; i++) {\n const component = components[i]!;\n\n // --- compact-tool grouping (unchanged logic) --------------------------\n const participant = component as CompactToolGroupingParticipant;\n const compactToolGroupKey = participant.getCompactToolGroupKey?.();\n const compactToolGroupSummary = participant.getCompactToolGroupSummary?.();\n const nextCompactToolGroupKey = nextCompactToolGroupKeys[i];\n const isContinuation = !!compactToolGroupKey && compactToolGroupKey === previousCompactToolGroupKey;\n participant.setCompactToolContinuation?.(isContinuation, isContinuation ? previousCompactToolSummary : undefined);\n participant.setCompactToolHasFollowingContinuation?.(\n !!compactToolGroupKey && compactToolGroupKey === nextCompactToolGroupKey,\n );\n if (compactToolGroupKey) {\n if (!isContinuation) flushCompactRunColor();\n currentCompactRun.push(participant);\n } else {\n flushCompactRunColor();\n participant.setCompactToolGroupLabelColor?.(undefined);\n }\n if (getChatSpacingKind(component)) {\n previousCompactToolGroupKey = compactToolGroupKey;\n previousCompactToolSummary = compactToolGroupSummary;\n }\n\n // --- spacer above this component --------------------------------------\n if (getChatSpacingKind(component) && previousSpacingComponent) {\n const spacing = getSpacingBetweenComponents(previousSpacingComponent, component);\n if (spacing > 0) {\n let spacer: ChatBoundarySpacer;\n if (poolIndex < spacerPool.length) {\n spacer = spacerPool[poolIndex]!;\n spacer.setLines(spacing);\n poolIndex++;\n } else {\n spacer = new ChatBoundarySpacer(spacing);\n }\n nextChildren.push(spacer);\n }\n }\n\n if (getChatSpacingKind(component)) {\n previousSpacingComponent = component;\n }\n\n nextChildren.push(component);\n }\n\n flushCompactRunColor();\n chatContainer.children = nextChildren as never[];\n chatContainer.invalidate();\n}\n\nfunction getCompactRunLabelColor(participants: CompactToolGroupingParticipant[]): CompactToolLabelColor | undefined {\n if (participants.length <= 1) return undefined;\n if (participants.some(participant => participant.getOwnCompactToolLabelColor?.() === 'error')) return 'error';\n return 'toolTitle';\n}\n","/**\n * Goal max-cycles input dialog.\n * Shows a preconfigured input with the current default value that the user can edit.\n */\n\nimport { Box, getKeybindings, Input, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable } from '@earendil-works/pi-tui';\n\nimport { theme } from '../theme.js';\n\nexport interface GoalCyclesDialogOptions {\n defaultValue: number;\n onSubmit: (maxCycles: number) => void;\n onCancel: () => void;\n}\n\nexport class GoalCyclesDialogComponent extends Box implements Focusable {\n private input: Input;\n private onSubmit: (maxCycles: number) => void;\n private onCancel: () => void;\n\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n this.input.focused = value;\n }\n\n constructor(options: GoalCyclesDialogOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.onSubmit = options.onSubmit;\n this.onCancel = options.onCancel;\n\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Max Attempts')), 0, 0));\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('text', 'How many attempts before pausing the goal?'), 0, 0));\n this.addChild(new Spacer(1));\n\n this.input = new Input();\n this.input.setValue(String(options.defaultValue));\n this.input.onSubmit = (value: string) => {\n const parsed = parseInt(value.trim(), 10);\n if (isNaN(parsed) || parsed < 1) {\n this.onSubmit(options.defaultValue);\n } else {\n this.onSubmit(parsed);\n }\n };\n this.addChild(this.input);\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('dim', ' Enter to confirm · Esc to cancel'), 0, 0));\n }\n\n handleInput(data: string): void {\n const kb = getKeybindings();\n if (kb.matches(data, 'tui.select.cancel')) {\n this.onCancel();\n return;\n }\n this.input.handleInput(data);\n }\n}\n","/**\n * Model selector component for switching between available models.\n * Uses pi-tui overlay pattern with search and fuzzy filtering.\n */\n\nimport { Box, Container, fuzzyFilter, getKeybindings, Input, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, TUI } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { theme } from '../theme.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ModelItem {\n /** Full model ID (e.g., \"anthropic/claude-sonnet-4\") */\n id: string;\n /** Provider name (e.g., \"anthropic\") */\n provider: string;\n /** Model name without provider (e.g., \"claude-sonnet-4\") */\n modelName: string;\n /** Whether the API key for this provider is available */\n hasApiKey: boolean;\n /** Environment variable name for the API key (e.g., \"ANTHROPIC_API_KEY\") */\n apiKeyEnvVar?: string;\n /** Number of times this model has been selected (for ranking) */\n useCount?: number;\n}\n\nexport interface ModelSelectorOptions {\n /** TUI instance for rendering */\n tui: TUI;\n /** List of available models */\n models: ModelItem[];\n /** Currently selected model ID */\n currentModelId?: string;\n /** Optional title for the selector */\n title?: string;\n /** Optional hex color for the title background (e.g. mode color) */\n titleColor?: string;\n /** Callback when a model is selected */\n onSelect: (model: ModelItem) => void;\n /** Callback when selection is cancelled */\n onCancel: () => void;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\n/**\n * Build a synthetic \"Use: <id>\" ModelItem for an arbitrary model id typed by\n * the user. The provider prefix is parsed from the id; key metadata is\n * derived from any sibling model that already lives under the same provider\n * so the API-key prompt still fires for known providers without a key.\n *\n * If no sibling is found (truly novel provider), we default `hasApiKey: false`\n * so the user is still prompted for a key by provider name.\n */\nexport function makeCustomModelItem(id: string, models: ModelItem[]): ModelItem {\n const parts = id.split('/');\n const provider = parts.length > 1 ? parts[0]! : 'custom';\n const modelName = parts.length > 1 ? parts.slice(1).join('/') : id;\n const sibling = models.find(m => m.provider === provider);\n return {\n id,\n provider,\n modelName,\n hasApiKey: sibling?.hasApiKey ?? false,\n apiKeyEnvVar: sibling?.apiKeyEnvVar,\n };\n}\n\n// =============================================================================\n// ModelSelectorComponent\n// =============================================================================\n\nexport class ModelSelectorComponent extends Box implements Focusable {\n private searchInput!: Input;\n private listContainer!: Container;\n private allModels: ModelItem[];\n private filteredModels: ModelItem[];\n private selectedIndex = 0;\n private currentModelId?: string;\n private onSelectCallback: (model: ModelItem) => void;\n private onCancelCallback: () => void;\n private tui: TUI;\n private title: string;\n private titleColor?: string;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n this.searchInput.focused = value;\n }\n\n constructor(options: ModelSelectorOptions) {\n // Box with padding and background\n super(4, 2, text => theme.bg('overlayBg', text));\n\n this.tui = options.tui;\n this.title = options.title ?? 'Select Model';\n this.titleColor = options.titleColor;\n this.allModels = this.sortModels(options.models, options.currentModelId);\n this.currentModelId = options.currentModelId;\n this.onSelectCallback = options.onSelect;\n this.onCancelCallback = options.onCancel;\n this.filteredModels = this.allModels;\n\n // Build UI\n this.buildUI();\n }\n\n private buildUI(): void {\n // Title — optionally with a mode-colored background\n const titleText = this.titleColor\n ? chalk.bgHex(this.titleColor).white.bold(` ${this.title} `)\n : theme.bold(theme.fg('accent', this.title));\n this.addChild(new Text(titleText, 0, 0));\n this.addChild(new Spacer(1));\n\n // Hint\n this.addChild(new Text(theme.fg('muted', 'Type to search • ↑↓ navigate • Enter select • Esc cancel'), 0, 0));\n this.addChild(new Spacer(1));\n\n // Search input (Input has built-in \"> \" prompt)\n this.searchInput = new Input();\n this.searchInput.onSubmit = () => {\n if (this.hasCustomItem && this.selectedIndex === 0) {\n const query = this.searchInput.getValue().trim();\n if (query) this.handleSelect(this.makeCustomModelItem(query));\n } else {\n const modelIndex = this.hasCustomItem ? this.selectedIndex - 1 : this.selectedIndex;\n const selected = this.filteredModels[modelIndex];\n if (selected) this.handleSelect(selected);\n }\n };\n this.addChild(this.searchInput);\n this.addChild(new Spacer(1));\n\n // List container\n this.listContainer = new Container();\n this.addChild(this.listContainer);\n\n // Initial render\n this.updateList();\n }\n\n private sortModels(models: ModelItem[], currentModelId?: string): ModelItem[] {\n const sorted = [...models];\n\n // Sort: current first, then API key available, then by use count (desc), then alphabetical\n sorted.sort((a, b) => {\n // Current model always first\n const aIsCurrent = a.id === currentModelId;\n const bIsCurrent = b.id === currentModelId;\n if (aIsCurrent && !bIsCurrent) return -1;\n if (!aIsCurrent && bIsCurrent) return 1;\n\n // Models with API keys come before those without\n if (a.hasApiKey && !b.hasApiKey) return -1;\n if (!a.hasApiKey && b.hasApiKey) return 1;\n\n // Then by use count (higher = first)\n const aCount = a.useCount ?? 0;\n const bCount = b.useCount ?? 0;\n if (aCount !== bCount) return bCount - aCount;\n\n // Then by provider\n const providerCompare = a.provider.localeCompare(b.provider);\n if (providerCompare !== 0) return providerCompare;\n\n // Then by model name\n return a.modelName.localeCompare(b.modelName);\n });\n\n return sorted;\n }\n\n /** Whether the custom \"Use: ...\" item is showing at the top */\n private hasCustomItem = false;\n\n private filterModels(query: string): void {\n // Apply fuzzy filter if there's a query, otherwise show all\n // Sorting already puts models with API keys first\n this.filteredModels = query\n ? fuzzyFilter(this.allModels, query, m => `${m.id} ${m.provider} ${m.modelName}`)\n : this.allModels;\n\n // Show \"Use: query\" custom item when query looks like a model ID\n // and doesn't exactly match the top result\n const trimmed = query.trim();\n this.hasCustomItem = trimmed.length > 0 && this.filteredModels[0]?.id !== trimmed;\n\n const totalItems = this.filteredModels.length + (this.hasCustomItem ? 1 : 0);\n this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, totalItems - 1));\n this.updateList();\n }\n\n private makeCustomModelItem(id: string): ModelItem {\n return makeCustomModelItem(id, this.allModels);\n }\n\n private updateList(): void {\n this.listContainer.clear();\n\n const totalItems = this.filteredModels.length + (this.hasCustomItem ? 1 : 0);\n const maxVisible = 12;\n const startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(maxVisible / 2), totalItems - maxVisible));\n const endIndex = Math.min(startIndex + maxVisible, totalItems);\n\n for (let i = startIndex; i < endIndex; i++) {\n // First item is the custom \"Use: ...\" entry when active\n if (this.hasCustomItem && i === 0) {\n const query = this.searchInput.getValue().trim();\n const isSelected = this.selectedIndex === 0;\n const line = isSelected\n ? theme.fg('accent', '→ ') + theme.bold(theme.fg('accent', `Use: ${query}`))\n : ' ' + theme.fg('muted', `Use: ${query}`);\n this.listContainer.addChild(new Text(line, 0, 0));\n continue;\n }\n\n // Offset into filteredModels (subtract 1 when custom item is present)\n const modelIndex = this.hasCustomItem ? i - 1 : i;\n const item = this.filteredModels[modelIndex];\n if (!item) continue;\n\n const isSelected = i === this.selectedIndex;\n const isCurrent = item.id === this.currentModelId;\n const checkmark = isCurrent ? theme.fg('success', ' ✓') : '';\n const noKeyIndicator = !item.hasApiKey\n ? theme.fg('error', ' ✗') + theme.fg('muted', item.apiKeyEnvVar ? ` (${item.apiKeyEnvVar})` : ' (no key)')\n : '';\n\n let line = '';\n if (isSelected) {\n line = theme.fg('accent', '→ ' + item.id) + checkmark + noKeyIndicator;\n } else {\n const modelText = item.hasApiKey ? item.id : theme.fg('muted', item.id);\n line = ' ' + modelText + checkmark + noKeyIndicator;\n }\n\n this.listContainer.addChild(new Text(line, 0, 0));\n }\n\n // Scroll indicator\n if (startIndex > 0 || endIndex < totalItems) {\n const scrollInfo = theme.fg('muted', `(${this.selectedIndex + 1}/${totalItems})`);\n this.listContainer.addChild(new Text(scrollInfo, 0, 0));\n }\n\n // Empty state\n if (totalItems === 0) {\n this.listContainer.addChild(new Text(theme.fg('muted', 'No matching models'), 0, 0));\n }\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n const totalItems = this.filteredModels.length + (this.hasCustomItem ? 1 : 0);\n\n // Up arrow\n if (kb.matches(keyData, 'tui.select.up')) {\n if (totalItems === 0) return;\n this.selectedIndex = this.selectedIndex === 0 ? totalItems - 1 : this.selectedIndex - 1;\n this.updateList();\n this.tui.requestRender();\n }\n // Down arrow\n else if (kb.matches(keyData, 'tui.select.down')) {\n if (totalItems === 0) return;\n this.selectedIndex = this.selectedIndex === totalItems - 1 ? 0 : this.selectedIndex + 1;\n this.updateList();\n this.tui.requestRender();\n }\n // Enter\n else if (kb.matches(keyData, 'tui.select.confirm')) {\n if (this.hasCustomItem && this.selectedIndex === 0) {\n const query = this.searchInput.getValue().trim();\n if (query) this.handleSelect(this.makeCustomModelItem(query));\n } else {\n const modelIndex = this.hasCustomItem ? this.selectedIndex - 1 : this.selectedIndex;\n const selected = this.filteredModels[modelIndex];\n if (selected) this.handleSelect(selected);\n }\n }\n // Escape or Ctrl+C\n else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancelCallback();\n }\n // Pass everything else to search input\n else {\n this.searchInput.handleInput(keyData);\n this.filterModels(this.searchInput.getValue());\n this.tui.requestRender();\n }\n }\n\n private handleSelect(model: ModelItem): void {\n this.onSelectCallback(model);\n }\n\n getSearchInput(): Input {\n return this.searchInput;\n }\n}\n","import type { Component, OverlayHandle, OverlayOptions, SizeValue, TUI } from '@earendil-works/pi-tui';\nimport { visibleWidth } from '@earendil-works/pi-tui';\n\nimport { theme } from './theme.js';\n\ntype ModalOverlayOptions = {\n widthPercent?: number;\n maxWidth?: number;\n maxHeight?: OverlayOptions['maxHeight'];\n minHeightPercent?: number;\n maxTopPadding?: number;\n};\n\nfunction parseSizeValue(value: SizeValue | undefined, total: number): number | undefined {\n if (typeof value === 'number') return value;\n const match = value?.match(/^(\\d+(?:\\.\\d+)?)%$/);\n return match?.[1] ? Math.floor((parseFloat(match[1]) / 100) * total) : undefined;\n}\n\nfunction modalMinHeight(tui: TUI, options: ModalOverlayOptions): number {\n const termHeight = tui.terminal?.rows ?? 40;\n const minHeight = Math.floor(termHeight * (options.minHeightPercent ?? 0.7));\n const maxHeight = parseSizeValue(options.maxHeight ?? '80%', termHeight) ?? termHeight;\n\n return Math.max(1, Math.min(minHeight, maxHeight));\n}\n\nclass MinHeightOverlay implements Component {\n constructor(\n private component: Component,\n private tui: TUI,\n private options: ModalOverlayOptions,\n ) {}\n\n get focused(): boolean {\n return (this.component as Component & { focused?: boolean }).focused ?? false;\n }\n\n set focused(value: boolean) {\n if ('focused' in this.component) {\n (this.component as Component & { focused: boolean }).focused = value;\n }\n }\n\n get wantsKeyRelease(): boolean | undefined {\n return this.component.wantsKeyRelease;\n }\n\n handleInput(data: string): void {\n this.component.handleInput?.(data);\n }\n\n invalidate(): void {\n this.component.invalidate?.();\n }\n\n render(width: number): string[] {\n const lines = this.component.render(width);\n const minHeight = modalMinHeight(this.tui, this.options);\n if (lines.length >= minHeight) return lines;\n\n const blank = theme.bg('overlayBg', ' '.repeat(width));\n const missingLines = minHeight - lines.length;\n const topPadding = Math.min(Math.floor(missingLines / 2), this.options.maxTopPadding ?? 4);\n const padded = [\n ...Array.from({ length: topPadding }, () => blank),\n ...lines,\n ...Array.from({ length: missingLines - topPadding }, () => blank),\n ];\n\n return padded.map(line => {\n const padNeeded = Math.max(0, width - visibleWidth(line));\n return padNeeded > 0 ? `${line}${theme.bg('overlayBg', ' '.repeat(padNeeded))}` : line;\n });\n }\n}\n\nexport function modalOverlayOptions(tui: TUI, options: ModalOverlayOptions = {}): OverlayOptions {\n const widthPercent = options.widthPercent ?? 0.9;\n const maxWidth = options.maxWidth ?? 160;\n const termWidth = tui.terminal?.columns ?? 120;\n\n const width = Math.max(1, Math.min(Math.floor(termWidth * widthPercent), maxWidth));\n\n return {\n width,\n minWidth: Math.min(width, 90),\n maxHeight: options.maxHeight ?? '80%',\n };\n}\n\nexport function showModalOverlay(tui: TUI, component: Component, options: ModalOverlayOptions = {}): OverlayHandle {\n return tui.showOverlay(new MinHeightOverlay(component, tui, options), modalOverlayOptions(tui, options));\n}\n","/**\n * MaskedInput - wraps pi-tui's Input to obscure displayed text with asterisks.\n * The actual value is preserved; only the rendered output is masked.\n */\n\nimport { Input } from '@earendil-works/pi-tui';\nimport type { Component, Focusable } from '@earendil-works/pi-tui';\n\nexport class MaskedInput implements Component, Focusable {\n private input: Input;\n\n get focused(): boolean {\n return this.input.focused;\n }\n set focused(value: boolean) {\n this.input.focused = value;\n }\n\n set onSubmit(fn: ((value: string) => void) | undefined) {\n this.input.onSubmit = fn;\n }\n\n set onEscape(fn: (() => void) | undefined) {\n this.input.onEscape = fn;\n }\n\n constructor() {\n this.input = new Input();\n }\n\n getValue(): string {\n return this.input.getValue();\n }\n\n setValue(value: string): void {\n this.input.setValue(value);\n }\n\n handleInput(data: string): void {\n this.input.handleInput(data);\n }\n\n invalidate(): void {\n this.input.invalidate();\n }\n\n render(width: number): string[] {\n // Temporarily swap the value to masked characters, render, then restore.\n const real = this.input.getValue();\n try {\n this.input.setValue('*'.repeat(real.length));\n return this.input.render(width);\n } finally {\n this.input.setValue(real);\n }\n }\n}\n","/**\n * API key input dialog component.\n * Shown when a user selects a model that doesn't have an API key configured.\n * Allows entering a key or cancelling to proceed without one.\n */\n\nimport { Box, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable } from '@earendil-works/pi-tui';\nimport { theme } from '../theme.js';\nimport { MaskedInput } from './masked-input.js';\n\nexport interface ApiKeyDialogOptions {\n /** Provider name shown in the title (e.g., \"Google\") */\n providerName: string;\n /** Environment variable name hint (e.g., \"GOOGLE_GENERATIVE_AI_API_KEY\") */\n apiKeyEnvVar?: string;\n /** Called with the entered key when the user submits */\n onSubmit: (key: string) => void;\n /** Called when the user cancels */\n onCancel: () => void;\n}\n\nexport class ApiKeyDialogComponent extends Box implements Focusable {\n private input: MaskedInput;\n private onSubmit: (key: string) => void;\n private onCancel: () => void;\n\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n this.input.focused = value;\n }\n\n constructor(options: ApiKeyDialogOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.onSubmit = options.onSubmit;\n this.onCancel = options.onCancel;\n\n // Title\n this.addChild(new Text(theme.bold(theme.fg('accent', `API Key Required`)), 0, 0));\n this.addChild(new Spacer(1));\n\n // Description\n this.addChild(new Text(theme.fg('text', `Enter an API key for ${options.providerName}:`), 0, 0));\n if (options.apiKeyEnvVar) {\n this.addChild(new Text(theme.fg('dim', `You can also set ${options.apiKeyEnvVar} in your environment.`), 0, 0));\n }\n this.addChild(new Spacer(1));\n\n // Input\n this.input = new MaskedInput();\n this.input.onSubmit = (value: string) => {\n const trimmed = value.trim();\n if (trimmed) {\n this.onSubmit(trimmed);\n } else {\n this.onCancel();\n }\n };\n this.addChild(this.input);\n this.addChild(new Spacer(1));\n\n // Hints\n this.addChild(new Text(theme.fg('dim', ' Enter to submit · Esc to cancel'), 0, 0));\n }\n\n handleInput(data: string): void {\n const kb = getKeybindings();\n if (kb.matches(data, 'tui.select.cancel')) {\n this.onCancel();\n return;\n }\n this.input.handleInput(data);\n }\n}\n","/**\n * Shared helper: prompt user for an API key when they select a model without one.\n */\n\nimport type { TUI } from '@earendil-works/pi-tui';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { ApiKeyDialogComponent } from './components/api-key-dialog.js';\nimport type { ModelItem } from './components/model-selector.js';\nimport { showModalOverlay } from './overlay.js';\n\n/**\n * If the selected model doesn't have an API key, show a dialog to enter one.\n * Returns the model ID on success or when cancelled (same behavior — cancelling\n * just means no key was stored, but the model is still selected).\n *\n * Resolves after the user submits or cancels the dialog.\n */\nexport function promptForApiKeyIfNeeded(\n ui: TUI,\n model: ModelItem,\n authStorage: AuthStorage | undefined,\n): Promise<void> {\n // Model already has a key (env var or stored) — nothing to do\n if (model.hasApiKey || !authStorage) {\n return Promise.resolve();\n }\n\n return new Promise<void>(resolve => {\n const dialog = new ApiKeyDialogComponent({\n providerName: model.provider,\n apiKeyEnvVar: model.apiKeyEnvVar,\n onSubmit: (key: string) => {\n ui.hideOverlay();\n // Store the key and set env var so model resolution picks it up\n authStorage.setStoredApiKey(model.provider, key, model.apiKeyEnvVar);\n resolve();\n },\n onCancel: () => {\n ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(ui, dialog, { widthPercent: 0.7, maxHeight: '50%' });\n dialog.focused = true;\n });\n}\n","/**\n * /goal command — persistent cross-turn goals (Ralph loop).\n *\n * Usage:\n * /goal <text> Set a standing goal (asks for judge defaults only if unset)\n * /goal Open goal actions\n * /goal status Show current goal status\n * /goal pause Pause the continuation loop\n * /goal resume Resume without resetting the turn counter\n * /goal clear Drop the goal\n * /goal judge Set the goal judge model and max-attempt defaults\n */\nimport { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SelectItem } from '@earendil-works/pi-tui';\nimport { createGoalReminderSignal } from '@mastra/code-sdk/goal-signal';\nimport { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport type { MastraDBMessage } from '@mastra/core/agent-controller';\nimport { createSignal } from '@mastra/core/signals';\nimport { GoalCyclesDialogComponent } from '../components/goal-cycles-dialog.js';\nimport { ModelSelectorComponent } from '../components/model-selector.js';\nimport type { ModelItem } from '../components/model-selector.js';\nimport { DEFAULT_MAX_TURNS } from '../goal-manager.js';\nimport type { GoalState } from '../goal-manager.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { promptForApiKeyIfNeeded } from '../prompt-api-key.js';\nimport { getSelectListTheme, theme } from '../theme.js';\n\nimport type { SlashCommandContext } from './types.js';\n\nexport interface StartGoalOptions {\n trigger?: 'send' | 'none';\n}\n\nexport async function handleGoalCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const { state } = ctx;\n const goalManager = state.goalManager;\n const subCommand = args[0]?.toLowerCase();\n\n if (!subCommand) {\n await showGoalActionModal(ctx);\n return;\n }\n\n // /goal status — show current state\n if (subCommand === 'status') {\n showGoalStatus(ctx);\n return;\n }\n\n // /goal pause\n if (subCommand === 'pause') {\n const goal = goalManager.pause();\n if (!goal) {\n ctx.showInfo('No goal to pause.');\n return;\n }\n await goalManager.saveToThread(state);\n ctx.updateStatusLine();\n ctx.showInfo(\n `Goal paused: \"${goal.objective}\" (${goal.turnsUsed}/${goal.maxTurns} turns used). Use /goal resume to continue.`,\n );\n return;\n }\n\n // /goal resume\n if (subCommand === 'resume') {\n const goal = goalManager.getGoal();\n if (!goal) {\n ctx.showInfo('No goal to resume. Use /goal <text> to set one.');\n return;\n }\n if (goal.status === 'active') {\n ctx.showInfo('Goal is already active.');\n return;\n }\n if (goal.status !== 'paused') {\n ctx.showInfo('Goal is already done. Use /goal <text> to set a new goal.');\n return;\n }\n\n goalManager.resume();\n await goalManager.saveToThread(state);\n ctx.updateStatusLine();\n\n // Kick off the next turn using the same goal-reminder signal format used by\n // startGoal, so the model receives a structured system-reminder rather than\n // a plain user message.\n const resumedGoal = goalManager.getGoal();\n try {\n await state.session.sendSignal(createGoalReminderSignal(resumedGoal!)).accepted;\n } catch (err) {\n goalManager.pause();\n await goalManager.saveToThread(state);\n ctx.showError(\n `Goal paused — failed to send continuation for \"${goal.objective}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return;\n }\n\n // /goal clear\n if (subCommand === 'clear') {\n goalManager.clear();\n state.planStartedGoalId = undefined;\n await goalManager.saveToThread(state);\n // Abort any in-flight turn. The cleared objective stops the core loop from\n // driving *new* goal continuations, but a turn that was already running when\n // the user cleared keeps going to completion — which reads as \"it's still\n // attempting the goal\". Stop it immediately so clear means stop. Mirrors the\n // Esc/abort cleanup so a turn parked in a tool suspension (e.g. ask_user) is\n // also aborted cleanly.\n if (state.session.run.isRunning() || state.session.suspensions.hasPending()) {\n state.activeInlineQuestion = undefined;\n state.pendingInlineQuestions.length = 0;\n state.pendingAskUserComponents?.clear();\n state.userInitiatedAbort = true;\n state.session.abort();\n }\n ctx.updateStatusLine();\n ctx.showInfo('Goal cleared.');\n return;\n }\n\n // /goal judge — set the judge model and max-attempt defaults\n if (subCommand === 'judge') {\n await handleJudgeCommand(ctx);\n return;\n }\n\n // /goal <text> — set a new goal using saved judge defaults, asking only once if needed.\n const objective = args.join(' ');\n await startGoalWithDefaults(ctx, objective);\n}\n\nfunction formatGoalStatus(goal: GoalState): string {\n return `Goal (${goal.status}): \"${goal.objective}\" — ${goal.turnsUsed}/${goal.maxTurns} turns used [judge: ${goal.judgeModelId}]`;\n}\n\nfunction formatGoalStatusRow(goal: GoalState): string {\n return formatGoalStatus(goal).replace(/\\s+/g, ' ');\n}\n\nfunction showGoalStatus(ctx: SlashCommandContext): void {\n const goal = ctx.state.goalManager.getGoal();\n if (!goal) {\n ctx.showInfo('No goal set. Use /goal <text> to set one.');\n return;\n }\n ctx.showInfo(formatGoalStatus(goal));\n}\n\nasync function showGoalActionModal(ctx: SlashCommandContext): Promise<void> {\n const goal = ctx.state.goalManager.getGoal();\n const items: SelectItem[] = [\n {\n value: 'status',\n label: ` Status ${theme.fg('dim', goal ? formatGoalStatusRow(goal) : 'No goal set')}`,\n },\n ];\n\n if (goal?.status === 'active') {\n items.push({ value: 'pause', label: ` Pause ${theme.fg('dim', 'Pause the continuation loop')}` });\n } else if (goal?.status === 'paused') {\n items.push({ value: 'resume', label: ` Resume ${theme.fg('dim', 'Resume and send a continuation')}` });\n }\n\n if (goal) {\n items.push({ value: 'clear', label: ` Clear ${theme.fg('dim', 'Drop the current goal')}` });\n }\n\n items.push(\n { value: 'judge', label: ` Judge settings ${theme.fg('dim', 'Set judge model and max attempts')}` },\n { value: 'new-hint', label: ` New goal ${theme.fg('dim', 'Type /goal <objective> to start')}` },\n );\n\n return new Promise<void>(resolve => {\n const container = new Box(4, 2, (text: string) => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', 'Goal Actions')), 0, 0));\n container.addChild(new Spacer(1));\n\n const selectList = new SelectList(items, items.length, getSelectListTheme());\n selectList.onSelect = async (item: SelectItem) => {\n ctx.state.ui.hideOverlay();\n try {\n if (item.value === 'status') showGoalStatus(ctx);\n else if (item.value === 'pause') await handleGoalCommand(ctx, ['pause']);\n else if (item.value === 'resume') await handleGoalCommand(ctx, ['resume']);\n else if (item.value === 'clear') await handleGoalCommand(ctx, ['clear']);\n else if (item.value === 'judge') await handleJudgeCommand(ctx);\n else if (item.value === 'new-hint') ctx.showInfo('Type /goal <objective> to start a new goal.');\n } finally {\n resolve();\n }\n };\n\n selectList.onCancel = () => {\n ctx.state.ui.hideOverlay();\n resolve();\n };\n\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc cancel'), 0, 0));\n\n const modal = container as Box & { handleInput: (data: string) => void };\n modal.handleInput = (data: string) => selectList.handleInput(data);\n showModalOverlay(ctx.state.ui, modal, { maxHeight: '60%' });\n });\n}\n\nexport async function handleJudgeCommand(ctx: SlashCommandContext): Promise<void> {\n const defaults = await promptForJudgeDefaults(ctx, 'Judge settings unchanged.');\n if (!defaults) return;\n\n const activeGoal = await ctx.state.goalManager.updateJudgeDefaults(\n ctx.state,\n defaults.judgeModelId,\n defaults.maxTurns,\n );\n if (activeGoal) {\n ctx.showInfo(\n `Judge defaults set: ${defaults.judgeModelId}, ${defaults.maxTurns} max attempts. Current goal updated.`,\n );\n return;\n }\n\n ctx.showInfo(`Judge defaults set: ${defaults.judgeModelId}, ${defaults.maxTurns} max attempts.`);\n}\n\ninterface JudgeDefaults {\n judgeModelId: string;\n maxTurns: number;\n}\n\nexport async function startGoalWithDefaults(\n ctx: SlashCommandContext,\n objective: string,\n cancelMessage = 'Goal cancelled.',\n options: StartGoalOptions = {},\n): Promise<void> {\n const defaults = getJudgeDefaults();\n const judgeDefaults = defaults ?? (await promptForJudgeDefaults(ctx, cancelMessage));\n if (!judgeDefaults) return;\n\n await startGoal(ctx, objective, judgeDefaults.judgeModelId, judgeDefaults.maxTurns, options);\n}\n\nfunction getJudgeDefaults(): JudgeDefaults | null {\n const settings = loadSettings();\n const judgeModelId = settings.models.goalJudgeModel;\n const maxTurns = settings.models.goalMaxTurns;\n if (!judgeModelId || typeof maxTurns !== 'number' || maxTurns <= 0) return null;\n return { judgeModelId, maxTurns };\n}\n\nasync function promptForJudgeDefaults(ctx: SlashCommandContext, cancelMessage: string): Promise<JudgeDefaults | null> {\n const { state } = ctx;\n const availableModels = await state.controller.listAvailableModels();\n\n if (availableModels.length === 0) {\n ctx.showError('No models available. Cannot set goal judge defaults.');\n return null;\n }\n\n const settings = loadSettings();\n const preselectedId = settings.models.goalJudgeModel ?? state.session.model.get() ?? undefined;\n const defaultMaxTurns =\n typeof settings.models.goalMaxTurns === 'number' && settings.models.goalMaxTurns > 0\n ? settings.models.goalMaxTurns\n : DEFAULT_MAX_TURNS;\n\n return new Promise(resolve => {\n const selector = new ModelSelectorComponent({\n tui: state.ui,\n models: availableModels,\n currentModelId: preselectedId,\n title: 'Select Goal Judge Model',\n onSelect: async (model: ModelItem) => {\n state.ui.hideOverlay();\n await promptForApiKeyIfNeeded(state.ui, model, ctx.authStorage);\n\n const cyclesDialog = new GoalCyclesDialogComponent({\n defaultValue: defaultMaxTurns,\n onSubmit: (maxTurns: number) => {\n state.ui.hideOverlay();\n const s = loadSettings();\n s.models.goalJudgeModel = model.id;\n s.models.goalMaxTurns = maxTurns;\n saveSettings(s);\n resolve({ judgeModelId: model.id, maxTurns });\n },\n onCancel: () => {\n state.ui.hideOverlay();\n ctx.showInfo(cancelMessage);\n resolve(null);\n },\n });\n\n state.ui.showOverlay(cyclesDialog, {\n width: '50%',\n maxHeight: '40%',\n anchor: 'center',\n });\n cyclesDialog.focused = true;\n },\n onCancel: () => {\n state.ui.hideOverlay();\n ctx.showInfo(cancelMessage);\n resolve(null);\n },\n });\n\n state.ui.showOverlay(selector, {\n width: '80%',\n maxHeight: '60%',\n anchor: 'center',\n });\n selector.focused = true;\n });\n}\n\nasync function startGoal(\n ctx: SlashCommandContext,\n objective: string,\n judgeModelId: string,\n maxTurns: number,\n options: StartGoalOptions = {},\n): Promise<void> {\n const { state } = ctx;\n const goalManager = state.goalManager;\n\n if (state.pendingNewThread) {\n await state.session.thread.create();\n state.pendingNewThread = false;\n }\n\n const shouldPersistToCreatedThread = !state.session.thread.getId();\n const goal = await goalManager.setGoal(state, objective, judgeModelId, maxTurns);\n if (!goal) {\n ctx.showError('Failed to set goal.');\n return;\n }\n\n state.planStartedGoalId = undefined;\n if (shouldPersistToCreatedThread) {\n goalManager.persistOnNextThreadCreate();\n }\n await goalManager.saveToThread(state);\n ctx.updateStatusLine();\n\n if (options.trigger === 'none') {\n return;\n }\n\n try {\n await state.session.sendSignal(createGoalReminderSignal(goal)).accepted;\n } catch (err) {\n goalManager.pause();\n await goalManager.saveToThread(state);\n ctx.showError(`Goal paused — failed to start: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nexport function createGoalReminderMessage(\n goalId: string,\n objective: string,\n maxTurns: number,\n judgeModelId: string,\n): MastraDBMessage {\n return createSignal({\n id: `goal-${goalId}`,\n type: 'reactive',\n tagName: 'system-reminder',\n contents: objective,\n attributes: { type: 'goal' },\n metadata: { goalMaxTurns: maxTurns, judgeModelId },\n } as Parameters<typeof createSignal>[0]).toDBMessage();\n}\n\nexport function createGoalReminderXml(message: string): string {\n return `<system-reminder type=\"goal\">${escapeXml(message)}</system-reminder>`;\n}\n\nfunction escapeXml(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\n}\n","/**\n * Help text builder — generates the inline help content shown by /help.\n */\n\nimport type { SlashCommandMetadata } from '@mastra/code-sdk/utils/slash-command-loader';\n\nexport interface HelpTextOptions {\n /** Number of available controller modes (mode commands shown when > 1) */\n modes: number;\n /** User-defined custom slash commands */\n customSlashCommands: SlashCommandMetadata[];\n /** Active direct shell passthrough mode label */\n shellModeLabel?: string;\n}\n\ninterface HelpEntry {\n key: string;\n description: string;\n}\n\n// =============================================================================\n// Data\n// =============================================================================\n\nfunction getCommands(modes: number): HelpEntry[] {\n const cmds: HelpEntry[] = [\n { key: '/new', description: 'Start a new thread' },\n { key: '/threads', description: 'Switch between threads' },\n { key: '/thread', description: 'Show current thread info' },\n { key: '/thread:tag-dir', description: 'Tag thread with current directory' },\n { key: '/name', description: 'Rename current thread' },\n { key: '/resource', description: 'Show/switch resource ID' },\n { key: '/skills', description: 'List available skills' },\n { key: '/skill/<name>', description: 'Activate a skill' },\n { key: '/models', description: 'Switch model pack' },\n { key: '/custom-providers', description: 'Manage custom providers and models' },\n { key: '/subagents', description: 'Configure subagent models' },\n { key: '/permissions', description: 'Tool approval permissions' },\n { key: '/settings', description: 'Notifications, YOLO, thinking' },\n { key: '/memory', description: 'Configure Observational Memory (/om alias)' },\n { key: '/review', description: 'Review a GitHub pull request' },\n { key: '/report-issue', description: 'Open or browse mastracode issues' },\n { key: '/cost', description: 'Token usage and costs' },\n {\n key: '/prune',\n description: 'Prune old storage data — closes the TUI (\"vacuum\" reclaims disk, \"keep-memory\" keeps chats)',\n },\n { key: '/diff', description: 'Modified files or git diff' },\n { key: '/sandbox', description: 'Manage sandbox allowed paths' },\n { key: '/hooks', description: 'Show/reload configured hooks' },\n { key: '/mcp', description: 'Show/reload MCP connections' },\n { key: '/login', description: 'Login with OAuth provider' },\n { key: '/logout', description: 'Logout from OAuth provider' },\n { key: '/setup', description: 'Run the setup wizard' },\n { key: '/browser', description: 'Configure browser automation' },\n { key: '/api-keys', description: 'Manage provider API keys' },\n { key: '/plugins', description: 'Manage Mastra Code plugins' },\n { key: '/theme', description: 'Switch color theme (auto/dark/light)' },\n { key: '/update', description: 'Check for and install updates' },\n { key: '/observability', description: 'Configure cloud observability' },\n { key: '/github', description: 'Subscribe/sync GitHub PR signals' },\n { key: '/goal', description: 'Set/manage persistent goal (Ralph loop)' },\n { key: '/goal judge', description: 'Set the goal judge model and max attempts' },\n ];\n\n if (modes > 1) {\n cmds.push({ key: '/mode', description: 'Switch or list modes' });\n }\n\n cmds.push({ key: '/exit', description: 'Exit' }, { key: '/help', description: 'Show this help' });\n\n return cmds;\n}\n\nfunction getShortcuts(modes: number): HelpEntry[] {\n const shortcuts: HelpEntry[] = [\n { key: 'Ctrl+C', description: 'Interrupt / clear input' },\n { key: 'Ctrl+C×2', description: 'Exit (double-tap)' },\n { key: 'Ctrl+D', description: 'Exit (when editor empty)' },\n { key: 'Enter', description: 'Send message' },\n { key: 'Ctrl+F', description: 'Queue follow-up' },\n { key: 'Ctrl+T', description: 'Toggle thinking blocks' },\n { key: 'Ctrl+E', description: 'Expand/collapse tool outputs' },\n { key: 'Ctrl+Y', description: 'Toggle YOLO mode' },\n { key: 'Ctrl+Z', description: 'Suspend process (fg to resume)' },\n { key: 'Alt+Z', description: 'Undo last clear' },\n ];\n\n if (modes > 1) {\n shortcuts.push({ key: '⇧+Tab', description: 'Cycle agent modes' });\n }\n\n shortcuts.push({ key: '/', description: 'Commands' }, { key: '!', description: 'Shell' });\n\n return shortcuts;\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\nfunction renderSection(title: string, entries: HelpEntry[]): string {\n const maxKeyLen = Math.max(...entries.map(e => e.key.length));\n const lines = entries.map(e => ` ${e.key.padEnd(maxKeyLen + 2)}${e.description}`).join('\\n');\n return `${title}\\n${lines}`;\n}\n\n/**\n * Build the full help text as a plain string for inline display via showInfo().\n */\nexport function buildHelpText(options: HelpTextOptions): string {\n const sections: string[] = [];\n\n sections.push(renderSection('Commands', getCommands(options.modes)));\n\n if (options.customSlashCommands.length > 0) {\n const customEntries = options.customSlashCommands.map(cmd => ({\n key: `//${cmd.name}`,\n description: cmd.description || 'No description',\n }));\n sections.push(renderSection('Custom Commands', customEntries));\n }\n\n sections.push(\n renderSection('Shell', [\n {\n key: '!<cmd>',\n description: `Run a direct shell command (${options.shellModeLabel ?? 'default shell'})`,\n },\n ]),\n );\n\n sections.push(renderSection('Keyboard Shortcuts', getShortcuts(options.modes)));\n\n return sections.join('\\n\\n');\n}\n","import type { ShellPassthroughSettings } from '@mastra/code-sdk/onboarding/settings';\n\nexport const MASTRACODE_SHELL_ENV = 'MASTRACODE_SHELL';\nexport const MASTRACODE_SHELL_MODE_ENV = 'MASTRACODE_SHELL_MODE';\n\nexport type ShellPassthroughMode = 'default' | 'path' | 'login';\nexport type ShellFamily = 'posix' | 'cmd' | 'powershell';\n\nexport interface DefaultShellInvocation {\n kind: 'default';\n mode: 'default';\n label: string;\n warnings: string[];\n}\n\nexport interface ExplicitShellInvocation {\n kind: 'explicit';\n mode: Exclude<ShellPassthroughMode, 'default'>;\n family: ShellFamily;\n executable: string;\n args: string[];\n label: string;\n warnings: string[];\n}\n\nexport type ShellPassthroughInvocation = DefaultShellInvocation | ExplicitShellInvocation;\n\nconst VALID_MODES = new Set<ShellPassthroughMode>(['default', 'path', 'login']);\nconst VALID_FAMILIES = new Set<ShellFamily>(['posix', 'cmd', 'powershell']);\nconst POWERSHELL_BASENAMES = new Set(['pwsh', 'pwsh.exe', 'powershell', 'powershell.exe']);\nconst CMD_BASENAMES = new Set(['cmd', 'cmd.exe']);\n\nfunction nonEmptyString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseMode(value: unknown): ShellPassthroughMode | undefined {\n const mode = nonEmptyString(value);\n return mode && VALID_MODES.has(mode as ShellPassthroughMode) ? (mode as ShellPassthroughMode) : undefined;\n}\n\nfunction parseFamily(value: unknown): ShellFamily | undefined {\n const family = nonEmptyString(value);\n return family && VALID_FAMILIES.has(family as ShellFamily) ? (family as ShellFamily) : undefined;\n}\n\nfunction executableBasename(executable: string): string {\n return executable.split(/[\\\\/]/).pop()?.toLowerCase() ?? executable.toLowerCase();\n}\n\nexport function inferShellFamily(executable: string, platform: NodeJS.Platform | string): ShellFamily | undefined {\n const basename = executableBasename(executable);\n if (POWERSHELL_BASENAMES.has(basename)) return 'powershell';\n if (CMD_BASENAMES.has(basename)) return 'cmd';\n return platform === 'win32' ? undefined : 'posix';\n}\n\nfunction shellDisplayName(executable: string): string {\n return executableBasename(executable).replace(/\\.exe$/i, '');\n}\n\nfunction quotePowerShellSingleQuotedString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nexport function buildPowerShellScript(command: string): string {\n return [\n \"$ErrorActionPreference = 'Stop'\",\n '$PSNativeCommandUseErrorActionPreference = $false',\n '$global:LASTEXITCODE = $null',\n `$scriptBlock = [scriptblock]::Create(${quotePowerShellSingleQuotedString(command)})`,\n 'try {',\n ' & $scriptBlock',\n ' $commandSucceeded = $?',\n ' $nativeExitCode = $global:LASTEXITCODE',\n ' if (-not $commandSucceeded) {',\n ' if ($nativeExitCode -is [int] -and $nativeExitCode -ne 0) { exit $nativeExitCode }',\n ' exit 1',\n ' }',\n ' exit 0',\n '} catch {',\n ' [Console]::Error.WriteLine($_.ToString())',\n ' exit 1',\n '}',\n ].join('\\n');\n}\n\nexport function encodePowerShellCommand(script: string): string {\n return Buffer.from(script, 'utf16le').toString('base64');\n}\n\nexport function buildPowerShellArgs(command: string, options: { loadProfile: boolean }): string[] {\n return [\n '-NoLogo',\n '-NonInteractive',\n ...(options.loadProfile ? [] : ['-NoProfile']),\n '-EncodedCommand',\n encodePowerShellCommand(buildPowerShellScript(command)),\n ];\n}\n\nfunction buildExplicitShellArgs(\n family: ShellFamily,\n mode: Exclude<ShellPassthroughMode, 'default'>,\n command: string,\n): string[] {\n if (family === 'powershell') {\n return buildPowerShellArgs(command, { loadProfile: mode === 'login' });\n }\n\n if (family === 'cmd') {\n // With /s, cmd.exe strips the first and last quote on the line and runs\n // everything in between verbatim. Wrapping the whole command in one pair of\n // quotes therefore preserves any inner quotes (e.g. quoted paths) exactly,\n // without needing to escape them. See the cmd /C quote-handling rules.\n return ['/d', '/s', '/c', `\"${command}\"`];\n }\n\n return mode === 'login' ? ['-l', '-c', command] : ['-c', command];\n}\n\nfunction defaultInvocation(warnings: string[] = []): DefaultShellInvocation {\n return {\n kind: 'default',\n mode: 'default',\n label: 'default shell',\n warnings,\n };\n}\n\nexport function resolveShellPassthroughInvocation(\n command: string,\n settings: ShellPassthroughSettings | undefined,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform | string = process.platform,\n): ShellPassthroughInvocation {\n const warnings: string[] = [];\n const envExecutable = nonEmptyString(env[MASTRACODE_SHELL_ENV]);\n const settingsExecutable = nonEmptyString(settings?.executable);\n const envModeValue = nonEmptyString(env[MASTRACODE_SHELL_MODE_ENV]);\n const settingsModeValue = nonEmptyString(settings?.mode);\n const settingsFamilyValue = nonEmptyString(settings?.family);\n const hasEnvExecutable = Boolean(envExecutable);\n\n let mode = parseMode(envModeValue);\n if (envModeValue && !mode) {\n warnings.push(`${MASTRACODE_SHELL_MODE_ENV} must be default, path, or login`);\n return defaultInvocation(warnings);\n }\n\n if (!mode) {\n const settingsMode = parseMode(settingsModeValue);\n if (settingsModeValue && !settingsMode && !hasEnvExecutable) {\n warnings.push('shellPassthrough.mode must be default, path, or login');\n return defaultInvocation(warnings);\n }\n mode = hasEnvExecutable\n ? settingsMode && settingsMode !== 'default'\n ? settingsMode\n : 'path'\n : (settingsMode ?? (settingsExecutable ? 'path' : undefined));\n }\n\n const executable = envExecutable ?? settingsExecutable;\n mode ??= 'default';\n\n if (mode === 'default') {\n return defaultInvocation(warnings);\n }\n\n if (!executable) {\n warnings.push(`shell passthrough ${mode} mode requires an executable`);\n return defaultInvocation(warnings);\n }\n\n let family = hasEnvExecutable ? undefined : parseFamily(settingsFamilyValue);\n if (settingsFamilyValue && !family && !hasEnvExecutable) {\n warnings.push('shellPassthrough.family must be posix, cmd, or powershell');\n return defaultInvocation(warnings);\n }\n\n family ??= inferShellFamily(executable, platform);\n if (!family) {\n warnings.push(`could not infer shell family for ${executable}`);\n return defaultInvocation(warnings);\n }\n\n const normalizedMode: Exclude<ShellPassthroughMode, 'default'> = mode === 'login' ? 'login' : 'path';\n const args = buildExplicitShellArgs(family, normalizedMode, command);\n const profileLabel =\n family === 'powershell' && normalizedMode === 'path'\n ? ', no profile'\n : normalizedMode === 'login' && family !== 'cmd'\n ? ', login/profile'\n : '';\n\n return {\n kind: 'explicit',\n mode: normalizedMode,\n family,\n executable,\n args,\n label: `${shellDisplayName(executable)} (${family}${profileLabel})`,\n warnings,\n };\n}\n\nexport function describeShellPassthroughInvocation(invocation: ShellPassthroughInvocation): string {\n return invocation.label;\n}\n","import { loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { buildHelpText } from '../components/help-overlay.js';\nimport { describeShellPassthroughInvocation, resolveShellPassthroughInvocation } from '../shell-config.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport function handleHelpCommand(ctx: SlashCommandContext): void {\n const shellInvocation = resolveShellPassthroughInvocation('', loadSettings().shellPassthrough);\n const text = buildHelpText({\n modes: ctx.controller.listModes().length,\n customSlashCommands: ctx.customSlashCommands,\n shellModeLabel: describeShellPassthroughInvocation(shellInvocation),\n });\n ctx.showInfo(text);\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport function handleCostCommand(ctx: SlashCommandContext): void {\n const formatNumber = (n: number) => n.toLocaleString();\n\n // Read from AgentController display state (canonical source)\n const ds = ctx.state.session.displayState.get();\n\n let omTokensText = '';\n if (ds.omProgress.observationTokens > 0) {\n omTokensText = `\n Memory: ${formatNumber(ds.omProgress.observationTokens)} tokens`;\n }\n\n ctx.showInfo(`Token Usage (Current Thread):\n Input: ${formatNumber(ds.tokenUsage.promptTokens)} tokens\n Output: ${formatNumber(ds.tokenUsage.completionTokens)} tokens${omTokensText}\n ─────────────────────────────────────────\n Total: ${formatNumber(ds.tokenUsage.totalTokens)} tokens\n \n Note: For cost estimates, check your provider's pricing page.`);\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport function handleYoloCommand(ctx: SlashCommandContext): void {\n const current = (ctx.state.session.state.get() as any)?.yolo === true;\n void ctx.state.session.state.set({ yolo: !current } as any);\n ctx.showInfo(!current ? 'YOLO mode ON — tools auto-approved' : 'YOLO mode OFF — tools require approval');\n}\n","/**\n * MultilineInput - wraps pi-tui's Editor to provide multiline text input\n * with the same interface as the single-line Input component.\n *\n * Supports:\n * - Enter to submit\n * - Shift+Enter for new line\n * - \\\\+Enter for new line (pi-tui convention)\n * - Text wrapping and scrolling\n */\n\nimport { Editor, matchesKey } from '@earendil-works/pi-tui';\nimport type { EditorTheme, TUI } from '@earendil-works/pi-tui';\n\nconst ANSI_STRIP_RE = /\\x1b\\[[0-9;]*m/g;\n\nexport class MultilineInput {\n private editor: Editor;\n private _focused = false;\n public onSubmit?: (value: string) => void;\n public onEscape?: () => void;\n public allowEmptySubmit = false;\n\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(tui: TUI, editorTheme: EditorTheme) {\n this.editor = new Editor(tui, editorTheme);\n }\n\n getText(): string {\n return this.editor.getText();\n }\n\n setText(text: string): void {\n this.editor.setText(text);\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape')) {\n this.onEscape?.();\n return;\n }\n\n if (matchesKey(data, 'enter')) {\n // Check if cursor is preceded by backslash (\\+Enter newline workaround)\n const lines = (this.editor as any).state?.lines;\n const cursorCol = (this.editor as any).state?.cursorCol;\n const currentLine = lines?.[(this.editor as any).state?.cursorLine] || '';\n if (cursorCol > 0 && currentLine[cursorCol - 1] === '\\\\') {\n this.editor.handleInput(data);\n return;\n }\n\n // Submit on plain Enter. Use trim() only to decide emptiness;\n // forward the raw buffer so leading indentation and trailing\n // newlines reach the caller intact.\n const rawText = this.editor.getText();\n if (rawText.trim() || this.allowEmptySubmit) {\n this.onSubmit?.(rawText);\n }\n return;\n }\n\n // Shift+Enter inserts a newline\n if (matchesKey(data, 'shift+enter')) {\n this.editor.handleInput('\\n');\n return;\n }\n\n this.editor.handleInput(data);\n }\n\n invalidate(): void {\n this.editor.invalidate();\n }\n\n /**\n * Render the editor content, stripping the Editor's own border chrome\n * so it can be embedded inside an existing bordered box.\n */\n render(width: number): string[] {\n const editorLines = this.editor.render(width);\n\n // The Editor wraps lines with its own borders: ─── top/bottom, │ sides\n // We strip these to embed content in the ask-question bordered box.\n const contentLines: string[] = [];\n let pastFirstBorder = false;\n\n for (const line of editorLines) {\n const stripped = line.replace(ANSI_STRIP_RE, '');\n\n // Skip horizontal rule border lines (───)\n if (stripped.length > 0 && /^─+$/.test(stripped)) {\n if (!pastFirstBorder) {\n pastFirstBorder = true;\n }\n continue;\n }\n\n // Skip dedicated scroll-indicator chrome (e.g. \"── ↑ ──\").\n // Match only full-line indicator format so user content with\n // arrow characters in it is preserved.\n if (/^─+\\s*[↑↓]\\s*─+$/.test(stripped.trim())) {\n continue;\n }\n\n if (pastFirstBorder) {\n contentLines.push(line);\n }\n }\n\n // If no content lines, return at least one empty line for the cursor\n if (contentLines.length === 0) {\n contentLines.push('');\n }\n\n return contentLines;\n }\n}\n","/**\n * Drop-in replacement for pi-tui's `SelectList` that wraps long item labels\n * across multiple terminal rows with a `↳ ` continuation marker instead of\n * truncating them. Arrow keys move item-to-item — not row-to-row — so\n * navigation stays predictable regardless of label height.\n */\n\nimport { getKeybindings, wrapTextWithAnsi } from '@earendil-works/pi-tui';\nimport type { Component, SelectItem, SelectListTheme } from '@earendil-works/pi-tui';\n\nconst SELECTED_PREFIX = '→ ';\nconst UNSELECTED_PREFIX = ' ';\nconst CONTINUATION_PREFIX = '↳ ';\nconst PREFIX_WIDTH = 2;\nconst CHECKBOX_CHECKED = '[x] ';\nconst CHECKBOX_UNCHECKED = '[ ] ';\nconst CHECKBOX_WIDTH = 4;\n\nexport class WrappingSelectList implements Component {\n private items: SelectItem[];\n private filteredItems: SelectItem[];\n private selectedIndex = 0;\n private maxVisible: number;\n private theme: SelectListTheme;\n /** When true, items are toggled (space) and confirmed together (enter) instead of selected one at a time. */\n private multiSelect: boolean;\n /** Values toggled on in multi-select mode. */\n private checkedValues = new Set<string>();\n\n onSelect?: (item: SelectItem) => void;\n onCancel?: () => void;\n onSelectionChange?: (item: SelectItem) => void;\n /** Called when the user confirms a multi-select list with Enter; receives all checked items in display order. */\n onConfirmMulti?: (items: SelectItem[]) => void;\n\n constructor(items: SelectItem[], maxVisible: number, theme: SelectListTheme, multiSelect = false) {\n this.items = items;\n this.filteredItems = items;\n this.maxVisible = maxVisible;\n this.theme = theme;\n this.multiSelect = multiSelect;\n }\n\n setFilter(filter: string): void {\n this.filteredItems = this.items.filter(item => item.value.toLowerCase().startsWith(filter.toLowerCase()));\n this.selectedIndex = 0;\n }\n\n setSelectedIndex(index: number): void {\n this.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));\n }\n\n invalidate(): void {}\n\n getSelectedItem(): SelectItem | null {\n return this.filteredItems[this.selectedIndex] ?? null;\n }\n\n render(width: number): string[] {\n const lines: string[] = [];\n\n if (this.filteredItems.length === 0) {\n lines.push(this.theme.noMatch(' No matching items'));\n return lines;\n }\n\n const startIndex = Math.max(\n 0,\n Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n );\n const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n for (let i = startIndex; i < endIndex; i++) {\n const item = this.filteredItems[i];\n if (!item) continue;\n const isSelected = i === this.selectedIndex;\n for (const row of this.renderItem(item, isSelected, width)) {\n lines.push(row);\n }\n }\n\n if (startIndex > 0 || endIndex < this.filteredItems.length) {\n lines.push(this.theme.scrollInfo(` (${this.selectedIndex + 1}/${this.filteredItems.length})`));\n }\n\n return lines;\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n if (kb.matches(keyData, 'tui.select.up')) {\n this.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1;\n this.notifySelectionChange();\n } else if (kb.matches(keyData, 'tui.select.down')) {\n this.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1;\n this.notifySelectionChange();\n } else if (this.multiSelect && keyData === ' ') {\n const current = this.filteredItems[this.selectedIndex];\n if (current) {\n if (this.checkedValues.has(current.value)) {\n this.checkedValues.delete(current.value);\n } else {\n this.checkedValues.add(current.value);\n }\n }\n } else if (kb.matches(keyData, 'tui.select.confirm')) {\n if (this.multiSelect) {\n const checked = this.items.filter(item => this.checkedValues.has(item.value));\n this.onConfirmMulti?.(checked);\n return;\n }\n const selected = this.filteredItems[this.selectedIndex];\n if (selected && this.onSelect) this.onSelect(selected);\n } else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancel?.();\n }\n }\n\n private renderItem(item: SelectItem, isSelected: boolean, width: number): string[] {\n const labelText = this.getDisplayValue(item);\n // In multi-select mode each row carries a `[x] `/`[ ] ` checkbox after the\n // cursor prefix, so reserve that extra width when wrapping the label.\n const checkboxWidth = this.multiSelect ? CHECKBOX_WIDTH : 0;\n const labelWidth = Math.max(1, width - PREFIX_WIDTH - checkboxWidth);\n const wrapped = wrapTextWithAnsi(labelText, labelWidth);\n const checkbox = this.multiSelect\n ? this.checkedValues.has(item.value)\n ? CHECKBOX_CHECKED\n : CHECKBOX_UNCHECKED\n : '';\n\n if (wrapped.length === 0) {\n const prefix = isSelected ? SELECTED_PREFIX : UNSELECTED_PREFIX;\n const rendered = `${prefix}${checkbox}`;\n return [isSelected ? this.theme.selectedText(rendered) : rendered];\n }\n\n return wrapped.map((chunk, index) => {\n const cursorPrefix = index === 0 ? (isSelected ? SELECTED_PREFIX : UNSELECTED_PREFIX) : CONTINUATION_PREFIX;\n // Only the first row shows the checkbox; continuation rows indent to align.\n const boxPart = index === 0 ? checkbox : ' '.repeat(checkbox.length);\n const rendered = `${cursorPrefix}${boxPart}${chunk}`;\n if (isSelected) return this.theme.selectedText(rendered);\n if (cursorPrefix === CONTINUATION_PREFIX) return this.theme.description(rendered);\n return rendered;\n });\n }\n\n private getDisplayValue(item: SelectItem): string {\n return item.label || item.value;\n }\n\n private notifySelectionChange(): void {\n const selected = this.filteredItems[this.selectedIndex];\n if (selected && this.onSelectionChange) this.onSelectionChange(selected);\n }\n}\n","/**\n * Ask question dialog component.\n * Shows a question with either selectable options or free-text input.\n * Used by the ask_user tool to collect structured answers from the user.\n */\n\nimport { Box, getKeybindings, Input, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, SelectItem, Component, TUI } from '@earendil-works/pi-tui';\nimport { theme, getSelectListTheme, getEditorTheme } from '../theme.js';\nimport type { AskQuestionSelectionMode } from './ask-question-inline.js';\nimport { MultilineInput } from './multiline-input.js';\nimport { WrappingSelectList } from './wrapping-select-list.js';\n\nexport interface AskQuestionDialogOptions {\n question: string;\n options?: Array<{ label: string; description?: string }>;\n /** Controls whether options are single- or multi-select. Defaults to single_select. */\n selectionMode?: AskQuestionSelectionMode;\n /**\n * Use a multiline editor for free-text input (Shift+Enter / \\+Enter for new lines).\n * Defaults to false. Enable for prompts that legitimately want paragraph-length replies.\n */\n multiline?: boolean;\n allowEmptyInput?: boolean;\n defaultValue?: string;\n allowCustomResponse?: boolean;\n selectedOptionLabel?: string;\n tui?: TUI;\n onSubmit: (answer: string) => void;\n /**\n * Called instead of `onSubmit` when the prompt is multi-select, with every selected\n * option label. Falls back to `onSubmit` with a comma-joined string when omitted.\n */\n onSubmitMulti?: (answers: string[]) => void;\n onCancel: () => void;\n}\n\nexport class AskQuestionDialogComponent extends Box implements Focusable {\n private static readonly CUSTOM_RESPONSE_VALUE = '__custom_response__';\n\n private selectList?: SelectList | WrappingSelectList;\n private input?: Input | MultilineInput;\n private tui?: TUI;\n private multiline = false;\n private multiSelect = false;\n private allowEmptyInput = false;\n private defaultValue?: string;\n private allowCustomResponse = true;\n private selectedOptionLabel?: string;\n private onSubmit: (answer: string) => void;\n private onSubmitMulti?: (answers: string[]) => void;\n private onCancel: () => void;\n\n /** Children added by buildSelectMode/buildInputMode, tracked for removal on mode switch */\n private modeChildren: Component[] = [];\n\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n if (this.input) this.input.focused = value;\n }\n\n constructor(options: AskQuestionDialogOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.onSubmit = options.onSubmit;\n this.onSubmitMulti = options.onSubmitMulti;\n this.onCancel = options.onCancel;\n this.tui = options.tui;\n this.multiline = Boolean(options.multiline);\n this.multiSelect = options.selectionMode === 'multi_select';\n this.allowEmptyInput = Boolean(options.allowEmptyInput);\n this.defaultValue = options.defaultValue;\n this.allowCustomResponse = options.allowCustomResponse ?? true;\n this.selectedOptionLabel = options.selectedOptionLabel;\n\n // Title\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Question')), 0, 0));\n this.addChild(new Spacer(1));\n\n // Question text (may be multi-line)\n for (const line of options.question.split('\\n')) {\n this.addChild(new Text(theme.fg('text', line), 0, 0));\n }\n this.addChild(new Spacer(1));\n\n if (options.options && options.options.length > 0) {\n this.buildSelectMode(options.options);\n } else {\n this.buildInputMode();\n }\n }\n\n private buildSelectMode(opts: Array<{ label: string; description?: string }>): void {\n const items: SelectItem[] = opts.map(opt => ({\n value: opt.label,\n label: opt.description ? ` ${opt.label} ${theme.fg('dim', opt.description)}` : ` ${opt.label}`,\n }));\n\n // \"Custom response...\" only applies to single-select: it switches to free-text.\n if (this.allowCustomResponse && !this.multiSelect) {\n items.push({\n value: AskQuestionDialogComponent.CUSTOM_RESPONSE_VALUE,\n label: ` ${theme.fg('dim', '✎ Custom response...')}`,\n });\n }\n\n let hintText: string;\n if (this.multiSelect) {\n const list = new WrappingSelectList(items, Math.min(items.length, 8), getSelectListTheme(), true);\n list.onConfirmMulti = (selected: SelectItem[]) => {\n const values = selected.map(item => item.value);\n if (this.onSubmitMulti) {\n this.onSubmitMulti(values);\n } else {\n this.onSubmit(values.join(', '));\n }\n };\n list.onCancel = this.onCancel;\n this.selectList = list;\n hintText = ' Space to toggle · Enter to confirm · Esc to skip';\n } else {\n const list = new SelectList(items, Math.min(items.length, 8), getSelectListTheme());\n const selectedIndex = items.findIndex(item => item.value === this.selectedOptionLabel);\n if (selectedIndex >= 0) list.setSelectedIndex(selectedIndex);\n list.onSelect = (item: SelectItem) => {\n if (item.value === AskQuestionDialogComponent.CUSTOM_RESPONSE_VALUE) {\n this.switchToCustomInput();\n return;\n }\n this.onSubmit(item.value);\n };\n list.onCancel = this.onCancel;\n this.selectList = list;\n hintText = ' ↑↓ to navigate · Enter to select · Esc to skip';\n }\n\n this.modeChildren = [];\n const selectChild = this.selectList as Component;\n this.addChild(selectChild);\n this.modeChildren.push(selectChild);\n const spacer = new Spacer(1);\n this.addChild(spacer);\n this.modeChildren.push(spacer);\n const hint = new Text(theme.fg('dim', hintText), 0, 0);\n this.addChild(hint);\n this.modeChildren.push(hint);\n }\n\n /** Whether this prompt should render a multiline editor (vs a single-line input). */\n private useMultiline(): boolean {\n return this.multiline && Boolean(this.tui);\n }\n\n private buildInputMode(): void {\n if (this.useMultiline()) {\n const multilineInput = new MultilineInput(this.tui!, getEditorTheme());\n multilineInput.allowEmptySubmit = this.allowEmptyInput;\n multilineInput.onSubmit = (value: string) => {\n // Trim only for the emptiness decision; forward the raw value\n // so leading indentation / trailing newlines survive.\n if (value.trim() || this.allowEmptyInput) {\n this.onSubmit(value);\n }\n };\n multilineInput.onEscape = () => {\n this.onCancel();\n };\n this.input = multilineInput;\n } else {\n this.input = new Input();\n this.input.onSubmit = (value: string) => {\n const trimmed = value.trim();\n if (trimmed || this.allowEmptyInput) {\n this.onSubmit(trimmed);\n }\n };\n }\n\n this.modeChildren = [];\n const inputChild = this.input;\n this.addChild(inputChild);\n this.modeChildren.push(inputChild);\n const spacer = new Spacer(1);\n this.addChild(spacer);\n this.modeChildren.push(spacer);\n const hintText = this.useMultiline()\n ? ' Enter to submit · Shift+Enter for new line · \\\\+Enter for new line · Esc to skip'\n : ' Enter to submit · Esc to skip';\n const hint = new Text(theme.fg('dim', hintText), 0, 0);\n this.addChild(hint);\n this.modeChildren.push(hint);\n\n if (this.defaultValue) {\n (this.input as Input).setValue?.(this.defaultValue);\n }\n\n // Carry focus over so switchToCustomInput() yields a focused input.\n this.input.focused = this._focused;\n }\n\n private switchToCustomInput(): void {\n // Remove select mode children\n for (const child of this.modeChildren) {\n this.removeChild(child);\n }\n this.selectList = undefined;\n this.buildInputMode();\n }\n\n handleInput(data: string): void {\n if (this.selectList) {\n this.selectList.handleInput(data);\n } else if (this.input) {\n const kb = getKeybindings();\n if (kb.matches(data, 'tui.select.cancel')) {\n this.onCancel();\n return;\n }\n this.input.handleInput(data);\n }\n }\n}\n","import type { OverlayOptions, TUI } from '@earendil-works/pi-tui';\n\nimport { AskQuestionDialogComponent } from './components/ask-question-dialog.js';\nimport { showModalOverlay } from './overlay.js';\n\nexport type ModalQuestionOption = { label: string; description?: string };\n\nexport type ModalQuestionOptions = {\n question: string;\n options?: ModalQuestionOption[];\n defaultValue?: string;\n allowEmptyInput?: boolean;\n allowCustomResponse?: boolean;\n selectedOptionLabel?: string;\n multiline?: boolean;\n overlay?: {\n widthPercent?: number;\n maxHeight?: OverlayOptions['maxHeight'];\n };\n};\n\nexport function askModalQuestion(tui: TUI, options: ModalQuestionOptions): Promise<string | null> {\n return new Promise(resolve => {\n const question = new AskQuestionDialogComponent({\n question: options.question,\n options: options.options,\n multiline: options.multiline,\n tui,\n allowEmptyInput: options.allowEmptyInput,\n allowCustomResponse: options.allowCustomResponse,\n selectedOptionLabel: options.selectedOptionLabel,\n defaultValue: options.defaultValue,\n onSubmit: answer => {\n tui.hideOverlay();\n resolve(answer);\n },\n onCancel: () => {\n tui.hideOverlay();\n resolve(null);\n },\n });\n\n showModalOverlay(tui, question, { maxHeight: '50%', ...options.overlay });\n question.focused = true;\n });\n}\n","/**\n * Open a macOS settings deep link (e.g. an `x-apple.systempreferences:` URL) so\n * the TUI can take the user straight to the right Privacy & Security pane\n * instead of telling them to go find it themselves.\n */\n\nimport { spawn } from 'node:child_process';\n\n/**\n * Open `url` with the macOS `open` command. Resolves `true` if the launcher\n * started cleanly, `false` otherwise (non-darwin, spawn failure, or non-zero\n * exit). Never throws — opening settings is best-effort guidance.\n */\nexport async function openMacSettings(url: string): Promise<boolean> {\n if (process.platform !== 'darwin') return false;\n return new Promise(resolve => {\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn('open', [url], { stdio: 'ignore' });\n } catch {\n resolve(false);\n return;\n }\n child.on('error', () => resolve(false));\n child.on('exit', code => resolve(code === 0));\n });\n}\n","/**\n * Speech-to-text transcription for push-to-talk voice input (cloud path).\n *\n * Provider-agnostic: most supported cloud providers speak the OpenAI\n * `/audio/transcriptions` shape (see `stt-registry.ts`), so we drive them\n * through Mastra's own voice abstraction — `OpenAIVoice` (a `MastraVoice`) from\n * `@mastra/voice-openai`. The `openai` provider uses the default endpoint; every\n * other OpenAI-compatible host is reached by pointing the underlying client at\n * its `baseURL`. Deepgram is not OpenAI-compatible, so it is driven through\n * `DeepgramVoice` from `@mastra/voice-deepgram` instead.\n *\n * Using `MastraVoice.listen()` keeps this aligned with the framework's voice\n * ecosystem and normalizes provider responses to a transcript string. The voice\n * package constructs its own SDK client internally, so this avoids coupling to a\n * specific `@ai-sdk/*` model-spec version.\n *\n * Note: OpenAI OAuth (Codex) tokens cannot be used for the audio transcription\n * REST endpoint, so a real provider API key is required.\n */\n\nimport { Readable } from 'node:stream';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { DEFAULT_STT_MODEL, resolveSTTModel } from '@mastra/code-sdk/voice/stt-registry';\nimport type { STTModel } from '@mastra/code-sdk/voice/stt-registry';\nimport { DeepgramVoice } from '@mastra/voice-deepgram';\nimport { OpenAIVoice } from '@mastra/voice-openai';\n\n/**\n * The minimal surface of a `MastraVoice` we use here. Declared structurally to\n * avoid coupling to a specific cross-package `MastraVoice` class identity\n * (`@mastra/voice-*` packages extend their own bundled copy).\n */\ninterface VoiceListener {\n listen(audioStream: NodeJS.ReadableStream, options?: Record<string, unknown>): Promise<unknown>;\n}\n\n/**\n * Per-provider environment variable that holds an API key, checked before the\n * stored credential. Mirrors the key names used elsewhere in MastraCode.\n */\nconst PROVIDER_ENV_VAR: Record<string, string> = {\n openai: 'OPENAI_API_KEY',\n groq: 'GROQ_API_KEY',\n alibaba: 'DASHSCOPE_API_KEY',\n 'alibaba-cn': 'DASHSCOPE_API_KEY',\n scaleway: 'SCALEWAY_API_KEY',\n nvidia: 'NVIDIA_API_KEY',\n nearai: 'NEAR_AI_API_KEY',\n evroc: 'EVROC_API_KEY',\n deepgram: 'DEEPGRAM_API_KEY',\n};\n\nexport class VoiceCredentialError extends Error {\n constructor(provider: string) {\n super(\n `Voice input needs a ${provider} API key. Set ${\n PROVIDER_ENV_VAR[provider] ?? `${provider.toUpperCase()}_API_KEY`\n } or add one with /api-keys (OAuth tokens are not supported for transcription).`,\n );\n this.name = 'VoiceCredentialError';\n }\n}\n\n/**\n * Resolve an API key for a cloud STT provider.\n * Honors the env-overrides-stored-key contract: the provider's env var wins,\n * then the stored credential is used as a fallback.\n */\nexport function resolveProviderApiKey(provider: string, authStorage?: AuthStorage): string | undefined {\n const envVar = PROVIDER_ENV_VAR[provider];\n const fromEnv = envVar ? process.env[envVar]?.trim() : undefined;\n if (fromEnv) return fromEnv;\n return authStorage?.getStoredApiKey(provider);\n}\n\n/**\n * Build a `MastraVoice` for an STT registry entry.\n * - `deepgram`: `DeepgramVoice` (Deepgram SDK; not OpenAI-compatible).\n * - everything else: `OpenAIVoice`, where `listeningModel.name` is the model id\n * and `options.baseURL` redirects OpenAI-compatible hosts at their endpoint.\n */\nfunction buildVoice(entry: STTModel, apiKey: string): VoiceListener {\n if (entry.resolver === 'deepgram') {\n return new DeepgramVoice({\n // `name` is typed for Deepgram's own ids; the model string is passed verbatim.\n listeningModel: { name: entry.model as never, apiKey },\n });\n }\n return new OpenAIVoice({\n // `name`/`options` are typed for OpenAI's own ids, but the underlying client\n // accepts any model string + baseURL — both are passed through verbatim.\n listeningModel: {\n name: entry.model as never,\n apiKey,\n ...(entry.resolver === 'openai-compatible' && entry.baseURL ? { options: { baseURL: entry.baseURL } } : {}),\n },\n });\n}\n\nexport interface TranscribeOptions {\n /** STT provider id (see `stt-registry.ts`). Defaults to the registry default. */\n provider?: string;\n /** Model id within the provider. Defaults to the provider's default model. */\n model?: string;\n authStorage?: AuthStorage;\n}\n\n/**\n * Transcribe recorded WAV audio to text via the configured cloud provider.\n * Throws VoiceCredentialError if no API key is available for the provider.\n */\nexport async function transcribeAudio(audio: Buffer, options: TranscribeOptions = {}): Promise<string> {\n const entry = resolveSTTModel(options.provider, options.model) ?? DEFAULT_STT_MODEL;\n const apiKey = resolveProviderApiKey(entry.provider, options.authStorage);\n if (!apiKey) {\n throw new VoiceCredentialError(entry.provider);\n }\n\n const voice = buildVoice(entry, apiKey);\n const result = await voice.listen(Readable.from(audio), { filetype: 'wav' });\n return normalizeTranscript(result);\n}\n\n/**\n * A reusable transcriber bound to one provider/model. Building the underlying\n * `MastraVoice` client once and reusing it across calls lets the HTTP client\n * keep its connection to the provider warm (keep-alive), which removes the\n * DNS + TLS handshake cost from every live-partial tick — the main reason the\n * first dictation streams in slowly while later ones feel instant.\n */\nexport interface ReusableTranscriber {\n transcribe(audio: Buffer): Promise<string>;\n}\n\n/**\n * Create a transcriber that reuses a single provider client across calls.\n * Resolves the provider/model and API key once up front (throwing\n * `VoiceCredentialError` if no key is available), so a session can build it on\n * start and call `transcribe()` per tick without re-resolving or reconnecting.\n */\nexport function createTranscriber(options: TranscribeOptions = {}): ReusableTranscriber {\n const entry = resolveSTTModel(options.provider, options.model) ?? DEFAULT_STT_MODEL;\n const apiKey = resolveProviderApiKey(entry.provider, options.authStorage);\n if (!apiKey) {\n throw new VoiceCredentialError(entry.provider);\n }\n const voice = buildVoice(entry, apiKey);\n return {\n async transcribe(audio: Buffer): Promise<string> {\n const result = await voice.listen(Readable.from(audio), { filetype: 'wav' });\n return normalizeTranscript(result);\n },\n };\n}\n\n/**\n * Check whether a cloud STT provider has a usable API key, without recording.\n */\nexport function hasProviderCredential(provider: string, authStorage?: AuthStorage): boolean {\n return resolveProviderApiKey(provider, authStorage) !== undefined;\n}\n\n/**\n * `MastraVoice.listen()` returns a string for OpenAI-shaped transcription, but\n * other provider subclasses may return `{ transcript }` — normalize both.\n */\nfunction normalizeTranscript(result: unknown): string {\n if (typeof result === 'string') return result.trim();\n if (result && typeof result === 'object' && 'transcript' in result) {\n const transcript = (result as { transcript?: unknown }).transcript;\n if (typeof transcript === 'string') return transcript.trim();\n }\n return '';\n}\n","import { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport type { VoiceEngine, VoiceSettings } from '@mastra/code-sdk/onboarding/settings';\nimport {\n defaultModelForProvider,\n resolveSTTModel,\n sttModelsForProvider,\n sttProviders,\n} from '@mastra/code-sdk/voice/stt-registry';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { PermissionGuidance } from '../voice/engines/types.js';\nimport { openMacSettings } from '../voice/native/open-settings.js';\nimport { hasProviderCredential } from '../voice/transcribe.js';\nimport type { SlashCommandContext } from './types.js';\n\n/**\n * `/voice` — manage push-to-talk voice input.\n *\n * Subcommands:\n * /voice Interactive menu (toggle / engine / provider / model / status)\n * /voice on|off Quick toggle (back-compat)\n * /voice status Print the current engine, provider/model, and readiness\n */\nexport async function handleVoiceCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n const controller = ctx.state.voiceController;\n if (!controller) {\n ctx.showError('Voice input is unavailable.');\n return;\n }\n\n const arg = args[0]?.toLowerCase();\n if (arg === 'on' || arg === 'off') {\n await setEnabled(ctx, arg === 'on');\n return;\n }\n if (arg === 'status') {\n await showStatus(ctx);\n return;\n }\n\n await runMenu(ctx);\n}\n\n/** Persist a settings patch and re-apply it to the live controller. */\nfunction applyVoiceSettings(ctx: SlashCommandContext, patch: Partial<VoiceSettings>): VoiceSettings {\n const settings = loadSettings();\n settings.voice = { ...settings.voice, ...patch };\n try {\n saveSettings(settings);\n } catch {\n // Persisting is best-effort; the in-session change still applies.\n }\n ctx.state.voiceController?.reconfigure(settings.voice);\n return settings.voice;\n}\n\nasync function setEnabled(ctx: SlashCommandContext, enable: boolean): Promise<void> {\n const controller = ctx.state.voiceController!;\n const currentlyEnabled = controller.isEnabled();\n if (enable === currentlyEnabled) {\n ctx.showInfo(`Voice input is already ${enable ? 'on' : 'off'}.`);\n return;\n }\n const nowEnabled = controller.toggle();\n applyVoiceSettings(ctx, { enabled: nowEnabled });\n // After turning voice on, proactively walk the user through any permissions\n // the active engine needs — don't make them discover the requirement by\n // failing to dictate.\n if (nowEnabled) await guidePermissions(ctx);\n}\n\n/**\n * Check the active engine's permission state and guide the user through fixing\n * it. For macOS native this means offering to open the exact Privacy & Security\n * pane when access is blocked, or explaining the first-run prompt when it isn't\n * granted yet. No-op for engines that need no permissions (cloud).\n */\nasync function guidePermissions(ctx: SlashCommandContext): Promise<void> {\n const controller = ctx.state.voiceController;\n const guidance = await controller?.permissionGuidance();\n if (!guidance || guidance.state === 'ok') return;\n await presentGuidance(ctx, guidance);\n}\n\nasync function presentGuidance(ctx: SlashCommandContext, guidance: PermissionGuidance): Promise<void> {\n const lines = [guidance.summary, ...(guidance.steps ?? []).map((step, i) => ` ${i + 1}. ${step}`)];\n\n // When we can jump straight to the right settings pane, offer to do it.\n if (guidance.settingsUrl && process.platform === 'darwin') {\n const open = guidance.actionLabel ?? 'Open System Settings';\n const choice = await askModalQuestion(ctx.state.ui, {\n question: lines.join('\\n'),\n options: [\n { label: open, description: 'Opens the exact settings pane for you' },\n { label: 'Not now', description: \"I'll do it later\" },\n ],\n });\n if (choice === open) {\n const opened = await openMacSettings(guidance.settingsUrl);\n ctx.showInfo(\n opened\n ? 'Opened System Settings. Turn on the toggle for your terminal, then fully quit and reopen it.'\n : `Open this URL to fix it: ${guidance.settingsUrl}`,\n );\n }\n return;\n }\n\n // No actionable deep link (e.g. will prompt on first use) — just explain.\n ctx.showInfo(lines.join('\\n'));\n}\n\nfunction describeReadiness(voice: VoiceSettings): string {\n if (voice.engine === 'macos-native') {\n return process.platform === 'darwin'\n ? 'macOS native (on-device). First use prompts for Speech Recognition + Microphone access.'\n : 'macOS native is only available on macOS — switch to a cloud provider.';\n }\n const entry = resolveSTTModel(voice.provider, voice.model);\n const hasKey = hasProviderCredential(entry.provider);\n const keyNote = hasKey ? 'API key found.' : `No API key for ${entry.provider} — add one via /api-keys.`;\n return `cloud · ${entry.provider}/${entry.model} (${entry.label}). ${keyNote}`;\n}\n\n/** Short engine label for the status header. */\nfunction engineLabel(voice: VoiceSettings): string {\n if (voice.engine === 'macos-native') return 'macOS native (on-device)';\n const entry = resolveSTTModel(voice.provider, voice.model);\n return `cloud · ${entry.provider}/${entry.model}`;\n}\n\nasync function showStatus(ctx: SlashCommandContext): Promise<void> {\n const voice = loadSettings().voice;\n const enabled = ctx.state.voiceController?.isEnabled() ? 'on' : 'off';\n\n const lines = [`Voice input: ${enabled}`, ` Engine: ${engineLabel(voice)}`];\n\n if (voice.engine === 'cloud') {\n const entry = resolveSTTModel(voice.provider, voice.model);\n lines.push(` API key: ${hasProviderCredential(entry.provider) ? 'found' : `missing — add one via /api-keys`}`);\n }\n\n // Deeper async preflight (e.g. native permission/toolchain probe) when the\n // engine supports it, so /voice status reports real readiness, not a static hint.\n const problem = await ctx.state.voiceController?.verifyReady();\n if (problem) {\n lines.push(` Status: ⚠ action needed`, ...problem.split('\\n').map(l => ` ${l}`));\n } else if (voice.engine === 'macos-native') {\n lines.push(` Status: ✓ ready — hold space to dictate (macOS may prompt on first use)`);\n } else {\n lines.push(` Status: ✓ ready — hold space to dictate`);\n }\n\n ctx.showInfo(lines.join('\\n'));\n}\n\nasync function runMenu(ctx: SlashCommandContext): Promise<void> {\n const voice = loadSettings().voice;\n const enabled = ctx.state.voiceController?.isEnabled() ?? voice.enabled;\n\n const choice = await askModalQuestion(ctx.state.ui, {\n question: 'Voice input settings',\n options: [\n { label: enabled ? 'Turn off' : 'Turn on', description: 'Toggle push-to-talk voice input' },\n { label: 'Engine', description: `Currently: ${voice.engine}` },\n { label: 'Provider', description: `Cloud provider (currently: ${voice.provider})` },\n { label: 'Model', description: `Cloud model (currently: ${voice.model ?? 'default'})` },\n { label: 'Status', description: 'Show engine, provider/model, and readiness' },\n ],\n });\n if (!choice) return;\n\n switch (choice) {\n case enabled ? 'Turn off' : 'Turn on':\n await setEnabled(ctx, !enabled);\n return;\n case 'Engine':\n await chooseEngine(ctx);\n return;\n case 'Provider':\n await chooseProvider(ctx);\n return;\n case 'Model':\n await chooseModel(ctx);\n return;\n case 'Status':\n await showStatus(ctx);\n return;\n }\n}\n\nasync function chooseEngine(ctx: SlashCommandContext): Promise<void> {\n const macOption = process.platform === 'darwin' ? 'macOS native (on-device)' : 'macOS native (macOS only)';\n const choice = await askModalQuestion(ctx.state.ui, {\n question: 'Choose STT engine',\n options: [\n { label: macOption, description: 'Free, offline, low-latency. Requires macOS.' },\n { label: 'Cloud provider', description: 'Use a cloud transcription provider.' },\n ],\n });\n if (!choice) return;\n\n const engine: VoiceEngine = choice.startsWith('macOS') ? 'macos-native' : 'cloud';\n if (engine === 'macos-native' && process.platform !== 'darwin') {\n ctx.showError('macOS native STT is only available on macOS. Pick a cloud provider instead.');\n return;\n }\n const voice = applyVoiceSettings(ctx, { engine });\n ctx.showInfo(`Voice engine set to ${engine}. ${describeReadiness(voice)}`);\n // If they switched to the native engine while voice is on, guide permissions now.\n if (engine === 'macos-native' && ctx.state.voiceController?.isEnabled()) {\n await guidePermissions(ctx);\n }\n}\n\nasync function chooseProvider(ctx: SlashCommandContext): Promise<void> {\n const providers = sttProviders();\n const choice = await askModalQuestion(ctx.state.ui, {\n question: 'Choose cloud STT provider',\n options: providers.map(provider => {\n const def = defaultModelForProvider(provider);\n return { label: provider, description: def ? def.label : undefined };\n }),\n });\n if (!choice) return;\n\n // Switching provider resets the model to that provider's default.\n const def = defaultModelForProvider(choice);\n const voice = applyVoiceSettings(ctx, { engine: 'cloud', provider: choice, model: def?.model });\n ctx.showInfo(`Voice provider set to ${choice}. ${describeReadiness(voice)}`);\n}\n\nasync function chooseModel(ctx: SlashCommandContext): Promise<void> {\n const voice = loadSettings().voice;\n const models = sttModelsForProvider(voice.provider);\n if (models.length === 0) {\n ctx.showError(`No STT models known for provider ${voice.provider}. Pick a provider first.`);\n return;\n }\n const choice = await askModalQuestion(ctx.state.ui, {\n question: `Choose model for ${voice.provider}`,\n options: models.map(m => ({ label: m.model, description: m.label })),\n });\n if (!choice) return;\n\n const updated = applyVoiceSettings(ctx, { engine: 'cloud', model: choice });\n ctx.showInfo(`Voice model set to ${updated.model}. ${describeReadiness(updated)}`);\n}\n","/**\n * Thinking level settings component.\n * Simple selector for reasoning depth levels.\n *\n * Changes apply immediately — Esc closes the panel.\n */\n\nimport { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SelectItem, Focusable } from '@earendil-works/pi-tui';\nimport { theme, getSelectListTheme } from '../theme.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ThinkingSettingsCallbacks {\n onLevelChange: (level: string) => void;\n onClose: () => void;\n}\n\n// =============================================================================\n// Thinking Levels\n// =============================================================================\n\nexport type ThinkingLevelId = 'off' | 'low' | 'medium' | 'high' | 'xhigh';\n\nexport interface ThinkingLevelOption {\n id: ThinkingLevelId;\n label: string;\n providerValue: 'none' | 'low' | 'medium' | 'high' | 'xhigh';\n description: string;\n}\n\nconst BASE_THINKING_LEVELS: ThinkingLevelOption[] = [\n { id: 'off', label: 'Off', providerValue: 'none', description: 'Reasoning disabled' },\n { id: 'low', label: 'Low', providerValue: 'low', description: 'Light reasoning' },\n { id: 'medium', label: 'Medium', providerValue: 'medium', description: 'Balanced reasoning' },\n { id: 'high', label: 'High', providerValue: 'high', description: 'Deep reasoning' },\n { id: 'xhigh', label: 'Very High', providerValue: 'xhigh', description: 'Maximum reasoning depth' },\n];\n\nfunction isOpenAIModel(modelId: string): boolean {\n return modelId.startsWith('openai/');\n}\n\nexport function getThinkingLevelsForModel(modelId: string): ThinkingLevelOption[] {\n if (!isOpenAIModel(modelId)) {\n return [...BASE_THINKING_LEVELS];\n }\n\n return BASE_THINKING_LEVELS.map(level => ({\n ...level,\n label: level.providerValue,\n }));\n}\n\nexport const THINKING_LEVELS = getThinkingLevelsForModel('');\n\nexport function getThinkingLevelForModel(modelId: string, levelId: string): ThinkingLevelOption {\n return (\n getThinkingLevelsForModel(modelId).find(level => level.id === levelId) ?? getThinkingLevelsForModel(modelId)[0]!\n );\n}\n\n// =============================================================================\n// Thinking Settings Component\n// =============================================================================\n\nexport class ThinkingSettingsComponent extends Box implements Focusable {\n private selectList: SelectList;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(currentLevel: string, callbacks: ThinkingSettingsCallbacks) {\n super(2, 1, (text: string) => theme.bg('overlayBg', text));\n\n // Title\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Thinking Level')), 0, 0));\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', 'Extended thinking for Anthropic models'), 0, 0));\n this.addChild(new Spacer(1));\n\n // Build items\n const items: SelectItem[] = THINKING_LEVELS.map(level => ({\n value: level.id,\n label: ` ${level.label} ${theme.fg('dim', level.description)}`,\n }));\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n\n // Pre-select current level\n const currentIndex = THINKING_LEVELS.findIndex(l => l.id === currentLevel);\n if (currentIndex !== -1) {\n this.selectList.setSelectedIndex(currentIndex);\n }\n\n this.selectList.onSelect = (item: SelectItem) => {\n callbacks.onLevelChange(item.value);\n callbacks.onClose();\n };\n this.selectList.onCancel = callbacks.onClose;\n\n this.addChild(this.selectList);\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('dim', ' Enter to select · Esc to close'), 0, 0));\n }\n\n handleInput(data: string): void {\n this.selectList.handleInput(data);\n }\n}\n","import { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SelectItem } from '@earendil-works/pi-tui';\n\nimport type { ThinkingLevelSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport {\n THINKING_LEVELS,\n getThinkingLevelForModel,\n getThinkingLevelsForModel,\n} from '../components/thinking-settings.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { theme, getSelectListTheme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\n/** Models that support reasoning effort. */\nfunction supportsThinking(modelId: string): boolean {\n return modelId.startsWith('openai/');\n}\n\nfunction getThinkingStatusLine(modelId: string, levelId: string): string {\n const level = getThinkingLevelForModel(modelId, levelId);\n return `Thinking: ${level.label}`;\n}\n\nfunction isThinkingLevelSetting(level: string): level is ThinkingLevelSetting {\n return THINKING_LEVELS.some(option => option.id === level);\n}\n\nfunction persistGlobalThinkingLevel(level: ThinkingLevelSetting): void {\n const settings = loadSettings();\n settings.preferences.thinkingLevel = level;\n saveSettings(settings);\n}\n\nfunction getModelNote(ctx: SlashCommandContext): string | null {\n const modelId = ctx.state.session.model.get() ?? '';\n if (!modelId) return 'No model selected.';\n if (!supportsThinking(modelId)) {\n return `Warning: current model (${modelId}) may not support reasoning effort. Setting will be saved but may not take effect.`;\n }\n return null;\n}\n\nexport async function handleThinkCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n const currentLevel = ((ctx.state.session.state.get() as any)?.thinkingLevel ?? 'off') as string;\n const modelId = ctx.state.session.model.get() ?? '';\n const thinkingLevels = getThinkingLevelsForModel(modelId);\n const arg = args[0]?.toLowerCase();\n\n if (arg === 'status') {\n ctx.showInfo(getThinkingStatusLine(modelId, currentLevel));\n return;\n }\n\n // Direct level argument: /think high\n if (arg) {\n const selected = thinkingLevels.find(l => l.id === arg);\n if (!selected) {\n ctx.showInfo(\n `Invalid thinking level: ${arg}. Use one of: ${THINKING_LEVELS.map(l => l.id).join(', ')} or 'status'.`,\n );\n return;\n }\n const note = getModelNote(ctx);\n await ctx.state.session.state.set({ thinkingLevel: selected.id } as any);\n persistGlobalThinkingLevel(selected.id);\n ctx.showInfo(getThinkingStatusLine(modelId, selected.id) + (note ? ` (${note})` : ''));\n return;\n }\n\n // No argument: show inline selector\n const items: SelectItem[] = thinkingLevels.map(l => ({\n value: l.id,\n label: ` ${l.label} ${theme.fg('dim', l.description)}${l.id === currentLevel ? theme.fg('dim', ' (current)') : ''}`,\n }));\n\n const modelNote = getModelNote(ctx);\n\n return new Promise<void>(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', 'Thinking Level')), 0, 0));\n container.addChild(new Spacer(1));\n if (modelNote) {\n container.addChild(new Text(theme.fg('warning', modelNote), 0, 0));\n container.addChild(new Spacer(1));\n }\n\n const selectList = new SelectList(items, items.length, getSelectListTheme());\n\n selectList.onSelect = async (item: SelectItem) => {\n ctx.state.ui.hideOverlay();\n const selectedLevel = item.value;\n if (!isThinkingLevelSetting(selectedLevel)) {\n resolve();\n return;\n }\n\n try {\n await ctx.state.session.state.set({ thinkingLevel: selectedLevel } as any);\n persistGlobalThinkingLevel(selectedLevel);\n const selectedLabel = getThinkingLevelForModel(modelId, selectedLevel).label;\n ctx.showInfo(`Thinking → ${selectedLevel === currentLevel ? `${selectedLabel} (unchanged)` : selectedLabel}`);\n } catch {\n // Keep cancel behavior silent.\n } finally {\n resolve();\n }\n };\n\n selectList.onCancel = () => {\n ctx.state.ui.hideOverlay();\n resolve();\n };\n\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc cancel'), 0, 0));\n\n // Pre-select current level (after adding to container, matching models-pack pattern)\n const currentIdx = thinkingLevels.findIndex(l => l.id === currentLevel);\n if (currentIdx > 0) selectList.setSelectedIndex(currentIdx);\n\n const modal = container as Box & { handleInput: (data: string) => void };\n modal.handleInput = (data: string) => selectList.handleInput(data);\n showModalOverlay(ctx.state.ui, modal, { maxHeight: '60%' });\n });\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport async function handlePermissionsCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n if (args[0] === 'set' && args.length >= 3) {\n const category = args[1] as any;\n const policy = args[2] as any;\n const validCategories = ['read', 'edit', 'execute', 'mcp'];\n const validPolicies = ['allow', 'ask', 'deny'];\n if (!validCategories.includes(category)) {\n ctx.showInfo(`Invalid category: ${category}. Must be one of: ${validCategories.join(', ')}`);\n return;\n }\n if (!validPolicies.includes(policy)) {\n ctx.showInfo(`Invalid policy: ${policy}. Must be one of: ${validPolicies.join(', ')}`);\n return;\n }\n await ctx.state.session.permissions.setForCategory({ category, policy });\n ctx.showInfo(`Set ${category} policy to: ${policy}`);\n return;\n }\n await showPermissions(ctx);\n}\n\nasync function showPermissions(ctx: SlashCommandContext): Promise<void> {\n const { TOOL_CATEGORIES, getToolsForCategory } = await import('@mastra/code-sdk/permissions');\n const rules = ctx.state.session.permissions.getRules();\n const grants = ctx.state.session.getGrants();\n const isYolo = (ctx.state.session.state.get() as any)?.yolo === true;\n\n const lines: string[] = [];\n lines.push('Tool Approval Permissions');\n lines.push('─'.repeat(40));\n\n if (isYolo) {\n lines.push('');\n lines.push('⚡ YOLO mode is ON — all tools are auto-approved');\n lines.push(' Use /yolo to toggle off');\n }\n\n lines.push('');\n lines.push('Category Policies:');\n for (const [cat, meta] of Object.entries(TOOL_CATEGORIES)) {\n const policy = rules.categories[cat as keyof typeof rules.categories] || 'ask';\n const sessionGranted = grants.categories.includes(cat as any);\n const tools = getToolsForCategory(cat as any);\n const status = sessionGranted ? `${policy} (session: always allow)` : policy;\n lines.push(` ${meta.label.padEnd(12)} ${status.padEnd(16)} tools: ${tools.join(', ')}`);\n }\n\n if (Object.keys(rules.tools).length > 0) {\n lines.push('');\n lines.push('Per-tool Overrides:');\n for (const [tool, policy] of Object.entries(rules.tools)) {\n lines.push(` ${tool.padEnd(24)} ${policy}`);\n }\n }\n\n if (grants.categories.length > 0 || grants.tools.length > 0) {\n lines.push('');\n lines.push('Session Grants (reset on restart):');\n if (grants.categories.length > 0) {\n lines.push(` Categories: ${grants.categories.join(', ')}`);\n }\n if (grants.tools.length > 0) {\n lines.push(` Tools: ${grants.tools.join(', ')}`);\n }\n }\n\n lines.push('');\n lines.push('Commands:');\n lines.push(' /permissions set <category> <allow|ask|deny>');\n lines.push(' /yolo — toggle auto-approve all tools');\n\n ctx.showInfo(lines.join('\\n'));\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport async function handleNameCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const title = args.join(' ').trim();\n if (!title) {\n ctx.showInfo('Usage: /name <title>');\n return;\n }\n if (!ctx.state.session.thread.getId()) {\n ctx.showInfo('No active thread. Send a message first.');\n return;\n }\n await ctx.state.session.thread.rename({ title });\n ctx.showInfo(`Thread renamed to: ${title}`);\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport function handleExitCommand(ctx: SlashCommandContext): void {\n ctx.stop();\n process.exit(0);\n}\n","import { VALID_EVENTS } from '@mastra/code-sdk/hooks/index';\nimport type { SlashCommandContext } from './types.js';\n\nexport function handleHooksCommand(ctx: SlashCommandContext, args: string[]): void {\n const hm = ctx.hookManager;\n if (!hm) {\n ctx.showInfo('Hooks system not initialized.');\n return;\n }\n\n const subcommand = args[0];\n if (subcommand === 'reload') {\n hm.reload();\n ctx.showInfo('Hooks config reloaded.');\n return;\n }\n\n const paths = hm.getConfigPaths();\n\n if (!hm.hasHooks()) {\n ctx.showInfo(\n `No hooks configured.\\n\\n` +\n `Add hooks to:\\n` +\n ` ${paths.project} (project)\\n` +\n ` ${paths.global} (global)\\n\\n` +\n `Example hooks.json:\\n` +\n ` {\\n` +\n ` \"PreToolUse\": [{\\n` +\n ` \"type\": \"command\",\\n` +\n ` \"command\": \"echo 'tool called'\",\\n` +\n ` \"matcher\": { \"tool_name\": \"execute_command\" }\\n` +\n ` }]\\n` +\n ` }`,\n );\n return;\n }\n\n const hookConfig = hm.getConfig();\n const lines: string[] = [`Hooks Configuration:`];\n lines.push(` Project: ${paths.project}`);\n lines.push(` Global: ${paths.global}`);\n lines.push('');\n\n const eventNames = VALID_EVENTS;\n\n for (const event of eventNames) {\n const hooks = hookConfig[event];\n if (hooks && hooks.length > 0) {\n lines.push(` ${event} (${hooks.length} hook${hooks.length > 1 ? 's' : ''}):`);\n for (const hook of hooks) {\n const matcherStr = hook.matcher?.tool_name ? ` [tool: ${hook.matcher.tool_name}]` : '';\n const desc = hook.description ? ` - ${hook.description}` : '';\n lines.push(` ${hook.command}${matcherStr}${desc}`);\n }\n }\n }\n\n lines.push('');\n lines.push(` /hooks reload - Reload config from disk`);\n\n ctx.showInfo(lines.join('\\n'));\n}\n","/**\n * Decode a terminal input sequence into a single-character shortcut.\n *\n * pi-tui pushes the Kitty keyboard protocol when supported, so printable keys\n * arrive as CSI-u sequences (`\\x1b[121u` for `y`) instead of raw bytes —\n * leaving `data === 'y'` style comparisons silently dropping every press.\n * Falls back to xterm modifyOtherKeys (`\\x1b[27;<mod>;<cp>~`) for terminals\n * without Kitty support.\n *\n * Single-character `parseKey` results pass through unchanged — letters,\n * digits, and unmodified punctuation (`y`, `?`, `0`). `Shift+<letter>`\n * decodes to the uppercase letter so `Y`-vs-`y` shortcuts survive both\n * encodings. Shifted digits and symbols (`shift+1`, `shift+!`, etc.) return\n * `undefined` because pi-tui's `parseKey` does not collapse them to a\n * single shifted glyph. Ctrl/Alt/Super and non-printable keys return\n * `undefined` so modifier-bearing variants never alias a shortcut.\n *\n * Callers that want to react to space or other keys whose `parseKey` name\n * is multi-character (`space`, `enter`, `tab`, function keys) should use\n * pi-tui's `matchesKey` directly.\n */\nimport { parseKey } from '@earendil-works/pi-tui';\n\nconst SHIFT_LETTER_RE = /^shift\\+([a-z])$/;\n\nexport function decodePrintableShortcut(data: string): string | undefined {\n const key = parseKey(data);\n if (key === undefined) return undefined;\n if (key.length === 1) return key;\n const shifted = SHIFT_LETTER_RE.exec(key);\n if (shifted) return shifted[1]!.toUpperCase();\n return undefined;\n}\n","/**\n * MCP server selector component for managing MCP server connections.\n * Uses pi-tui overlay pattern with navigation.\n */\n\nimport { Box, Container, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, TUI } from '@earendil-works/pi-tui';\nimport type { McpServerStatus, McpSkippedServer } from '@mastra/code-sdk/mcp/types';\nimport chalk from 'chalk';\nimport { decodePrintableShortcut } from '../key-input.js';\nimport { theme } from '../theme.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface McpSelectorOptions {\n /** TUI instance for rendering */\n tui: TUI;\n /** Server statuses */\n statuses: McpServerStatus[];\n /** Skipped servers */\n skipped: McpSkippedServer[];\n /** Config file paths for display */\n configPaths: { project: string; global: string; claude: string };\n /** Get current statuses (for polling during initial connect) */\n getStatuses: () => { statuses: McpServerStatus[]; skipped: McpSkippedServer[] };\n /** Callback to reload all servers — should return fresh statuses/skipped */\n onReloadAll: () => Promise<{ statuses: McpServerStatus[]; skipped: McpSkippedServer[] }>;\n /** Callback to reconnect a single server by name — returns updated status */\n onReconnectServer: (name: string) => Promise<McpServerStatus>;\n /** Callback to run the OAuth flow for a single server by name — returns updated status */\n onAuthenticateServer: (name: string) => Promise<McpServerStatus>;\n /** Callback to cancel a pending OAuth flow for a server by name — resolves true if one was cancelled */\n onCancelAuthenticateServer: (name: string) => Promise<boolean>;\n /** Get captured stderr logs for a server */\n getServerLogs: (name: string) => string[];\n /** Show an info message in the chat area */\n showInfo: (msg: string) => void;\n /** Callback when selector is dismissed */\n onClose: () => void;\n}\n\n// =============================================================================\n// Sub-menu actions\n// =============================================================================\n\ninterface ServerAction {\n label: string;\n key: string;\n}\n\nconst CONNECTED_ACTIONS: ServerAction[] = [\n { label: 'View tools', key: 'tools' },\n { label: 'View logs', key: 'logs' },\n { label: 'Reconnect', key: 'reconnect' },\n];\n\nconst FAILED_ACTIONS: ServerAction[] = [\n { label: 'View error', key: 'error' },\n { label: 'View logs', key: 'logs' },\n { label: 'Reconnect', key: 'reconnect' },\n];\n\nconst NEEDS_AUTH_ACTIONS: ServerAction[] = [\n { label: 'Authenticate', key: 'authenticate' },\n { label: 'View error', key: 'error' },\n { label: 'View logs', key: 'logs' },\n { label: 'Reconnect', key: 'reconnect' },\n];\n\nconst CONNECTING_ACTIONS: ServerAction[] = [{ label: 'Waiting for connection...', key: 'none' }];\n\nconst AUTHENTICATING_ACTIONS: ServerAction[] = [{ label: 'Cancel authentication', key: 'cancel-authenticate' }];\n\n// =============================================================================\n// McpSelectorComponent\n// =============================================================================\n\nexport class McpSelectorComponent extends Box implements Focusable {\n private listContainer!: Container;\n private statuses: McpServerStatus[];\n private skipped: McpSkippedServer[];\n private selectedIndex = 0;\n private getStatusesCallback: McpSelectorOptions['getStatuses'];\n private onReloadAllCallback: McpSelectorOptions['onReloadAll'];\n private onReconnectServerCallback: McpSelectorOptions['onReconnectServer'];\n private onAuthenticateServerCallback: McpSelectorOptions['onAuthenticateServer'];\n private onCancelAuthenticateServerCallback: McpSelectorOptions['onCancelAuthenticateServer'];\n private getServerLogsCallback: McpSelectorOptions['getServerLogs'];\n private showInfoCallback: McpSelectorOptions['showInfo'];\n private onCloseCallback: () => void;\n private tui: TUI;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n // Sub-menu state\n private subMenuOpen = false;\n private subMenuIndex = 0;\n private subMenuActions: ServerAction[] = [];\n\n // Detail view state (tool list / error display)\n private _detailView = false;\n\n // Loading state during reload\n private _reloading = false;\n\n // Names of servers with an in-flight OAuth flow (so their sub-menu offers a\n // cancel path while they show as connecting).\n private _authenticating = new Set<string>();\n\n // Names of servers the user is actively cancelling. The authenticate flow\n // resolves with a failed status when cancelled, so we track this to suppress\n // the misleading \"Failed to authenticate\" toast on a deliberate cancel.\n private _cancelling = new Set<string>();\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(options: McpSelectorOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.tui = options.tui;\n this.statuses = options.statuses;\n this.skipped = options.skipped;\n this.getStatusesCallback = options.getStatuses;\n this.onReloadAllCallback = options.onReloadAll;\n this.onReconnectServerCallback = options.onReconnectServer;\n this.onAuthenticateServerCallback = options.onAuthenticateServer;\n this.onCancelAuthenticateServerCallback = options.onCancelAuthenticateServer;\n this.getServerLogsCallback = options.getServerLogs;\n this.showInfoCallback = options.showInfo;\n this.onCloseCallback = options.onClose;\n\n this.buildUI();\n this.startPollingIfNeeded();\n }\n\n private buildUI(): void {\n // Title\n const titleText = chalk.bgHex('#16c858').white.bold(' Manage MCP servers ');\n this.addChild(new Text(titleText, 0, 0));\n this.addChild(new Spacer(1));\n\n // List container (includes server count + server list)\n this.listContainer = new Container();\n this.addChild(this.listContainer);\n\n // Footer spacer + hints\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', '↑↓ navigate • Enter select • r reload all • Esc close'), 0, 0));\n\n // Initial render\n this.updateList();\n }\n\n private getTotalItems(): number {\n return this.statuses.length + this.skipped.length;\n }\n\n private updateList(): void {\n this.listContainer.clear();\n\n // Server count line\n const total = this.getTotalItems();\n const countLabel = this._reloading\n ? `${total} server${total !== 1 ? 's' : ''} — reconnecting...`\n : `${total} server${total !== 1 ? 's' : ''}`;\n this.listContainer.addChild(new Text(theme.fg(this._reloading ? 'warning' : 'muted', countLabel), 0, 0));\n this.listContainer.addChild(new Spacer(1));\n\n const totalItems = this.getTotalItems();\n\n for (let i = 0; i < this.statuses.length; i++) {\n const status = this.statuses[i]!;\n const isSelected = i === this.selectedIndex && !this.subMenuOpen;\n\n let icon: string;\n let stateText: string;\n if (this._reloading) {\n icon = theme.fg('warning', '⟳');\n stateText = theme.fg('warning', 'reconnecting...');\n } else if (this.isAuthenticating(status)) {\n // A flow is in flight for this server. This is authoritative even if a\n // polled status refresh from the manager no longer reports `connecting`,\n // so the \"Enter to cancel\" affordance never disappears mid-flow. The\n // manager-owned `authenticating` flag also survives close/reopen of the\n // selector, when the local set has been discarded with the old instance.\n icon = theme.fg('warning', '⟳');\n stateText = theme.fg('warning', 'authenticating — Enter to cancel');\n } else if (status.connecting) {\n icon = theme.fg('warning', '⟳');\n stateText = theme.fg('warning', 'connecting...');\n } else if (status.connected) {\n icon = theme.fg('success', '✔');\n stateText = theme.fg('success', 'connected');\n } else if (status.needsAuth) {\n icon = theme.fg('warning', '⚠');\n stateText = theme.fg('warning', 'needs auth');\n } else {\n icon = theme.fg('error', '✗');\n stateText = theme.fg('error', 'failed');\n }\n\n const cursor = isSelected ? theme.fg('accent', '› ') : ' ';\n const name = isSelected ? theme.bold(theme.fg('accent', status.name)) : status.name;\n const transport = theme.fg('muted', `[${status.transport}]`);\n const toolInfo =\n !this._reloading && status.toolCount > 0 ? theme.fg('muted', ` · ${status.toolCount} tools`) : '';\n\n this.listContainer.addChild(new Text(`${cursor}${icon} ${name} ${transport} ${stateText}${toolInfo}`, 0, 0));\n\n // Sub-menu for this server\n if (i === this.selectedIndex && this.subMenuOpen) {\n for (let j = 0; j < this.subMenuActions.length; j++) {\n const action = this.subMenuActions[j]!;\n const actionSelected = j === this.subMenuIndex;\n const actionCursor = actionSelected ? theme.fg('accent', ' › ') : ' ';\n const actionText = actionSelected\n ? theme.bold(theme.fg('accent', action.label))\n : theme.fg('muted', action.label);\n this.listContainer.addChild(new Text(`${actionCursor}${actionText}`, 0, 0));\n }\n }\n }\n\n // Skipped servers\n if (this.skipped.length > 0) {\n this.listContainer.addChild(new Spacer(1));\n this.listContainer.addChild(new Text(theme.fg('muted', 'Skipped:'), 0, 0));\n for (let i = 0; i < this.skipped.length; i++) {\n const s = this.skipped[i]!;\n const idx = this.statuses.length + i;\n const isSelected = idx === this.selectedIndex && !this.subMenuOpen;\n const cursor = isSelected ? theme.fg('accent', '› ') : ' ';\n const name = isSelected ? theme.bold(theme.fg('accent', s.name)) : s.name;\n this.listContainer.addChild(\n new Text(`${cursor}${theme.fg('warning', '⊘')} ${name} — ${theme.fg('muted', s.reason)}`, 0, 0),\n );\n }\n }\n\n // Empty state\n if (totalItems === 0) {\n this.listContainer.addChild(new Text(theme.fg('muted', 'No MCP servers configured'), 0, 0));\n }\n\n this.tui.requestRender();\n }\n\n /**\n * Whether an OAuth flow is in flight for this server. True if either the local\n * set (this selector instance started the flow) or the manager-owned status\n * flag (survives close/reopen) says so.\n */\n private isAuthenticating(status: McpServerStatus): boolean {\n return status.authenticating === true || this._authenticating.has(status.name);\n }\n\n private isBusy(): boolean {\n return this.statuses.some(s => s.connecting || this.isAuthenticating(s)) || this._authenticating.size > 0;\n }\n\n private startPollingIfNeeded(): void {\n if (this.pollTimer) return;\n if (!this.isBusy()) return;\n\n this.pollTimer = setInterval(() => {\n // Don't refresh while in a detail view or mid-reload\n if (this._detailView || this._reloading) return;\n\n const fresh = this.getStatusesCallback();\n this.statuses = fresh.statuses;\n this.skipped = fresh.skipped;\n\n // Clamp index\n const total = this.getTotalItems();\n if (this.selectedIndex >= total) {\n this.selectedIndex = Math.max(0, total - 1);\n }\n\n this.updateList();\n\n // Stop polling only when nothing is connecting and no auth flow is pending\n if (!this.isBusy()) {\n this.stopPolling();\n }\n }, 500);\n }\n\n private stopPolling(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /** Clean up resources when component is removed. */\n dispose(): void {\n this.stopPolling();\n }\n\n handleInput(data: string): void {\n const kb = getKeybindings();\n\n // During reload, only allow closing the selector\n if (this._reloading) {\n if (kb.matches(data, 'tui.select.cancel')) {\n this.onCloseCallback();\n }\n return;\n }\n const totalItems = this.getTotalItems();\n\n // Detail view (tool list or error) — Esc goes back to server list\n if (this._detailView) {\n if (kb.matches(data, 'tui.select.cancel')) {\n this._detailView = false;\n this.updateList();\n }\n return;\n }\n\n if (this.subMenuOpen) {\n this.handleSubMenuInput(data, kb);\n return;\n }\n\n // Up arrow\n if (kb.matches(data, 'tui.select.up')) {\n if (totalItems === 0) return;\n this.selectedIndex = this.selectedIndex === 0 ? totalItems - 1 : this.selectedIndex - 1;\n this.updateList();\n }\n // Down arrow\n else if (kb.matches(data, 'tui.select.down')) {\n if (totalItems === 0) return;\n this.selectedIndex = this.selectedIndex === totalItems - 1 ? 0 : this.selectedIndex + 1;\n this.updateList();\n }\n // Enter — open sub-menu for the selected server\n else if (kb.matches(data, 'tui.select.confirm')) {\n if (this.selectedIndex < this.statuses.length) {\n this.openSubMenu();\n }\n // Skipped servers have no sub-menu actions\n }\n // 'r' — reload all servers\n else if (decodePrintableShortcut(data) === 'r') {\n this.doReloadAll();\n }\n // Escape or Ctrl+C\n else if (kb.matches(data, 'tui.select.cancel')) {\n this.stopPolling();\n this.onCloseCallback();\n }\n }\n\n private openSubMenu(): void {\n const status = this.statuses[this.selectedIndex];\n if (!status) return;\n\n if (this.isAuthenticating(status)) {\n // A server mid-OAuth shows a cancel path (the user may have closed the\n // browser). Authoritative even if a polled refresh cleared `connecting`,\n // and after a close/reopen via the manager-owned status flag.\n this.subMenuActions = AUTHENTICATING_ACTIONS;\n } else if (status.connecting) {\n this.subMenuActions = CONNECTING_ACTIONS;\n } else if (status.connected) {\n this.subMenuActions = CONNECTED_ACTIONS;\n } else if (status.needsAuth) {\n this.subMenuActions = NEEDS_AUTH_ACTIONS;\n } else {\n this.subMenuActions = FAILED_ACTIONS;\n }\n\n this.subMenuOpen = true;\n this.subMenuIndex = 0;\n this.updateList();\n }\n\n private handleSubMenuInput(data: string, kb: ReturnType<typeof getKeybindings>): void {\n // Up arrow\n if (kb.matches(data, 'tui.select.up')) {\n this.subMenuIndex = this.subMenuIndex === 0 ? this.subMenuActions.length - 1 : this.subMenuIndex - 1;\n this.updateList();\n }\n // Down arrow\n else if (kb.matches(data, 'tui.select.down')) {\n this.subMenuIndex = this.subMenuIndex === this.subMenuActions.length - 1 ? 0 : this.subMenuIndex + 1;\n this.updateList();\n }\n // Enter — execute action\n else if (kb.matches(data, 'tui.select.confirm')) {\n const action = this.subMenuActions[this.subMenuIndex];\n if (!action || action.key === 'none') return;\n this.executeAction(action.key);\n }\n // Escape — close sub-menu\n else if (kb.matches(data, 'tui.select.cancel')) {\n this.subMenuOpen = false;\n this.updateList();\n }\n }\n\n private executeAction(actionKey: string): void {\n const status = this.statuses[this.selectedIndex];\n if (!status) return;\n\n switch (actionKey) {\n case 'tools': {\n this.subMenuOpen = false;\n this.showToolList(status);\n break;\n }\n case 'error': {\n this.subMenuOpen = false;\n this.showError(status);\n break;\n }\n case 'logs': {\n this.subMenuOpen = false;\n this.showLogs(status);\n break;\n }\n case 'reconnect': {\n this.subMenuOpen = false;\n this.doReconnectServer(status);\n break;\n }\n case 'authenticate': {\n this.subMenuOpen = false;\n this.doAuthenticateServer(status);\n break;\n }\n case 'cancel-authenticate': {\n this.subMenuOpen = false;\n this.doCancelAuthentication(status);\n break;\n }\n }\n }\n\n private doReloadAll(): void {\n this._reloading = true;\n this.updateList();\n\n this.onReloadAllCallback()\n .then((result: { statuses: McpServerStatus[]; skipped: McpSkippedServer[] }) => {\n this.statuses = result.statuses;\n this.skipped = result.skipped;\n // Reload disconnects the client, which cancels any pending auth flow\n // server-side. Drop authenticating markers for servers that no longer\n // exist so isBusy() can settle and polling can stop.\n const liveNames = new Set(result.statuses.map(s => s.name));\n for (const name of this._authenticating) {\n if (!liveNames.has(name)) this._authenticating.delete(name);\n }\n // Reload aborts every pending flow, so no cancel is still resolving.\n this._cancelling.clear();\n // Clamp selected index in case server count changed\n const total = this.getTotalItems();\n if (this.selectedIndex >= total) {\n this.selectedIndex = Math.max(0, total - 1);\n }\n const connected = result.statuses.filter(s => s.connected);\n const totalTools = connected.reduce((sum, s) => sum + s.toolCount, 0);\n this.showInfoCallback(`MCP: Reloaded. ${connected.length} server(s) connected, ${totalTools} tool(s).`);\n for (const s of result.statuses.filter(s => !s.connected)) {\n if (s.needsAuth) {\n this.showInfoCallback(`MCP: \\u26a0 \"${s.name}\" needs authentication \\u2192 run /mcp to authenticate`);\n } else {\n this.showInfoCallback(`MCP: Failed to connect to \"${s.name}\": ${s.error ?? 'Unknown error'}`);\n }\n }\n })\n .catch(() => {\n this.showInfoCallback('MCP: Reload failed. Retrying may help.');\n })\n .finally(() => {\n this._reloading = false;\n this.updateList();\n });\n }\n\n private doReconnectServer(status: McpServerStatus): void {\n if (status.connecting) return;\n const name = status.name;\n\n // Mark this server as connecting\n const idx = this.statuses.findIndex(s => s.name === name);\n if (idx >= 0) {\n this.statuses[idx] = {\n name,\n connected: false,\n connecting: true,\n toolCount: 0,\n toolNames: [],\n transport: status.transport,\n };\n }\n this.updateList();\n\n this.onReconnectServerCallback(name)\n .then((updated: McpServerStatus) => {\n // If a reload-all started, ignore stale reconnect results\n if (this._reloading) return;\n const i = this.statuses.findIndex(s => s.name === name);\n if (i >= 0) {\n this.statuses[i] = updated;\n }\n if (updated.connected) {\n this.showInfoCallback(`MCP: Reconnected \"${name}\" — ${updated.toolCount} tool(s)`);\n } else {\n this.showInfoCallback(`MCP: Failed to reconnect \"${name}\": ${updated.error ?? 'Unknown error'}`);\n }\n })\n .catch((err: unknown) => {\n if (this._reloading) return;\n const errMsg = err instanceof Error ? err.message : String(err);\n const i = this.statuses.findIndex(s => s.name === name);\n if (i >= 0) {\n this.statuses[i] = {\n name,\n connected: false,\n connecting: false,\n toolCount: 0,\n toolNames: [],\n transport: status.transport,\n error: errMsg,\n };\n }\n this.showInfoCallback(`MCP: Failed to reconnect \"${name}\": ${errMsg}`);\n })\n .finally(() => {\n if (!this._reloading) {\n this.updateList();\n }\n });\n }\n\n private doAuthenticateServer(status: McpServerStatus): void {\n if (status.connecting) return;\n const name = status.name;\n\n // Mark this server as connecting while the OAuth flow runs\n const idx = this.statuses.findIndex(s => s.name === name);\n if (idx >= 0) {\n this.statuses[idx] = {\n name,\n connected: false,\n connecting: true,\n toolCount: 0,\n toolNames: [],\n transport: status.transport,\n };\n }\n this._authenticating.add(name);\n // Surface the cancel path immediately: keep this server selected and open\n // its sub-menu with \"Cancel authentication\" pre-selected, so a user who\n // abandons the browser sign-in can just press Enter to back out.\n if (idx >= 0) {\n this.selectedIndex = idx;\n }\n this.openSubMenu();\n this.startPollingIfNeeded();\n this.showInfoCallback(`MCP: Authenticating \"${name}\" — complete the sign-in in your browser.`);\n\n this.onAuthenticateServerCallback(name)\n .then((updated: McpServerStatus) => {\n // If a reload-all started, ignore stale authenticate results\n if (this._reloading) return;\n const i = this.statuses.findIndex(s => s.name === name);\n if (i >= 0) {\n this.statuses[i] = updated;\n }\n if (updated.connected) {\n this.showInfoCallback(`MCP: Authenticated \"${name}\" — ${updated.toolCount} tool(s)`);\n } else if (!updated.cancelled && !this._cancelling.has(name)) {\n // A deliberate cancel also resolves with a failed status; the manager\n // marks it `cancelled` (which survives a reopened selector) and the\n // cancel path already messaged the user, so don't stack a \"Failed\" toast.\n this.showInfoCallback(`MCP: Failed to authenticate \"${name}\": ${updated.error ?? 'Unknown error'}`);\n }\n })\n .catch((err: unknown) => {\n if (this._reloading) return;\n const errMsg = err instanceof Error ? err.message : String(err);\n const i = this.statuses.findIndex(s => s.name === name);\n if (i >= 0) {\n this.statuses[i] = {\n name,\n connected: false,\n connecting: false,\n toolCount: 0,\n toolNames: [],\n transport: status.transport,\n error: errMsg,\n needsAuth: true,\n };\n }\n // A rejection carries no status object, so we can't read the durable\n // `cancelled` flag here; fall back to the local set, which is populated\n // for the same-instance cancel that produced this rejection.\n if (!this._cancelling.has(name)) {\n this.showInfoCallback(`MCP: Failed to authenticate \"${name}\": ${errMsg}`);\n }\n })\n .finally(() => {\n this._authenticating.delete(name);\n this._cancelling.delete(name);\n // The auth flow has ended (connected, failed, or cancelled). Close the\n // auto-opened cancel sub-menu so the row shows its resolved state — but\n // only if the user is still looking at *this* server's sub-menu, so we\n // don't yank shut a different server's menu they navigated to meanwhile.\n if (this.subMenuOpen && this.statuses[this.selectedIndex]?.name === name) {\n this.subMenuOpen = false;\n }\n if (!this._reloading) {\n this.updateList();\n }\n });\n }\n\n private doCancelAuthentication(status: McpServerStatus): void {\n const name = status.name;\n // Nothing to cancel unless a flow is actually in flight for this server.\n // Accept the manager-owned flag too, so a reopened selector (whose local\n // set was discarded with the previous instance) can still cancel.\n if (!this.isAuthenticating(status)) return;\n\n // Mark the cancel so the pending authenticate flow suppresses its \"Failed\"\n // toast, then repaint immediately so the row reflects the cancelling state\n // instead of waiting for the authenticate promise to settle.\n this._cancelling.add(name);\n this.showInfoCallback(`MCP: Cancelling authentication for \"${name}\"...`);\n this.updateList();\n this.onCancelAuthenticateServerCallback(name)\n .then((cancelled: boolean) => {\n if (cancelled) {\n this.showInfoCallback(`MCP: Cancelled authentication for \"${name}\".`);\n }\n })\n .catch(() => {\n // The pending authenticate flow's own rejection handler restores the\n // server's needs-auth status; a failed cancel needs no extra message.\n });\n }\n\n private showToolList(status: McpServerStatus): void {\n this.listContainer.clear();\n\n this.listContainer.addChild(\n new Text(theme.bold(`Tools for ${status.name}`) + theme.fg('muted', ` (${status.toolCount})`), 0, 0),\n );\n this.listContainer.addChild(new Spacer(1));\n\n if (status.toolNames.length === 0) {\n this.listContainer.addChild(new Text(theme.fg('muted', 'No tools available'), 0, 0));\n } else {\n for (const toolName of status.toolNames) {\n this.listContainer.addChild(new Text(` ${theme.fg('muted', '–')} ${toolName}`, 0, 0));\n }\n }\n\n this.listContainer.addChild(new Spacer(1));\n this.listContainer.addChild(new Text(theme.fg('muted', 'Press Esc to go back'), 0, 0));\n\n this._detailView = true;\n this.tui.requestRender();\n }\n\n private showError(status: McpServerStatus): void {\n this.listContainer.clear();\n\n this.listContainer.addChild(new Text(theme.bold(`Error for ${status.name}`), 0, 0));\n this.listContainer.addChild(new Spacer(1));\n this.listContainer.addChild(new Text(theme.fg('error', status.error ?? 'Unknown error'), 0, 0));\n this.listContainer.addChild(new Spacer(1));\n this.listContainer.addChild(new Text(theme.fg('muted', 'Press Esc to go back'), 0, 0));\n\n this._detailView = true;\n this.tui.requestRender();\n }\n\n private showLogs(status: McpServerStatus): void {\n this.listContainer.clear();\n\n const logs = this.getServerLogsCallback(status.name);\n\n this.listContainer.addChild(\n new Text(theme.bold(`Logs for ${status.name}`) + theme.fg('muted', ` (${logs.length} lines)`), 0, 0),\n );\n this.listContainer.addChild(new Spacer(1));\n\n if (logs.length === 0) {\n const hint =\n status.transport === 'http'\n ? 'No logs available (HTTP servers do not produce stderr output)'\n : 'No logs captured yet';\n this.listContainer.addChild(new Text(theme.fg('muted', hint), 0, 0));\n } else {\n // Show last 50 lines to avoid overwhelming the overlay\n const tail = logs.slice(-50);\n if (logs.length > 50) {\n this.listContainer.addChild(\n new Text(theme.fg('muted', ` ... ${logs.length - 50} earlier lines omitted`), 0, 0),\n );\n }\n for (const line of tail) {\n this.listContainer.addChild(new Text(theme.fg('muted', ` ${line}`), 0, 0));\n }\n }\n\n this.listContainer.addChild(new Spacer(1));\n this.listContainer.addChild(new Text(theme.fg('muted', 'Press Esc to go back'), 0, 0));\n\n this._detailView = true;\n this.tui.requestRender();\n }\n}\n","/**\n * Notification utility for alerting the user when the TUI needs attention.\n * Sends a terminal bell and optionally a native OS notification.\n */\n\nimport { execFile } from 'node:child_process';\nimport type { HookManager } from '@mastra/code-sdk/hooks/manager';\n\nexport type NotificationMode = 'bell' | 'system' | 'both' | 'off';\n\nexport type NotificationReason = 'agent_done' | 'ask_question' | 'tool_approval' | 'plan_approval' | 'sandbox_access';\n\n/**\n * Send a notification to the user.\n * - \"bell\": writes \\x07 to stdout (terminal bell)\n * - \"system\": sends a native OS notification (macOS only for now)\n * - \"both\": bell + system\n * - \"off\": no-op\n *\n * Also fires Notification hooks if a hookManager is provided.\n */\nexport function sendNotification(\n reason: NotificationReason,\n opts: {\n mode: NotificationMode;\n message?: string;\n hookManager?: HookManager;\n },\n): void {\n const { mode, message, hookManager } = opts;\n\n if (mode === 'off') {\n // Still fire hooks even when built-in notifications are off\n hookManager?.runNotification(reason, message);\n return;\n }\n\n if (mode === 'bell' || mode === 'both') {\n process.stdout.write('\\x07');\n }\n\n if (mode === 'system' || mode === 'both') {\n sendSystemNotification(reason, message);\n }\n\n hookManager?.runNotification(reason, message);\n}\n\nfunction sendSystemNotification(reason: NotificationReason, message?: string): void {\n if (process.platform === 'darwin') {\n const title = 'Mastra Code';\n const body = message || reasonToMessage(reason);\n // The message can contain arbitrary text (including model output), so:\n // - escape backslashes before quotes for the AppleScript string literal\n // - pass the script via execFile args so no shell is involved\n // (CodeQL js/incomplete-sanitization)\n const escaped = body.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n const script = `display notification \"${escaped}\" with title \"${title}\"`;\n execFile('osascript', ['-e', script], () => {\n // Best-effort: ignore notification failures\n });\n }\n // Linux/Windows: could add notify-send / powershell in the future\n}\n\nfunction reasonToMessage(reason: NotificationReason): string {\n switch (reason) {\n case 'agent_done':\n return 'Agent finished — waiting for your input';\n case 'ask_question':\n return 'Agent has a question for you';\n case 'tool_approval':\n return 'Tool requires your approval';\n case 'plan_approval':\n return 'Plan requires your approval';\n case 'sandbox_access':\n return 'Sandbox access requested';\n }\n}\n","/**\n * Display helpers for the TUI: error messages, info messages, notifications.\n */\nimport { Container, Text } from '@earendil-works/pi-tui';\n\nimport { parseError } from '@mastra/code-sdk/utils/errors';\nimport { insertChatComponentWithBoundarySpacing } from './chat-boundary-reconciliation.js';\nimport type { ChatSpacingKind } from './components/chat-spacing.js';\nimport type { NotificationMode, NotificationReason } from './notify.js';\nimport { sendNotification } from './notify.js';\nimport type { TUIState } from './state.js';\nimport { theme } from './theme.js';\n\nclass InfoMessageComponent extends Container {\n constructor(lines: Text[]) {\n super();\n for (const line of lines) {\n this.addChild(line);\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n}\n\nexport function showError(state: TUIState, message: string): void {\n const component = new InfoMessageComponent([new Text(theme.fg('error', `Error: ${message}`), 1, 0)]);\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n state.ui.requestRender();\n}\n\nexport function showInfo(state: TUIState, message: string): void {\n const component = new InfoMessageComponent([new Text(theme.fg('muted', message), 1, 0)]);\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n state.ui.requestRender();\n}\n\nexport function showFormattedError(\n state: TUIState,\n event:\n | {\n error: Error;\n errorType?: string;\n retryable?: boolean;\n retryDelay?: number;\n retryAttempt?: number;\n maxRetries?: number;\n }\n | Error,\n): void {\n const error = 'error' in event ? event.error : event;\n const parsed = parseError(error);\n\n // Show the main error message\n let errorText = `Error: ${parsed.message}`;\n if (parsed.detail && parsed.detail !== parsed.message) {\n errorText += theme.fg('muted', ` (${parsed.detail})`);\n }\n if (parsed.requestUrl) {\n errorText += theme.fg('muted', ` [url: ${parsed.requestUrl}]`);\n }\n\n // Retry timing is only shown when the controller explicitly scheduled a retry.\n const retryable = 'error' in event && event.retryable === true;\n const retryDelay = 'error' in event ? event.retryDelay : undefined;\n if (retryable && retryDelay) {\n const seconds = retryDelay / 1000;\n const retryAttempt = 'retryAttempt' in event ? event.retryAttempt : undefined;\n const maxRetries = 'maxRetries' in event ? event.maxRetries : undefined;\n const retryProgress = retryAttempt && maxRetries ? ` ${retryAttempt}/${maxRetries}` : '';\n errorText += theme.fg('muted', ` (retry${retryProgress} in ${seconds}s)`);\n }\n\n const lines: Text[] = [new Text(theme.fg('error', errorText), 1, 0)];\n\n const isObservationalMemoryError = /observational memory|\\bOM (?:observation|reflection)/i.test(error.message);\n const omRole = /reflect/i.test(error.message) ? state.session.om.reflector : state.session.om.observer;\n const hint = withOMGuidance(getErrorHint(parsed.type), isObservationalMemoryError ? omRole.modelId() : undefined);\n if (hint) {\n lines.push(new Text(theme.fg('muted', ` Hint: ${hint}`), 1, 0));\n }\n\n const component = new InfoMessageComponent(lines);\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n state.ui.requestRender();\n}\n\nfunction withOMGuidance(typeHint: string | null, omModelId: string | undefined): string | null {\n if (!omModelId) return typeHint;\n return [`Observational Memory is using ${omModelId}`, typeHint, 'Use /memory to choose another OM model']\n .filter(Boolean)\n .join('. ');\n}\n\nfunction getErrorHint(errorType: string): string | null {\n switch (errorType) {\n case 'auth':\n return 'Use /login to authenticate with a provider';\n case 'model_not_found':\n return 'Use /models to select a different model';\n case 'context_length':\n return 'Use /new to start a fresh conversation';\n case 'rate_limit':\n return 'Wait a moment and try again';\n case 'network':\n return 'Check your internet connection';\n default:\n return null;\n }\n}\n\nexport function notify(state: TUIState, reason: NotificationReason, message?: string): void {\n const mode = ((state.session.state.get() as any)?.notifications ?? 'off') as NotificationMode;\n sendNotification(reason, {\n mode,\n message,\n hookManager: state.hookManager,\n });\n}\n","/**\n * Best-effort browser opening for OAuth and other login flows.\n */\n\nimport { spawn } from 'node:child_process';\n\n/**\n * Open a URL in the default browser without going through a shell.\n * Only well-formed http(s) URLs are opened; anything else is ignored\n * (the URL is still displayed for the user to open manually).\n */\nexport function openUrlInBrowser(url: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return;\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return;\n }\n\n const [cmd, args]: [string, string[]] =\n process.platform === 'darwin'\n ? ['open', [url]]\n : process.platform === 'win32'\n ? ['rundll32', ['url.dll,FileProtocolHandler', url]]\n : ['xdg-open', [url]];\n\n const child = spawn(cmd, args, { stdio: 'ignore', detached: true });\n // Opening the browser is best-effort — the URL is shown to the user as well.\n child.on('error', () => {});\n child.unref();\n}\n","import { McpSelectorComponent } from '../components/mcp-selector.js';\nimport { showInfo } from '../display.js';\nimport { openUrlInBrowser } from '../open-url.js';\nimport { showModalOverlay } from '../overlay.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handleMcpCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const mm = ctx.mcpManager;\n if (!mm) {\n ctx.showInfo('MCP system not initialized.');\n return;\n }\n\n const subcommand = args[0];\n\n // /mcp reload — reconnect all servers (also available from the selector)\n if (subcommand === 'reload') {\n await reloadServers(ctx);\n return;\n }\n\n // /mcp status — text-only status dump (non-interactive fallback)\n if (subcommand === 'status') {\n showTextStatus(ctx);\n return;\n }\n\n const paths = mm.getConfigPaths();\n\n // No servers? Show setup instructions.\n if (!mm.hasServers()) {\n ctx.showInfo(\n `No MCP servers configured.\\n\\n` +\n `Add servers to:\\n` +\n ` ${paths.project} (project)\\n` +\n ` ${paths.global} (global)\\n` +\n ` ${paths.claude} (Claude Code compat)\\n\\n` +\n `Example mcp.json:\\n` +\n ` {\\n` +\n ` \"mcpServers\": {\\n` +\n ` \"filesystem\": {\\n` +\n ` \"command\": \"npx\",\\n` +\n ` \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/path\"],\\n` +\n ` \"env\": {}\\n` +\n ` },\\n` +\n ` \"remote-api\": {\\n` +\n ` \"url\": \"https://mcp.example.com/sse\",\\n` +\n ` \"headers\": { \"Authorization\": \"Bearer <token>\" }\\n` +\n ` }\\n` +\n ` }\\n` +\n ` }\\n\\n` +\n `Servers that require OAuth can be added with just a \"url\" —\\n` +\n `authenticate them from the /mcp selector.`,\n );\n return;\n }\n\n // Default: show interactive selector overlay\n const statuses = mm.getServerStatuses();\n const skipped = mm.getSkippedServers();\n\n const selector = new McpSelectorComponent({\n tui: ctx.state.ui,\n statuses,\n skipped,\n configPaths: paths,\n getStatuses: () => ({\n statuses: mm.getServerStatuses(),\n skipped: mm.getSkippedServers(),\n }),\n onReloadAll: async () => {\n await mm.reload();\n return {\n statuses: mm.getServerStatuses(),\n skipped: mm.getSkippedServers(),\n };\n },\n onReconnectServer: async (name: string) => {\n return mm.reconnectServer(name);\n },\n onAuthenticateServer: async (name: string) => {\n return mm.authenticateServer(name, {\n onAuthorizationUrl: (url: string) => {\n // Always print the URL so headless (or failed-open) environments can\n // complete the flow manually; opening the browser is best-effort.\n showInfo(ctx.state, `MCP: To authenticate \"${name}\", open:\\n ${url}`);\n if (process.env.MASTRA_MCP_OAUTH_NO_BROWSER !== '1') {\n openUrlInBrowser(url);\n }\n },\n });\n },\n onCancelAuthenticateServer: async (name: string) => {\n return mm.cancelServerAuthentication(name);\n },\n getServerLogs: (name: string) => {\n return mm.getServerLogs(name);\n },\n showInfo: (msg: string) => {\n showInfo(ctx.state, msg);\n },\n onClose: () => {\n selector.dispose();\n ctx.state.ui.hideOverlay();\n },\n });\n\n showModalOverlay(ctx.state.ui, selector, { widthPercent: 0.8, maxHeight: '70%' });\n selector.focused = true;\n}\n\nasync function reloadServers(ctx: SlashCommandContext): Promise<void> {\n const mm = ctx.mcpManager;\n if (!mm) return;\n ctx.showInfo('MCP: Reconnecting to servers...');\n try {\n await mm.reload();\n const statuses = mm.getServerStatuses();\n const connected = statuses.filter(s => s.connected);\n const totalTools = connected.reduce((sum, s) => sum + s.toolCount, 0);\n ctx.showInfo(`MCP: Reloaded. ${connected.length} server(s) connected, ${totalTools} tool(s).`);\n for (const s of statuses.filter(s => !s.connected)) {\n if (s.needsAuth) {\n ctx.showInfo(`MCP: \\u26a0 \"${s.name}\" needs authentication \\u2192 run /mcp to authenticate`);\n } else {\n ctx.showInfo(`MCP: Failed to connect to \"${s.name}\": ${s.error}`);\n }\n }\n } catch (error) {\n ctx.showError(`MCP reload failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nfunction showTextStatus(ctx: SlashCommandContext): void {\n const mm = ctx.mcpManager;\n if (!mm) return;\n const paths = mm.getConfigPaths();\n const statuses = mm.getServerStatuses();\n const skipped = mm.getSkippedServers();\n\n const lines: string[] = [`MCP Servers:`];\n lines.push(` Project: ${paths.project}`);\n lines.push(` Global: ${paths.global}`);\n lines.push(` Claude: ${paths.claude}`);\n lines.push('');\n\n for (const status of statuses) {\n const icon = status.authenticating\n ? '\\u26a0'\n : status.connecting\n ? '⟳'\n : status.connected\n ? '\\u2713'\n : status.needsAuth\n ? '\\u26a0'\n : '\\u2717';\n const state = status.authenticating\n ? 'authenticating — cancel via /mcp'\n : status.connecting\n ? 'connecting...'\n : status.connected\n ? 'connected'\n : status.needsAuth\n ? 'needs auth — authenticate via /mcp'\n : `error: ${status.error}`;\n lines.push(` ${icon} ${status.name} [${status.transport}] (${state})`);\n if (status.toolNames.length > 0) {\n for (const toolName of status.toolNames) {\n lines.push(` - ${toolName}`);\n }\n }\n }\n\n if (skipped.length > 0) {\n lines.push('');\n lines.push(' Skipped:');\n for (const s of skipped) {\n lines.push(` \\u2717 ${s.name}: ${s.reason}`);\n }\n }\n\n lines.push('');\n lines.push(` /mcp reload - Disconnect and reconnect all servers`);\n\n ctx.showInfo(lines.join('\\n'));\n}\n","import type { IToolExecutionComponent } from '../components/tool-execution-interface.js';\nimport type { SlashCommandContext } from './types.js';\n\nfunction applyCurrentModeColorToRenderedTools(ctx: SlashCommandContext): void {\n const color = ctx.state.session.mode.resolve().metadata?.color;\n const modeColor = typeof color === 'string' ? color : undefined;\n for (const tool of ctx.state.allToolComponents as IToolExecutionComponent[]) {\n tool.setCompactToolModeColor?.(modeColor);\n }\n ctx.state.ui.requestRender();\n}\n\nexport async function handleModeCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const modes = ctx.controller.listModes();\n if (modes.length <= 1) {\n ctx.showInfo('Only one mode available');\n return;\n }\n if (args[0]) {\n try {\n await ctx.state.session.mode.switch({ modeId: args[0] });\n applyCurrentModeColorToRenderedTools(ctx);\n } catch (err) {\n ctx.showError(`Failed to switch mode: ${err instanceof Error ? err.message : String(err)}`);\n }\n } else {\n const currentMode = ctx.state.session.mode.resolve();\n const modeList = modes\n .map(m => ` ${m.id === currentMode?.id ? '* ' : ' '}${m.name}${m.description ? ` - ${m.description}` : ''}`)\n .join('\\n');\n ctx.showInfo(`Modes:\\n${modeList}`);\n }\n}\n","import { Container } from '@earendil-works/pi-tui';\n\n/** Rebuilds width-derived children only when state or the received render width changes. */\nexport abstract class WidthAwareContainer extends Container {\n private builtWidth: number | undefined;\n\n protected get renderWidth(): number {\n return this.builtWidth!;\n }\n\n protected rebuild(): void {\n if (this.builtWidth !== undefined) {\n this.rebuildForWidth(this.builtWidth);\n }\n }\n\n protected abstract rebuildForWidth(width: number): void;\n\n override render(width: number): string[] {\n if (this.builtWidth !== width) {\n this.builtWidth = width;\n this.rebuildForWidth(width);\n }\n return super.render(width);\n }\n}\n","/**\n * SlashCommandComponent - renders a bordered box for slash command messages\n * showing the command name as a heading and truncated content that can be\n * expanded with ctrl+e. The full content is still sent to the assistant.\n */\n\nimport { Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nconst MAX_COLLAPSED_LINES = 3;\nconst getBorderColor = () => mastra.green;\n\nexport class SlashCommandComponent extends WidthAwareContainer {\n private commandName: string;\n private contentLines: string[];\n private expanded = false;\n\n constructor(commandName: string, content?: string) {\n super();\n this.commandName = commandName;\n this.contentLines = content ? content.split('\\n').filter(l => l.trim()) : [];\n this.rebuild();\n }\n\n matches(commandName: string, content: string): boolean {\n return (\n this.commandName === commandName &&\n this.contentLines.join('\\n') ===\n content\n .split('\\n')\n .filter(l => l.trim())\n .join('\\n')\n );\n }\n\n setExpanded(expanded: boolean): void {\n if (this.expanded === expanded) return;\n this.expanded = expanded;\n this.rebuild();\n }\n\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n const border = (char: string) => chalk.bold.hex(getBorderColor())(char);\n const maxLineWidth = Math.max(1, termWidth - 6 - BOX_INDENT * 2);\n\n const heading = chalk.hex(mastra.specialGray)(`/${this.commandName}`);\n\n if (this.contentLines.length === 0) {\n this.addChild(new Text(`${border('╰──')} ${heading}`, BOX_INDENT, 0));\n return;\n }\n\n // Top border\n this.addChild(new Text(`${border('╭──')}`, BOX_INDENT, 0));\n\n // Word-wrap content lines\n const wrappedLines: string[] = [];\n for (const line of this.contentLines) {\n if (line.length > maxLineWidth) {\n let remaining = line;\n while (remaining.length > maxLineWidth) {\n const breakAt = remaining.lastIndexOf(' ', maxLineWidth);\n const splitAt = breakAt > 0 ? breakAt : maxLineWidth;\n wrappedLines.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n if (remaining) wrappedLines.push(remaining);\n } else {\n wrappedLines.push(line);\n }\n }\n\n const truncated = !this.expanded && wrappedLines.length > MAX_COLLAPSED_LINES + 1;\n const displayLines = truncated ? wrappedLines.slice(0, MAX_COLLAPSED_LINES) : wrappedLines;\n\n const contentText = displayLines\n .map(\n line =>\n `${border('│')} ${chalk.hex(mastra.mainGray)(line.length > maxLineWidth ? line.slice(0, maxLineWidth - 1) + '…' : line)}`,\n )\n .join('\\n');\n this.addChild(new Text(contentText, BOX_INDENT, 0));\n\n if (truncated) {\n const moreText = chalk.hex(mastra.darkGray)(\n `... ${wrappedLines.length - MAX_COLLAPSED_LINES} more lines (ctrl+e to expand)`,\n );\n this.addChild(new Text(`${border('│')} ${moreText}`, BOX_INDENT, 0));\n }\n\n // Bottom border with command name\n this.addChild(new Text(`${border('╰──')} ${heading}`, BOX_INDENT, 0));\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n","/**\n * Inline ask question component.\n * Shows a question with either selectable options or free-text input\n * directly in the conversation flow instead of as an overlay dialog.\n *\n * Supports three lifecycle phases:\n * 1. **Streaming** — Created early by handleToolInputStart with no args.\n * As partial JSON arrives via handleToolInputDelta, `updateArgs()` feeds\n * the question text and option labels into the bordered box progressively.\n * 2. **Active** — When handleAskQuestion fires, `activate()` wires up the\n * interactive SelectList / Input and the submit/cancel callbacks.\n * 3. **Answered** — After the user responds, the box freezes with ✓/✗ icons.\n */\n\nimport {\n Container,\n getKeybindings,\n Input,\n truncateToWidth,\n visibleWidth,\n wrapTextWithAnsi,\n} from '@earendil-works/pi-tui';\nimport type { Focusable, SelectItem, TUI } from '@earendil-works/pi-tui';\nimport { BOX_INDENT_STR, theme, getSelectListTheme, getEditorTheme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { MultilineInput } from './multiline-input.js';\nimport { WrappingSelectList } from './wrapping-select-list.js';\n\n/**\n * Selection mode for option prompts. `single_select` selects one option on Enter\n * (the default). `multi_select` lets the user toggle several options with Space and\n * confirm them together with Enter, returning all selected labels as an array.\n */\nexport type AskQuestionSelectionMode = 'single_select' | 'multi_select';\n\nexport interface AskQuestionInlineOptions {\n question: string;\n options?: Array<{ label: string; description?: string }>;\n /** Controls whether options are single- or multi-select. Defaults to single_select. */\n selectionMode?: AskQuestionSelectionMode;\n /** Format the text shown after an answer is selected. Defaults to `question → answer`. */\n formatResult?: (answer: string) => string;\n /** If provided, determines whether an answer should be shown with error styling (red ✗). */\n isNegativeAnswer?: (answer: string) => boolean;\n /** Allow submitting an empty string in free-text mode. */\n allowEmptyInput?: boolean;\n /** Show the \"Custom response...\" option in select mode. Defaults to true. */\n allowCustomResponse?: boolean;\n /**\n * Use a multiline editor for free-text input (Shift+Enter / \\+Enter for new lines).\n * Defaults to false — most prompts ask for short answers like names, paths, or yes/no.\n * Enable for prompts that legitimately want paragraph-length replies (e.g. ask_user).\n */\n multiline?: boolean;\n onSubmit: (answer: string) => void;\n /**\n * Called instead of `onSubmit` when the prompt is multi-select, with every selected\n * option label. Falls back to `onSubmit` with a comma-joined string when omitted.\n */\n onSubmitMulti?: (answers: string[]) => void;\n onCancel: () => void;\n}\n\n/**\n * A renderable that wraps the ask-question content in a full bordered box\n * (┌─┐ / │ │ / └─┘) including the interactive SelectList or Input.\n */\nclass AskQuestionBorderedBox {\n questionLines: string[];\n private selectList?: WrappingSelectList;\n private input?: Input | MultilineInput;\n private hintText: string;\n items: Array<{ label: string; description?: string }>;\n private answered = false;\n private cancelled = false;\n private selectedValue?: string;\n /** Selected option labels when the box was answered in multi-select mode. */\n private selectedValues?: string[];\n private answerIsNegative = false;\n /** True when created during streaming, before activate() is called */\n private streaming = false;\n\n constructor(\n questionLines: string[],\n hintText: string,\n items: Array<{ label: string; description?: string }>,\n selectList?: WrappingSelectList,\n input?: Input | MultilineInput,\n streaming?: boolean,\n ) {\n this.questionLines = questionLines;\n this.hintText = hintText;\n this.items = items;\n this.selectList = selectList;\n this.input = input;\n this.streaming = streaming ?? false;\n }\n\n invalidate() {\n this.selectList?.invalidate();\n }\n\n setInteractive(selectList?: WrappingSelectList, input?: Input | MultilineInput, hintText?: string) {\n this.streaming = false;\n this.selectList = selectList;\n this.input = input;\n if (hintText) this.hintText = hintText;\n }\n\n setAnswered(selectedValue: string, isNegative: boolean) {\n this.streaming = false;\n this.answered = true;\n this.selectedValue = selectedValue;\n this.answerIsNegative = isNegative;\n }\n\n setAnsweredMulti(selectedValues: string[]) {\n this.streaming = false;\n this.answered = true;\n this.selectedValues = selectedValues;\n this.answerIsNegative = false;\n }\n\n setCancelled() {\n this.streaming = false;\n this.answered = true;\n this.cancelled = true;\n }\n\n render(width: number): string[] {\n try {\n return this._render(width);\n } catch {\n // Fallback: render a minimal box so the TUI doesn't crash\n return [\n BOX_INDENT_STR + theme.fg('dim', '╭──── Question ────╮'),\n BOX_INDENT_STR + theme.fg('dim', '│ (render error) │'),\n BOX_INDENT_STR + theme.fg('dim', '╰──────────────────╯'),\n ];\n }\n }\n\n private _render(width: number): string[] {\n const border = (s: string) => theme.fg('dim', s);\n\n // Inner width: total width minus indent, minus 4 for \"│ \" + \" │\"\n const innerWidth = Math.max(1, width - BOX_INDENT_STR.length - 4);\n const boxWidth = innerWidth + 4; // \"│ \" + content + \" │\"\n\n const lines: string[] = [];\n\n // Top border: ╭──...──╮\n lines.push(BOX_INDENT_STR + border(`╭${'─'.repeat(boxWidth - 2)}╮`));\n\n // Helper to add a bordered line (truncates content that exceeds innerWidth)\n const addLine = (content: string, contentVisWidth: number) => {\n let finalContent = content;\n let finalWidth = contentVisWidth;\n if (finalWidth > innerWidth) {\n finalContent = truncateToWidth(content, innerWidth);\n finalWidth = visibleWidth(finalContent);\n }\n const pad = Math.max(0, innerWidth - finalWidth);\n lines.push(BOX_INDENT_STR + border('│') + ' ' + finalContent + ' '.repeat(pad) + ' ' + border('│'));\n };\n\n // Question header\n const header = theme.bold(theme.fg('accent', 'Question'));\n addLine(header, visibleWidth(header));\n\n // Question text (word-wrap to fit inside bordered box)\n for (const qLine of this.questionLines) {\n const wrapped = wrapTextWithAnsi(qLine, innerWidth);\n for (const wLine of wrapped) {\n const text = theme.fg('text', wLine);\n addLine(text, visibleWidth(wLine));\n }\n }\n\n // Empty separator\n addLine('', 0);\n\n // Wrap a labelled option line so long labels don't overflow the bordered box.\n // Mirrors the free-text answered branch below: first wrapped line keeps the\n // styled prefix (icon/spaces), continuation lines indent 3 spaces.\n const continuationPrefix = ' ';\n const addWrappedOptionLine = (prefix: string, label: string, style: (s: string) => string) => {\n const prefixVis = visibleWidth(prefix);\n const wrapped = wrapTextWithAnsi(label, Math.max(1, innerWidth - prefixVis));\n wrapped.forEach((line, index) => {\n const linePrefix = index === 0 ? prefix : continuationPrefix;\n const content = `${linePrefix}${style(line)}`;\n addLine(content, visibleWidth(linePrefix) + visibleWidth(line));\n });\n };\n\n if (this.streaming) {\n // Streaming: show option labels as they arrive (dimmed, no interactivity)\n const dim = (s: string) => theme.fg('dim', s);\n for (const item of this.items) {\n addWrappedOptionLine(continuationPrefix, item.label, dim);\n }\n // Waiting indicator\n const waiting = theme.fg('dim', '…');\n addLine(waiting, visibleWidth(waiting));\n } else if (this.answered && this.items.length > 0) {\n // Render frozen item list\n const dim = (s: string) => theme.fg('dim', s);\n if (this.cancelled) {\n // All items dimmed, cancelled notice\n for (const item of this.items) {\n addWrappedOptionLine(continuationPrefix, item.label, dim);\n }\n const cancelLine = `${theme.fg('error', '✗')} ${theme.fg('dim', '(cancelled)')}`;\n addLine(cancelLine, visibleWidth(cancelLine));\n } else {\n // ✓/✗ on selected, dimmed unselected\n const text = (s: string) => theme.fg('text', s);\n for (const item of this.items) {\n const isSelected = this.selectedValues\n ? this.selectedValues.includes(item.label)\n : item.label === this.selectedValue;\n if (isSelected) {\n const icon = this.answerIsNegative ? theme.fg('error', '✗') : theme.fg('success', '✓');\n addWrappedOptionLine(`${icon} `, item.label, text);\n } else {\n addWrappedOptionLine(continuationPrefix, item.label, dim);\n }\n }\n }\n addLine('', 0);\n } else if (this.answered && this.selectedValue != null) {\n // Free-text input answered\n const icon = this.answerIsNegative ? theme.fg('error', '✗') : theme.fg('success', '✓');\n const iconPrefix = `${icon} `;\n const continuationPrefix = ' ';\n const wrappedAnswer = wrapTextWithAnsi(this.selectedValue!, Math.max(1, innerWidth - visibleWidth(iconPrefix)));\n\n wrappedAnswer.forEach((line, index) => {\n const prefix = index === 0 ? iconPrefix : continuationPrefix;\n const content = `${prefix}${theme.fg('text', line)}`;\n addLine(content, visibleWidth(prefix) + visibleWidth(line));\n });\n } else if (this.answered && this.cancelled) {\n // Free-text cancelled\n const cancelLine = `${theme.fg('error', '✗')} ${theme.fg('dim', '(cancelled)')}`;\n addLine(cancelLine, visibleWidth(cancelLine));\n } else {\n // Interactive content (SelectList or Input)\n if (this.selectList) {\n // SelectList renders its own lines — wrap each one with borders\n const selectLines = this.selectList.render(innerWidth);\n for (const sLine of selectLines) {\n addLine(sLine, visibleWidth(sLine));\n }\n } else if (this.input) {\n const inputLines = this.input.render(innerWidth);\n for (const iLine of inputLines) {\n addLine(iLine, visibleWidth(iLine));\n }\n }\n\n // Hint text\n const hint = theme.fg('dim', this.hintText);\n addLine(hint, visibleWidth(hint));\n }\n\n // Bottom border: ╰──...──╯\n lines.push(BOX_INDENT_STR + border(`╰${'─'.repeat(boxWidth - 2)}╯`));\n\n return lines;\n }\n}\n\nexport class AskQuestionInlineComponent extends Container implements Focusable {\n private borderedBox: AskQuestionBorderedBox;\n private selectList?: WrappingSelectList;\n private input?: Input | MultilineInput;\n private tui?: TUI;\n private onSubmit?: (answer: string) => void;\n private onSubmitMulti?: (answers: string[]) => void;\n private onCancel?: () => void;\n private isNegativeAnswer?: (answer: string) => boolean;\n private allowEmptyInput = false;\n private multiline = false;\n private allowCustomResponse = true;\n private multiSelect = false;\n private answered = false;\n\n /**\n * Create a pre-answered instance for rendering from chat history.\n * No interactive elements — just shows the question and the answer in the bordered box.\n */\n static fromHistory(\n question: string,\n options: Array<{ label: string; description?: string }> | undefined,\n answer: string,\n cancelled: boolean,\n ): AskQuestionInlineComponent {\n const component = AskQuestionInlineComponent.createStreaming();\n component.updateArgs({ question, options });\n component.answered = true;\n if (cancelled) {\n component.borderedBox.setCancelled();\n } else {\n component.borderedBox.setAnswered(answer, false);\n }\n return component;\n }\n\n /**\n * Create a streaming instance for early rendering during tool input streaming.\n * Shows the bordered box with \"…\" indicator. Call updateArgs() as partial JSON\n * arrives, then activate() when the question event fires.\n */\n static createStreaming(tui?: TUI): AskQuestionInlineComponent {\n const component = new AskQuestionInlineComponent();\n component.tui = tui;\n return component;\n }\n\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n if (!this.answered && this.input) {\n this.input.focused = value;\n }\n }\n\n render(width: number): string[] {\n try {\n return super.render(width);\n } catch {\n return [\n BOX_INDENT_STR + theme.fg('dim', '╭──── Question ────╮'),\n BOX_INDENT_STR + theme.fg('dim', '│ (render error) │'),\n BOX_INDENT_STR + theme.fg('dim', '╰──────────────────╯'),\n ];\n }\n }\n\n /**\n * Private constructor — use static factories or the options constructor.\n */\n constructor(options?: AskQuestionInlineOptions, _ui?: TUI) {\n super();\n\n this.tui = _ui;\n\n if (options) {\n // Full construction with interactive elements\n this.onSubmit = options.onSubmit;\n this.onSubmitMulti = options.onSubmitMulti;\n this.onCancel = options.onCancel;\n this.isNegativeAnswer = options.isNegativeAnswer;\n this.allowEmptyInput = Boolean(options.allowEmptyInput);\n this.multiline = Boolean(options.multiline);\n this.allowCustomResponse = options.allowCustomResponse ?? true;\n this.multiSelect = options.selectionMode === 'multi_select';\n\n const questionLines = options.question.split('\\n');\n\n let hintText: string;\n if (options.options && options.options.length > 0) {\n hintText = this.selectHintText();\n this.buildSelectMode(options.options);\n } else {\n hintText = this.useMultiline()\n ? 'Enter to submit · Shift+Enter/\\\\+Enter for new line · Esc to skip'\n : 'Enter to submit · Esc to skip';\n this.buildInputMode();\n }\n\n this.borderedBox = new AskQuestionBorderedBox(\n questionLines,\n hintText,\n options.options || [],\n this.selectList,\n this.input,\n );\n } else {\n // Streaming mode — empty bordered box, will be populated by updateArgs()\n this.borderedBox = new AskQuestionBorderedBox([], '', [], undefined, undefined, true);\n }\n\n this.addChild(this.borderedBox as any);\n }\n\n /**\n * Update the question text and options from streaming partial args.\n * Called during tool input delta streaming.\n */\n updateArgs(args: unknown): void {\n if (this.answered) return;\n if (!args || typeof args !== 'object') return;\n const a = args as Record<string, unknown>;\n if (typeof a.question === 'string') {\n this.borderedBox.questionLines = a.question.split('\\n');\n }\n if (Array.isArray(a.options)) {\n this.borderedBox.items = a.options.filter(\n (o: unknown): o is { label: string; description?: string } =>\n typeof o === 'object' && o !== null && typeof (o as any).label === 'string',\n );\n }\n }\n\n /**\n * Activate the interactive elements (SelectList or Input) and wire up callbacks.\n * Called by handleAskQuestion when the question event fires after streaming.\n */\n activate(options: {\n question: string;\n options?: Array<{ label: string; description?: string }>;\n selectionMode?: AskQuestionSelectionMode;\n isNegativeAnswer?: (answer: string) => boolean;\n allowEmptyInput?: boolean;\n allowCustomResponse?: boolean;\n multiline?: boolean;\n tui?: TUI;\n onSubmit: (answer: string) => void;\n onSubmitMulti?: (answers: string[]) => void;\n onCancel: () => void;\n }): void {\n if (this.answered) return;\n if (options.tui) this.tui = options.tui;\n this.onSubmit = options.onSubmit;\n this.onSubmitMulti = options.onSubmitMulti;\n this.onCancel = options.onCancel;\n this.isNegativeAnswer = options.isNegativeAnswer;\n this.allowEmptyInput = Boolean(options.allowEmptyInput);\n this.allowCustomResponse = options.allowCustomResponse ?? true;\n this.multiline = Boolean(options.multiline);\n this.multiSelect = options.selectionMode === 'multi_select';\n\n // Update question text and items to final values\n this.borderedBox.questionLines = options.question.split('\\n');\n this.borderedBox.items = options.options || [];\n\n // Build interactive elements\n let hintText: string;\n if (options.options && options.options.length > 0) {\n hintText = this.selectHintText();\n this.buildSelectMode(options.options);\n } else {\n hintText = this.useMultiline()\n ? 'Enter to submit · Shift+Enter/\\\\+Enter for new line · Esc to skip'\n : 'Enter to submit · Esc to skip';\n this.buildInputMode();\n }\n\n // Switch bordered box out of streaming mode\n this.borderedBox.setInteractive(this.selectList, this.input, hintText);\n }\n\n private static readonly CUSTOM_RESPONSE_VALUE = '__custom_response__';\n\n /** Hint line shown under an option list, tailored to single- vs multi-select. */\n private selectHintText(): string {\n return this.multiSelect\n ? 'Space to toggle · Enter to confirm · Esc to skip'\n : '↑↓ to navigate · Enter to select · Esc to skip';\n }\n\n private buildSelectMode(opts: Array<{ label: string; description?: string }>): void {\n const items: SelectItem[] = opts.map(opt => ({\n value: opt.label,\n label: opt.description ? `${opt.label} ${theme.fg('dim', opt.description)}` : opt.label,\n }));\n\n // \"Custom response...\" only applies to single-select: it switches to free-text.\n // Multi-select toggles a fixed option set, so the escape hatch doesn't apply.\n if (this.allowCustomResponse && !this.multiSelect) {\n items.push({\n value: AskQuestionInlineComponent.CUSTOM_RESPONSE_VALUE,\n label: theme.fg('dim', '✎ Custom response...'),\n });\n }\n\n this.selectList = new WrappingSelectList(items, Math.min(items.length, 8), getSelectListTheme(), this.multiSelect);\n\n if (this.multiSelect) {\n this.selectList.onConfirmMulti = (selected: SelectItem[]) => {\n this.handleMultiAnswer(selected.map(item => item.value));\n };\n } else {\n this.selectList.onSelect = (item: SelectItem) => {\n if (item.value === AskQuestionInlineComponent.CUSTOM_RESPONSE_VALUE) {\n this.switchToCustomInput();\n return;\n }\n this.handleAnswer(item.value);\n };\n }\n this.selectList.onCancel = () => {\n this.handleCancel();\n };\n }\n\n private switchToCustomInput(): void {\n // Tear down the select list and switch to free-text input\n this.selectList = undefined;\n this.buildInputMode();\n\n // Clear items so the answered state renders as free-text, not select\n this.borderedBox.items = [];\n this.borderedBox.setInteractive(\n undefined,\n this.input,\n this.useMultiline()\n ? 'Enter to submit · Shift+Enter/\\\\+Enter for new line · Esc to skip'\n : 'Enter to submit · Esc to skip',\n );\n }\n\n /** Whether this prompt should render a multiline editor (vs a single-line input). */\n private useMultiline(): boolean {\n return this.multiline && Boolean(this.tui);\n }\n\n private buildInputMode(): void {\n if (this.useMultiline()) {\n // Multiline editor — opted in by callers that expect paragraph-length answers.\n const multilineInput = new MultilineInput(this.tui!, getEditorTheme());\n multilineInput.allowEmptySubmit = this.allowEmptyInput;\n multilineInput.onSubmit = (value: string) => {\n // Trim only for the emptiness decision; forward the raw value\n // so leading indentation / trailing newlines survive.\n if (value.trim() || this.allowEmptyInput) {\n this.handleAnswer(value);\n }\n };\n multilineInput.onEscape = () => {\n this.handleCancel();\n };\n this.input = multilineInput;\n } else {\n // Single-line input — the right default for short answers (paths, names, yes/no).\n this.input = new Input();\n this.input.onSubmit = (value: string) => {\n const trimmed = value.trim();\n if (trimmed || this.allowEmptyInput) {\n this.handleAnswer(trimmed);\n }\n };\n (this.input as any).keybindings = getKeybindings();\n }\n\n // Carry focus over so callers (constructor, activate, switchToCustomInput)\n // don't have to reapply it manually after rebuilding the input.\n this.input.focused = this._focused;\n }\n\n answer(answer: string, isNegative = false): void {\n if (this.answered) return;\n this.answered = true;\n\n this.borderedBox.setAnswered(answer, isNegative);\n }\n\n private handleAnswer(answer: string): void {\n if (this.answered) return;\n const isNegative = this.isNegativeAnswer?.(answer) ?? false;\n this.answer(answer, isNegative);\n\n this.onSubmit?.(answer);\n }\n\n private handleMultiAnswer(answers: string[]): void {\n if (this.answered) return;\n this.answered = true;\n this.borderedBox.setAnsweredMulti(answers);\n\n // Prefer the array-shaped callback; fall back to a comma-joined string so\n // single-select-only callers still receive a usable answer.\n if (this.onSubmitMulti) {\n this.onSubmitMulti(answers);\n } else {\n this.onSubmit?.(answers.join(', '));\n }\n }\n\n private handleCancel(): void {\n if (this.answered) return;\n this.answered = true;\n\n this.borderedBox.setCancelled();\n\n this.onCancel?.();\n }\n\n /**\n * Retract the question without invoking any submit/cancel callback. Used when\n * the underlying tool suspension was cancelled (the suspended run died, e.g.\n * its snapshot failed to persist), so an answer could never be delivered.\n */\n dismiss(): void {\n if (this.answered) return;\n this.answered = true;\n this.focused = false;\n\n this.borderedBox.setCancelled();\n }\n\n handleInput(data: string): void {\n if (this.answered) return;\n\n if (this.selectList) {\n this.selectList.handleInput(data);\n } else if (this.input) {\n const kb = getKeybindings();\n if (kb.matches(data, 'tui.select.cancel')) {\n this.handleCancel();\n return;\n }\n this.input.handleInput(data);\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n","import type { MastraDBMessage } from '@mastra/core/agent-controller';\nimport { mastraDBMessageToSignal } from '@mastra/core/signals';\nimport type { CreatedAgentSignal } from '@mastra/core/signals';\n\n/**\n * DB-native accessors for `MastraDBMessage`.\n *\n * The harness now emits and persists the canonical `MastraDBMessage` shape\n * (`content.format: 2` + nested `content.parts`, `role: 'signal'` for signals)\n * instead of the removed flat `AgentControllerMessage` union. These helpers are\n * the single place mastracode reads that nested shape, so the TUI renderer and\n * the streaming handler share one translation of parts -> render items.\n */\n\ntype MessagePart = MastraDBMessage['content']['parts'][number];\n\nexport interface TextRenderPart {\n kind: 'text';\n text: string;\n}\n\nexport interface ThinkingRenderPart {\n kind: 'thinking';\n text: string;\n}\n\nexport interface ToolRenderPart {\n kind: 'tool';\n toolCallId: string;\n toolName: string;\n args: unknown;\n result: unknown;\n hasResult: boolean;\n isError: boolean;\n}\n\nexport interface OmRenderPart {\n kind: 'om';\n event: 'start' | 'end' | 'failed' | 'thread-title';\n operationType: string;\n data: Record<string, unknown>;\n}\n\nexport type AssistantRenderPart = TextRenderPart | ThinkingRenderPart | ToolRenderPart | OmRenderPart;\n\nfunction getParts(message: MastraDBMessage): MessagePart[] {\n const content = message.content;\n if (typeof content === 'string' || !content?.parts) return [];\n return content.parts;\n}\n\n/** Join the text of all `text` parts on a message (assistant/user), newline-separated. */\nexport function getMessageText(message: MastraDBMessage): string {\n return getParts(message)\n .filter((part): part is Extract<MessagePart, { type: 'text' }> => part.type === 'text')\n .map(part => part.text)\n .join('\\n');\n}\n\nconst OM_EVENT_BY_TYPE: Record<string, OmRenderPart['event']> = {\n 'data-om-observation-start': 'start',\n 'data-om-observation-end': 'end',\n 'data-om-observation-failed': 'failed',\n 'data-om-thread-update': 'thread-title',\n};\n\n/**\n * Walk a message's `content.parts` and project them into flat render items in\n * document order. Text/reasoning/tool-invocation/data-om-* parts are surfaced;\n * bookkeeping parts (`step-start`, `data-om-status`, etc.) are skipped.\n */\nexport function getAssistantRenderParts(message: MastraDBMessage): AssistantRenderPart[] {\n const out: AssistantRenderPart[] = [];\n const toolCalls = new Map<string, { toolName: string; args: unknown }>();\n\n for (const part of getParts(message)) {\n const partType = (part as { type: string }).type;\n switch (partType) {\n case 'text': {\n out.push({ kind: 'text', text: (part as { text: string }).text });\n break;\n }\n case 'reasoning': {\n out.push({ kind: 'thinking', text: (part as { reasoning?: string }).reasoning ?? '' });\n break;\n }\n case 'tool-invocation': {\n const inv = (part as { toolInvocation: Record<string, unknown> }).toolInvocation;\n const hasResult = inv.state === 'result' && inv.result !== undefined;\n out.push({\n kind: 'tool',\n toolCallId: String(inv.toolCallId ?? ''),\n toolName: String(inv.toolName ?? ''),\n args: inv.args,\n result: inv.result,\n hasResult,\n isError: hasResult && (typeof inv.isError === 'boolean' ? inv.isError : isErrorResult(inv.result)),\n });\n break;\n }\n case 'tool-call': {\n const legacyPart = part as { toolCallId?: string; toolName?: string; args?: unknown };\n const toolCallId = String(legacyPart.toolCallId ?? '');\n toolCalls.set(toolCallId, { toolName: String(legacyPart.toolName ?? ''), args: legacyPart.args });\n break;\n }\n case 'tool-result': {\n const legacyPart = part as { toolCallId?: string; toolName?: string; result?: unknown; isError?: boolean };\n const toolCallId = String(legacyPart.toolCallId ?? '');\n const call = toolCalls.get(toolCallId);\n out.push({\n kind: 'tool',\n toolCallId,\n toolName: String(legacyPart.toolName ?? call?.toolName ?? ''),\n args: call?.args,\n result: legacyPart.result,\n hasResult: true,\n isError: legacyPart.isError === true || isErrorResult(legacyPart.result),\n });\n toolCalls.delete(toolCallId);\n break;\n }\n default: {\n const event = OM_EVENT_BY_TYPE[part.type];\n if (event) {\n const data = ((part as { data?: Record<string, unknown> }).data ?? {}) as Record<string, unknown>;\n out.push({\n kind: 'om',\n event,\n operationType: typeof data.operationType === 'string' ? data.operationType : 'observation',\n data,\n });\n }\n break;\n }\n }\n }\n\n for (const [toolCallId, call] of toolCalls) {\n out.push({\n kind: 'tool',\n toolCallId,\n toolName: call.toolName,\n args: call.args,\n result: undefined,\n hasResult: false,\n isError: false,\n });\n }\n\n return out;\n}\n\nfunction isErrorResult(result: unknown): boolean {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const record = result as Record<string, unknown>;\n return record.isError === true || 'error' in record;\n }\n return false;\n}\n\n/** A message persisted/streamed as a signal carries `role: 'signal'`. */\nexport function isSignalMessage(message: MastraDBMessage): boolean {\n return message.role === 'signal';\n}\n\n/**\n * Reconstruct the original signal (type, tagName, contents, attributes, metadata)\n * from a `role: 'signal'` `MastraDBMessage`. Delegates to core's canonical\n * reconstruction so mastracode never re-parses `content.metadata.signal` by hand.\n */\nexport function getSignalView(message: MastraDBMessage): CreatedAgentSignal {\n return mastraDBMessageToSignal(message);\n}\n\nexport type SignalKind = 'state' | 'reminder' | 'notification-summary' | 'notification' | 'reactive' | 'user';\n\n/**\n * Classify a `role: 'signal'` message into the render branch it drives. Mirrors\n * the dispatch order of the removed core `convertToControllerMessage` signal\n * handling: state -> reminder -> notification-summary -> notification -> reactive -> user.\n */\nexport function getSignalKind(message: MastraDBMessage): SignalKind {\n const signal = getSignalView(message);\n const { type, tagName } = signal;\n if (type === 'state') return 'state';\n if (type === 'reactive' && tagName === 'system-reminder') return 'reminder';\n if (type === 'notification' && tagName === 'notification-summary') return 'notification-summary';\n if (type === 'notification' && tagName === 'notification') return 'notification';\n if (type === 'reactive') return 'reactive';\n return 'user';\n}\n\nfunction contentsToText(contents: CreatedAgentSignal['contents']): string {\n if (typeof contents === 'string') return contents;\n return contents\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map(part => part.text)\n .join('\\n');\n}\n\n/** Flatten a signal message's `contents` to plain text (string or text parts). */\nexport function getSignalContentsText(message: MastraDBMessage): string {\n return contentsToText(getSignalView(message).contents);\n}\n\nexport interface UserSignalView {\n message: string;\n imageCount: number;\n fileCount: number;\n}\n\n/** Fields needed to render a user-kind signal as a user message. */\nexport function getUserSignalView(message: MastraDBMessage): UserSignalView {\n const contents = getSignalView(message).contents;\n if (typeof contents === 'string') {\n return { message: contents, imageCount: 0, fileCount: 0 };\n }\n\n let imageCount = 0;\n let fileCount = 0;\n for (const part of contents) {\n if (part.type !== 'file') continue;\n if (part.mediaType.startsWith('image/')) imageCount++;\n else fileCount++;\n }\n\n return {\n message: contentsToText(contents),\n imageCount,\n fileCount,\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n return typeof value === 'number' ? value : undefined;\n}\n\nexport interface ReminderView {\n reminderType?: string;\n path?: string;\n precedesMessageId?: string;\n gapText?: string;\n message: string;\n goalMaxTurns?: number;\n judgeModelId?: string;\n goalEvaluation?: unknown;\n}\n\n/**\n * Fields the reminder/judge UI needs, sourced from a `system-reminder` signal.\n * Mirrors the placement the removed core `toSystemReminderContent` helper used:\n * reminder metadata lives under `attributes` (type/path/gapText/precedesMessageId)\n * and `metadata` (goalMaxTurns/judgeModelId/goalEvaluation).\n */\nexport function getReminderView(message: MastraDBMessage): ReminderView {\n const signal = getSignalView(message);\n const attributes = asRecord(signal.attributes) ?? {};\n const metadata = asRecord(signal.metadata) ?? {};\n return {\n reminderType: asString(attributes.type) ?? asString(signal.type),\n path: asString(attributes.path),\n precedesMessageId: asString(attributes.precedesMessageId),\n gapText: asString(attributes.gapText),\n message: contentsToText(signal.contents),\n goalMaxTurns: asNumber(metadata.goalMaxTurns),\n judgeModelId: asString(metadata.judgeModelId),\n goalEvaluation: metadata.goalEvaluation,\n };\n}\n\n/** True for the persisted mirror of a live goal evaluation lifecycle event. */\nexport function isGoalJudgeEvaluationSignal(message: MastraDBMessage): boolean {\n if (!isSignalMessage(message) || getSignalKind(message) !== 'reminder') return false;\n const reminder = getReminderView(message);\n return reminder.reminderType === 'goal-judge' && reminder.goalEvaluation !== undefined;\n}\n\nexport interface StateSignalView {\n stateId: string;\n mode: 'snapshot' | 'delta';\n cacheKey?: string;\n version?: number;\n message: string;\n}\n\n/** Fields the state-signal UI needs, sourced from a `state` signal's `metadata.state`. */\nexport function getStateSignalView(message: MastraDBMessage): StateSignalView {\n const signal = getSignalView(message);\n const stateMeta = asRecord(asRecord(signal.metadata)?.state) ?? {};\n return {\n stateId: asString(stateMeta.id) ?? asString(signal.tagName) ?? 'state',\n mode: stateMeta.mode === 'delta' ? 'delta' : 'snapshot',\n cacheKey: asString(stateMeta.cacheKey),\n version: asNumber(stateMeta.version),\n message: contentsToText(signal.contents),\n };\n}\n\nexport interface ReactiveSignalView {\n tagName?: string;\n message: string;\n}\n\n/** Fields the reactive-signal UI needs, sourced from a reactive signal. */\nexport function getReactiveSignalView(message: MastraDBMessage): ReactiveSignalView {\n const signal = getSignalView(message);\n return {\n tagName: asString(signal.tagName),\n message: contentsToText(signal.contents),\n };\n}\n\nexport interface NotificationView {\n message: string;\n source?: string;\n kind?: string;\n priority?: string;\n status?: string;\n}\n\n/** Fields the notification UI needs, sourced from a notification signal's `attributes`/`metadata`. */\nexport function getNotificationView(message: MastraDBMessage): NotificationView {\n const signal = getSignalView(message);\n const attributes = asRecord(signal.attributes) ?? {};\n const notificationMeta = asRecord(asRecord(signal.metadata)?.notification) ?? {};\n return {\n message: contentsToText(signal.contents),\n source: asString(attributes.source) ?? asString(notificationMeta.source),\n kind: asString(attributes.kind) ?? asString(attributes.type) ?? asString(notificationMeta.kind),\n priority: asString(attributes.priority) ?? asString(notificationMeta.priority),\n status: asString(attributes.status) ?? asString(notificationMeta.status),\n };\n}\n\nexport interface NotificationSummaryView {\n message: string;\n pending: number;\n bySource: Record<string, number>;\n}\n\n/** Fields the notification-summary UI needs, sourced from `metadata.notificationSummary`. */\nexport function getNotificationSummaryView(message: MastraDBMessage): NotificationSummaryView {\n const signal = getSignalView(message);\n const summary = asRecord(asRecord(signal.metadata)?.notificationSummary) ?? {};\n const bySourceRaw = asRecord(summary.bySource) ?? {};\n const notificationIds = Array.isArray(summary.notificationIds)\n ? summary.notificationIds.filter((id): id is string => typeof id === 'string')\n : [];\n const pending = asNumber(summary.pending);\n return {\n message: contentsToText(signal.contents),\n pending: pending ?? notificationIds.length,\n bySource: Object.fromEntries(\n Object.entries(bySourceRaw).filter((entry): entry is [string, number] => typeof entry[1] === 'number'),\n ),\n };\n}\n","/**\n * Sanitize ANSI escape codes in text content before it enters the TUI\n * rendering pipeline.\n *\n * pi-tui's extractAnsiCode() only recognises CSI sequences that end with\n * one of {m, G, K, H, J}. When a CSI sequence uses a different final byte\n * (e.g. \\x1b[1A – cursor-up, ending with 'A'), the scanner skips past\n * the real terminator and swallows all subsequent text until it finally\n * hits one of those five letters. This makes visibleWidth() dramatically\n * undercount, wrapTextWithAnsi() produces far fewer lines, and the TUI\n * collapses to a handful of rows — permanently corrupting the session's\n * rendered height.\n *\n * This module strips every CSI sequence whose final byte is NOT 'm'\n * (SGR — Select Graphic Rendition, i.e. colours/styles). SGR codes are\n * the only CSI sequences that belong in rendered text content; all others\n * (cursor movement, screen clearing, mode switches, etc.) are terminal\n * control operations that should never appear in message or tool-result\n * text.\n */\n\n// CSI (Control Sequence Introducer) format:\n// ESC [ <params> <final-byte>\n// Where:\n// <params> = zero or more bytes in the range 0x20–0x3F (space through ?)\n// <final-byte> = one byte in the range 0x40–0x7E (@ through ~)\n//\n// We keep only SGR (final byte = 'm') since those are colour/style codes\n// that pi-tui's extractAnsiCode handles correctly.\n//\n// The regex below matches:\n// \\x1b\\[ — ESC [\n// [^@-~]* — parameter bytes (anything that isn't the final byte range)\n// [^m@-~]? — NOT used; instead we match a final byte that isn't 'm'\n//\n// Strategy: match ALL CSI sequences, then conditionally keep SGR ones.\n\nconst CSI_SEQUENCE_RE = /\\x1b\\[[\\x20-\\x3f]*[\\x40-\\x7e]/g;\n\n/**\n * Strip non-SGR CSI sequences from text.\n *\n * Keeps: \\x1b[...m (SGR — colours, bold, italic, etc.)\n * Strips: \\x1b[...A, \\x1b[...h, \\x1b[...l, etc.\n *\n * Also strips lone ESC bytes that aren't part of any recognised sequence\n * (bare ESC can confuse terminal state).\n */\nexport function sanitizeAnsiForRendering(text: string): string {\n if (!text.includes('\\x1b')) return text;\n\n return text.replace(CSI_SEQUENCE_RE, match => {\n // Keep SGR sequences (ending with 'm')\n if (match.endsWith('m')) return match;\n // Strip everything else\n return '';\n });\n}\n","/**\n * Component that renders an assistant message with streaming support.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Container, Markdown, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { MarkdownTheme } from '@earendil-works/pi-tui';\nimport type { MastraDBMessage } from '@mastra/core/agent-controller';\nimport { getAssistantRenderParts } from '../db-message-parts.js';\nimport type { AssistantRenderPart } from '../db-message-parts.js';\nimport { sanitizeAnsiForRendering } from '../sanitize-ansi.js';\nimport { CHAT_INDENT, getMarkdownTheme, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nlet _compId = 0;\nfunction asmDebugLog(...args: unknown[]) {\n if (!['true', '1'].includes(process.env.MASTRA_TUI_DEBUG!)) {\n return;\n }\n const line = `[ASM ${new Date().toISOString()}] ${args.map(a => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ')}\\n`;\n try {\n fs.appendFileSync(path.join(process.cwd(), 'tui-debug.log'), line);\n } catch {}\n}\n\nfunction getStopReason(message: MastraDBMessage): { stopReason?: string; errorMessage?: string } {\n const content = message.content;\n if (typeof content === 'string') return {};\n const metadata = content.metadata as { stopReason?: string; errorMessage?: string } | undefined;\n return { stopReason: metadata?.stopReason, errorMessage: metadata?.errorMessage };\n}\n\nexport class AssistantMessageComponent extends Container {\n private contentContainer: Container;\n private hideThinkingBlock: boolean;\n private markdownTheme: MarkdownTheme;\n private lastMessage?: MastraDBMessage;\n private _id: number;\n\n constructor(message?: MastraDBMessage, hideThinkingBlock = false, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n super();\n this._id = ++_compId;\n\n this.hideThinkingBlock = hideThinkingBlock;\n this.markdownTheme = markdownTheme;\n\n // Container for text/thinking content\n this.contentContainer = new Container();\n this.addChild(this.contentContainer);\n\n asmDebugLog(`COMP#${this._id} CREATED`);\n\n if (message) {\n this.updateContent(message);\n }\n }\n\n override invalidate(): void {\n super.invalidate();\n if (this.lastMessage) {\n const summary = getAssistantRenderParts(this.lastMessage)\n .map(part => (part.kind === 'text' ? `text(${part.text.length}ch)` : part.kind))\n .join(', ');\n asmDebugLog(`COMP#${this._id} INVALIDATE lastMessage=[${summary}]`);\n this.updateContent(this.lastMessage);\n }\n }\n\n setHideThinkingBlock(hide: boolean): void {\n this.hideThinkingBlock = hide;\n }\n\n getChatSpacingKind(): ChatSpacingKind | undefined {\n return this.contentContainer.children.length > 0 ? 'assistant-message' : undefined;\n }\n\n updateContent(message: MastraDBMessage): void {\n this.lastMessage = message;\n\n // Clear content container\n this.contentContainer.clear();\n\n // Project the nested DB message parts into ordered render items, then render\n // text and thinking traces in document order (tool parts are rendered by the\n // dedicated ToolExecutionComponent, so they are ignored here).\n const renderParts = getAssistantRenderParts(message).filter(\n (part): part is Extract<AssistantRenderPart, { kind: 'text' | 'thinking' }> =>\n part.kind === 'text' || part.kind === 'thinking',\n );\n\n for (let i = 0; i < renderParts.length; i++) {\n const part = renderParts[i]!;\n\n if (part.kind === 'text' && part.text.trim()) {\n // Assistant text messages - trim and sanitize escape codes\n this.contentContainer.addChild(\n new Markdown(sanitizeAnsiForRendering(part.text.trim()), CHAT_INDENT, 0, this.markdownTheme, {\n color: (text: string) => theme.fg('text', text),\n }),\n );\n } else if (part.kind === 'thinking' && part.text.trim()) {\n // Check if there's text content after this thinking block\n const hasTextAfter = renderParts.slice(i + 1).some(p => p.kind === 'text' && p.text.trim());\n\n if (this.hideThinkingBlock) {\n // Show static \"Thinking...\" label when hidden\n this.contentContainer.addChild(\n new Text(theme.italic(theme.fg('thinkingText', 'Thinking...')), CHAT_INDENT, 0),\n );\n if (hasTextAfter) {\n this.contentContainer.addChild(new Spacer(1));\n }\n } else {\n // Thinking traces in thinkingText color, italic\n this.contentContainer.addChild(\n new Markdown(sanitizeAnsiForRendering(part.text.trim()), CHAT_INDENT, 0, this.markdownTheme, {\n color: (text: string) => theme.fg('thinkingText', text),\n italic: true,\n }),\n );\n this.contentContainer.addChild(new Spacer(1));\n }\n }\n }\n\n // Check if aborted or error - show after partial content\n const { stopReason, errorMessage } = getStopReason(message);\n if (stopReason === 'aborted') {\n const abortMessage = errorMessage || 'Interrupted';\n this.contentContainer.addChild(new Text(theme.fg('error', abortMessage), CHAT_INDENT, 0));\n } else if (stopReason === 'error') {\n const errorMsg = errorMessage || 'Unknown error';\n this.contentContainer.addChild(new Text(theme.fg('error', `Error: ${errorMsg}`), CHAT_INDENT, 0));\n }\n }\n}\n","/**\n * JudgeDisplayComponent — renders the goal judge's decision inline in the chat.\n */\n\nimport { Text } from '@earendil-works/pi-tui';\nimport type { GoalEvaluationPayload } from '@mastra/core/stream';\nimport chalk from 'chalk';\nimport stripAnsi from 'strip-ansi';\n\nimport { BOX_INDENT, mastraBrand, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\n/** Display-only decision derived from a goal evaluation. */\nexport interface GoalJudgeResult {\n decision: 'done' | 'continue' | 'waiting' | 'paused';\n reason: string;\n}\n\n/** Map a core {@link GoalEvaluationPayload} to a display decision. */\nexport function evaluationToJudgeResult(payload: GoalEvaluationPayload): GoalJudgeResult {\n const decision: GoalJudgeResult['decision'] = payload.passed\n ? 'done'\n : payload.waitingForUser\n ? 'waiting'\n : payload.status === 'paused'\n ? 'paused'\n : 'continue';\n return { decision, reason: payload.reason ?? '' };\n}\n\nconst JUDGE_COLOR = mastraBrand.blue;\nconst MUTED_COLOR = '#8a8a8a';\nconst PAUSED_COLOR = '#f5a524';\nconst WAITING_COLOR = '#8a8a8a';\n\nexport class JudgeDisplayComponent extends WidthAwareContainer {\n private result: GoalJudgeResult | null;\n private turnsUsed: number;\n private maxTurns: number;\n private activity: string[] = [];\n private streamingReason = '';\n\n constructor(result: GoalJudgeResult | null = null, turnsUsed = 0, maxTurns = 0) {\n super();\n this.result = result;\n this.turnsUsed = turnsUsed;\n this.maxTurns = maxTurns;\n this.rebuild();\n }\n\n addActivity(line: string): void {\n if (this.activity[this.activity.length - 1] !== line) {\n this.activity.push(line);\n }\n if (this.activity.length > 6) {\n this.activity = this.activity.slice(-6);\n }\n this.rebuild();\n }\n\n setStreamingReason(reason: string): void {\n this.streamingReason = reason;\n this.rebuild();\n }\n\n setResult(result: GoalJudgeResult, turnsUsed: number, maxTurns: number): void {\n this.result = result;\n this.streamingReason = '';\n this.turnsUsed = turnsUsed;\n this.maxTurns = maxTurns;\n this.rebuild();\n }\n\n /** Render the result of an in-loop goal evaluation chunk. */\n setEvaluation(payload: GoalEvaluationPayload): void {\n this.setResult(evaluationToJudgeResult(payload), payload.iteration, payload.maxRuns);\n }\n\n setInterrupted(): void {\n this.setResult({ decision: 'paused', reason: 'Judge evaluation was interrupted.' }, this.turnsUsed, this.maxTurns);\n }\n\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n const border = (char: string) => chalk.hex(JUDGE_COLOR)(char);\n const title = chalk.hex(JUDGE_COLOR).bold('Goal');\n const innerWidth = Math.max(20, termWidth - BOX_INDENT * 2 - 4);\n const horizontal = '─'.repeat(innerWidth + 1);\n\n this.addChild(new Text(`${border('╭')}${border(horizontal)}${border('╮')}`, BOX_INDENT, 0));\n this.addChild(new Text(this.renderRow(this.renderHeader(title), innerWidth, border), BOX_INDENT, 0));\n\n if (!this.result && this.activity.length === 0 && !this.streamingReason) {\n this.addChild(new Text(this.renderRow(chalk.dim('evaluating…'), innerWidth, border), BOX_INDENT, 0));\n }\n\n for (const line of this.activity) {\n this.addChild(new Text(this.renderRow(this.renderActivityLine(line), innerWidth, border), BOX_INDENT, 0));\n }\n\n if (this.activity.length > 0 && (this.result || this.streamingReason)) {\n this.addChild(new Text(this.renderRow('', innerWidth, border), BOX_INDENT, 0));\n }\n\n const reason = this.result?.reason ?? this.streamingReason;\n if (reason) {\n for (const line of this.wrapLine(reason, innerWidth)) {\n this.addChild(new Text(this.renderRow(chalk.dim(line), innerWidth, border), BOX_INDENT, 0));\n }\n }\n\n this.addChild(new Text(`${border('╰')}${border(horizontal)}${border('╯')}`, BOX_INDENT, 0));\n }\n\n private renderActivityLine(line: string): string {\n const toolName = getActivityToolName(line);\n if (!toolName) return theme.fg('dim', `• ${line}`);\n\n const rest = line.slice(toolName.length);\n return `${theme.fg('dim', '• ')}${theme.fg('dim', theme.italic(toolName))}${theme.fg('dim', rest)}`;\n }\n\n private renderHeader(title: string): string {\n if (!this.result) {\n return `${title} ◌ ${chalk.hex(WAITING_COLOR).bold('evaluating')}`;\n }\n\n const decisionIcon =\n this.result.decision === 'done'\n ? '●'\n : this.result.decision === 'paused'\n ? '!'\n : this.result.decision === 'waiting'\n ? '◌'\n : '○';\n const decisionText = getDecisionText(this.result.decision);\n const turnInfo = this.maxTurns > 0 ? chalk.hex(MUTED_COLOR)(`(${this.turnsUsed}/${this.maxTurns})`) : '';\n return `${title} ${decisionIcon} ${decisionText}${turnInfo ? ` ${turnInfo}` : ''}`;\n }\n\n private renderRow(text: string, width: number, border: (char: string) => string): string {\n const content = this.padLine(text, width);\n return `${border('│')} ${content}${border('│')}`;\n }\n\n private wrapLine(text: string, width: number): string[] {\n const lines: string[] = [];\n let remaining = text;\n while (remaining.length > width) {\n const breakAt = remaining.lastIndexOf(' ', width);\n const splitAt = breakAt > 0 ? breakAt : width;\n lines.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n lines.push(remaining);\n return lines;\n }\n\n private padLine(text: string, width: number): string {\n const visibleLength = stripAnsi(text).length;\n if (visibleLength >= width) {\n return stripAnsi(text).slice(0, width);\n }\n return text + ' '.repeat(width - visibleLength);\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n\nfunction getActivityToolName(line: string): string | null {\n if (line.startsWith('find files ')) return 'find files';\n const [toolName] = line.split(' ');\n return toolName || null;\n}\n\nfunction getDecisionText(decision: GoalJudgeResult['decision']): string {\n if (decision === 'done') return chalk.hex('#16c858').bold('done');\n if (decision === 'paused') return chalk.hex(PAUSED_COLOR).bold('paused');\n if (decision === 'waiting') return chalk.hex(WAITING_COLOR).bold('waiting');\n return chalk.hex(JUDGE_COLOR).bold('continue');\n}\n","import { Container, Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nexport interface NotificationSummaryOptions {\n message: string;\n pending: number;\n bySource: Record<string, number>;\n}\n\nexport class NotificationSummaryComponent extends Container {\n constructor(options: NotificationSummaryOptions) {\n super();\n\n const title = chalk.hex(mastra.orange).bold(`Notification summary: ${options.pending} pending`);\n this.addChild(new Text(title, BOX_INDENT, 0));\n\n const sourceSummary = Object.entries(options.bySource)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([source, count]) => `${source}: ${count}`)\n .join(', ');\n const message = sourceSummary || options.message.trim();\n\n if (message) {\n this.addChild(new Text(theme.fg('dim', message), BOX_INDENT + 2, 0));\n }\n\n this.addChild(\n new Text(theme.fg('dim', 'Use notification_inbox to inspect pending notifications.'), BOX_INDENT + 2, 0),\n );\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n}\n","import { Text, visibleWidth } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nexport interface NotificationOptions {\n message: string;\n source?: string;\n kind?: string;\n priority?: string;\n status?: string;\n}\n\nfunction priorityColor(priority?: string): string {\n if (priority === 'urgent' || priority === 'high') return mastra.orange;\n if (priority === 'medium') return mastra.blue;\n return mastra.darkGray;\n}\n\nconst MAX_NOTIFICATION_CONTENT_WIDTH = 100;\nconst MIN_NOTIFICATION_CONTENT_WIDTH = 24;\n\nfunction padLine(value: string, width: number): string {\n return value + ' '.repeat(Math.max(0, width - visibleWidth(value)));\n}\n\nfunction splitLongWord(word: string, maxWidth: number): string[] {\n const segments: string[] = [];\n let current = '';\n\n for (const char of word) {\n if (current && visibleWidth(current + char) > maxWidth) {\n segments.push(current);\n current = char;\n } else {\n current += char;\n }\n }\n\n if (current) segments.push(current);\n return segments;\n}\n\nfunction wrapText(value: string, maxWidth: number): string[] {\n const lines: string[] = [];\n\n for (const paragraph of value.split('\\n')) {\n const words = paragraph.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) {\n lines.push('');\n continue;\n }\n\n let current = '';\n for (const word of words) {\n const wordSegments = visibleWidth(word) > maxWidth ? splitLongWord(word, maxWidth) : [word];\n for (const segment of wordSegments) {\n const next = current ? `${current} ${segment}` : segment;\n if (current && visibleWidth(next) > maxWidth) {\n lines.push(current);\n current = segment;\n } else {\n current = next;\n }\n }\n }\n\n if (current) lines.push(current);\n }\n\n return lines;\n}\n\nexport class NotificationComponent extends WidthAwareContainer {\n private readonly options: NotificationOptions;\n\n constructor(options: NotificationOptions) {\n super();\n this.options = options;\n }\n\n protected rebuildForWidth(width: number): void {\n this.clear();\n\n const options = this.options;\n const titleText = options.source ? `notification from ${options.source}` : 'notification';\n const details = [options.priority, options.kind, options.status].filter(Boolean).join(' · ');\n const message = options.message.trim();\n const maxContentWidth = Math.max(\n MIN_NOTIFICATION_CONTENT_WIDTH,\n Math.min(MAX_NOTIFICATION_CONTENT_WIDTH, width - BOX_INDENT - 4),\n );\n const titleLines = wrapText(titleText, maxContentWidth);\n const detailLines = details ? wrapText(details, maxContentWidth) : [];\n const messageLines = message ? wrapText(message, maxContentWidth) : [];\n const allLines = [...titleLines, ...detailLines, ...messageLines];\n const contentWidth = Math.max(...allLines.map(line => visibleWidth(line)), 1);\n const borderColor = chalk.hex(mastra.blue);\n const top = `╭${'─'.repeat(contentWidth + 2)}╮`;\n const bottom = `╰${'─'.repeat(contentWidth + 2)}╯`;\n\n this.addChild(new Text(borderColor(top), BOX_INDENT, 0));\n for (const line of titleLines) {\n this.addChild(\n new Text(\n `${borderColor('│')} ${chalk.hex(priorityColor(options.priority)).bold(padLine(line, contentWidth))} ${borderColor('│')}`,\n BOX_INDENT,\n 0,\n ),\n );\n }\n\n for (const line of detailLines) {\n this.addChild(\n new Text(\n `${borderColor('│')} ${theme.fg('dim', padLine(line, contentWidth))} ${borderColor('│')}`,\n BOX_INDENT,\n 0,\n ),\n );\n }\n\n for (const line of messageLines) {\n this.addChild(new Text(`${borderColor('│')} ${padLine(line, contentWidth)} ${borderColor('│')}`, BOX_INDENT, 0));\n }\n\n this.addChild(new Text(borderColor(bottom), BOX_INDENT, 0));\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n}\n","/**\n * TUI component for rendering OM observation markers in chat history.\n * Supports updating in-place (start → end/failed).\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport { BOX_INDENT, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\n/**\n * Format token count for display (e.g., 7234 -> \"7.2k\", 234 -> \"0.2k\", 0 -> \"0\")\n */\nfunction formatTokens(tokens: number): string {\n if (tokens === 0) return '0';\n const k = tokens / 1000;\n return k % 1 === 0 ? `${k}k` : `${k.toFixed(1)}k`;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n\n const totalMinutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (totalMinutes < 60) return seconds === 0 ? `${totalMinutes}m` : `${totalMinutes}m${seconds}s`;\n\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n return minutes === 0 ? `${hours}h` : `${hours}h${minutes}m`;\n}\nexport type OMMarkerData =\n | {\n type: 'om_observation_start';\n tokensToObserve: number;\n operationType?: 'observation' | 'reflection';\n }\n | {\n type: 'om_observation_end';\n tokensObserved: number;\n observationTokens: number;\n durationMs: number;\n operationType?: 'observation' | 'reflection';\n }\n | {\n type: 'om_observation_failed';\n error: string;\n tokensAttempted?: number;\n operationType?: 'observation' | 'reflection';\n }\n | {\n type: 'om_buffering_start';\n operationType: 'observation' | 'reflection';\n tokensToBuffer: number;\n }\n | {\n type: 'om_buffering_end';\n operationType: 'observation' | 'reflection';\n tokensBuffered: number;\n bufferedTokens: number;\n observations?: string;\n }\n | {\n type: 'om_buffering_failed';\n operationType: 'observation' | 'reflection';\n error: string;\n }\n | {\n type: 'om_activation';\n operationType: 'observation' | 'reflection';\n tokensActivated: number;\n observationTokens: number;\n activationCount?: number;\n activateAfterIdle?: number;\n }\n | {\n type: 'om_activation_provider_change';\n previousModel: string;\n currentModel: string;\n }\n | {\n type: 'om_thread_title_updated';\n oldTitle?: string;\n newTitle: string;\n };\n\n/**\n * Renders an inline OM observation marker in the chat history.\n * Can be updated in-place to transition from start → end/failed.\n */\nexport class OMMarkerComponent extends Container {\n private textChild: Text;\n\n constructor(data: OMMarkerData) {\n super();\n this.textChild = new Text(formatMarker(data), BOX_INDENT, 0);\n this.addChild(this.textChild);\n }\n\n /**\n * Update the marker in-place (e.g., from start → end).\n */\n update(data: OMMarkerData): void {\n this.textChild.setText(formatMarker(data));\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\nfunction formatMarker(data: OMMarkerData): string {\n const isReflection = 'operationType' in data && data.operationType === 'reflection';\n const label = isReflection ? 'Reflection' : 'Observation';\n\n switch (data.type) {\n case 'om_observation_start': {\n const tokens = data.tokensToObserve > 0 ? ` ~${formatTokens(data.tokensToObserve)} tokens` : '';\n return theme.fg('muted', ` 🧠 ${label} in progress${tokens}...`);\n }\n case 'om_observation_end': {\n const observed = formatTokens(data.tokensObserved);\n const compressed = formatTokens(data.observationTokens);\n const ratio =\n data.tokensObserved > 0 && data.observationTokens > 0\n ? `${Math.round(data.tokensObserved / data.observationTokens)}x`\n : '';\n const duration = (data.durationMs / 1000).toFixed(1);\n const ratioStr = ratio ? ` (${ratio} compression)` : '';\n return theme.fg('success', ` 🧠 Observed: ${observed} → ${compressed} tokens${ratioStr} in ${duration}s ✓`);\n }\n case 'om_observation_failed': {\n const tokens = data.tokensAttempted ? ` (${formatTokens(data.tokensAttempted)} tokens)` : '';\n return theme.fg('error', ` ✗ ${label} failed${tokens}: ${data.error}`);\n }\n case 'om_buffering_start': {\n const tokens = data.tokensToBuffer > 0 ? ` ~${formatTokens(data.tokensToBuffer)} tokens` : '';\n return theme.fg('muted', ` ⟳ Buffering ${label.toLowerCase()}${tokens}...`);\n }\n case 'om_buffering_end': {\n const input = formatTokens(data.tokensBuffered);\n // For observations: bufferedTokens is cumulative total, not this cycle's output.\n // Estimate output from observations string (~4 chars/token).\n // For reflections: bufferedTokens IS the output token count.\n const outputTokens =\n data.operationType === 'observation' && data.observations\n ? Math.round(data.observations.length / 4)\n : data.bufferedTokens;\n const output = formatTokens(outputTokens);\n const ratio =\n data.tokensBuffered > 0 && outputTokens > 0 ? ` (${Math.round(data.tokensBuffered / outputTokens)}x)` : '';\n return theme.fg('success', ` ✓ Buffered ${label.toLowerCase()}: ${input} → ${output} tokens${ratio}`);\n }\n case 'om_buffering_failed': {\n return theme.fg('error', ` ✗ Buffering ${label.toLowerCase()} failed: ${data.error}`);\n }\n case 'om_activation': {\n if (data.operationType === 'reflection') {\n // For reflection, tokensActivated = obs tokens before, observationTokens = obs tokens after.\n // Reflection compresses observations in place — no message tokens move.\n const before = formatTokens(data.tokensActivated);\n const after = formatTokens(data.observationTokens);\n const delta = data.tokensActivated - data.observationTokens;\n const deltaStr = delta > 0 ? ` (-${formatTokens(delta)})` : delta < 0 ? ` (+${formatTokens(-delta)})` : '';\n return theme.fg('success', ` ✓ Activated reflection: ${before} → ${after} obs tokens${deltaStr}`);\n }\n const msgTokens = formatTokens(data.tokensActivated);\n const obsTokens = formatTokens(data.observationTokens);\n const label =\n data.activationCount && data.activationCount > 1 ? `${data.activationCount} observations` : 'observations';\n const idleSuffix =\n data.activateAfterIdle !== undefined ? ` (${formatDuration(data.activateAfterIdle)} idle timeout)` : '';\n return theme.fg(\n 'success',\n ` ✓ Activated ${label}: -${msgTokens} msg tokens, +${obsTokens} obs tokens${idleSuffix}`,\n );\n }\n case 'om_activation_provider_change': {\n return theme.fg('muted', ` Model changed ${data.previousModel} → ${data.currentModel}, activating observations`);\n }\n case 'om_thread_title_updated': {\n return theme.fg('muted', ` thread title updated: ${data.newTitle}`);\n }\n }\n}\n","/**\n * TUI component for rendering OM observation/reflection output in a bordered box.\n * Uses observer (amber) color for observations and reflector (red) color for reflections.\n * Collapsed to COLLAPSED_LINES by default, expandable with ctrl+e.\n * Includes marker info (emoji, compression stats) in the footer.\n */\n\nimport { Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\n// Read from proxy at render time so they pick up contrast adaptation\nconst getObserverColor = () => mastra.orange;\nconst getReflectorColor = () => mastra.red;\nconst COLLAPSED_LINES = 10;\n\nfunction formatTokens(tokens: number): string {\n if (tokens === 0) return '0';\n const k = tokens / 1000;\n return k % 1 === 0 ? `${k}k` : `${k.toFixed(1)}k`;\n}\n\n/** Truncate a string with ANSI codes to a visible width */\nfunction truncateAnsi(str: string, maxWidth: number): string {\n const ansiRegex = /\\x1b\\[[0-9;]{0,32}m/g;\n let visibleLength = 0;\n let result = '';\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = ansiRegex.exec(str)) !== null) {\n const textBefore = str.slice(lastIndex, match.index);\n for (const char of textBefore) {\n if (visibleLength >= maxWidth) break;\n result += char;\n visibleLength++;\n }\n if (visibleLength >= maxWidth) break;\n result += match[0];\n lastIndex = match.index + match[0].length;\n }\n\n const remaining = str.slice(lastIndex);\n for (const char of remaining) {\n if (visibleLength >= maxWidth) break;\n result += char;\n visibleLength++;\n }\n\n if (visibleLength >= maxWidth) {\n result += '\\x1b[0m';\n }\n return result;\n}\n\n/**\n * Soft-wrap an array of lines to fit within maxWidth, preserving words where possible.\n * Returns groups where each group corresponds to one original line split into wrapped segments.\n */\nfunction softWrapLines(lines: string[], maxWidth: number): { groups: string[][]; flat: string[] } {\n const groups: string[][] = [];\n const flat: string[] = [];\n for (const line of lines) {\n if (line.length <= maxWidth) {\n groups.push([line]);\n flat.push(line);\n continue;\n }\n // Word-wrap: break at spaces when possible\n const group: string[] = [];\n let remaining = line;\n while (remaining.length > maxWidth) {\n let breakAt = remaining.lastIndexOf(' ', maxWidth);\n if (breakAt <= 0) {\n breakAt = maxWidth;\n }\n const segment = remaining.slice(0, breakAt);\n group.push(segment);\n flat.push(segment);\n remaining = remaining.slice(breakAt).replace(/^ /, '');\n }\n if (remaining.length > 0) {\n group.push(remaining);\n flat.push(remaining);\n }\n groups.push(group);\n }\n return { groups, flat };\n}\n\nexport type OMOutputType = 'observation' | 'reflection';\n\nexport interface OMOutputData {\n type: OMOutputType;\n observations: string;\n currentTask?: string;\n suggestedResponse?: string;\n durationMs?: number;\n tokensObserved?: number;\n observationTokens?: number;\n compressedTokens?: number;\n}\n\nexport class OMOutputComponent extends WidthAwareContainer {\n private data: OMOutputData;\n private expanded: boolean = false;\n\n constructor(data: OMOutputData) {\n super();\n this.data = data;\n this.rebuild();\n }\n\n setExpanded(expanded: boolean): void {\n this.expanded = expanded;\n this.rebuild();\n }\n\n toggleExpanded(): void {\n this.setExpanded(!this.expanded);\n }\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n const isReflection = this.data.type === 'reflection';\n const color = isReflection ? getReflectorColor() : getObserverColor();\n const border = (char: string) => chalk.bold.hex(color)(char);\n\n const maxLineWidth = termWidth - 6 - BOX_INDENT * 2; // \"│ \" prefix + buffer + indent\n // Soft-wrap all original lines to terminal width\n const originalLines = this.data.observations.split('\\n');\n const { groups, flat: wrappedLines } = softWrapLines(originalLines, maxLineWidth);\n const originalLineCount = originalLines.length;\n const wrappedLineCount = wrappedLines.length;\n\n // Build footer text with marker info (emoji + compression stats)\n const footerText = this.buildFooterText(color);\n\n // Top border\n this.addChild(new Text(border('╭──'), BOX_INDENT, 0));\n\n // Content lines with left border\n let truncated = false;\n const borderedLines: string[] = [];\n if (!this.expanded && wrappedLineCount > COLLAPSED_LINES + 1) {\n // Collect head groups until we hit ~half the budget\n const headBudget = Math.ceil(COLLAPSED_LINES / 2);\n const headLines: string[] = [];\n let headGroupCount = 0;\n for (const group of groups) {\n if (headLines.length + group.length > headBudget && headLines.length > 0) break;\n headLines.push(...group);\n headGroupCount++;\n }\n\n // Collect tail groups from the end until we hit the other half\n const tailBudget = COLLAPSED_LINES - headLines.length;\n const tailLines: string[] = [];\n let tailGroupStart = groups.length;\n for (let i = groups.length - 1; i >= headGroupCount; i--) {\n if (tailLines.length + groups[i]!.length > tailBudget && tailLines.length > 0) break;\n tailLines.unshift(...groups[i]!);\n tailGroupStart = i;\n }\n\n const hiddenGroups = tailGroupStart - headGroupCount;\n truncated = hiddenGroups > 0;\n\n if (truncated) {\n for (const line of headLines) {\n borderedLines.push(border('│') + ' ' + chalk.hex(mastra.specialGray)(line));\n }\n borderedLines.push(\n border('│') + ' ' + chalk.hex(mastra.mainGray)(`... ${originalLineCount} lines total (ctrl+e to expand)`),\n );\n for (const line of tailLines) {\n borderedLines.push(border('│') + ' ' + chalk.hex(mastra.specialGray)(line));\n }\n } else {\n // Edge case: all groups fit when snapped to boundaries\n for (const line of wrappedLines) {\n borderedLines.push(border('│') + ' ' + chalk.hex(mastra.specialGray)(line));\n }\n }\n } else {\n for (const line of wrappedLines) {\n borderedLines.push(border('│') + ' ' + chalk.hex(mastra.specialGray)(line));\n }\n }\n\n const displayOutput = borderedLines.join('\\n');\n if (displayOutput.trim()) {\n this.addChild(new Text(displayOutput, BOX_INDENT, 0));\n }\n\n // Current task / suggested response sections\n if (this.data.currentTask && (this.expanded || !truncated)) {\n const taskLine =\n border('│') +\n ' ' +\n chalk.hex(color).bold('Current task: ') +\n chalk.hex(mastra.specialGray)(this.data.currentTask);\n this.addChild(new Text(truncateAnsi(taskLine, termWidth - 2 - BOX_INDENT * 2), BOX_INDENT, 0));\n }\n\n if (this.data.suggestedResponse && (this.expanded || !truncated)) {\n const sugLine =\n border('│') +\n ' ' +\n chalk.hex(color).bold('Suggested response: ') +\n chalk.hex(mastra.specialGray)(this.data.suggestedResponse);\n this.addChild(new Text(truncateAnsi(sugLine, termWidth - 2 - BOX_INDENT * 2), BOX_INDENT, 0));\n }\n\n // Bottom border with footer\n this.addChild(new Text(`${border('╰──')} ${footerText}`, BOX_INDENT, 0));\n }\n\n private buildFooterText(color: string): string {\n const isReflection = this.data.type === 'reflection';\n const emoji = '🧠';\n\n if (isReflection) {\n // Reflection: \"🧠 Reflected: Xk → Yk tokens (Zx compression) in Ns ✓\"\n const observed = formatTokens(this.data.tokensObserved ?? 0);\n const compressed = formatTokens(this.data.compressedTokens ?? this.data.observationTokens ?? 0);\n const ratio =\n (this.data.tokensObserved ?? 0) > 0 && (this.data.compressedTokens ?? this.data.observationTokens ?? 0) > 0\n ? `${Math.round((this.data.tokensObserved ?? 0) / (this.data.compressedTokens ?? this.data.observationTokens ?? 1))}x`\n : '';\n const durationStr = this.data.durationMs ? ` in ${(this.data.durationMs / 1000).toFixed(1)}s` : '';\n const ratioStr = ratio ? ` (${ratio} compression)` : '';\n return `${emoji} ${chalk.hex(color)(`Reflected: ${observed} → ${compressed} tokens${ratioStr}${durationStr}`)} ${chalk.hex(mastra.green)('✓')}`;\n } else {\n // Observation: \"🧠 Observed: Xk → Yk tokens (Zx compression) in Ns ✓\"\n const observed = formatTokens(this.data.tokensObserved ?? 0);\n const compressed = formatTokens(this.data.observationTokens ?? 0);\n const ratio =\n (this.data.tokensObserved ?? 0) > 0 && (this.data.observationTokens ?? 0) > 0\n ? `${Math.round((this.data.tokensObserved ?? 0) / (this.data.observationTokens ?? 1))}x`\n : '';\n const durationStr = this.data.durationMs ? ` in ${(this.data.durationMs / 1000).toFixed(1)}s` : '';\n const ratioStr = ratio ? ` (${ratio} compression)` : '';\n return `${emoji} ${chalk.hex(color)(`Observed: ${observed} → ${compressed} tokens${ratioStr}${durationStr}`)} ${chalk.hex(mastra.green)('✓')}`;\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n","/**\n * Inline plan approval component.\n * Shows a submitted plan as rendered markdown with Approve/Use as Goal/Request Changes options\n * directly in the conversation flow. When a previous plan exists, shows a diff of changes.\n *\n * \"Request changes\" rejects the plan and stops the agent — the user provides\n * revision feedback via a regular chat message rather than inline input.\n */\n\nimport {\n Box,\n Container,\n Markdown,\n SelectList,\n Spacer,\n Text,\n visibleWidth,\n wrapTextWithAnsi,\n} from '@earendil-works/pi-tui';\nimport type { Component, Focusable, SelectItem, TUI } from '@earendil-works/pi-tui';\nimport type { DiffEntry } from '@mastra/code-sdk/utils/plan-diff';\nimport { generatePlanDiff } from '@mastra/code-sdk/utils/plan-diff';\nimport chalk from 'chalk';\nimport { BOX_INDENT, theme, getSelectListTheme, getMarkdownTheme, mastra } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nexport interface PlanApprovalInlineOptions {\n toolCallId: string;\n title: string;\n plan: string;\n /** Filename on disk (e.g. `add-dark-mode.md`). */\n planFilename?: string;\n /** Previous plan content for diff display on resubmission. */\n previousPlan?: string;\n onApprove: () => void;\n onGoal: () => void;\n onReject: () => void;\n}\n\nclass PlanContentBox implements Component {\n constructor(private plan: string) {}\n\n invalidate(): void {}\n\n render(width: number): string[] {\n const availableWidth = Math.max(24, width - BOX_INDENT);\n const innerWidth = Math.max(20, availableWidth - 4);\n const markdown = new Markdown(this.plan, 0, 0, getMarkdownTheme(), {\n color: (text: string) => theme.fg('text', text),\n });\n const rendered = markdown.render(innerWidth).flatMap(line => (line.length > 0 ? [line] : ['']));\n const border = (text: string) => chalk.hex(mastra.purple)(text);\n const top = `${border('╭')}${border('─'.repeat(innerWidth + 2))}${border('╮')}`;\n const bottom = `${border('╰')}${border('─'.repeat(innerWidth + 2))}${border('╯')}`;\n const body: string[] = [];\n for (const line of rendered) {\n // Always wrap every line to innerWidth using the library's ANSI-aware\n // wrapper. This handles paragraphs that the Markdown renderer outputs\n // as single long lines without wrapping.\n const wrapped = wrapTextWithAnsi(line, innerWidth);\n for (const chunk of wrapped) {\n const chunkVis = visibleWidth(chunk);\n const padding = ' '.repeat(Math.max(0, innerWidth - chunkVis));\n body.push(`${border('│')} ${chunk}${padding} ${border('│')}`);\n }\n }\n return [top, ...body, bottom];\n }\n}\n\n/**\n * Renders a unified diff between two plan texts inside a bordered box.\n * Long lines are wrapped (not truncated) so the full plan text is visible.\n */\nclass PlanDiffBox implements Component {\n private diffEntries: DiffEntry[];\n\n constructor(oldPlan: string, newPlan: string) {\n this.diffEntries = generatePlanDiff(oldPlan, newPlan);\n }\n\n invalidate(): void {}\n\n render(width: number): string[] {\n const availableWidth = Math.max(24, width - BOX_INDENT);\n const innerWidth = Math.max(20, availableWidth - 4);\n const border = (text: string) => chalk.hex(mastra.purple)(text);\n const top = `${border('╭')}${border('─'.repeat(innerWidth + 2))}${border('╮')}`;\n const bottom = `${border('╰')}${border('─'.repeat(innerWidth + 2))}${border('╯')}`;\n\n const removedColor = chalk.hex(mastra.red);\n const addedColor = chalk.hex(theme.getTheme().success);\n\n const body: string[] = [];\n for (const entry of this.diffEntries) {\n const colorFn =\n entry.type === 'added'\n ? addedColor\n : entry.type === 'removed'\n ? removedColor\n : (t: string) => theme.fg('muted', t);\n const prefix = entry.type === 'added' ? '+ ' : entry.type === 'removed' ? '- ' : ' ';\n const prefixWidth = 2;\n const textWidth = innerWidth - prefixWidth;\n\n // Use the library's ANSI-aware word-wrap on the raw text first, then\n // colorize each resulting chunk. This guarantees every line fits.\n const wrappedChunks = wrapTextWithAnsi(entry.text, textWidth);\n for (let ci = 0; ci < wrappedChunks.length; ci++) {\n const linePrefix = ci === 0 ? prefix : ' ';\n const content = colorFn(`${linePrefix}${wrappedChunks[ci]}`);\n const contentVis = visibleWidth(content);\n const padding = ' '.repeat(Math.max(0, innerWidth - contentVis));\n body.push(`${border('│')} ${content}${padding} ${border('│')}`);\n }\n }\n return [top, ...body, bottom];\n }\n}\n\nexport class PlanApprovalInlineComponent extends Container implements Focusable {\n private contentBox: Box;\n private selectList?: SelectList;\n private onApprove?: () => void;\n private onGoal?: () => void;\n private onReject?: () => void;\n private resolved = false;\n private mode: 'streaming' | 'select' = 'select';\n private planTitle: string;\n private planContent: string;\n private planFilename?: string;\n private previousPlan?: string;\n\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(\n options: PlanApprovalInlineOptions,\n private ui: TUI,\n ) {\n super();\n this.planTitle = options.title;\n this.planContent = options.plan;\n this.planFilename = options.planFilename;\n this.previousPlan = options.previousPlan;\n this.contentBox = new Box(BOX_INDENT, 0, (text: string) => text);\n this.addChild(this.contentBox);\n this.activate(options);\n }\n\n static createStreaming(ui: TUI): PlanApprovalInlineComponent {\n const component = new PlanApprovalInlineComponent(\n {\n toolCallId: '',\n title: 'Untitled plan',\n plan: '',\n onApprove: () => {},\n onGoal: () => {},\n onReject: () => {},\n },\n ui,\n );\n component.mode = 'streaming';\n component.resolved = false;\n component.renderStreaming();\n return component;\n }\n\n activate(options: PlanApprovalInlineOptions): void {\n this.onApprove = options.onApprove;\n this.onGoal = options.onGoal;\n this.onReject = options.onReject;\n this.planTitle = options.title;\n this.planContent = options.plan;\n this.planFilename = options.planFilename;\n this.previousPlan = options.previousPlan;\n this.mode = 'select';\n this.resolved = false;\n this.renderSelectable();\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'plan';\n }\n\n updateArgs(args: unknown): void {\n if (!args || typeof args !== 'object' || this.resolved) return;\n const partial = args as { path?: unknown };\n // submit_plan streams only the `path` arg; title/plan are read from disk on suspend.\n if (typeof partial.path === 'string' && partial.path) {\n this.planFilename = partial.path;\n }\n if (this.mode === 'streaming') {\n this.renderStreaming();\n }\n }\n\n private renderSelectable(): void {\n this.contentBox.clear();\n this.selectList = undefined;\n this.renderPlanHeader();\n\n // Show diff when this is a resubmission with a previous plan\n if (this.previousPlan) {\n this.contentBox.addChild(new Text(theme.fg('dim', 'Changes from previous plan:'), 0, 0));\n this.contentBox.addChild(new Spacer(1));\n this.contentBox.addChild(new PlanDiffBox(this.previousPlan, this.planContent));\n } else {\n this.renderPlanContent();\n }\n this.contentBox.addChild(new Spacer(1));\n\n const items: SelectItem[] = [\n {\n value: 'approve',\n label: ` ${theme.fg('success', 'Approve')} ${theme.fg('dim', '— switch to Build mode and implement')}`,\n },\n {\n value: 'goal',\n label: ` ${theme.fg('success', 'Use as /goal')} ${theme.fg('dim', '— switch to Build mode and pursue this plan')}`,\n },\n {\n value: 'changes',\n label: ` ${theme.fg('warning', 'Request changes')} ${theme.fg('dim', '— reject and provide feedback via chat')}`,\n },\n ];\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n\n this.selectList.onSelect = (item: SelectItem) => {\n this.handleSelection(item.value);\n };\n this.selectList.onCancel = () => {\n this.handleReject();\n };\n\n this.contentBox.addChild(this.selectList);\n this.contentBox.addChild(new Spacer(1));\n this.contentBox.addChild(new Text(theme.fg('dim', 'Up/Down navigate Enter select Esc reject'), 0, 0));\n }\n\n private renderStreaming(): void {\n this.contentBox.clear();\n this.selectList = undefined;\n this.renderPlanHeader();\n this.renderPlanContent();\n this.contentBox.addChild(new Text(theme.fg('dim', 'Submitting plan…'), 0, 0));\n }\n\n private renderPlanHeader(prefix = ''): void {\n this.contentBox.addChild(new Text(`${prefix}${theme.bold(theme.fg('accent', `Plan: ${this.planTitle}`))}`, 0, 0));\n if (this.planFilename) {\n this.contentBox.addChild(new Text(theme.fg('dim', this.planFilename), 0, 0));\n }\n this.contentBox.addChild(new Spacer(1));\n }\n\n private renderPlanContent(): void {\n this.contentBox.addChild(new PlanContentBox(this.planContent));\n }\n\n private handleSelection(value: string): void {\n if (this.resolved) return;\n\n switch (value) {\n case 'approve':\n this.handleApprove();\n break;\n case 'goal':\n this.handleGoal();\n break;\n case 'changes':\n this.handleReject();\n break;\n }\n }\n\n private handleApprove(): void {\n if (this.resolved) return;\n this.resolved = true;\n this.showResult('Approved', true);\n this.onApprove?.();\n }\n\n private handleGoal(): void {\n if (this.resolved) return;\n this.resolved = true;\n this.showResult('Set as goal', true);\n this.onGoal?.();\n }\n\n private handleReject(): void {\n if (this.resolved) return;\n this.resolved = true;\n this.showResult('Changes requested', false);\n this.onReject?.();\n }\n\n private showResult(status: string, isApproved: boolean): void {\n this.contentBox.clear();\n\n const icon = isApproved ? theme.fg('success', '✓') : theme.fg('error', '✗');\n this.renderPlanHeader();\n this.renderPlanContent();\n this.contentBox.addChild(new Spacer(1));\n this.contentBox.addChild(new Text(`${icon} ${theme.fg('dim', status)}`, 0, 0));\n this.contentBox.addChild(new Spacer(1));\n if (!isApproved) {\n this.contentBox.addChild(new Text(theme.fg('dim', 'Send a message with your revision feedback'), 0, 0));\n this.contentBox.addChild(new Spacer(1));\n }\n }\n\n handleInput(data: string): void {\n if (this.resolved) return;\n\n if (this.selectList) {\n this.selectList.handleInput(data);\n }\n }\n}\n\n/**\n * Static component for rendering a resolved plan in history.\n * Shows the plan content with approval/rejection status.\n */\nexport interface PlanResultOptions {\n title: string;\n plan: string;\n /** Filename on disk (e.g. `add-dark-mode.md`). */\n planFilename?: string;\n isApproved: boolean;\n feedback?: string;\n}\n\nexport class PlanResultComponent extends Container {\n getChatSpacingKind(): ChatSpacingKind {\n return 'plan';\n }\n\n constructor(options: PlanResultOptions) {\n super();\n\n const contentBox = new Box(BOX_INDENT, 0, (text: string) => text);\n this.addChild(contentBox);\n\n const icon = options.isApproved ? theme.fg('success', '✓') : theme.fg('error', '✗');\n const status = options.isApproved ? 'Approved' : options.feedback ? 'Changes requested' : 'Rejected';\n\n contentBox.addChild(new Text(theme.bold(theme.fg('accent', `Plan: ${options.title}`)), 0, 0));\n if (options.planFilename) {\n contentBox.addChild(new Text(theme.fg('dim', options.planFilename), 0, 0));\n }\n contentBox.addChild(new Spacer(1));\n contentBox.addChild(new PlanContentBox(options.plan));\n contentBox.addChild(new Spacer(1));\n contentBox.addChild(new Text(`${icon} ${theme.fg('dim', status)}`, 0, 0));\n contentBox.addChild(new Spacer(1));\n\n if (options.feedback && options.feedback !== 'Revision requested') {\n contentBox.addChild(new Text(theme.fg('warning', `Requested changes: ${options.feedback}`), 0, 0));\n contentBox.addChild(new Spacer(1));\n }\n }\n}\n","import { Container, Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nexport interface ReactiveSignalOptions {\n tagName: string;\n message?: string;\n}\n\nexport class ReactiveSignalComponent extends Container {\n constructor(options: ReactiveSignalOptions) {\n super();\n\n this.addChild(new Text(chalk.hex(mastra.orange).bold(`Signal: ${options.tagName}`), BOX_INDENT, 0));\n if (options.message?.trim()) {\n this.addChild(new Text(theme.fg('dim', options.message.trim()), BOX_INDENT + 2, 0));\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n}\n","import { Container, Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, mastra, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nexport interface StateSignalOptions {\n stateId: string;\n mode: 'snapshot' | 'delta';\n version?: number;\n message?: string;\n}\n\nexport class StateSignalComponent extends Container {\n constructor(options: StateSignalOptions) {\n super();\n\n const title = chalk.hex(mastra.blue).bold(`State ${options.mode}: ${options.stateId}`);\n this.addChild(new Text(title, BOX_INDENT, 0));\n\n const message = options.message?.trim();\n if (message) {\n const preview = message.length > 180 ? `${message.slice(0, 177)}...` : message;\n this.addChild(new Text(theme.fg('dim', preview), BOX_INDENT + 2, 0));\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n}\n","/**\n * Subagent execution rendering component.\n * Shows real-time activity from a delegated subagent task using\n * the same bordered box style as shell/view tools:\n * - Top border\n * - Task description (always visible)\n * - Streaming tool call activity (capped rolling window)\n * - Bottom border with agent type, model, status, duration\n */\n\nimport { Text } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport { safeStringify } from '@mastra/core/utils';\nimport chalk from 'chalk';\nimport { BOX_INDENT, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport type { IToolExecutionComponent } from './tool-execution-interface.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type SubagentActivity =\n | {\n kind: 'tool';\n name: string;\n args: unknown;\n result?: string;\n isError?: boolean;\n done: boolean;\n }\n | {\n kind: 'text';\n text: string;\n };\n\nexport type SubagentToolCall = Extract<SubagentActivity, { kind: 'tool' }>;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Component\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst MAX_ACTIVITY_LINES = 15;\nconst COLLAPSED_LINES = 15;\n\nexport interface SubagentExecutionOptions {\n /** When true, auto-collapse to a single summary line on completion. Default false. */\n collapseOnComplete?: boolean;\n /** True when this subagent is running on a forked copy of the parent thread. */\n forked?: boolean;\n /** When true, show full completed content including the final result. Default false. */\n expandOnComplete?: boolean;\n /** Footer label before the agent type. Default \"subagent\". */\n label?: string;\n /** Max activity lines shown while running. Default 15. */\n maxActivityLines?: number;\n /** Max activity lines shown when completed and collapsed. Default 15. */\n collapsedLines?: number;\n colors?: {\n border?: string;\n label?: string;\n agentType?: string;\n icon?: string;\n };\n icons?: {\n running?: string;\n success?: string;\n error?: string;\n };\n}\n\nexport class SubagentExecutionComponent extends WidthAwareContainer implements IToolExecutionComponent {\n private ui: TUI;\n\n // State\n private agentType: string;\n private task: string;\n private modelId?: string;\n private activity: SubagentActivity[] = [];\n private lastTextSnapshot = '';\n private done = false;\n private isError = false;\n private startTime = Date.now();\n private durationMs = 0;\n private finalResult?: string;\n private expanded = false;\n private collapseOnComplete: boolean;\n private expandOnComplete: boolean;\n private forked: boolean;\n private label: string;\n private maxActivityLines: number;\n private collapsedLines: number;\n private colors: NonNullable<SubagentExecutionOptions['colors']>;\n private icons: Required<NonNullable<SubagentExecutionOptions['icons']>>;\n\n constructor(agentType: string, task: string, ui: TUI, modelId?: string, options?: SubagentExecutionOptions) {\n super();\n this.agentType = agentType;\n this.task = task;\n this.modelId = modelId;\n this.ui = ui;\n this.collapseOnComplete = options?.collapseOnComplete ?? false;\n this.expandOnComplete = options?.expandOnComplete ?? false;\n this.forked = options?.forked ?? false;\n this.label = options?.label ?? 'subagent';\n this.maxActivityLines = clampPositiveInt(options?.maxActivityLines, MAX_ACTIVITY_LINES);\n this.collapsedLines = clampPositiveInt(options?.collapsedLines, COLLAPSED_LINES);\n this.colors = options?.colors ?? {};\n this.icons = {\n running: options?.icons?.running ?? '⋯',\n success: options?.icons?.success ?? '✓',\n error: options?.icons?.error ?? '✗',\n };\n\n this.rebuild();\n }\n\n // ── Mutation API ──────────────────────────────────────────────────────\n\n addToolStart(name: string, args: unknown): void {\n this.activity.push({ kind: 'tool', name, args, done: false });\n this.rebuild();\n }\n\n setTask(task: string): void {\n this.task = task;\n this.rebuild();\n }\n\n setText(text: string): void {\n const nextSnapshot = text.trim();\n if (!nextSnapshot || nextSnapshot === this.lastTextSnapshot) return;\n\n const last = this.activity.at(-1);\n const extendsPreviousSnapshot = Boolean(this.lastTextSnapshot && nextSnapshot.startsWith(this.lastTextSnapshot));\n let textToRender = nextSnapshot;\n if (extendsPreviousSnapshot) {\n const delta = nextSnapshot.slice(this.lastTextSnapshot.length);\n textToRender = last?.kind === 'text' ? delta : delta.trimStart();\n }\n this.lastTextSnapshot = nextSnapshot;\n if (!textToRender) return;\n\n if (last?.kind === 'text') {\n last.text = extendsPreviousSnapshot ? `${last.text}${textToRender}` : textToRender;\n } else {\n this.activity.push({ kind: 'text', text: textToRender });\n }\n this.rebuild();\n }\n\n addText(text: string): void {\n this.setText(text);\n }\n\n addToolEnd(name: string, result: unknown, isError: boolean): void {\n for (let i = this.activity.length - 1; i >= 0; i--) {\n const item = this.activity[i]!;\n if (item.kind === 'tool' && item.name === name && !item.done) {\n item.done = true;\n item.isError = isError;\n item.result = typeof result === 'string' ? result : safeStringify(result ?? '');\n break;\n }\n }\n this.rebuild();\n }\n\n finish(isError: boolean, durationMs: number, result?: string): void {\n this.done = true;\n this.isError = isError;\n this.durationMs = durationMs;\n this.finalResult = isDuplicateFinalResult(result, this.activity, this.lastTextSnapshot) ? undefined : result;\n if (this.expandOnComplete) {\n this.expanded = true;\n } else if (this.collapseOnComplete) {\n this.expanded = false;\n }\n this.rebuild();\n }\n\n setExpanded(expanded: boolean): void {\n this.expanded = expanded;\n this.rebuild();\n }\n\n toggleExpanded(): void {\n this.expanded = !this.expanded;\n this.rebuild();\n }\n\n // IToolExecutionComponent interface methods\n updateArgs(_args: unknown): void {}\n updateResult(_result: unknown, _isPartial: boolean): void {}\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'normal-tool';\n }\n\n // ── Rendering ──────────────────────────────────────────────────────────\n\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n const border = (char: string) =>\n theme.bold(colorText(this.colors.border, char, (text: string) => theme.fg('accent', text)));\n const maxLineWidth = Math.max(1, termWidth - 6 - BOX_INDENT * 2);\n\n // ── Bottom border with info (always rendered) ──\n const typeLabelText = this.forked ? 'fork' : this.agentType;\n const typeLabel = theme.bold(\n colorText(this.colors.agentType, typeLabelText, (text: string) => theme.fg('accent', text)),\n );\n const modelLabel = this.modelId ? theme.fg('muted', ` ${this.modelId}`) : '';\n const statusIcon = this.done\n ? this.isError\n ? colorText(this.colors.icon, ` ${this.icons.error}`, (text: string) => theme.fg('error', text))\n : colorText(this.colors.icon, ` ${this.icons.success}`, (text: string) => theme.fg('success', text))\n : colorText(this.colors.icon, ` ${this.icons.running}`, (text: string) => theme.fg('muted', text));\n const durationStr = this.done ? theme.fg('muted', ` ${formatDuration(this.durationMs)}`) : '';\n const footerText = `${theme.bold(colorText(this.colors.label, this.label, (text: string) => theme.fg('toolTitle', text)))} ${typeLabel}${modelLabel}${durationStr}${statusIcon}`;\n\n // When collapse-on-complete is enabled, render only the single-line footer summary.\n // Quiet mode does not enable this for subagents; it is kept for explicit callers/tests.\n if (this.collapseOnComplete && this.done && !this.expanded) {\n this.addChild(new Text(`${border('╰──')} ${footerText}`, BOX_INDENT, 0));\n this.invalidate();\n this.ui.requestRender();\n return;\n }\n\n // ── Top border ──\n this.addChild(new Text(border('╭──'), BOX_INDENT, 0));\n\n // ── Task description (capped when collapsed) ──\n const taskLines = this.task.split('\\n');\n const wrappedTaskLines: string[] = [];\n for (const line of taskLines) {\n if (line.length > maxLineWidth) {\n let remaining = line;\n while (remaining.length > maxLineWidth) {\n const breakAt = remaining.lastIndexOf(' ', maxLineWidth);\n const splitAt = breakAt > 0 ? breakAt : maxLineWidth;\n wrappedTaskLines.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n if (remaining) wrappedTaskLines.push(remaining);\n } else {\n wrappedTaskLines.push(line);\n }\n }\n const maxTaskLines = 5;\n const taskTruncated = !this.expanded && wrappedTaskLines.length > maxTaskLines + 1;\n const displayTaskLines = taskTruncated ? wrappedTaskLines.slice(0, maxTaskLines) : wrappedTaskLines;\n\n const taskContent = displayTaskLines.map(line => `${border('│')} ${line}`).join('\\n');\n this.addChild(new Text(taskContent, BOX_INDENT, 0));\n\n if (taskTruncated) {\n const moreText = theme.fg('muted', `... ${wrappedTaskLines.length - maxTaskLines} more lines (ctrl+e to expand)`);\n this.addChild(new Text(`${border('│')} ${moreText}`, BOX_INDENT, 0));\n }\n\n // ── Activity lines (assistant text and tool calls — capped rolling window) ──\n if (this.activity.length > 0) {\n // Separator between task and activity\n this.addChild(new Text(`${border('│')} ${theme.fg('muted', '───')}`, BOX_INDENT, 0));\n\n const activityLines = this.activity.flatMap(item =>\n formatActivityLine(item, maxLineWidth, this.icons, this.colors.icon),\n );\n\n // While streaming: rolling window. When done: collapsible.\n const cap = this.done ? this.collapsedLines : this.maxActivityLines;\n let displayLines = activityLines;\n let hiddenCount = 0;\n const minHidden = this.done ? 2 : 1;\n if (!this.expanded && activityLines.length > cap + minHidden - 1) {\n hiddenCount = activityLines.length - cap;\n displayLines = activityLines.slice(-cap);\n }\n\n if (hiddenCount > 0) {\n const hiddenText = theme.fg(\n 'muted',\n ` ... ${hiddenCount} more above${this.done ? ' (ctrl+e to expand)' : ''}`,\n );\n this.addChild(new Text(`${border('│')} ${hiddenText}`, BOX_INDENT, 0));\n }\n\n const activityContent = displayLines.map(line => `${border('│')} ${line}`).join('\\n');\n this.addChild(new Text(activityContent, BOX_INDENT, 0));\n }\n\n // ── Final result (shown after completion, only when expanded) ──\n if (this.done && this.finalResult && this.expanded) {\n this.addChild(new Text(`${border('│')} ${theme.fg('muted', '───')}`, BOX_INDENT, 0));\n const resultLines = this.finalResult!.split('\\n');\n\n const resultContent = resultLines\n .map(line => {\n const truncatedLine = line.length > maxLineWidth ? line.slice(0, maxLineWidth - 1) + '…' : line;\n return `${border('│')} ${theme.fg('muted', truncatedLine)}`;\n })\n .join('\\n');\n if (resultContent.trim()) {\n this.addChild(new Text(resultContent, BOX_INDENT, 0));\n }\n }\n\n // ── Bottom border ──\n this.addChild(new Text(`${border('╰──')} ${footerText}`, BOX_INDENT, 0));\n\n this.invalidate();\n this.ui.requestRender();\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction clampPositiveInt(value: number | undefined, fallback: number): number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : fallback;\n}\n\nfunction colorText(color: string | undefined, text: string, fallback: (text: string) => string): string {\n if (!color) return fallback(text);\n try {\n return chalk.hex(color)(text);\n } catch {\n return fallback(text);\n }\n}\n\nfunction formatActivityLine(\n activity: SubagentActivity,\n maxWidth: number,\n icons: Required<NonNullable<SubagentExecutionOptions['icons']>>,\n iconColor?: string,\n): string[] {\n if (activity.kind === 'text') return formatTextActivityLines(activity.text, maxWidth);\n return [formatToolCallLine(activity, maxWidth, icons, iconColor)];\n}\n\nfunction formatTextActivityLines(text: string, maxWidth: number): string[] {\n return text\n .trim()\n .split('\\n')\n .map(line => theme.fg('muted', line.length > maxWidth ? `${line.slice(0, maxWidth - 1)}…` : line));\n}\n\nfunction formatToolCallLine(\n tc: SubagentToolCall,\n maxWidth: number,\n icons: Required<NonNullable<SubagentExecutionOptions['icons']>>,\n iconColor?: string,\n): string {\n const iconText = tc.done ? (tc.isError ? icons.error : icons.success) : icons.running;\n const icon = tc.done\n ? tc.isError\n ? colorText(iconColor, iconText, (text: string) => theme.fg('error', text))\n : colorText(iconColor, iconText, (text: string) => theme.fg('success', text))\n : colorText(iconColor, iconText, (text: string) => theme.fg('muted', text));\n const name = theme.fg('toolTitle', tc.name);\n const prefix = `${icon} ${name}`;\n const argsSummary = summarizeArgs(tc.args, Math.max(20, maxWidth - stripAnsi(prefix).length - 1));\n return `${prefix} ${argsSummary}`;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = (ms / 1000).toFixed(1);\n return `${s}s`;\n}\n\nfunction stripAnsi(value: string): string {\n return value.replace(/\\x1b\\[[0-9;]*m/g, '');\n}\n\nfunction normalizeText(value: string): string {\n return value.trim().replace(/\\s+/g, ' ');\n}\n\nfunction isDuplicateFinalResult(\n result: string | undefined,\n activity: SubagentActivity[],\n lastTextSnapshot: string,\n): boolean {\n if (!result) return false;\n if (lastTextSnapshot && normalizeText(lastTextSnapshot) === normalizeText(result)) return true;\n const textItems = activity.filter(\n (item): item is Extract<SubagentActivity, { kind: 'text' }> => item.kind === 'text',\n );\n const lastText = textItems.at(-1)?.text;\n return lastText ? normalizeText(lastText) === normalizeText(result) : false;\n}\n\nfunction summarizeArgs(args: unknown, maxWidth = 40): string {\n if (!args || typeof args !== 'object') return '';\n const obj = args as Record<string, unknown>;\n const parts: string[] = [];\n\n // Special handling for task list snapshots.\n if (obj.tasks && Array.isArray(obj.tasks)) {\n const maxTasksInSummary = 5;\n const tasks = obj.tasks as Array<{\n content?: string;\n status?: string;\n activeForm?: string;\n }>;\n const visibleTasks = tasks.slice(0, maxTasksInSummary);\n const taskSummaries = visibleTasks.map(t => {\n const icon = t.status === 'completed' ? '✓' : t.status === 'in_progress' ? '→' : '○';\n const content = t.content || t.activeForm || 'task';\n return `${icon} ${content}`;\n });\n const extraCount = tasks.length - visibleTasks.length;\n if (extraCount > 0) {\n taskSummaries.push(`… +${extraCount} more`);\n }\n return theme.fg('muted', taskSummaries.join(', '));\n }\n\n let remainingWidth = maxWidth;\n for (const [_key, val] of Object.entries(obj)) {\n if (typeof val === 'string') {\n const short = val.length > remainingWidth ? val.slice(0, Math.max(1, remainingWidth - 1)) + '…' : val;\n parts.push(theme.fg('muted', short));\n remainingWidth -= short.length + 1;\n } else if (Array.isArray(val)) {\n parts.push(theme.fg('muted', `${val.length} items`));\n } else if (typeof val === 'object' && val !== null) {\n parts.push(theme.fg('muted', '{...}'));\n }\n }\n return parts.join(' ');\n}\n","/**\n * SystemReminderComponent - renders system-generated reminder messages\n * inline with an amber notice style.\n */\n\nimport process from 'node:process';\nimport { Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport stripAnsi from 'strip-ansi';\nimport { BOX_INDENT, mastraBrand, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nconst MAX_COLLAPSED_LINES = 10;\nconst LOADED_INSTRUCTION_INDENT = BOX_INDENT + 2;\n\nexport interface SystemReminderOptions {\n message?: string;\n reminderType?: string;\n path?: string;\n goalMaxTurns?: number;\n judgeModelId?: string;\n}\n\nexport class SystemReminderComponent extends WidthAwareContainer {\n private messageLines: string[];\n private readonly reminderType?: string;\n private readonly path?: string;\n private readonly goalMaxTurns?: number;\n private readonly judgeModelId?: string;\n private expanded = false;\n\n isExpanded(): boolean {\n return this.expanded;\n }\n\n constructor(options: SystemReminderOptions) {\n super();\n\n this.messageLines = splitMessageLines(resolveReminderMessage(options.message));\n this.reminderType = options.reminderType;\n this.path = options.path;\n this.goalMaxTurns = options.goalMaxTurns;\n this.judgeModelId = options.judgeModelId;\n\n this.rebuild();\n }\n\n setExpanded(expanded: boolean): void {\n if (this.expanded === expanded) {\n return;\n }\n\n this.expanded = expanded;\n this.rebuild();\n }\n\n toggleExpanded(): void {\n this.setExpanded(!this.expanded);\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'system';\n }\n\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n if (isLoadedInstructionPathReminder(this.reminderType, this.path)) {\n const path = formatReminderPath(this.path!);\n this.addChild(new Text(theme.fg('toolTitle', `loaded ${path}`), LOADED_INSTRUCTION_INDENT, 0));\n return;\n }\n\n const accent = getReminderAccent(this.reminderType);\n const border = (char: string) => (accent ? chalk.hex(accent).bold(char) : theme.bold(theme.fg('toolTitle', char)));\n const titleText = getReminderTitle(this.reminderType, this.path, {\n goalMaxTurns: this.goalMaxTurns,\n judgeModelId: this.judgeModelId,\n });\n const title = accent ? chalk.hex(accent).bold(titleText) : theme.bold(theme.fg('toolTitle', titleText));\n const metadataColor = (text: string) => theme.fg('dim', text);\n const bodyColor = (text: string) => theme.fg('text', text);\n const hintColor = (text: string) => theme.fg('dim', text);\n const innerWidth = Math.max(20, termWidth - BOX_INDENT * 2 - 4);\n const horizontal = '─'.repeat(innerWidth + 1);\n\n const metadataLines = [this.path ? formatReminderPath(this.path) : undefined].filter((line): line is string =>\n Boolean(line),\n );\n\n const wrappedMessageLines = wrapLines(this.messageLines, innerWidth);\n const shouldCollapse = wrappedMessageLines.length > MAX_COLLAPSED_LINES;\n const visibleMessageLines =\n shouldCollapse && !this.expanded ? wrappedMessageLines.slice(0, MAX_COLLAPSED_LINES) : wrappedMessageLines;\n\n this.addChild(new Text(`${border('╭')}${border(horizontal)}${border('╮')}`, BOX_INDENT, 0));\n this.addChild(new Text(renderRow(title, innerWidth, border), BOX_INDENT, 0));\n\n for (const line of metadataLines) {\n this.addChild(new Text(renderRow(metadataColor(line), innerWidth, border), BOX_INDENT, 0));\n }\n\n if (metadataLines.length > 0 && visibleMessageLines.length > 0) {\n this.addChild(new Text(renderRow('', innerWidth, border), BOX_INDENT, 0));\n }\n\n for (const line of visibleMessageLines) {\n this.addChild(new Text(renderRow(bodyColor(line), innerWidth, border), BOX_INDENT, 0));\n }\n\n if (shouldCollapse && !this.expanded) {\n const remaining = wrappedMessageLines.length - visibleMessageLines.length;\n const hint = hintColor(`... ${remaining} more lines (ctrl+e to expand)`);\n this.addChild(new Text(renderRow(hint, innerWidth, border), BOX_INDENT, 0));\n }\n\n this.addChild(new Text(`${border('╰')}${border(horizontal)}${border('╯')}`, BOX_INDENT, 0));\n }\n}\n\nfunction renderRow(text: string, width: number, border: (char: string) => string): string {\n const content = padLine(text, width);\n const rightPadding = hasWideGlyph(stripAnsi(text)) ? ' ' : '';\n return `${border('│')} ${content}${rightPadding}${border('│')}`;\n}\n\nfunction splitMessageLines(message: string): string[] {\n return message\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line.length > 0);\n}\n\nfunction isLoadedInstructionPathReminder(reminderType: string | undefined, path: string | undefined): boolean {\n return Boolean(path && (reminderType === 'dynamic-agents-md' || isAgentsInstructionPath(path)));\n}\n\nfunction resolveReminderMessage(message: string | undefined): string {\n const trimmedMessage = message?.trim();\n return trimmedMessage && trimmedMessage !== 'undefined' ? trimmedMessage : '';\n}\n\nfunction getReminderTitle(\n reminderType: string | undefined,\n path: string | undefined,\n metadata: { goalMaxTurns?: number; judgeModelId?: string } = {},\n): string {\n if (reminderType === 'goal') {\n const details = [\n typeof metadata.goalMaxTurns === 'number' ? `${metadata.goalMaxTurns} max attempts` : undefined,\n metadata.judgeModelId ? `judge: ${metadata.judgeModelId}` : undefined,\n ].filter(Boolean);\n return details.length > 0 ? `Goal (${details.join(', ')})` : 'Goal';\n }\n if (reminderType === 'goal-judge') return 'Goal';\n return reminderType === 'dynamic-agents-md' || isAgentsInstructionPath(path) ? 'Loaded AGENTS.md' : 'System Reminder';\n}\n\nfunction getReminderAccent(reminderType: string | undefined): string | undefined {\n return reminderType === 'goal' || reminderType === 'goal-judge' ? mastraBrand.blue : undefined;\n}\n\nfunction isAgentsInstructionPath(path: string | undefined): boolean {\n return typeof path === 'string' && /(?:^|\\/)AGENTS\\.md$/i.test(path);\n}\n\nfunction formatReminderPath(path: string): string {\n const cwd = process.cwd();\n if (path === cwd) {\n return '.';\n }\n\n const cwdPrefix = `${cwd}/`;\n return path.startsWith(cwdPrefix) ? path.slice(cwdPrefix.length) : path;\n}\n\nfunction hasWideGlyph(text: string): boolean {\n return [...text].some(char =>\n /[\\p{Extended_Pictographic}\\u1100-\\u115F\\u2329\\u232A\\u2E80-\\uA4CF\\uAC00-\\uD7A3\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE6F\\uFF00-\\uFF60\\uFFE0-\\uFFE6]/u.test(\n char,\n ),\n );\n}\n\nfunction wrapLines(lines: string[], maxLineWidth: number): string[] {\n if (lines.length === 0) {\n return [''];\n }\n\n const wrappedLines: string[] = [];\n\n for (const line of lines) {\n if (line.length <= maxLineWidth) {\n wrappedLines.push(line);\n continue;\n }\n\n let remaining = line;\n while (remaining.length > maxLineWidth) {\n const breakAt = remaining.lastIndexOf(' ', maxLineWidth);\n const splitAt = breakAt > 0 ? breakAt : maxLineWidth;\n wrappedLines.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n\n if (remaining.length > 0) {\n wrappedLines.push(remaining);\n }\n }\n\n return wrappedLines;\n}\n\nfunction padLine(text: string, width: number): string {\n const visibleLength = stripAnsi(text).length;\n if (visibleLength === width) {\n return text;\n }\n\n if (visibleLength > width) {\n return truncateLine(text, width);\n }\n\n return text + ' '.repeat(width - visibleLength);\n}\n\nfunction truncateLine(text: string, width: number): string {\n const plain = stripAnsi(text);\n return plain.length <= width ? text : plain.slice(0, Math.max(0, width - 1)) + '…';\n}\n","/**\n * Shared ANSI text-handling helpers for TUI components.\n */\n\nimport { visibleWidth } from '@earendil-works/pi-tui';\n\nconst ANSI_CLOSERS = '\\x1b]8;;\\x07\\x1b[0m';\nconst ELLIPSIS = '…';\nconst ELLIPSIS_WIDTH = visibleWidth(ELLIPSIS);\n\nfunction fitVisibleText(text: string, maxWidth: number): { text: string; width: number; truncated: boolean } {\n if (maxWidth <= 0) return { text: '', width: 0, truncated: text.length > 0 };\n\n const targetWidth = Math.max(0, maxWidth - ELLIPSIS_WIDTH);\n let width = 0;\n let result = '';\n let resultWidth = 0;\n\n for (const char of text) {\n const charWidth = visibleWidth(char);\n if (width + charWidth > maxWidth) {\n return { text: `${result}${ELLIPSIS}`, width: resultWidth + ELLIPSIS_WIDTH, truncated: true };\n }\n if (width + charWidth <= targetWidth) {\n result += char;\n resultWidth += charWidth;\n }\n width += charWidth;\n }\n\n return { text, width, truncated: false };\n}\n\n/** Truncate a string with ANSI codes to a visible width.\n * Handles both SGR sequences (\\x1b[...m) and OSC 8 hyperlinks (\\x1b]8;...;\\x07).\n */\nexport function truncateAnsi(str: string, maxWidth: number): string {\n if (maxWidth <= 0) return '';\n\n // The OSC 8 hyperlink body is terminated by BEL (\\x07). We also\n // break on a new ESC (\\x1b) so a missing terminator cannot scan\n // unbounded input and amplify polynomial backtracking.\n const ansiRegex = /\\x1b\\[[0-9;]{0,32}m|\\x1b\\]8;[^\\x07\\x1b]{0,8192}\\x07/g;\n let visibleLength = 0;\n let result = '';\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = ansiRegex.exec(str)) !== null) {\n // Add text before this ANSI code\n const textBefore = str.slice(lastIndex, match.index);\n const fitted = fitVisibleText(textBefore, maxWidth - visibleLength);\n if (fitted.truncated) {\n result += fitted.text;\n result += ANSI_CLOSERS; // Close any open hyperlink + reset styles\n return result;\n }\n result += fitted.text;\n visibleLength += fitted.width;\n\n // Add the ANSI code (doesn't count toward visible length)\n result += match[0];\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text after last ANSI code\n const remaining = str.slice(lastIndex);\n const fitted = fitVisibleText(remaining, maxWidth - visibleLength);\n result += fitted.text;\n if (fitted.truncated) result += ANSI_CLOSERS; // Close hyperlink + reset\n\n return result;\n}\n","/**\n * Task progress component for the TUI.\n * Shows a persistent, compact display of the current task list.\n * Hidden when no tasks exist OR when all tasks are completed.\n * Renders between status and editor.\n */\nimport { Text, Spacer, visibleWidth } from '@earendil-works/pi-tui';\nimport type { TaskItemInput } from '@mastra/core/signals';\nimport chalk from 'chalk';\nimport { theme } from '../theme.js';\nimport { truncateAnsi } from './ansi.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nexport function formatTaskProgressLine(task: TaskItemInput, indent = ' '): string {\n switch (task.status) {\n case 'completed': {\n const icon = theme.fg('success', '\\u2713');\n const text = chalk.hex(theme.getTheme().success).strikethrough(task.content);\n return `${indent}${icon} ${text}`;\n }\n case 'in_progress': {\n const icon = theme.fg('warning', '\\u25B6');\n const text = theme.bold(theme.fg('warning', task.activeForm));\n return `${indent}${icon} ${text}`;\n }\n case 'pending': {\n const icon = theme.fg('dim', '\\u25CB');\n const text = theme.fg('dim', task.content);\n return `${indent}${icon} ${text}`;\n }\n }\n}\n\nexport class TaskProgressComponent extends WidthAwareContainer {\n private tasks: TaskItemInput[] = [];\n private quietMode = false;\n\n constructor() {\n super();\n this.rebuild();\n }\n\n /**\n * Replace the entire task list and re-render.\n */\n updateTasks(tasks: TaskItemInput[]): void {\n this.tasks = tasks;\n this.rebuild();\n }\n\n setQuietMode(enabled: boolean): void {\n this.quietMode = enabled;\n this.rebuild();\n }\n\n /**\n * Get the current task list (read-only copy).\n */\n getTasks(): TaskItemInput[] {\n return [...this.tasks];\n }\n\n protected rebuildForWidth(width: number): void {\n this.clear();\n\n const completed = this.tasks.filter(t => t.status === 'completed').length;\n const total = this.tasks.length;\n const hasVisibleTasks = total > 0 && completed !== total;\n\n if (!hasVisibleTasks) {\n this.addChild(new Spacer(1));\n return;\n }\n\n this.addChild(new Spacer(1));\n\n if (this.quietMode) {\n for (const line of this.formatQuietTaskLines(completed, total, width)) {\n this.addChild(new Text(line, 0, 0));\n }\n return;\n }\n\n // Progress header\n const headerText =\n ' ' + theme.bold(theme.fg('accent', 'Tasks')) + theme.fg('dim', ` [${completed}/${total} completed]`);\n\n this.addChild(new Text(headerText, 0, 0));\n\n // Render each task\n for (const task of this.tasks) {\n this.addChild(new Text(formatTaskProgressLine(task), 0, 0));\n }\n }\n\n private formatQuietTaskLines(completed: number, total: number, width: number): string[] {\n const prefix = ' ' + theme.fg('muted', `${completed}/${total}`);\n const prefixWidth = visibleWidth(prefix);\n const continuationPrefix = ' '.repeat(prefixWidth);\n const maxWidth = Math.max(20, width);\n const itemSeparator = ' ';\n const separatorWidth = itemSeparator.length;\n const lines: string[] = [prefix];\n\n for (const task of this.tasks) {\n const item = this.formatQuietTaskItem(task);\n const currentLine = lines[lines.length - 1]!;\n const currentWidth = visibleWidth(currentLine);\n const separator = currentWidth === 0 ? '' : itemSeparator;\n const sepWidth = currentWidth === 0 ? 0 : separatorWidth;\n const candidateWidth = currentWidth + sepWidth + visibleWidth(item);\n\n if (candidateWidth <= maxWidth) {\n lines[lines.length - 1] = `${currentLine}${separator}${item}`;\n continue;\n }\n\n const itemLineWidth = maxWidth - prefixWidth - separatorWidth;\n lines.push(`${continuationPrefix}${itemSeparator}${truncateAnsi(item, itemLineWidth)}`);\n }\n\n return lines;\n }\n\n private formatQuietTaskItem(task: TaskItemInput): string {\n switch (task.status) {\n case 'completed': {\n const icon = theme.fg('dim', '✓');\n const text = chalk.strikethrough(theme.fg('dim', task.content));\n return `${icon} ${text}`;\n }\n case 'in_progress': {\n const icon = theme.fg('warning', '▶');\n const text = theme.bold(theme.fg('warning', task.activeForm));\n return `${icon} ${text}`;\n }\n case 'pending': {\n const icon = theme.fg('dim', '○');\n const text = theme.fg('muted', task.content);\n return `${icon} ${text}`;\n }\n }\n }\n}\n","/**\n * Lightweight inline indicator for temporal gaps between messages.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport { BOX_INDENT, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nexport interface TemporalGapOptions {\n message?: string;\n gapText?: string;\n}\n\nexport class TemporalGapComponent extends Container {\n constructor(options: TemporalGapOptions) {\n super();\n\n this.addChild(new Text(theme.fg('dim', ` ⏳ ${resolveGapText(options)}`), BOX_INDENT, 0));\n }\n\n setExpanded(_expanded: boolean): void {}\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n\nfunction resolveGapText(options: TemporalGapOptions): string {\n const gapText = options.gapText?.trim();\n if (gapText) {\n return gapText;\n }\n\n const message = options.message?.trim();\n if (!message) {\n return 'Time passed';\n }\n\n const separatorIndex = message.indexOf(' — ');\n return separatorIndex >= 0 ? message.slice(0, separatorIndex).trim() : message;\n}\n","/**\n * Generic collapsible container component.\n * Can be used to wrap any content that should be expandable/collapsible.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport { highlight } from 'cli-highlight';\nimport { theme } from '../theme.js';\n\nexport interface CollapsibleOptions {\n /** Initial expanded state */\n expanded?: boolean;\n /** Header text or component */\n header: string | Container;\n /** Summary shown when collapsed */\n summary?: string;\n /** Max lines to show when collapsed (0 = fully collapsed) */\n collapsedLines?: number;\n /** Max lines to show when expanded */\n expandedLines?: number;\n /** Whether to show line count in header */\n showLineCount?: boolean;\n}\n\nexport class CollapsibleComponent extends Container {\n private expanded: boolean;\n private header: string | Container;\n protected summary?: string;\n private content: string[] = [];\n private options: CollapsibleOptions;\n private ui: TUI;\n\n constructor(options: CollapsibleOptions, ui: TUI) {\n super();\n this.options = {\n expanded: false,\n collapsedLines: 10,\n expandedLines: 100,\n showLineCount: true,\n ...options,\n };\n this.expanded = this.options.expanded ?? false;\n this.header = options.header;\n this.summary = options.summary;\n this.ui = ui;\n this.updateDisplay();\n }\n\n setContent(content: string | string[]): void {\n this.content = Array.isArray(content) ? content : content.split('\\n');\n this.updateDisplay();\n }\n\n isExpanded(): boolean {\n return this.expanded;\n }\n\n setExpanded(expanded: boolean): void {\n this.expanded = expanded;\n this.updateDisplay();\n }\n\n toggle(): void {\n this.expanded = !this.expanded;\n this.updateDisplay();\n }\n\n private updateDisplay(): void {\n this.clear();\n\n const lineCount =\n this.options.showLineCount && this.content.length > 0 ? theme.fg('muted', ` (${this.content.length} lines)`) : '';\n\n const headerText = typeof this.header === 'string' ? `${this.header}${lineCount}` : this.header;\n\n if (typeof headerText === 'string') {\n this.addChild(new Text(headerText, 0, 0));\n } else {\n this.addChild(headerText);\n }\n\n // Show summary when collapsed if provided\n if (!this.expanded && this.summary) {\n this.addChild(new Text(theme.fg('muted', this.summary), 0, 0));\n return;\n }\n\n // Show content\n if (this.content.length === 0) return;\n\n const maxLines = this.expanded ? this.options.expandedLines! : this.options.collapsedLines!;\n\n if (maxLines === 0 && !this.expanded) {\n // Fully collapsed, show nothing\n return;\n }\n\n const linesToShow = Math.min(this.content.length, maxLines);\n const hasMore = this.content.length > maxLines;\n\n // Add content lines\n for (let i = 0; i < linesToShow; i++) {\n this.addChild(new Text(this.content[i], 0, 0));\n }\n\n // Show truncation indicator\n if (hasMore) {\n const remaining = this.content.length - linesToShow;\n const action = this.expanded ? 'collapse' : 'expand';\n const hint = theme.fg('muted', `... ${remaining} more lines (Ctrl+E to ${action} all)`);\n this.addChild(new Text(hint, 0, 0));\n }\n }\n}\n\n/**\n * File viewer with collapsible content\n */\nexport class CollapsibleFileViewer extends CollapsibleComponent {\n constructor(path: string, content: string, options: Partial<CollapsibleOptions>, ui: TUI) {\n let lines = content.split('\\n').map(line => line.trimEnd());\n\n // Remove \"Here's the result of running `cat -n`...\" header if present\n if (lines.length > 0 && lines[0]!.includes(\"Here's the result of running\")) {\n lines = lines.slice(1);\n }\n\n // Strip line numbers from cat -n format: \" 123\\tcode\" -> \"code\"\n const lineNumberRegex = /^\\s*\\d+\\t/;\n const codeLines = lines.map(line => line.replace(lineNumberRegex, ''));\n\n // Remove trailing empty lines\n while (codeLines.length > 0 && codeLines[codeLines.length - 1] === '') {\n codeLines.pop();\n }\n\n // Apply syntax highlighting\n let highlightedLines = codeLines;\n try {\n const highlighted = highlight(codeLines.join('\\n'), {\n language: getLanguageFromPath(path),\n ignoreIllegals: true,\n });\n highlightedLines = highlighted.split('\\n');\n } catch {\n // If highlighting fails, use original content\n }\n\n const header = `${theme.bold(theme.fg('toolTitle', '📄 view'))} ${theme.fg('accent', path)}`;\n\n super(\n {\n header,\n collapsedLines: 20,\n expandedLines: 200,\n showLineCount: true,\n ...options,\n },\n ui,\n );\n\n this.setContent(highlightedLines);\n }\n}\n\n/** Map file extensions to highlight.js language names */\nfunction getLanguageFromPath(path: string): string | undefined {\n const ext = path.split('.').pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n json: 'json',\n md: 'markdown',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n go: 'go',\n java: 'java',\n kt: 'kotlin',\n swift: 'swift',\n c: 'c',\n cpp: 'cpp',\n h: 'c',\n hpp: 'cpp',\n cs: 'csharp',\n php: 'php',\n sh: 'bash',\n bash: 'bash',\n zsh: 'bash',\n fish: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n toml: 'ini',\n ini: 'ini',\n xml: 'xml',\n html: 'html',\n htm: 'html',\n css: 'css',\n scss: 'scss',\n sass: 'scss',\n less: 'less',\n sql: 'sql',\n graphql: 'graphql',\n gql: 'graphql',\n dockerfile: 'dockerfile',\n makefile: 'makefile',\n cmake: 'cmake',\n vue: 'vue',\n svelte: 'xml',\n };\n return ext ? langMap[ext] : undefined;\n}\n\n/**\n * Diff viewer with collapsible hunks\n */\nexport class CollapsibleDiffViewer extends CollapsibleComponent {\n private oldContent: string;\n private newContent: string;\n\n constructor(path: string, oldContent: string, newContent: string, options: Partial<CollapsibleOptions>, ui: TUI) {\n const header = `${theme.bold(theme.fg('toolTitle', '✏️ edit'))} ${theme.fg('accent', path)}`;\n\n super(\n {\n header,\n collapsedLines: 15,\n expandedLines: 100,\n showLineCount: false,\n ...options,\n },\n ui,\n );\n\n this.oldContent = oldContent;\n this.newContent = newContent;\n this.generateDiff();\n }\n\n private generateDiff(): void {\n const oldLines = this.oldContent.split('\\n');\n const newLines = this.newContent.split('\\n');\n const diff: string[] = [];\n\n // Simple line-by-line diff (in production, use a proper diff algorithm)\n const maxLines = Math.max(oldLines.length, newLines.length);\n let addedCount = 0;\n let removedCount = 0;\n\n for (let i = 0; i < maxLines; i++) {\n if (i >= oldLines.length) {\n diff.push(theme.fg('success', `+ ${newLines[i]}`));\n addedCount++;\n } else if (i >= newLines.length) {\n diff.push(theme.fg('error', `- ${oldLines[i]}`));\n removedCount++;\n } else if (oldLines[i] !== newLines[i]) {\n diff.push(theme.fg('error', `- ${oldLines[i]}`));\n diff.push(theme.fg('success', `+ ${newLines[i]}`));\n addedCount++;\n removedCount++;\n } else {\n // Context line\n diff.push(theme.fg('muted', ` ${oldLines[i]}`));\n }\n }\n\n this.summary = `+${addedCount} -${removedCount} lines changed`;\n this.setContent(diff);\n }\n}\n\n/**\n * Command output viewer with collapsible sections\n */\nexport class CollapsibleCommandOutput extends CollapsibleComponent {\n constructor(command: string, output: string, exitCode: number, options: Partial<CollapsibleOptions>, ui: TUI) {\n const status = exitCode === 0 ? theme.fg('success', '✓') : theme.fg('error', `✗ (exit ${exitCode})`);\n\n const header = `${theme.bold(theme.fg('toolTitle', 'command'))} ${theme.fg('accent', command)} ${status}`;\n\n // Clean up output\n const lines = output.split('\\n').map(line => line.trimEnd());\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n super(\n {\n header,\n collapsedLines: exitCode === 0 ? 10 : 50, // Show more on error\n expandedLines: 500,\n showLineCount: true,\n ...options,\n },\n ui,\n );\n\n this.setContent(lines);\n }\n}\n","/**\n * Enhanced error display component with collapsible stack traces,\n * syntax highlighting, and smart summarization.\n */\n\nimport { Box, Container, Text, Spacer } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport { BOX_INDENT, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { CollapsibleComponent } from './collapsible.js';\n\nexport interface ErrorInfo {\n message: string;\n name?: string;\n stack?: string;\n code?: string;\n file?: string;\n line?: number;\n column?: number;\n context?: {\n before?: string[];\n line?: string;\n after?: string[];\n };\n}\n\n/**\n * Parse error information from various error formats\n */\nfunction parseErrorInfo(error: Error | string): ErrorInfo {\n if (typeof error === 'string') {\n // Try to parse error-like string\n const lines = error.split('\\n').filter(line => line.trim());\n const firstLine = lines[0] || '';\n\n // Check for shell command errors\n if (firstLine.includes('command not found')) {\n const cmdMatch = firstLine.match(/(\\w+):\\s*command not found/);\n return {\n name: 'CommandNotFoundError',\n message: cmdMatch ? `'${cmdMatch[1]}' is not a recognized command` : firstLine,\n };\n }\n\n // Check for \"Output:\" prefix (from tool execution)\n const cleanedError = error.replace(/^Output:\\s*/m, '');\n const cleanedLines = cleanedError.split('\\n').filter(line => line.trim());\n\n // Match Node.js error patterns\n const nodeErrorMatch = cleanedError.match(/^([A-Z][a-zA-Z]*Error):\\s*(.+)$/m);\n if (nodeErrorMatch) {\n // Extract stack trace\n const stackLines = cleanedLines.filter(line => line.match(/^\\s*at\\s+/));\n return {\n name: nodeErrorMatch[1]!,\n message: nodeErrorMatch[2]!,\n stack: stackLines.length > 0 ? stackLines.join('\\n') : undefined,\n };\n }\n\n // Match common error patterns\n const errorMatch = firstLine.match(/^([A-Z][a-zA-Z]*Error):\\s*(.+)$/);\n if (errorMatch) {\n return {\n name: errorMatch[1]!,\n message: errorMatch[2]!,\n stack: lines.slice(1).join('\\n'),\n };\n }\n\n // Extract file location if present\n const fileMatch = error.match(/at\\s+(.+?):(\\d+):?(\\d+)?/);\n\n return {\n message: cleanedLines[0] || firstLine,\n stack: cleanedLines.length > 1 ? cleanedLines.slice(1).join('\\n') : undefined,\n file: fileMatch?.[1],\n line: fileMatch?.[2] ? parseInt(fileMatch[2]) : undefined,\n column: fileMatch?.[3] ? parseInt(fileMatch[3]) : undefined,\n };\n }\n\n // Error object\n return {\n name: error.name,\n message: error.message,\n stack: error.stack,\n code: (error as any).code,\n };\n}\n\n/**\n * Format stack trace lines with syntax highlighting\n */\nfunction formatStackTrace(stack: string): string[] {\n const lines = stack.split('\\n');\n return lines.map(line => {\n // Highlight file paths\n if (line.match(/^\\s*at\\s+/)) {\n return line.replace(\n /(\\s+at\\s+)([^(]+)(\\s*\\()([^)]+)(\\))/,\n (match, at, fn, open, loc, close) =>\n `${theme.fg('muted', at)}${theme.fg('function', fn)}${theme.fg('muted', open)}${theme.fg('path', loc)}${theme.fg('muted', close)}`,\n );\n }\n\n // Mute empty lines and framework traces\n if (!line.trim() || line.includes('node_modules')) {\n return theme.fg('muted', line);\n }\n\n return line;\n });\n}\n\n/**\n * Collapsible stack trace component\n */\nclass CollapsibleStackTrace extends CollapsibleComponent {\n constructor(stack: string, options: { expanded?: boolean } = {}, ui: TUI) {\n super(\n {\n header: 'Stack Trace',\n expanded: options.expanded ?? false,\n collapsedLines: 5,\n expandedLines: 100,\n showLineCount: true,\n },\n ui,\n );\n\n // Format and set the content\n const formattedLines = formatStackTrace(stack);\n this.setContent(formattedLines.join('\\n'));\n }\n}\n\n/**\n * Enhanced error display component\n */\nexport class ErrorDisplayComponent extends Container {\n constructor(\n private error: Error | string,\n private options: {\n showStack?: boolean;\n showContext?: boolean;\n expanded?: boolean;\n } = {},\n private ui: TUI,\n ) {\n super();\n this.build();\n }\n\n private build(): void {\n const info = parseErrorInfo(this.error);\n\n // Wrap everything in a box (borders provide structure, no extra padding)\n const box = new Box(BOX_INDENT, 0, (text: string) => text);\n this.addChild(box);\n\n // Add a visible border around the entire error display\n const borderTop = new Text(theme.fg('error', '╭─ Error ─' + '─'.repeat(50) + '╮'), 0, 0);\n box.addChild(borderTop);\n\n // Error header container with background\n const errorContainer = new Container();\n\n // Add a colored background to the error message\n const errorBg = (text: string) => theme.bg('errorBg', text);\n\n // Error type and message with proper formatting\n if (info.name && info.name !== 'Error') {\n const typeLine = new Container();\n typeLine.addChild(new Text('│ ', 0, 0));\n typeLine.addChild(new Text(errorBg(` ${theme.bold(theme.fg('error', info.name))} `), 0, 0));\n errorContainer.addChild(typeLine);\n }\n\n // Error message\n const msgLine = new Container();\n msgLine.addChild(new Text('│ ', 0, 0));\n msgLine.addChild(new Text(theme.bold(info.message), 0, 0));\n errorContainer.addChild(msgLine);\n\n // File location if available\n if (info.file && info.line) {\n const location = `${info.file}:${info.line}${info.column ? `:${info.column}` : ''}`;\n errorContainer.addChild(new Text(theme.fg('muted', ` at ${location}`), 0, 0));\n }\n\n box.addChild(errorContainer);\n\n // Code context if available\n if (this.options.showContext && info.context) {\n box.addChild(new Spacer(1));\n box.addChild(this.createCodeContext(info.context, info.line));\n }\n\n // Stack trace (collapsible)\n if (this.options.showStack && info.stack) {\n box.addChild(new Spacer(1));\n box.addChild(new CollapsibleStackTrace(info.stack, { expanded: this.options.expanded }, this.ui));\n }\n\n // Add bottom border\n const borderBottom = new Text(theme.fg('error', '╰' + '─'.repeat(59) + '╯'), 0, 0);\n box.addChild(borderBottom);\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n\n private createCodeContext(context: NonNullable<ErrorInfo['context']>, errorLine?: number): Container {\n const container = new Container();\n const codeBlock = new Container();\n\n // Add a header\n codeBlock.addChild(new Text(theme.fg('muted', 'Code context:'), 0, 0));\n\n // Before lines\n if (context.before) {\n context.before.forEach((line, i) => {\n const lineNum = errorLine ? errorLine - context.before!.length + i : i + 1;\n codeBlock.addChild(new Text(theme.fg('muted', `${lineNum.toString().padStart(4)} │ ${line}`), 0, 0));\n });\n }\n\n // Error line (highlighted)\n if (context.line && errorLine) {\n codeBlock.addChild(new Text(theme.fg('error', `${errorLine.toString().padStart(4)} │ ${context.line}`), 0, 0));\n }\n\n // After lines\n if (context.after) {\n context.after.forEach((line, i) => {\n const lineNum = errorLine ? errorLine + i + 1 : i + 1;\n codeBlock.addChild(new Text(theme.fg('muted', `${lineNum.toString().padStart(4)} │ ${line}`), 0, 0));\n });\n }\n\n container.addChild(codeBlock);\n return container;\n }\n}\n","/**\n * Enhanced display component for tool validation errors.\n * Provides clear, actionable feedback when tool inputs are invalid.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport { MC_TOOLS } from '@mastra/code-sdk/tool-names';\nimport { safeStringify } from '@mastra/core/utils';\nimport { theme } from '../theme.js';\n\nexport interface ValidationError {\n field: string;\n message: string;\n expected?: string;\n received?: string;\n}\n\nexport interface ToolValidationErrorOptions {\n toolName: string;\n errors: ValidationError[];\n args?: unknown;\n schema?: unknown;\n}\n\n/**\n * Parse validation errors from various error formats\n */\nexport function parseValidationErrors(error: unknown): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (typeof error === 'string') {\n // Try to parse Zod-style errors. Restrict the gap between the field\n // name and the ': ' separator to non-newline characters and bound it\n // to avoid the polynomial backtracking CodeQL flagged on\n // attacker-crafted repetitions of `at \"!\"`.\n const zodMatch = error.match(/at \"([^\"\\n]{1,256})\"[^:\\n]{0,256}: ([^\\n]{1,4096})/g);\n if (zodMatch) {\n zodMatch.forEach(match => {\n const [, field, message] = match.match(/at \"([^\"\\n]{1,256})\"[^:\\n]{0,256}: ([^\\n]{1,4096})/) || [];\n if (field && message) {\n errors.push({ field, message });\n }\n });\n }\n\n // Try to parse \"missing required parameter\" errors. Bound the gap\n // so the lazy quantifier cannot drive O(n^2) behaviour on large\n // inputs without a closing quote.\n const missingMatch = error.match(/missing required[^\"`'\\n]{0,256}[\"`'](\\w{1,128})[\"`']/i);\n if (missingMatch) {\n errors.push({\n field: missingMatch[1]!,\n message: 'Required parameter is missing',\n });\n }\n\n // Generic fallback\n if (errors.length === 0) {\n errors.push({\n field: 'unknown',\n message: error,\n });\n }\n } else if (typeof error === 'object' && error !== null) {\n // Handle structured error objects\n const err = error as any;\n\n // Zod error format\n if (err.issues && Array.isArray(err.issues)) {\n err.issues.forEach((issue: any) => {\n errors.push({\n field: issue.path?.join('.') || 'unknown',\n message: issue.message,\n expected: issue.expected,\n received: issue.received,\n });\n });\n }\n // Generic error with message\n else if (err.message) {\n errors.push({\n field: err.field || 'unknown',\n message: err.message,\n });\n }\n }\n\n return errors.length > 0 ? errors : [{ field: 'unknown', message: String(error) }];\n}\n\n/**\n * Format tool arguments for display\n */\nfunction formatArgs(args: unknown): string[] {\n if (!args || typeof args !== 'object') return [];\n\n const lines: string[] = [];\n const obj = args as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(obj)) {\n let valueStr: string;\n if (value === null || value === undefined) {\n valueStr = theme.fg('muted', 'undefined');\n } else if (typeof value === 'string') {\n valueStr = value.length > 50 ? `\"${value.slice(0, 47)}...\"` : `\"${value}\"`;\n } else if (typeof value === 'object') {\n valueStr = safeStringify(value);\n if (valueStr.length > 50) {\n valueStr = valueStr.slice(0, 47) + '...';\n }\n } else {\n valueStr = String(value);\n }\n\n lines.push(` ${theme.fg('accent', key)}: ${valueStr}`);\n }\n\n return lines;\n}\n\n/**\n * Enhanced tool validation error display component\n */\nexport class ToolValidationErrorComponent extends Container {\n constructor(options: ToolValidationErrorOptions, _ui: TUI) {\n super();\n\n const { toolName, errors, args } = options;\n\n // Header\n this.addChild(\n new Text(\n `${theme.fg('error', '✗ Tool validation failed: ')}${theme.bold(theme.fg('toolTitle', toolName))}`,\n 0,\n 0,\n ),\n );\n this.addChild(new Text('', 0, 0));\n\n // Error details\n errors.forEach((error, index) => {\n if (index > 0) {\n this.addChild(new Text('', 0, 0));\n }\n\n if (error.field !== 'unknown') {\n this.addChild(new Text(`${theme.fg('muted', ' Parameter: ')}${theme.fg('accent', error.field)}`, 0, 0));\n }\n\n this.addChild(new Text(`${theme.fg('muted', ' Issue: ')}${theme.fg('error', error.message)}`, 0, 0));\n\n if (error.expected || error.received) {\n let detail = '';\n if (error.expected) {\n detail += `${theme.fg('muted', ' Expected: ')}${theme.fg('success', error.expected)}`;\n if (error.received) detail += theme.fg('muted', ', ');\n }\n if (error.received) {\n detail += `${theme.fg('muted', 'Received: ')}${theme.fg('error', error.received)}`;\n }\n this.addChild(new Text(detail, 0, 0));\n }\n });\n\n // Show provided arguments if available\n if (args && Object.keys(args as any).length > 0) {\n this.addChild(new Text('', 0, 0));\n this.addChild(new Text(theme.fg('muted', 'Provided arguments:'), 0, 0));\n const argsLines = formatArgs(args);\n argsLines.forEach(line => {\n this.addChild(new Text(line, 0, 0));\n });\n }\n\n // Suggestions\n const suggestions = this.generateSuggestions(toolName, errors);\n if (suggestions.length > 0) {\n this.addChild(new Text('', 0, 0));\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Suggestions:')), 0, 0));\n suggestions.forEach(suggestion => {\n this.addChild(new Text(` • ${suggestion}`, 0, 0));\n });\n }\n }\n\n private generateSuggestions(toolName: string, errors: ValidationError[]): string[] {\n const suggestions: string[] = [];\n\n const missingParams = errors.filter(\n e => e.message.toLowerCase().includes('required') || e.message.toLowerCase().includes('missing'),\n );\n\n if (missingParams.length > 0) {\n const params = missingParams.map(e => e.field).filter(f => f !== 'unknown');\n if (params.length > 0) {\n suggestions.push(`Add the required parameter${params.length > 1 ? 's' : ''}: ${params.join(', ')}`);\n }\n }\n\n const typeErrors = errors.filter(\n e => e.message.toLowerCase().includes('type') || e.message.toLowerCase().includes('expected'),\n );\n\n if (typeErrors.length > 0) {\n suggestions.push('Check that parameter types match the expected format');\n }\n\n if (toolName === 'ask_user' && errors.some(e => e.field === 'question')) {\n suggestions.push('Make sure to provide a \"question\" parameter with your question text');\n }\n\n if (toolName === MC_TOOLS.EXECUTE_COMMAND && errors.some(e => e.field === 'command')) {\n suggestions.push('Provide a \"command\" parameter with the command to execute');\n }\n\n if (toolName === MC_TOOLS.VIEW && errors.some(e => e.field === 'path')) {\n suggestions.push('Provide a \"path\" parameter with the file or directory path');\n }\n\n return suggestions;\n }\n}\n","/**\n * Enhanced tool execution component with better collapsible support.\n * This will replace the existing tool-execution.ts\n */\n\nimport * as os from 'node:os';\nimport { Box, Spacer, Text, visibleWidth } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport { MC_TOOLS } from '@mastra/code-sdk/tool-names';\nimport type { TaskItemInput } from '@mastra/core/signals';\nimport chalk from 'chalk';\nimport { highlight } from 'cli-highlight';\nimport type { Theme as HighlightTheme } from 'cli-highlight';\nimport { sanitizeAnsiForRendering } from '../sanitize-ansi.js';\nimport { BOX_INDENT, theme, mastra, tintHex, ensureTerminalGlyphContrast } from '../theme.js';\nimport { truncateAnsi } from './ansi.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { ErrorDisplayComponent } from './error-display.js';\nimport type {\n CompactToolLabelColor,\n IToolExecutionComponent,\n QuietToolDisplayMode,\n ToolResult,\n} from './tool-execution-interface.js';\nimport { ToolValidationErrorComponent, parseValidationErrors } from './tool-validation-error.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nexport type { ToolResult };\n\nconst CODE_HIGHLIGHT_THEME: HighlightTheme = {\n default: text => theme.fg('toolArgs', text),\n keyword: chalk.hex('#c084fc'),\n built_in: chalk.hex('#93c5fd'),\n type: chalk.hex('#93c5fd'),\n literal: chalk.hex('#fca5a5'),\n number: chalk.hex('#fbbf24'),\n string: chalk.hex('#86efac'),\n regexp: chalk.hex('#fca5a5'),\n title: chalk.hex('#93c5fd'),\n function: chalk.hex('#93c5fd'),\n params: chalk.hex('#d4d4d8'),\n comment: chalk.hex('#71717a'),\n meta: chalk.hex('#a1a1aa'),\n attr: chalk.hex('#fbbf24'),\n variable: chalk.hex('#d4d4d8'),\n tag: chalk.hex('#c084fc'),\n name: chalk.hex('#c084fc'),\n};\n\nconst COMPACT_TOOL_COLOR = mastra.orange;\nconst COMPACT_TOOL_ARGS_BG = '#141414';\nconst QUIET_TOOL_RAIL = tintHex(COMPACT_TOOL_COLOR, 0.35);\nconst QUIET_CODE_PREVIEW_MAX_CHARS = 2_000;\nconst QUIET_SHELL_COMMAND_HIGHLIGHT_MAX_CHARS = 2_000;\n\nfunction normalizeHexColor(color: string | undefined): string | undefined {\n if (!color || !/^#[0-9a-f]{6}$/i.test(color)) return undefined;\n return color;\n}\n\nconst QUIET_CODE_HIGHLIGHT_THEME: HighlightTheme = {\n default: chalk.hex('#b4b4bd'),\n keyword: chalk.hex('#c4b5fd'),\n built_in: chalk.hex('#93c5fd'),\n type: chalk.hex('#93c5fd'),\n literal: chalk.hex('#fca5a5'),\n number: chalk.hex('#fbbf24'),\n string: chalk.hex('#9ecfa9'),\n regexp: chalk.hex('#fca5a5'),\n title: chalk.hex('#93c5fd'),\n function: chalk.hex('#7dd3fc'),\n params: chalk.hex('#b4b4bd'),\n comment: chalk.hex('#71717a'),\n meta: chalk.hex('#71717a'),\n attr: chalk.hex('#fbbf24'),\n variable: chalk.hex('#d4d4d8'),\n tag: chalk.hex('#c4b5fd'),\n name: chalk.hex('#c4b5fd'),\n};\n\nconst SHELL_CONTROL_WORDS = new Set([\n 'if',\n 'then',\n 'else',\n 'elif',\n 'fi',\n 'for',\n 'while',\n 'until',\n 'do',\n 'done',\n 'case',\n 'esac',\n 'in',\n 'function',\n]);\n\nexport interface ToolExecutionOptions {\n showImages?: boolean;\n autoCollapse?: boolean;\n collapsedByDefault?: boolean;\n quietDisplayMode?: QuietToolDisplayMode;\n quietPreviewLineLimit?: number;\n compactToolModeColor?: string;\n}\n/**\n * Convert absolute path to tilde notation if it's in home directory\n */\nfunction shortenPath(path: string): string {\n const home = os.homedir();\n if (path.startsWith(home)) {\n return `~${path.slice(home.length)}`;\n }\n return path;\n}\n\n/**\n * Resolve a file path to an absolute path for use in file:// URLs.\n */\nfunction resolveAbsolutePath(filePath: string): string {\n if (filePath.startsWith('/')) return filePath;\n if (filePath.startsWith('~')) {\n return os.homedir() + filePath.slice(1);\n }\n return process.cwd() + '/' + filePath;\n}\n\n/**\n * Wrap text in an OSC 8 hyperlink to a file path.\n * Terminals that support OSC 8 (iTerm2, WezTerm, Kitty, etc.) will\n * render the text as a clickable link that opens the file.\n * Other terminals will just show the visible text.\n */\nfunction fileLink(displayText: string, filePath: string, line?: number): string {\n const absPath = resolveAbsolutePath(filePath);\n const lineFragment = line ? `#${line}` : '';\n // OSC 8: \\x1b]8;params;URI\\x07 ... \\x1b]8;;\\x07\n return `\\x1b]8;;file://${absPath}${lineFragment}\\x07${displayText}\\x1b]8;;\\x07`;\n}\n\n/** Check if a tool name is a web search provider tool (e.g. web_search, web_search_20250305) */\nfunction isWebSearchTool(name: string): boolean {\n return name === 'web_search' || /^web_search_\\d+$/.test(name);\n}\n\nfunction isBrowserTool(name: string): boolean {\n return name.startsWith('browser_');\n}\n\nfunction isSkillTool(name: string): boolean {\n return name === 'skill' || name === 'skill_search' || name === 'skill_read';\n}\n\n/**\n * Extract the actual content from tool result text.\n */\nfunction extractContent(text: string): { content: string; isError: boolean } {\n try {\n const parsed = JSON.parse(text);\n if (typeof parsed === 'object' && parsed !== null) {\n if ('content' in parsed) {\n const content = parsed.content;\n let contentStr: string;\n\n if (typeof content === 'string') {\n contentStr = content;\n } else if (Array.isArray(content)) {\n contentStr = content\n .filter(\n (part: unknown) =>\n typeof part === 'object' && part !== null && (part as Record<string, unknown>).type === 'text',\n )\n .map((part: unknown) => (part as Record<string, unknown>).text || '')\n .join('');\n } else {\n contentStr = JSON.stringify(content, null, 2);\n }\n\n return {\n content: contentStr,\n isError: Boolean(parsed.isError),\n };\n }\n return { content: JSON.stringify(parsed, null, 2), isError: false };\n }\n } catch {\n // Not JSON, use as-is\n }\n return { content: text, isError: false };\n}\n\n/**\n * Enhanced tool execution component with collapsible sections\n */\nexport class ToolExecutionComponentEnhanced extends WidthAwareContainer implements IToolExecutionComponent {\n private contentBox: Box;\n private toolName: string;\n private args: unknown;\n private expanded = false;\n private isPartial = true;\n private ui: TUI;\n private result?: ToolResult;\n private options: ToolExecutionOptions;\n private startTime = Date.now();\n private streamingOutput = ''; // Buffer for streaming shell output\n private quietDisplayMode: QuietToolDisplayMode;\n private quietPreviewLineLimit: number;\n private quietPreviewRowFloor = 0;\n private compactToolContinuation = false;\n private compactToolHasFollowingContinuation = false;\n private compactToolPreviousSummary: string | undefined;\n private compactToolGroupLabelColor: CompactToolLabelColor | undefined;\n private compactToolModeColor: string | undefined;\n\n constructor(toolName: string, args: unknown, options: ToolExecutionOptions = {}, ui: TUI) {\n super();\n this.toolName = toolName;\n this.args = args;\n this.ui = ui;\n this.options = {\n autoCollapse: true,\n collapsedByDefault: true,\n ...options,\n };\n this.expanded = !this.options.collapsedByDefault;\n this.quietDisplayMode = this.options.quietDisplayMode ?? 'normal';\n this.quietPreviewLineLimit = this.options.quietPreviewLineLimit ?? 2;\n this.compactToolModeColor = normalizeHexColor(this.options.compactToolModeColor);\n\n // Content box - left indent for chat history alignment, no background\n this.contentBox = new Box(BOX_INDENT, 0, (text: string) => text);\n this.addChild(this.contentBox);\n this.updateTrailingSpacer();\n\n this.rebuild();\n }\n\n updateArgs(args: unknown, rebuild = true): void {\n this.args = args;\n if (rebuild) this.rebuild();\n }\n\n refresh(): void {\n this.rebuild();\n }\n\n updateResult(result: ToolResult, isPartial = false): void {\n this.result = result;\n this.isPartial = isPartial;\n // Keep streaming output for colored display in final result\n this.rebuild();\n }\n\n /**\n * Append streaming shell output.\n * Only for execute_command tool - shows live output while command runs.\n */\n appendStreamingOutput(output: string): void {\n if (\n this.toolName !== MC_TOOLS.EXECUTE_COMMAND &&\n this.toolName !== MC_TOOLS.GET_PROCESS_OUTPUT &&\n this.toolName !== MC_TOOLS.KILL_PROCESS\n ) {\n return;\n }\n this.streamingOutput += sanitizeAnsiForRendering(output);\n this.rebuild();\n }\n\n setExpanded(expanded: boolean): void {\n this.expanded = expanded;\n this.rebuild();\n }\n\n setQuietModeDisplay(mode: QuietToolDisplayMode): void {\n this.quietDisplayMode = mode;\n this.updateTrailingSpacer();\n this.rebuild();\n }\n\n setQuietPreviewLineLimit(limit: number): void {\n const normalizedLimit = Number.isFinite(limit) ? limit : 2;\n this.quietPreviewLineLimit = Math.min(8, Math.max(0, Math.floor(normalizedLimit)));\n this.quietPreviewRowFloor = Math.min(this.quietPreviewRowFloor, this.quietPreviewLineLimit);\n this.rebuild();\n }\n\n setCompactToolModeColor(color: string | undefined): void {\n const nextColor = normalizeHexColor(color);\n if (this.compactToolModeColor === nextColor) return;\n this.compactToolModeColor = nextColor;\n if (this.quietDisplayMode === 'quiet') this.rebuild();\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n if (this.quietDisplayMode === 'quiet') {\n return this.toolName === MC_TOOLS.EXECUTE_COMMAND ? 'quiet-shell-tool' : 'quiet-compact-tool';\n }\n return 'normal-tool';\n }\n\n getCompactToolGroupKey(): string | undefined {\n if (this.getChatSpacingKind() !== 'quiet-compact-tool') return undefined;\n return this.getCompactToolLabel();\n }\n\n getCompactToolGroupSummary(): string | undefined {\n if (this.getChatSpacingKind() !== 'quiet-compact-tool') return undefined;\n return this.getCompactToolSummary();\n }\n\n hasQuietStreamingPreview(): boolean {\n return (\n this.quietDisplayMode === 'quiet' &&\n this.toolName !== MC_TOOLS.EXECUTE_COMMAND &&\n this.quietPreviewLineLimit > 0 &&\n (this.quietPreviewRowFloor > 0 || this.getQuietActivePreview() !== '')\n );\n }\n\n setCompactToolContinuation(continuation: boolean, previousSummary?: string): void {\n if (this.compactToolContinuation === continuation && this.compactToolPreviousSummary === previousSummary) return;\n this.compactToolContinuation = continuation;\n this.compactToolPreviousSummary = previousSummary;\n this.rebuild();\n }\n\n setCompactToolHasFollowingContinuation(hasFollowingContinuation: boolean): void {\n if (this.compactToolHasFollowingContinuation === hasFollowingContinuation) return;\n this.compactToolHasFollowingContinuation = hasFollowingContinuation;\n this.rebuild();\n }\n\n isComplete(): boolean {\n return !this.isPartial;\n }\n\n toggleExpanded(): void {\n this.setExpanded(!this.expanded);\n }\n\n override invalidate(): void {\n super.invalidate();\n // invalidate is called by the layout system — only update bg, don't rebuild\n this.updateBgColor();\n }\n\n private updateBgColor(): void {\n // No background for any tools - use bordered box style instead\n this.contentBox.setBgFn((text: string) => text);\n }\n\n private updateTrailingSpacer(): void {\n const trailingSpacerHeight = 0;\n const desiredChildren = trailingSpacerHeight > 0 ? 2 : 1;\n while (this.children.length > desiredChildren) {\n this.children.pop();\n }\n if (this.children.length < desiredChildren) {\n this.addChild(new Spacer(trailingSpacerHeight));\n }\n }\n\n private getCollapsedLineLimit(defaultLimit: number): number {\n return defaultLimit;\n }\n\n private shouldShowLeadingPadding(): boolean {\n return this.quietDisplayMode === 'normal';\n }\n\n private addLeadingPadding(): void {\n if (this.shouldShowLeadingPadding()) {\n this.contentBox.addChild(new Text('', 0, 0));\n }\n }\n\n private limitQuietShellLines(lines: string[]): string[] {\n if (this.quietDisplayMode !== 'quiet' || lines.length <= 15) {\n return lines;\n }\n return lines.slice(-15);\n }\n\n /**\n * Full clear-and-rebuild. Called when:\n * - args change (updateArgs)\n * - result arrives or changes (updateResult)\n * - expand/collapse on a tool with no collapsible child\n * - initial construction\n */\n protected rebuildForWidth(_width: number): void {\n this.updateBgColor();\n this.contentBox.clear();\n\n if (this.quietDisplayMode === 'quiet' && this.toolName !== MC_TOOLS.EXECUTE_COMMAND) {\n this.renderCompactTool();\n return;\n }\n\n switch (this.toolName) {\n case MC_TOOLS.VIEW:\n this.renderViewToolEnhanced();\n break;\n case MC_TOOLS.EXECUTE_COMMAND:\n this.renderBashToolEnhanced();\n break;\n case MC_TOOLS.STRING_REPLACE_LSP:\n this.renderEditToolEnhanced();\n break;\n case MC_TOOLS.WRITE_FILE:\n this.renderWriteToolEnhanced();\n break;\n case MC_TOOLS.FIND_FILES:\n this.renderListFilesEnhanced();\n break;\n case MC_TOOLS.LSP_INSPECT:\n this.renderLspInspectEnhanced();\n break;\n case MC_TOOLS.GET_PROCESS_OUTPUT:\n case MC_TOOLS.KILL_PROCESS:\n this.renderProcessToolEnhanced();\n break;\n case 'task_write':\n this.renderTaskWriteEnhanced();\n break;\n default:\n if (isWebSearchTool(this.toolName)) {\n this.renderWebSearchEnhanced();\n } else {\n this.renderGenericToolEnhanced();\n }\n }\n }\n\n private renderCompactTool(): void {\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - BOX_INDENT * 2 - 2;\n const lines = this.getCompactToolSummaryLines();\n\n for (const line of lines) {\n this.contentBox.addChild(new Text(truncateAnsi(line, maxLineWidth), 0, 0));\n }\n }\n\n private getQuietPreviewLines(maxLineWidth: number): string[] {\n if (\n this.quietDisplayMode !== 'quiet' ||\n this.toolName === MC_TOOLS.EXECUTE_COMMAND ||\n this.quietPreviewLineLimit <= 0\n )\n return [];\n\n const preview = this.getQuietActivePreview();\n let lines: string[] = [];\n\n if (preview) {\n if (this.isQuietCodePreviewTool()) {\n lines = this.getQuietCodePreviewLines(preview, maxLineWidth);\n } else {\n const firstLineWidth = Math.max(10, maxLineWidth - 4);\n const continuationWidth = Math.max(10, maxLineWidth - 4);\n const wrapped = this.wrapPreviewLines(preview, firstLineWidth, continuationWidth).slice(\n -this.quietPreviewLineLimit,\n );\n\n lines = wrapped.map(line => {\n const linePrefix = ` ${chalk.hex(this.getQuietToolRailColor())('│')} `;\n return truncateAnsi(`${linePrefix}${this.formatQuietActivePreview(line)}`, maxLineWidth);\n });\n }\n }\n\n this.quietPreviewRowFloor = Math.min(this.quietPreviewLineLimit, Math.max(this.quietPreviewRowFloor, lines.length));\n const padding = Array.from({ length: this.quietPreviewRowFloor - lines.length }, () => {\n const linePrefix = ` ${chalk.hex(this.getQuietToolRailColor())('│')} `;\n return truncateAnsi(linePrefix, maxLineWidth);\n });\n return [...padding, ...lines];\n }\n\n private getQuietCodePreviewLines(preview: string, maxLineWidth: number): string[] {\n const linePrefix = ` ${chalk.hex(this.getQuietToolRailColor())('│')} `;\n return this.highlightQuietCodePreview(preview)\n .split('\\n')\n .slice(-this.quietPreviewLineLimit)\n .map(line => truncateAnsi(`${linePrefix}${line}`, maxLineWidth));\n }\n\n private isQuietCodePreviewTool(): boolean {\n return (\n this.toolName === MC_TOOLS.VIEW ||\n this.toolName === MC_TOOLS.WRITE_FILE ||\n this.toolName === MC_TOOLS.STRING_REPLACE_LSP\n );\n }\n\n private getQuietPreviewCapLine(): string {\n return ` ${chalk.hex(this.getQuietToolRailColor())('╰──')}`;\n }\n\n private getQuietPreviewSpacerLine(): string {\n return ` ${chalk.hex(this.getQuietToolRailColor())('│')}`;\n }\n\n private shouldCloseQuietPreview(): boolean {\n return !this.compactToolHasFollowingContinuation;\n }\n\n private formatQuietActivePreview(preview: string): string {\n if (this.toolName === MC_TOOLS.FIND_FILES || this.toolName === MC_TOOLS.SEARCH_CONTENT) {\n return theme.fg('toolOutput', preview);\n }\n\n return theme.fg('text', preview);\n }\n\n private highlightQuietCodePreview(preview: string): string {\n const path = this.getFirstStringArg('path');\n try {\n return highlight(preview, {\n language: getLanguageFromPath(path),\n ignoreIllegals: true,\n theme: QUIET_CODE_HIGHLIGHT_THEME,\n });\n } catch {\n return theme.fg('toolArgs', preview);\n }\n }\n\n private highlightQuietShellCommandToken(token: string): string {\n if (token === '&&' || token === '||' || token === '|' || token === ';' || token === '&') {\n return theme.fg('muted', token);\n }\n if (token === '(' || token === ')' || token === '<' || token === '>') {\n return theme.fg('muted', token);\n }\n if (/^\\d+(?:\\.\\d+)?$/.test(token)) return chalk.white(token);\n if (SHELL_CONTROL_WORDS.has(token)) return chalk.blue(token);\n return theme.fg('toolArgs', token);\n }\n\n private highlightQuietShellCommandLine(\n line: string,\n quote: 'single' | 'double' | undefined,\n ): { line: string; quote: 'single' | 'double' | undefined } {\n let highlighted = '';\n let plain = '';\n let quoted = '';\n let activeQuote = quote;\n\n const flushPlain = () => {\n if (!plain) return;\n highlighted += plain.replace(\n /&&|\\|\\||[|;&()<>]|-{1,2}[a-zA-Z0-9_.=/-]+|\\b\\d+(?:\\.\\d+)?\\b|\\b[a-zA-Z_][a-zA-Z0-9_]*\\b/g,\n token => this.highlightQuietShellCommandToken(token),\n );\n plain = '';\n };\n const flushQuoted = () => {\n if (!quoted) return;\n highlighted += chalk.white(quoted);\n quoted = '';\n };\n\n for (let index = 0; index < line.length; index++) {\n const char = line[index]!;\n\n if (activeQuote) {\n quoted += char;\n let precedingBackslashes = 0;\n for (let cursor = index - 1; cursor >= 0 && line[cursor] === '\\\\'; cursor--) {\n precedingBackslashes++;\n }\n const closesQuote =\n (activeQuote === 'single' && char === \"'\") ||\n (activeQuote === 'double' && char === '\"' && precedingBackslashes % 2 === 0);\n if (closesQuote) {\n flushQuoted();\n activeQuote = undefined;\n }\n continue;\n }\n\n if (char === \"'\" || char === '\"') {\n flushPlain();\n activeQuote = char === \"'\" ? 'single' : 'double';\n quoted += char;\n continue;\n }\n\n plain += char;\n }\n\n flushPlain();\n flushQuoted();\n return { line: highlighted, quote: activeQuote };\n }\n\n private wrapQuietShellCommand(command: string, width: number): string[] {\n const lines: string[] = [];\n let current = '';\n let currentWidth = 0;\n let highlightedChars = 0;\n let quote: 'single' | 'double' | undefined;\n\n const pushCurrent = () => {\n const highlightLength = Math.min(current.length, QUIET_SHELL_COMMAND_HIGHLIGHT_MAX_CHARS - highlightedChars);\n const highlighted = this.highlightQuietShellCommandLine(current.slice(0, highlightLength), quote);\n lines.push(highlighted.line + current.slice(highlightLength));\n highlightedChars += highlightLength;\n quote = highlighted.quote;\n current = '';\n currentWidth = 0;\n };\n\n for (const char of command) {\n if (char === '\\n') {\n pushCurrent();\n continue;\n }\n\n const charWidth = visibleWidth(char);\n if (current && currentWidth + charWidth > width) {\n pushCurrent();\n }\n if (!current && /^\\s$/.test(char)) continue;\n\n current += char;\n currentWidth += charWidth;\n }\n\n if (current || lines.length === 0) pushCurrent();\n return lines;\n }\n\n private wrapPreviewLines(preview: string, firstLineWidth: number, continuationWidth: number): string[] {\n const lines: string[] = [];\n let width = firstLineWidth;\n\n for (const sourceLine of preview.split('\\n')) {\n if (sourceLine.length === 0) {\n if (lines.length > 0) width = continuationWidth;\n continue;\n }\n\n let remaining = sourceLine;\n while (remaining.length > width) {\n lines.push(remaining.slice(0, width));\n remaining = remaining.slice(width);\n width = continuationWidth;\n }\n\n lines.push(remaining);\n width = continuationWidth;\n }\n\n return lines;\n }\n\n private getCompactToolSummaryLines(): string[] {\n const status = this.getCompactStatusIndicator();\n const toolLabel = this.getCompactToolLabel();\n const toolLabelColor = this.getCompactToolLabelColor();\n const summary = this.compactToolContinuation ? this.getCompactContinuationSummary() : this.getCompactToolSummary();\n const detailLines = this.getQuietPreviewLines(this.renderWidth - BOX_INDENT * 2 - 2);\n const firstLine = this.compactToolContinuation\n ? summary\n ? `${this.getCompactContinuationIndent()}${this.formatCompactContinuationLine(summary)}${status}`\n : this.compactToolPreviousSummary\n ? `${this.getCompactContinuationIndent()}${this.formatEmptyCompactContinuationLine()}${status}`\n : `${this.getCompactContinuationIndent()}${this.formatCompactToolHeader(toolLabel, toolLabelColor, '')}${status}`\n : `${this.formatCompactToolHeader(toolLabel, toolLabelColor, summary)}${status}`;\n\n if (detailLines.length === 0) return [firstLine];\n const previewLines = this.shouldCloseQuietPreview() ? [...detailLines, this.getQuietPreviewCapLine()] : detailLines;\n if (this.compactToolHasFollowingContinuation) previewLines.push(this.getQuietPreviewSpacerLine());\n return [firstLine, ...previewLines];\n }\n\n private getCompactStatusIndicator(): string {\n return this.isErrorResult() ? theme.fg('error', ' ✗') : '';\n }\n\n private formatCompactToolHeader(toolLabel: string, toolLabelColor: CompactToolLabelColor, summary: string): string {\n const color = this.getCompactToolAccentColor(toolLabelColor);\n const argsBg = this.getCompactToolArgsBg(toolLabelColor);\n const argsColor = this.getCompactToolArgsColor(toolLabelColor);\n const leftHalf = chalk.hex(color)('▐');\n const rightHalf = summary ? chalk.hex(color).bgHex(argsBg)('▌') : chalk.hex(color)('▌');\n const label = `${leftHalf}${chalk.bgHex(color).hex('#000000').bold(toolLabel)}${rightHalf}`;\n const args = summary ? this.formatCompactSummaryBadge(summary, argsBg, argsColor) : '';\n const trail = summary ? chalk.hex(argsBg)('▌') : '';\n return `${label}${args}${trail}`;\n }\n\n private getCompactToolAccentColor(toolLabelColor: CompactToolLabelColor): string {\n if (this.isErrorResult() || toolLabelColor === 'error') return mastra.red;\n return this.compactToolModeColor ?? COMPACT_TOOL_COLOR;\n }\n\n private getCompactToolArgsBg(toolLabelColor: CompactToolLabelColor): string {\n if (this.isErrorResult() || toolLabelColor === 'error') return tintHex(mastra.red, 0.15);\n return COMPACT_TOOL_ARGS_BG;\n }\n\n private getCompactToolArgsColor(toolLabelColor: CompactToolLabelColor): string | undefined {\n if (this.isErrorResult() || toolLabelColor === 'error') return undefined;\n return this.compactToolModeColor ?? COMPACT_TOOL_COLOR;\n }\n\n private getQuietToolRailColor(): string {\n const color = this.isErrorResult()\n ? tintHex(mastra.red, 0.35)\n : this.compactToolModeColor\n ? tintHex(this.compactToolModeColor, 0.35)\n : QUIET_TOOL_RAIL;\n return ensureTerminalGlyphContrast(color);\n }\n\n private getQuietToolCircleColor(color: string): string {\n return ensureTerminalGlyphContrast(color);\n }\n\n private formatToolBorder(char: string): string {\n return theme.bold(chalk.hex(ensureTerminalGlyphContrast(theme.getTheme().toolBorderSuccess))(char));\n }\n\n getCompactToolLabelColor(): CompactToolLabelColor {\n if (this.compactToolGroupLabelColor) return this.compactToolGroupLabelColor;\n return this.getOwnCompactToolLabelColor();\n }\n\n setCompactToolGroupLabelColor(color: CompactToolLabelColor | undefined): void {\n if (this.compactToolGroupLabelColor === color) return;\n this.compactToolGroupLabelColor = color;\n this.rebuild();\n }\n\n getOwnCompactToolLabelColor(): CompactToolLabelColor {\n return this.isErrorResult() ? 'error' : 'toolTitle';\n }\n\n private isErrorResult(): boolean {\n if (this.result?.isError) return true;\n if (!this.result) return false;\n\n const output = this.getFormattedOutput();\n if (this.toolName === MC_TOOLS.STRING_REPLACE_LSP && /specified text was not found/i.test(output)) return true;\n return false;\n }\n\n private getQuietActivePreview(): string {\n if (this.isErrorResult()) return this.formatQuietErrorPreview();\n if (isWebSearchTool(this.toolName)) return this.formatQuietWebSearchPreview();\n if (isBrowserTool(this.toolName)) return this.formatQuietBrowserPreview();\n if (isSkillTool(this.toolName)) return this.formatQuietSkillPreview();\n if (this.toolName === MC_TOOLS.GET_PROCESS_OUTPUT) return this.formatQuietProcessOutputPreview();\n if (this.toolName === MC_TOOLS.FILE_STAT) return this.formatQuietFileStatPreview();\n\n switch (this.toolName) {\n case MC_TOOLS.VIEW:\n return this.formatQuietViewPreview();\n case MC_TOOLS.FIND_FILES:\n return this.formatQuietListPreview();\n case 'skill':\n return '';\n case MC_TOOLS.STRING_REPLACE_LSP:\n return this.formatQuietEditPreview();\n case MC_TOOLS.WRITE_FILE:\n return this.getLatestCodePreview('content');\n case MC_TOOLS.SEARCH_CONTENT:\n return this.formatSearchDetail();\n case MC_TOOLS.LSP_INSPECT:\n return this.getFirstLineArg('match', 80);\n default:\n return this.formatQuietGenericResultPreview();\n }\n }\n\n private formatQuietEditPreview(): string {\n return (\n this.getLatestCodePreview('new_str') ||\n this.getLatestCodePreview('new_string') ||\n this.getLatestCodePreview('old_str') ||\n this.getLatestCodePreview('old_string')\n );\n }\n\n private getLatestCodePreview(key: string): string {\n const value = this.getFirstStringArg(key);\n if (!value) return '';\n const normalized = value.replace(/\\r\\n/g, '\\n').replace(/^\\n+|\\n+$/g, '');\n if (!normalized) return '';\n const lines = normalized.split('\\n');\n const latestLines = lines.slice(-Math.max(1, this.quietPreviewLineLimit)).join('\\n');\n if (this.isPartial && (this.toolName === MC_TOOLS.WRITE_FILE || this.toolName === MC_TOOLS.STRING_REPLACE_LSP)) {\n return latestLines;\n }\n if (latestLines.length <= QUIET_CODE_PREVIEW_MAX_CHARS) return latestLines;\n return latestLines.slice(-QUIET_CODE_PREVIEW_MAX_CHARS);\n }\n\n private formatQuietErrorPreview(): string {\n const outputLines = this.stripAnsi(this.getFormattedOutput())\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n if (outputLines.some(line => line.startsWith('Validation error:') || line.startsWith('Parameter:'))) {\n return outputLines.join(' — ');\n }\n return outputLines.slice(0, 2).join('\\n');\n }\n\n private formatQuietViewPreview(): string {\n if (!this.result) return '';\n\n const output = this.getFormattedOutput();\n if (!output || !this.looksLikeViewOutput(output)) return '';\n\n const argsObj = this.args as Record<string, unknown> | undefined;\n const viewRange = argsObj?.view_range as [number, number] | undefined;\n const startLine = viewRange?.[0] ?? (argsObj?.offset as number | undefined) ?? 1;\n return getPlainCodeFromViewOutput(output, startLine);\n }\n\n private formatQuietListPreview(): string {\n if (!this.result) return '';\n\n const entries = this.getListResultEntries();\n if (entries.length === 0) return '';\n\n return entries.slice(0, 2).join('\\n');\n }\n\n private formatQuietWebSearchPreview(): string {\n if (!this.result) return '';\n\n return this.stripAnsi(this.formatWebSearchResults())\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean)\n .slice(0, 2)\n .join('\\n');\n }\n\n private formatQuietBrowserPreview(): string {\n if (!this.result || !['browser_snapshot', 'browser_evaluate'].includes(this.toolName)) return '';\n const output = this.unwrapBrowserToolOutput(this.getFormattedOutput());\n return this.stripAnsi(output)\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n .slice(0, 2)\n .join('\\n');\n }\n\n private unwrapBrowserToolOutput(output: string): string {\n try {\n const parsed = JSON.parse(output) as unknown;\n if (typeof parsed !== 'object' || parsed === null) return output;\n const record = parsed as Record<string, unknown>;\n if (this.toolName === 'browser_evaluate' && record.result !== undefined) {\n return this.formatBrowserEvaluateResult(record.result);\n }\n if (this.toolName === 'browser_snapshot' && typeof record.snapshot === 'string') return record.snapshot;\n if (typeof record.error === 'string') return record.error;\n return '';\n } catch {\n return output;\n }\n }\n\n private formatBrowserEvaluateResult(result: unknown): string {\n if (typeof result === 'string') return result;\n if (typeof result !== 'object' || result === null) return String(result);\n if (Array.isArray(result)) return `[${result.length} items]`;\n\n return Object.entries(result as Record<string, unknown>)\n .slice(0, 3)\n .map(([key, value]) => `${key}: ${this.formatCompactBrowserValue(value)}`)\n .join('\\n');\n }\n\n private formatCompactBrowserValue(value: unknown): string {\n if (typeof value === 'string') return value === '' ? '\"\"' : value;\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (Array.isArray(value)) return `[${value.length} items]`;\n if (typeof value === 'object') return '{…}';\n return String(value);\n }\n\n private formatQuietProcessOutputPreview(): string {\n if (!this.result) return '';\n return this.stripAnsi(this.getFormattedOutput())\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n .slice(0, 3)\n .join('\\n');\n }\n\n private formatQuietFileStatPreview(): string {\n if (!this.result) return '';\n const output = this.stripAnsi(this.getFormattedOutput()).trim();\n return output.replace(/^\\S+\\s+/, '').replace(/\\s+/g, ' ');\n }\n\n private formatQuietGenericResultPreview(): string {\n if (!this.result) return '';\n const output = this.stripAnsi(this.getFormattedOutput()).trim();\n if (!output) return '';\n\n const compactJson = this.formatCompactJsonResult(output);\n const preview = compactJson || output;\n const argsSummary = this.stripAnsi(this.formatArgsSummary()).trim();\n if (argsSummary && preview === argsSummary) return '';\n\n const lines = preview\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean);\n\n return (this.isPartial ? lines : lines.slice(0, this.quietPreviewLineLimit)).join('\\n');\n }\n\n private formatCompactJsonResult(output: string): string {\n try {\n const parsed = JSON.parse(output) as unknown;\n if (typeof parsed !== 'object' || parsed === null) return String(parsed);\n if (Array.isArray(parsed)) return `[${parsed.length} items]`;\n return Object.entries(parsed as Record<string, unknown>)\n .slice(0, 3)\n .map(([key, value]) => `${key}: ${this.formatCompactBrowserValue(value)}`)\n .join('\\n');\n } catch {\n return '';\n }\n }\n\n private formatQuietSkillPreview(): string {\n if (!this.result || this.toolName !== 'skill_search') return '';\n return this.stripAnsi(this.getFormattedOutput())\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean)\n .slice(0, 2)\n .join('\\n');\n }\n\n private getListResultEntries(): string[] {\n return this.getFormattedOutput()\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line.trim() !== '' && line.trim() !== '.');\n }\n\n private looksLikeViewOutput(output: string): boolean {\n return output.split('\\n').some(line => /^\\s*\\d+[\\t→]/.test(line));\n }\n\n private stripAnsi(value: string): string {\n return value.replace(/\\x1b\\[[0-9;]*m/g, '');\n }\n\n private getCompactContinuationIndent(): string {\n return ' ';\n }\n\n private formatEmptyCompactContinuationLine(): string {\n const railColor = this.getQuietToolRailColor();\n const isStreamingContinuation = !this.isComplete() && this.quietPreviewLineLimit > 0;\n if (isStreamingContinuation) {\n const circleColor = this.getQuietToolCircleColor(this.getCompactToolAccentColor(this.getCompactToolLabelColor()));\n return `${chalk.hex(circleColor)('●')}${chalk.hex(railColor)('─')}`;\n }\n return chalk.hex(railColor)(this.compactToolHasFollowingContinuation ? '├─' : '╰─');\n }\n\n private formatCompactContinuationLine(summary: string): string {\n const lineMatch = summary.match(/^─+/);\n const linePrefix = lineMatch?.[0] ?? '';\n const separator = linePrefix ? '' : ' ';\n const hasFollowing = this.compactToolHasFollowingContinuation || this.hasQuietStreamingPreview();\n const hasPreview = this.hasQuietStreamingPreview();\n const toolLabelColor = this.getCompactToolLabelColor();\n const color = this.getCompactToolAccentColor(toolLabelColor);\n const argsBg = this.getCompactToolArgsBg(toolLabelColor);\n const argsColor = this.getCompactToolArgsColor(toolLabelColor);\n const railColor = this.getQuietToolRailColor();\n const circleColor = this.getQuietToolCircleColor(color);\n const isStreamingContinuation =\n this.compactToolContinuation && !this.isComplete() && this.quietPreviewLineLimit > 0;\n const branch =\n hasFollowing || isStreamingContinuation\n ? `${hasPreview || isStreamingContinuation ? chalk.hex(circleColor)('●') : chalk.hex(railColor)('├')}${chalk.hex(railColor)(`─${separator}${linePrefix}`)}`\n : chalk.hex(railColor)(`╰─${separator}${linePrefix}`);\n const continuationSummary = ` ${summary.slice(linePrefix.length)}`;\n const trail = continuationSummary ? chalk.hex(argsBg)('▌') : '';\n return `${branch}${this.formatCompactSummaryBadge(continuationSummary, argsBg, argsColor)}${trail}`;\n }\n\n private formatCompactSummaryBadge(summary: string, argsBg: string, argsColor?: string): string {\n const styleText = (text: string) => (argsColor ? chalk.hex(argsColor)(text) : theme.fg('text', text));\n const rangeMatch = summary.match(/(:\\d+(?:-\\d+)?)$/);\n if (!rangeMatch?.[1]) return chalk.bgHex(argsBg)(styleText(summary));\n\n const rangeStart = summary.length - rangeMatch[1].length;\n return `${chalk.bgHex(argsBg)(styleText(summary.slice(0, rangeStart)))}${chalk.bgHex(argsBg)(theme.fg('dim', rangeMatch[1]))}`;\n }\n\n private getCompactContinuationSummary(): string {\n const summary = this.getCompactToolSummary();\n const previousSummary = this.compactToolPreviousSummary;\n if (!summary) return '';\n if (!previousSummary) return this.isComplete() ? summary : '';\n\n if (previousSummary.startsWith(`${summary}:`)) {\n const dirnameStart = this.getImmediateDirnameStart(summary);\n if (dirnameStart !== undefined) {\n return `${this.formatSharedPrefixPlaceholder(summary, dirnameStart)}${summary.slice(dirnameStart)}`;\n }\n }\n\n const sharedPrefixLength = this.getSharedPrefixLength(previousSummary, summary);\n if (sharedPrefixLength === 0) return summary;\n\n const visibleRemainder = summary.slice(sharedPrefixLength);\n if (!visibleRemainder && this.hasCompletePathSegment(summary)) {\n const dirnameStart = this.getImmediateDirnameStart(summary);\n if (dirnameStart !== undefined) {\n return `${this.formatSharedPrefixPlaceholder(summary, dirnameStart)}${summary.slice(dirnameStart)}`;\n }\n }\n return `${this.formatSharedPrefixPlaceholder(summary, sharedPrefixLength)}${visibleRemainder}`;\n }\n\n private getImmediateDirnameStart(summary: string): number | undefined {\n const pathEnd = summary.indexOf(':');\n const path = pathEnd >= 0 ? summary.slice(0, pathEnd) : summary;\n const filenameSlashIndex = path.lastIndexOf('/');\n if (filenameSlashIndex < 0) return undefined;\n const dirnameSlashIndex = path.lastIndexOf('/', filenameSlashIndex - 1);\n return dirnameSlashIndex >= 0 ? dirnameSlashIndex : filenameSlashIndex;\n }\n\n private hasCompletePathSegment(summary: string): boolean {\n const pathEnd = summary.indexOf(':');\n const path = pathEnd >= 0 ? summary.slice(0, pathEnd) : summary;\n const lastSegment = path.slice(path.lastIndexOf('/') + 1);\n return lastSegment.length > 0 && (pathEnd >= 0 || lastSegment.includes('.'));\n }\n\n private formatSharedPrefixPlaceholder(summary: string, sharedPrefixLength: number): string {\n if (sharedPrefixLength <= 0) return '';\n if (summary[sharedPrefixLength - 1] === '/') {\n return `${'─'.repeat(sharedPrefixLength)}/`;\n }\n return '─'.repeat(sharedPrefixLength + 1);\n }\n\n private getSharedPrefixLength(a: string, b: string): number {\n let i = 0;\n while (i < a.length && i < b.length && a[i] === b[i]) {\n i++;\n }\n\n const pathEnd = b.indexOf(':');\n const path = pathEnd >= 0 ? b.slice(0, pathEnd) : b;\n const sharedPathLength = Math.min(i, path.length);\n if (sharedPathLength === 0) return 0;\n\n const matchingSegmentBoundary = path.lastIndexOf('/', sharedPathLength - 1);\n const currentSegmentStart = path.lastIndexOf('/', Math.max(0, sharedPathLength - 1));\n\n if (i === b.length && i === a.length) {\n return this.getImmediateDirnameStart(b) ?? b.length;\n }\n\n if (i === b.length || i === a.length) {\n return b.length;\n }\n\n if (i < b.length && i < a.length) {\n const visiblePathStart = this.getImmediateDirnameStart(b) ?? currentSegmentStart;\n if (currentSegmentStart < 0) return 0;\n return Math.min(currentSegmentStart, visiblePathStart);\n }\n\n return matchingSegmentBoundary >= 0 ? matchingSegmentBoundary + 1 : 0;\n }\n\n private getCompactToolSummary(): string {\n if (isWebSearchTool(this.toolName)) return this.formatWebSearchSummary();\n if (isBrowserTool(this.toolName)) return this.formatBrowserSummary();\n if (isSkillTool(this.toolName)) return this.formatSkillSummary();\n\n switch (this.toolName) {\n case MC_TOOLS.VIEW:\n return this.formatPathWithRange();\n case MC_TOOLS.STRING_REPLACE_LSP:\n return this.formatEditSummary();\n case MC_TOOLS.WRITE_FILE:\n return this.getFirstStringArg('path');\n case MC_TOOLS.FIND_FILES:\n return this.formatListSummary();\n case MC_TOOLS.DELETE_FILE:\n case MC_TOOLS.FILE_STAT:\n case MC_TOOLS.MKDIR:\n return this.getFirstStringArg('path');\n case MC_TOOLS.AST_SMART_EDIT:\n return this.getFirstStringArg('path') || this.getFirstStringArg('targetName');\n case MC_TOOLS.SEARCH_CONTENT:\n return this.formatSearchSummary();\n case MC_TOOLS.LSP_INSPECT:\n return this.formatPathWithRange();\n case MC_TOOLS.GET_PROCESS_OUTPUT:\n case MC_TOOLS.KILL_PROCESS:\n return this.getFirstStringArg('pid');\n case 'skill':\n return this.getFirstStringArg('name');\n case 'subagent':\n return this.formatSubagentSummary();\n default:\n return this.formatPlainArgsSummary().trim();\n }\n }\n\n private getCompactToolLabel(): string {\n if (isWebSearchTool(this.toolName)) return 'web';\n\n switch (this.toolName) {\n case MC_TOOLS.EXECUTE_COMMAND:\n return '$';\n case MC_TOOLS.STRING_REPLACE_LSP:\n return 'edit';\n case MC_TOOLS.WRITE_FILE:\n return 'write';\n case MC_TOOLS.FIND_FILES:\n return 'list';\n case MC_TOOLS.SEARCH_CONTENT:\n return 'grep';\n case MC_TOOLS.DELETE_FILE:\n return 'delete';\n case MC_TOOLS.FILE_STAT:\n return 'stat';\n case MC_TOOLS.MKDIR:\n return 'mkdir';\n case MC_TOOLS.GET_PROCESS_OUTPUT:\n return 'process';\n case MC_TOOLS.KILL_PROCESS:\n return 'kill';\n case MC_TOOLS.AST_SMART_EDIT:\n return 'ast_edit';\n default:\n return this.toolName;\n }\n }\n\n private formatPathWithRange(): string {\n const rawPath = this.getFirstStringArg('path');\n if (!rawPath) return '';\n\n const argsObj = this.args as Record<string, unknown> | undefined;\n const viewRange = argsObj?.view_range as [number, number] | undefined;\n const offset = typeof argsObj?.offset === 'number' ? argsObj.offset : undefined;\n const limit = typeof argsObj?.limit === 'number' ? argsObj.limit : undefined;\n const line = typeof argsObj?.line === 'number' ? argsObj.line : undefined;\n const start = viewRange?.[0] ?? offset ?? line;\n const end = viewRange?.[1] ?? (offset !== undefined && limit !== undefined ? offset + limit - 1 : line);\n const path = rawPath;\n\n if (start === undefined) return path;\n return end !== undefined && end !== start ? `${path}:${start}-${end}` : `${path}:${start}`;\n }\n\n private formatEditSummary(): string {\n const path = this.getFirstStringArg('path');\n if (!path) return '';\n\n const output = this.getFormattedOutput();\n const escapedPath = path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const match = output.match(new RegExp(`Replaced \\\\d+ occurrences? in ${escapedPath} \\\\(lines ([^)]+)\\\\)`));\n return match?.[1] ? `${path}:${match[1]}` : path;\n }\n\n private formatListSummary(): string {\n const target = this.getFirstStringArg('path') || this.getFirstStringArg('pattern');\n const resultCount = this.result ? this.getListResultEntries().length : undefined;\n if (resultCount === undefined) return target;\n return `${target} (${resultCount} ${resultCount === 1 ? 'result' : 'results'})`;\n }\n\n private formatSearchSummary(): string {\n return this.getFirstStringArg('path');\n }\n\n private formatWebSearchSummary(): string {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const action = argsObj?.action as Record<string, unknown> | undefined;\n const query = argsObj?.query ? String(argsObj.query) : action?.query ? String(action.query) : '';\n return query ? `\"${query}\"` : '';\n }\n\n private formatBrowserSummary(): string {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const first = (...keys: string[]) =>\n keys.map(key => argsObj?.[key]).find(value => value !== undefined && value !== null);\n const quote = (value: unknown) => (typeof value === 'string' ? `\"${value}\"` : String(value));\n\n switch (this.toolName) {\n case 'browser_goto':\n return this.getFirstStringArg('url');\n case 'browser_snapshot': {\n const interactiveOnly = first('interactiveOnly');\n const maxDepth = first('maxDepth');\n return [\n interactiveOnly !== undefined ? `interactive=${interactiveOnly}` : '',\n maxDepth !== undefined ? `depth=${maxDepth}` : '',\n ]\n .filter(Boolean)\n .join(' ');\n }\n case 'browser_click':\n return [\n this.getFirstStringArg('ref'),\n first('button') ? `button=${first('button')}` : '',\n first('clickCount') ? `x${first('clickCount')}` : '',\n ]\n .filter(Boolean)\n .join(' ');\n case 'browser_type':\n return [\n this.getFirstStringArg('ref'),\n this.getFirstStringArg('text') ? quote(this.getFirstStringArg('text')) : '',\n ]\n .filter(Boolean)\n .join(' ');\n case 'browser_press':\n return this.getFirstStringArg('key');\n case 'browser_select':\n return [\n this.getFirstStringArg('ref'),\n first('value', 'label', 'index') !== undefined ? quote(first('value', 'label', 'index')) : '',\n ]\n .filter(Boolean)\n .join(' ');\n case 'browser_scroll':\n return [\n this.getFirstStringArg('direction'),\n first('amount') !== undefined ? `${first('amount')}px` : '',\n this.getFirstStringArg('ref'),\n ]\n .filter(Boolean)\n .join(' ');\n case 'browser_wait':\n return [this.getFirstStringArg('ref'), this.getFirstStringArg('state')].filter(Boolean).join(' ');\n case 'browser_tabs':\n return [this.getFirstStringArg('action'), this.getFirstStringArg('url')].filter(Boolean).join(' ');\n case 'browser_evaluate':\n return this.getFirstLineArg('script', 80);\n default:\n return this.formatPlainArgsSummary().trim();\n }\n }\n\n private formatSubagentSummary(): string {\n const agentType = this.getFirstStringArg('agentType');\n const task = this.getFirstLineArg('task', 80);\n return [agentType, task].filter(Boolean).join(' ');\n }\n\n private formatSkillSummary(): string {\n switch (this.toolName) {\n case 'skill':\n return this.getFirstStringArg('name');\n case 'skill_search':\n return this.getFirstStringArg('query');\n case 'skill_read':\n return [this.getFirstStringArg('skillName'), this.getFirstStringArg('path')].filter(Boolean).join(' ');\n default:\n return '';\n }\n }\n\n private formatSearchDetail(): string {\n const pattern = this.getFirstStringArg('pattern');\n if (!pattern) return '';\n\n const resultCount = this.getSearchResultCount();\n return resultCount === undefined ? pattern : `${pattern} (${resultCount} results)`;\n }\n\n private getSearchResultCount(): number | undefined {\n if (!this.result) return undefined;\n\n const output = this.getFormattedOutput();\n const explicitMatch = output.match(/(\\d+)\\s+(?:matches|results)/i);\n if (explicitMatch?.[1]) return Number(explicitMatch[1]);\n\n const matchLines = output\n .split('\\n')\n .filter(line => /:\\d+:/.test(line) || /^\\s*(?:\\.|\\/|[\\w.-]+\\/).+:\\d+/.test(line));\n return matchLines.length > 0 ? matchLines.length : undefined;\n }\n\n private getFirstStringArg(key: string): string {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const value = argsObj?.[key];\n return typeof value === 'string' ? value : '';\n }\n\n private getFirstLineArg(key: string, maxLength: number): string {\n const value = this.getFirstStringArg(key);\n if (!value) return '';\n const firstLine = value.split('\\n')[0] ?? '';\n return firstLine.length > maxLength ? `${firstLine.slice(0, maxLength)}…` : firstLine;\n }\n\n private renderViewToolEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const fullPath = argsObj?.path ? String(argsObj.path) : '';\n const viewRange = argsObj?.view_range as [number, number] | undefined;\n const offset = argsObj?.offset as number | undefined;\n const limit = argsObj?.limit as number | undefined;\n // view tool uses view_range[0], workspace read_file uses offset\n const startLine = viewRange?.[0] ?? offset ?? 1;\n\n // Build range display from view_range or offset/limit\n let rangeDisplay = '';\n if (viewRange) {\n rangeDisplay = theme.fg('muted', `:${viewRange[0]}-${viewRange[1]}`);\n } else if (offset || limit) {\n const from = offset ?? 1;\n const to = limit ? from + limit - 1 : undefined;\n rangeDisplay = theme.fg('muted', to ? `:${from}-${to}` : `:${from}`);\n }\n\n const border = (char: string) => this.formatToolBorder(char);\n\n if (!this.result || this.isPartial) {\n const path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n const status = this.getStatusIndicator();\n const pathDisplay = fullPath\n ? fileLink(theme.fg('toolArgs', path), fullPath, startLine)\n : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'view'))} ${pathDisplay}${rangeDisplay}${status}`;\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n const status = this.getStatusIndicator();\n\n // Calculate available width for path and truncate from beginning if needed\n const termWidth = this.renderWidth;\n const fixedParts = '╰── view ' + (rangeDisplay ? `:XXX,XXX` : '') + ' ✓'; // approximate fixed width\n const availableForPath = termWidth - fixedParts.length - 6 - BOX_INDENT * 2; // buffer\n let path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n if (path.length > availableForPath && availableForPath > 10) {\n path = '…' + path.slice(-(availableForPath - 1));\n }\n\n const pathDisplay = fullPath\n ? fileLink(theme.fg('toolArgs', path), fullPath, startLine)\n : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'view'))} ${pathDisplay}${rangeDisplay}${status}`;\n\n // Empty line padding above\n this.addLeadingPadding();\n\n // Top border\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n // Syntax-highlighted content with left border, truncated to prevent soft wrap\n const output = this.getFormattedOutput();\n if (output) {\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2; // Account for border \"│ \" (2) + buffer (2)\n const highlighted = highlightCode(output, fullPath, startLine);\n let lines = highlighted.split('\\n');\n\n // Limit lines when collapsed\n const collapsedLines = this.getCollapsedLineLimit(20);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n\n if (hasMore) {\n lines = lines.slice(0, collapsedLines);\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n // Show truncation indicator\n if (hasMore) {\n const remaining = totalLines - collapsedLines;\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${remaining} more lines (ctrl+e to expand)`), 0, 0),\n );\n }\n }\n\n // Bottom border with tool info\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n }\n\n private renderBashToolEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n let command = argsObj?.command ? String(argsObj.command) : '...';\n const timeout = argsObj?.timeout as number | undefined;\n const cwd = argsObj?.cwd ? shortenPath(String(argsObj.cwd)) : '';\n\n // Strip \"cd $CWD && \" from the start since we show cwd in the footer\n const cdPattern = /^cd\\s+[^\\s]+\\s+&&\\s+/;\n command = command.replace(cdPattern, '');\n\n // Extract tail value from command (e.g., \"| tail -5\" or \"| tail -n 5\")\n let maxStreamLines: number | undefined;\n const tailMatch = command.match(/\\|\\s*tail\\s+(?:-n\\s+)?(-?\\d+)\\s*$/);\n if (tailMatch) {\n maxStreamLines = Math.abs(parseInt(tailMatch[1]!, 10));\n }\n\n const timeoutSuffix = timeout ? theme.fg('muted', ` (timeout ${timeout}s)`) : '';\n const cwdSuffix = cwd ? theme.fg('muted', ` in ${cwd}`) : '';\n const timeSuffix = this.isPartial ? timeoutSuffix : this.getDurationSuffix();\n\n // Helper to render shell command with terminal-like bordered box\n const renderBorderedShell = (status: string, outputLines: string[]) => {\n const border = (char: string) => this.formatToolBorder(char);\n const footerPrompt = `${theme.bold(theme.fg('toolTitle', '$'))} `;\n const footerSuffix = `${cwdSuffix}${timeSuffix}${status}`;\n const termWidth = this.renderWidth;\n const contentWidth = Math.max(20, termWidth - BOX_INDENT * 2 - 4); // Account for \"│ \" + \" │\"\n const horizontal = '─'.repeat(contentWidth + 2);\n const renderLine = (line: string, color: (value: string) => string = value => theme.fg('toolOutput', value)) => {\n const truncated = truncateAnsi(line, contentWidth);\n const padding = ' '.repeat(Math.max(0, contentWidth - visibleWidth(truncated)));\n return `${border('│')} ${color(truncated)}${padding} ${border('│')}`;\n };\n const displayOutput = outputLines.map(line => renderLine(line)).join('\\n');\n const hasOutput = displayOutput.trim() !== '';\n\n this.contentBox.addChild(new Text(`${border('╭')}${border(horizontal)}${border('╮')}`, 0, 0));\n if (hasOutput) {\n this.contentBox.addChild(new Text(displayOutput, 0, 0));\n this.contentBox.addChild(new Text(`${border('├')}${border(horizontal)}${border('┤')}`, 0, 0));\n }\n const footerWrapWidth = Math.max(1, contentWidth - 4);\n const footerLines = this.wrapQuietShellCommand(command, footerWrapWidth);\n const footerSuffixWidth = visibleWidth(footerSuffix);\n footerLines.forEach((footerLine, index) => {\n const prefix = index === 0 ? footerPrompt : ' ';\n const isLast = index === footerLines.length - 1;\n const suffixFits = isLast && visibleWidth(footerLine) + footerSuffixWidth <= footerWrapWidth;\n const suffix = suffixFits ? footerSuffix : '';\n this.contentBox.addChild(\n new Text(\n renderLine(`${prefix}${footerLine}${suffix}`, value => value),\n 0,\n 0,\n ),\n );\n });\n const lastFooterLine = footerLines[footerLines.length - 1] ?? '';\n if (visibleWidth(lastFooterLine) + footerSuffixWidth > footerWrapWidth) {\n this.contentBox.addChild(\n new Text(\n renderLine(` ${footerSuffix}`, value => value),\n 0,\n 0,\n ),\n );\n }\n this.contentBox.addChild(new Text(`${border('╰')}${border(horizontal)}${border('╯')}`, 0, 0));\n };\n\n if (!this.result || this.isPartial) {\n const status = this.getStatusIndicator();\n let lines = this.streamingOutput ? this.streamingOutput.split('\\n') : [];\n // Remove leading empty lines during streaming\n while (lines.length > 0 && lines[0] === '') {\n lines.shift();\n }\n // Remove trailing empty lines during streaming (from trailing newline)\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n // Apply tail limit to streaming output to match final result\n if (maxStreamLines && lines.length > maxStreamLines) {\n lines = lines.slice(-maxStreamLines);\n }\n renderBorderedShell(status, this.limitQuietShellLines(lines));\n return;\n }\n\n // Helper to apply tail limit and clean up lines\n const prepareOutputLines = (output: string): string[] => {\n let lines = output.split('\\n');\n // Remove leading/trailing empty lines\n while (lines.length > 0 && lines[0] === '') {\n lines.shift();\n }\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n // Apply tail limit to match streaming display\n if (maxStreamLines && lines.length > maxStreamLines) {\n lines = lines.slice(-maxStreamLines);\n }\n return lines;\n };\n\n // For errors, use bordered box with error status\n if (this.result.isError) {\n const status = theme.fg('error', ' ✗');\n const output = this.streamingOutput.trim() || this.getFormattedOutput();\n renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));\n return;\n }\n\n // Also check if output contains common error patterns\n const outputText = this.getFormattedOutput();\n const looksLikeError = outputText.match(\n /Error:|TypeError:|SyntaxError:|ReferenceError:|command not found|fatal:|error:/i,\n );\n if (looksLikeError) {\n const status = theme.fg('error', ' ✗');\n const output = this.streamingOutput.trim() || this.getFormattedOutput();\n renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));\n return;\n }\n\n // Success - use bordered box with checkmark\n const status = theme.fg('success', ' ✓');\n const output = this.streamingOutput.trim() || this.getFormattedOutput();\n {\n renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));\n }\n }\n\n private renderProcessToolEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const pid = argsObj?.pid ? Number(argsObj.pid) : 0;\n const isKill = this.toolName === MC_TOOLS.KILL_PROCESS;\n const isWait = !isKill && argsObj?.wait === true;\n\n const timeSuffix = this.isPartial ? '' : this.getDurationSuffix();\n const label = isKill ? 'kill' : isWait ? 'wait' : 'output';\n\n const renderBorderedProcess = (status: string, outputLines: string[]) => {\n const border = (char: string) => this.formatToolBorder(char);\n const footerText = `${theme.bold(theme.fg('toolTitle', label))} ${theme.fg('toolArgs', `PID ${pid}`)}${timeSuffix}${status}`;\n\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n const borderedLines = outputLines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n const displayOutput = borderedLines.join('\\n');\n if (displayOutput.trim()) {\n this.contentBox.addChild(new Text(displayOutput, 0, 0));\n }\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n };\n\n const prepareOutputLines = (output: string): string[] => {\n let lines = output.split('\\n');\n while (lines.length > 0 && lines[0] === '') lines.shift();\n while (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();\n return lines;\n };\n\n if (!this.result || this.isPartial) {\n const status = this.getStatusIndicator();\n let lines = this.streamingOutput ? this.streamingOutput.split('\\n') : [];\n while (lines.length > 0 && lines[0] === '') lines.shift();\n while (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();\n renderBorderedProcess(status, lines);\n return;\n }\n\n const status = this.result.isError ? theme.fg('error', ' ✗') : theme.fg('success', ' ✓');\n const output = this.streamingOutput.trim() || this.getFormattedOutput();\n {\n renderBorderedProcess(status, prepareOutputLines(output));\n }\n }\n\n private renderEditToolEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const fullPath = argsObj?.path ? String(argsObj.path) : '';\n const startLineNum = argsObj?.start_line ? Number(argsObj.start_line) : undefined;\n const startLine = startLineNum ? `:${String(startLineNum)}` : '';\n\n // While streaming / pending — show diff preview if old_str + new_str available\n if (!this.result || this.isPartial) {\n const path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n const status = this.getStatusIndicator();\n const pathDisplay = fullPath\n ? fileLink(theme.fg('toolArgs', path), fullPath, startLineNum)\n : theme.fg('toolArgs', path);\n\n // If both old_str/old_string and new_str/new_string are available, show a bordered diff preview\n const oldStr = argsObj?.old_str ?? argsObj?.old_string;\n const newStr = argsObj?.new_str ?? argsObj?.new_string;\n if (oldStr != null && newStr != null) {\n const border = (char: string) => this.formatToolBorder(char);\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n const footerText = `${theme.bold(theme.fg('toolTitle', 'edit'))} ${pathDisplay}${theme.fg('muted', startLine)}${status}`;\n\n this.addLeadingPadding();\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n const { lines: diffLines } = this.generateDiffLines(String(oldStr), String(newStr));\n\n // While streaming, show the tail so new content scrolls in at the bottom\n const collapsedLines = this.getCollapsedLineLimit(15);\n const totalLines = diffLines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n let linesToShow = diffLines;\n let skippedAbove = 0;\n if (hasMore) {\n skippedAbove = totalLines - collapsedLines;\n linesToShow = diffLines.slice(-collapsedLines);\n }\n\n if (skippedAbove > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${skippedAbove} lines above (ctrl+e to expand)`), 0, 0),\n );\n }\n\n const borderedLines = linesToShow.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // No diff args yet — show bordered header\n const editBorder = (char: string) => this.formatToolBorder(char);\n const headerText = `${theme.bold(theme.fg('toolTitle', 'edit'))} ${pathDisplay}${theme.fg('muted', startLine)}${status}`;\n this.contentBox.addChild(new Text(editBorder('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${editBorder('╰──')} ${headerText}`, 0, 0));\n return;\n }\n\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n\n // Calculate available width for path and truncate from beginning if needed\n const termWidth = this.renderWidth;\n const fixedParts = '╰── edit ' + startLine + ' ✓'; // approximate fixed width\n const availableForPath = termWidth - fixedParts.length - 6 - BOX_INDENT * 2; // buffer\n let path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n if (path.length > availableForPath && availableForPath > 10) {\n path = '…' + path.slice(-(availableForPath - 1));\n }\n\n const pathDisplay = fullPath\n ? fileLink(theme.fg('toolArgs', path), fullPath, startLineNum)\n : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'edit'))} ${pathDisplay}${theme.fg('muted', startLine)}${status}`;\n\n // Empty line padding above\n this.addLeadingPadding();\n\n // Top border\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n // For edits, show the diff\n const finalOldStr = argsObj?.old_str ?? argsObj?.old_string;\n const finalNewStr = argsObj?.new_str ?? argsObj?.new_string;\n if (finalOldStr != null && finalNewStr != null && !this.result.isError) {\n const { lines: diffLines, firstChangeIndex } = this.generateDiffLines(String(finalOldStr), String(finalNewStr));\n\n // Limit lines when collapsed, windowed around first change\n const collapsedLines = this.getCollapsedLineLimit(15);\n const totalLines = diffLines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n\n let linesToShow = diffLines;\n let skippedBefore = 0;\n if (hasMore) {\n // Show 3 context lines before the first change, rest after\n const contextBefore = 3;\n const start = Math.max(0, firstChangeIndex - contextBefore);\n linesToShow = diffLines.slice(start, start + collapsedLines);\n skippedBefore = start;\n }\n // Render diff lines with border, truncated to prevent wrap\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n // Show \"skipped above\" indicator\n if (skippedBefore > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${skippedBefore} lines above`), 0, 0),\n );\n }\n\n const borderedLines = linesToShow.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n // Show truncation indicator\n if (hasMore) {\n const remaining = totalLines - (skippedBefore + linesToShow.length);\n if (remaining > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${remaining} more lines (ctrl+e to expand)`), 0, 0),\n );\n }\n }\n } else if (this.result.isError) {\n // Show error output\n const output = this.getFormattedOutput();\n if (output) {\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n const lines = output.split('\\n').map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('error', truncated);\n });\n this.contentBox.addChild(new Text(lines.join('\\n'), 0, 0));\n }\n }\n\n // Bottom border with tool info\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n\n // LSP diagnostics below the box\n const diagnostics = this.parseLSPDiagnostics();\n if (diagnostics && !diagnostics.hasIssues) {\n this.contentBox.addChild(new Text(theme.fg('muted', ` ✓ No LSP issues`), 0, 0));\n } else if (diagnostics && diagnostics.hasIssues) {\n const COLLAPSED_DIAG_LINES = 3;\n const shouldCollapse = !this.expanded && diagnostics.entries.length > COLLAPSED_DIAG_LINES + 1;\n const maxDiags = shouldCollapse ? COLLAPSED_DIAG_LINES : diagnostics.entries.length;\n const entriesToShow = diagnostics.entries.slice(0, maxDiags);\n for (const diag of entriesToShow) {\n const t = theme.getTheme();\n const color = diag.severity === 'error' ? t.error : diag.severity === 'warning' ? t.warning : t.muted;\n const icon = diag.severity === 'error' ? '✗' : diag.severity === 'warning' ? '⚠' : 'ℹ';\n const location = diag.location ? chalk.hex(color)(diag.location) + ' ' : '';\n const line = ` ${chalk.hex(color)(icon)} ${location}${theme.fg('thinkingText', diag.message)}`;\n this.contentBox.addChild(new Text(line, 0, 0));\n }\n if (shouldCollapse) {\n const remaining = diagnostics.entries.length - COLLAPSED_DIAG_LINES;\n this.contentBox.addChild(\n new Text(\n theme.fg('muted', ` ... ${remaining} more diagnostic${remaining > 1 ? 's' : ''} (ctrl+e to expand)`),\n 0,\n 0,\n ),\n );\n }\n }\n }\n\n private parseLSPDiagnostics(): {\n hasIssues: boolean;\n entries: Array<{\n severity: 'error' | 'warning' | 'info' | 'hint';\n location: string;\n message: string;\n }>;\n } | null {\n const output = this.getFormattedOutput();\n const lspIdx = output.indexOf('LSP Diagnostics:');\n if (lspIdx === -1) return null;\n\n const lspText = output.slice(lspIdx + 'LSP Diagnostics:'.length);\n if (lspText.includes('No errors or warnings')) {\n return { hasIssues: false, entries: [] };\n }\n\n const entries: Array<{\n severity: 'error' | 'warning' | 'info' | 'hint';\n location: string;\n message: string;\n }> = [];\n let currentSeverity: 'error' | 'warning' | 'info' | 'hint' = 'error';\n\n for (const line of lspText.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed === 'Errors:') {\n currentSeverity = 'error';\n } else if (trimmed === 'Warnings:') {\n currentSeverity = 'warning';\n } else if (trimmed === 'Info:') {\n currentSeverity = 'info';\n } else if (trimmed === 'Hints:') {\n currentSeverity = 'hint';\n } else {\n const match = trimmed.match(/^((?:.*:)?\\d+:\\d+)\\s*-\\s*(.+)$/);\n if (match) {\n entries.push({\n severity: currentSeverity,\n location: match[1]!,\n message: match[2]!,\n });\n }\n }\n }\n\n return { hasIssues: entries.length > 0, entries };\n }\n private generateDiffLines(oldStr: string, newStr: string): { lines: string[]; firstChangeIndex: number } {\n const oldLines = oldStr.split('\\n');\n const newLines = newStr.split('\\n');\n const lines: string[] = [];\n let firstChangeIndex = -1;\n\n // Use soft red for removed, green for added\n const removedColor = chalk.hex(mastra.red); // soft red\n const addedColor = chalk.hex(theme.getTheme().success); // soft green\n\n const maxLines = Math.max(oldLines.length, newLines.length);\n\n for (let i = 0; i < maxLines; i++) {\n if (i >= oldLines.length) {\n if (firstChangeIndex === -1) firstChangeIndex = lines.length;\n lines.push(addedColor(newLines[i]));\n } else if (i >= newLines.length) {\n if (firstChangeIndex === -1) firstChangeIndex = lines.length;\n lines.push(removedColor(oldLines[i]));\n } else if (oldLines[i] !== newLines[i]) {\n if (firstChangeIndex === -1) firstChangeIndex = lines.length;\n lines.push(removedColor(oldLines[i]!));\n lines.push(addedColor(newLines[i]!));\n } else {\n // Context line\n lines.push(theme.fg('muted', oldLines[i]!));\n }\n }\n\n return {\n lines,\n firstChangeIndex: firstChangeIndex === -1 ? 0 : firstChangeIndex,\n };\n }\n private renderWriteToolEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const fullPath = argsObj?.path ? String(argsObj.path) : '';\n const content = argsObj?.content ? String(argsObj.content) : '';\n\n // While streaming args (no result yet), show bordered box with content as it arrives\n if (!this.result || this.isPartial) {\n if (!content) {\n // No content yet — show bordered pending header\n const writeBorder = (char: string) => this.formatToolBorder(char);\n const path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n const status = this.getStatusIndicator();\n const pathDisplay = fullPath ? fileLink(theme.fg('toolArgs', path), fullPath) : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'write'))} ${pathDisplay}${status}`;\n this.contentBox.addChild(new Text(writeBorder('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${writeBorder('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // Content is streaming in — show bordered box with syntax-highlighted preview\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n let path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n const fixedParts = '╰── write ⋯';\n const availableForPath = termWidth - fixedParts.length - 6 - BOX_INDENT * 2;\n if (path.length > availableForPath && availableForPath > 10) {\n path = '…' + path.slice(-(availableForPath - 1));\n }\n const pathDisplay = fullPath ? fileLink(theme.fg('toolArgs', path), fullPath) : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'write'))} ${pathDisplay}${status}`;\n\n this.addLeadingPadding();\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n const highlighted = highlightCode(content, fullPath);\n let lines = highlighted.split('\\n');\n\n const collapsedLines = this.getCollapsedLineLimit(20);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n let skippedAbove = 0;\n if (hasMore) {\n skippedAbove = totalLines - collapsedLines;\n lines = lines.slice(-collapsedLines);\n }\n\n if (skippedAbove > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${skippedAbove} lines above (ctrl+e to expand)`), 0, 0),\n );\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // Complete — show final bordered result\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n let path = argsObj?.path ? shortenPath(String(argsObj.path)) : '...';\n const fixedParts = '╰── write ✓';\n const availableForPath = termWidth - fixedParts.length - 6 - BOX_INDENT * 2;\n if (path.length > availableForPath && availableForPath > 10) {\n path = '…' + path.slice(-(availableForPath - 1));\n }\n const pathDisplay = fullPath ? fileLink(theme.fg('toolArgs', path), fullPath) : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'write'))} ${pathDisplay}${status}`;\n\n this.addLeadingPadding();\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n if (this.result.isError) {\n const output = this.getFormattedOutput();\n if (output) {\n const lines = output.split('\\n').map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('error', truncated);\n });\n this.contentBox.addChild(new Text(lines.join('\\n'), 0, 0));\n }\n } else if (content) {\n const highlighted = highlightCode(content, fullPath);\n let lines = highlighted.split('\\n');\n\n const collapsedLines = this.getCollapsedLineLimit(20);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n let skippedAbove = 0;\n if (hasMore) {\n skippedAbove = totalLines - collapsedLines;\n lines = lines.slice(-collapsedLines);\n }\n\n if (skippedAbove > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${skippedAbove} lines above (ctrl+e to expand)`), 0, 0),\n );\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n }\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n }\n private renderListFilesEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const fullPath = argsObj?.path ? String(argsObj.path) : '';\n const path = argsObj?.path ? shortenPath(String(argsObj.path)) : '/';\n const pattern = argsObj?.pattern ? String(argsObj.pattern) : '';\n const patternDisplay = pattern ? ' ' + theme.fg('muted', pattern) : '';\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n if (!this.result || this.isPartial) {\n const pathDisplay = fullPath ? fileLink(theme.fg('toolArgs', path), fullPath) : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'list'))} ${pathDisplay}${patternDisplay}${status}`;\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n const output = this.getFormattedOutput();\n if (output) {\n // Extract summary line (e.g. \"5 directories, 9 files\") from tree output for the footer\n let lines = output.split('\\n');\n const lastLine = lines[lines.length - 1]?.trim() || '';\n const summaryMatch = lastLine.match(/^\\d+\\s+directories?,\\s+\\d+\\s+files?$/);\n const summaryDisplay = summaryMatch ? ' ' + theme.fg('muted', lastLine) : '';\n // Remove the summary line from content if it matched\n if (summaryMatch) {\n lines = lines.slice(0, -1);\n }\n\n const collapsedLines = this.getCollapsedLineLimit(15);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n let skippedAbove = 0;\n if (hasMore) {\n skippedAbove = totalLines - collapsedLines;\n lines = lines.slice(-collapsedLines);\n }\n\n const pathDisplay = fullPath ? fileLink(theme.fg('toolArgs', path), fullPath) : theme.fg('toolArgs', path);\n const footerText = `${theme.bold(theme.fg('toolTitle', 'list'))} ${pathDisplay}${patternDisplay}${summaryDisplay}${status}`;\n\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n if (skippedAbove > 0) {\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${skippedAbove} lines above (ctrl+e to expand)`), 0, 0),\n );\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n }\n }\n\n private renderLspInspectEnhanced(): void {\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n const argsObj = this.args as { path?: string; line?: number; match?: string } | undefined;\n const path_ = argsObj?.path;\n const line = argsObj?.line;\n const match = argsObj?.match;\n\n // Build args summary for footer\n const argsSummary = [\n path_ ? shortenPath(path_.replace(process.cwd() + '/', '')) : null,\n line ? `L${line}` : null,\n match ? truncateAnsi(match.replace(/<<</g, '‹‹‹'), 40) : null,\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!this.result || this.isPartial) {\n const footerText = `${theme.bold(theme.fg('toolTitle', 'lsp_inspect'))}${argsSummary ? ' ' + theme.fg('toolArgs', argsSummary) : ''}${status}`;\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // Extract raw text from result\n const rawText = this.result.content\n .filter(c => c.type === 'text' && c.text)\n .map(c => c.text!)\n .join('\\n');\n\n if (this.result.isError || !rawText.trim()) {\n const footerText = `${theme.bold(theme.fg('toolTitle', 'lsp_inspect'))}${argsSummary ? ' ' + theme.fg('toolArgs', argsSummary) : ''}${status}`;\n const output = this.getFormattedOutput();\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n if (output) {\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('error', output), 0, 0));\n }\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // Parse lsp_inspect result\n let parsed: {\n hover?: { value: string; kind: string };\n diagnostics?: Array<{ severity: string; message: string; source: string | null }>;\n definition?: Array<{ location: string; preview: string | null }>;\n implementation?: string[];\n error?: string;\n };\n try {\n parsed = JSON.parse(rawText);\n } catch {\n // Fall back to generic rendering if not valid JSON\n this.renderGenericToolEnhanced();\n return;\n }\n\n if (parsed.error) {\n const footerText = `${theme.bold(theme.fg('toolTitle', 'lsp_inspect'))}${argsSummary ? ' ' + theme.fg('toolArgs', argsSummary) : ''}${status}`;\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('error', parsed.error), 0, 0));\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n const footerText = `${theme.bold(theme.fg('toolTitle', 'lsp_inspect'))}${argsSummary ? ' ' + theme.fg('toolArgs', argsSummary) : ''}${status}`;\n\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n // Render hover content\n if (parsed.hover) {\n const hoverValue = parsed.hover.value || '';\n const hoverLines = hoverValue.split('\\n').filter(line => line.trim() !== '');\n if (hoverLines.length > 0) {\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('toolArgs', 'hover:'), 0, 0));\n }\n for (const line of hoverLines) {\n const truncated = truncateAnsi(line, maxLineWidth - 2);\n const prefix = border('│') + ' ';\n this.contentBox.addChild(new Text(prefix + theme.fg('text', truncated), 0, 0));\n }\n }\n\n // Render line diagnostics\n if (parsed.diagnostics && parsed.diagnostics.length > 0) {\n this.contentBox.addChild(new Text(border('│'), 0, 0));\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('toolArgs', 'diagnostics:'), 0, 0));\n\n for (const diagnostic of parsed.diagnostics) {\n const label = diagnostic.source ? `${diagnostic.severity} (${diagnostic.source})` : diagnostic.severity;\n const diagLine = `${label}: ${diagnostic.message}`;\n this.contentBox.addChild(\n new Text(\n border('│') +\n ' ' +\n theme.fg(diagnostic.severity === 'error' ? 'error' : 'text', truncateAnsi(diagLine, maxLineWidth - 2)),\n 0,\n 0,\n ),\n );\n }\n }\n\n // Render definition entries\n if (parsed.definition && parsed.definition.length > 0) {\n // Add blank line before definition section for visual separation\n this.contentBox.addChild(new Text(border('│'), 0, 0));\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('toolArgs', 'definition:'), 0, 0));\n\n for (const def of parsed.definition) {\n const location = def.location || '';\n const preview = def.preview || '';\n // Parse location: \"$cwd/path:Lline:Cchar\" or just \"path:Lline:Cchar\"\n const parsedLoc = this.parseLspLocation(location);\n const displayLoc = parsedLoc\n ? fileLink(\n theme.fg('toolOutput', parsedLoc.shortPath + ':' + parsedLoc.lineCol),\n parsedLoc.absPath,\n parsedLoc.line,\n )\n : theme.fg('toolOutput', location);\n\n const defLine = border('│') + ' ' + displayLoc;\n this.contentBox.addChild(new Text(truncateAnsi(defLine, maxLineWidth), 0, 0));\n\n if (preview) {\n const previewLine = border('│') + ' ' + theme.fg('text', truncateAnsi(preview, maxLineWidth - 3));\n this.contentBox.addChild(new Text(previewLine, 0, 0));\n }\n }\n }\n\n // Render implementation entries\n if (parsed.implementation && parsed.implementation.length > 0) {\n const implCount = parsed.implementation.length;\n const implLabel = implCount === 1 ? 'implementation:' : `implementations (${implCount}):`;\n\n // Add blank line before implementation section for visual separation\n this.contentBox.addChild(new Text(border('│'), 0, 0));\n\n // Show first few implementations inline, collapse rest\n const maxShow = this.expanded ? parsed.implementation.length : 5;\n const shown = parsed.implementation.slice(0, maxShow);\n const remaining = parsed.implementation.length - maxShow;\n\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('toolArgs', implLabel), 0, 0));\n\n for (const loc of shown) {\n const parsedLoc = this.parseLspLocation(loc);\n const displayLoc = parsedLoc\n ? fileLink(\n theme.fg('toolOutput', parsedLoc.shortPath + ':' + parsedLoc.lineCol),\n parsedLoc.absPath,\n parsedLoc.line,\n )\n : theme.fg('toolOutput', loc);\n const implLine = border('│') + ' ' + displayLoc;\n this.contentBox.addChild(new Text(truncateAnsi(implLine, maxLineWidth), 0, 0));\n }\n\n if (remaining > 0 && !this.expanded) {\n const moreLine = border('│') + ' ' + theme.fg('toolOutput', `... ${remaining} more (ctrl+e to expand)`);\n this.contentBox.addChild(new Text(moreLine, 0, 0));\n }\n }\n\n // Show message if no results found\n if (!parsed.hover && !parsed.diagnostics?.length && !parsed.definition?.length && !parsed.implementation?.length) {\n this.contentBox.addChild(\n new Text(\n border('│') + ' ' + theme.fg('muted', 'No hover, diagnostics, definition, or implementation results'),\n 0,\n 0,\n ),\n );\n }\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n }\n\n /**\n * Parse an LSP location string like \"$cwd/path:Lline:Cchar\" into components.\n */\n private parseLspLocation(\n location: string,\n ): { absPath: string; shortPath: string; line: number; lineCol: string } | null {\n // Match patterns like:\n // - \"$cwd/packages/core/src/foo.ts:L10:C5\"\n // - \"/absolute/path/to/file.ts:L1:C1\"\n // - \"path/to/file.ts:L10:C5\"\n const match = location.match(/^(.+?):L(\\d+):C(\\d+)$/);\n if (!match) return null;\n\n const rawPath = match[1]!;\n const line = parseInt(match[2]!, 10);\n const lineCol = `L${match[2]}:C${match[3]}`;\n\n // Resolve to absolute path\n let absPath: string;\n let shortPath: string;\n if (rawPath.startsWith('$cwd/')) {\n absPath = process.cwd() + '/' + rawPath.slice(5);\n shortPath = rawPath.slice(5); // Strip $cwd/ prefix\n } else if (rawPath.startsWith('~')) {\n absPath = os.homedir() + rawPath.slice(1);\n shortPath = shortenPath(absPath);\n } else if (rawPath.startsWith('/')) {\n absPath = rawPath;\n shortPath = absPath.startsWith(process.cwd() + '/')\n ? absPath.slice(process.cwd().length + 1)\n : shortenPath(absPath);\n } else {\n absPath = process.cwd() + '/' + rawPath;\n shortPath = rawPath;\n }\n\n return { absPath, shortPath, line, lineCol };\n }\n\n private renderTaskWriteEnhanced(): void {\n const argsObj = this.args as { tasks?: TaskItemInput[] } | undefined;\n const tasks = argsObj?.tasks;\n const status = this.getStatusIndicator();\n const border = (char: string) => this.formatToolBorder(char);\n\n // Show a compact bordered header — the pinned TaskProgressComponent handles live rendering\n const count = tasks?.length ?? 0;\n const countSuffix = count > 0 ? theme.fg('muted', ` (${count} tasks)`) : '';\n const footerText = `${theme.bold(theme.fg('toolTitle', 'task_write'))}${countSuffix}${status}`;\n\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n // Surface error details when the tool call fails\n if (!this.isPartial && this.result?.isError) {\n const output = this.getFormattedOutput();\n if (output) {\n this.contentBox.addChild(new Text(border('│') + ' ' + theme.fg('error', output), 0, 0));\n }\n }\n\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n }\n\n private renderWebSearchEnhanced(): void {\n const argsObj = this.args as Record<string, unknown> | undefined;\n const action = argsObj?.action as Record<string, unknown> | undefined;\n let query = argsObj?.query ? String(argsObj.query) : action?.query ? String(action.query) : '';\n // Fallback: extract query from result content (OpenAI format: { action: { query } })\n if (!query && this.result) {\n try {\n const raw = this.getFormattedOutput();\n const parsed = JSON.parse(raw);\n if (parsed?.action?.query) query = String(parsed.action.query);\n } catch {\n /* ignore */\n }\n }\n const status = this.getStatusIndicator();\n\n const queryDisplay = query ? ` ${theme.fg('toolArgs', `\"${query}\"`)}` : '';\n const footerText = `${theme.bold(theme.fg('toolTitle', 'web_search'))}${queryDisplay}${status}`;\n const border = (char: string) => this.formatToolBorder(char);\n\n if (!this.result || this.isPartial) {\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n if (this.result.isError) {\n this.renderErrorResult(footerText);\n return;\n }\n\n // Parse search results and format as a clean list of titles + URLs\n const output = this.formatWebSearchResults();\n if (output) {\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n // Empty line padding above\n this.addLeadingPadding();\n\n // Top border\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n let lines = output.split('\\n');\n\n // Limit lines when collapsed\n const collapsedLines = this.getCollapsedLineLimit(10);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n\n if (hasMore) {\n lines = lines.slice(0, collapsedLines);\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n // Show truncation indicator\n if (hasMore) {\n const remaining = totalLines - collapsedLines;\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${remaining} more lines (ctrl+e to expand)`), 0, 0),\n );\n }\n\n // Bottom border with tool info\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n } else {\n this.contentBox.addChild(new Text(footerText, 0, 0));\n }\n }\n\n /**\n * Format web search results as a clean list of titles + URLs.\n * Handles both Anthropic provider results (JSON array with encryptedContent)\n * and Tavily results (markdown-formatted text).\n */\n private formatWebSearchResults(): string {\n const raw = this.getFormattedOutput();\n if (!raw) return '';\n\n // Try to parse as JSON\n try {\n const parsed = JSON.parse(raw);\n\n // Anthropic provider format: JSON array of { url, title, pageAge, ... }\n if (Array.isArray(parsed)) {\n const lines: string[] = [];\n for (const item of parsed) {\n if (typeof item !== 'object' || item === null) continue;\n const url = typeof item.url === 'string' ? item.url : '';\n if (!url) continue;\n const title = typeof item.title === 'string' && item.title ? item.title : '';\n const age = typeof item.pageAge === 'string' && item.pageAge ? theme.fg('muted', ` (${item.pageAge})`) : '';\n if (title) {\n lines.push(` ${theme.fg('toolOutput', title)}${age}`);\n lines.push(` ${theme.fg('muted', url)}`);\n } else {\n lines.push(` ${theme.fg('toolOutput', url)}${age}`);\n }\n }\n if (lines.length > 0) return lines.join('\\n');\n\n // Parsed as JSON array but couldn't extract results — strip encryptedContent\n // before falling through, so we never dump huge base64 blobs to the terminal\n const stripped = parsed.map((item: unknown) => {\n if (typeof item !== 'object' || item === null) return item;\n const { encryptedContent, ...rest } = item as Record<string, unknown>;\n return rest;\n });\n return JSON.stringify(stripped, null, 2);\n }\n\n // OpenAI provider format: { action: { query }, sources: [{ url, title }, ...] }\n if (typeof parsed === 'object' && parsed !== null && Array.isArray(parsed.sources)) {\n const lines: string[] = [];\n for (const source of parsed.sources) {\n if (typeof source !== 'object' || source === null) continue;\n const url = typeof source.url === 'string' ? source.url : '';\n if (!url) continue;\n const title = typeof source.title === 'string' && source.title ? source.title : '';\n if (title) {\n lines.push(` ${theme.fg('toolOutput', title)}`);\n lines.push(` ${theme.fg('muted', url)}`);\n } else {\n lines.push(` ${theme.fg('toolOutput', url)}`);\n }\n }\n if (lines.length > 0) return lines.join('\\n');\n }\n } catch {\n // Not JSON — fall through to raw text (Tavily format)\n }\n\n // Not JSON (e.g. Tavily format) — already readable text, return as-is\n return raw;\n }\n\n private renderGenericToolEnhanced(): void {\n const border = (char: string) => this.formatToolBorder(char);\n const status = this.getStatusIndicator();\n\n const argsSummary = this.formatArgsSummary();\n\n const footerText = `${theme.bold(theme.fg('toolTitle', this.toolName))}${argsSummary}${status}`;\n\n if (!this.result || this.isPartial) {\n const partialOutput = this.result ? this.getFormattedOutput() : '';\n const preview = partialOutput ? partialOutput.split('\\n') : this.formatArgsPreview();\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n if (preview.length > 0) {\n const previewLines = preview.map(line => border('│') + ' ' + theme.fg('toolOutput', line));\n this.contentBox.addChild(new Text(previewLines.join('\\n'), 0, 0));\n }\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n return;\n }\n\n // Use enhanced error display for errors\n if (this.result.isError) {\n this.renderErrorResult(footerText);\n return;\n }\n\n const output = this.getFormattedOutput();\n if (output) {\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2;\n\n // Empty line padding above\n this.addLeadingPadding();\n\n // Top border\n this.contentBox.addChild(new Text(border('╭──'), 0, 0));\n\n let lines = output.split('\\n');\n const collapsedLines = this.getCollapsedLineLimit(10);\n const totalLines = lines.length;\n const hasMore = !this.expanded && totalLines > collapsedLines + 1;\n\n if (hasMore) {\n lines = lines.slice(0, collapsedLines);\n }\n\n const borderedLines = lines.map(line => {\n const truncated = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + theme.fg('toolOutput', truncated);\n });\n this.contentBox.addChild(new Text(borderedLines.join('\\n'), 0, 0));\n\n if (hasMore) {\n const remaining = totalLines - collapsedLines;\n this.contentBox.addChild(\n new Text(border('│') + ' ' + theme.fg('muted', `... ${remaining} more lines (ctrl+e to expand)`), 0, 0),\n );\n }\n\n // Bottom border with tool info\n this.contentBox.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n } else {\n // No output - just show the footer line\n this.contentBox.addChild(new Text(footerText, 0, 0));\n }\n }\n\n /**\n * Format a compact args preview as key=\"value\" pairs.\n * Long values are truncated, multiline values show first line + count.\n * Returns an array of formatted lines.\n */\n private formatArgsPreview(maxLines = 4, maxValueLen = 60): string[] {\n if (!this.args || typeof this.args !== 'object') return [];\n const argsObj = this.args as Record<string, unknown>;\n const keys = Object.keys(argsObj);\n if (keys.length === 0) return [];\n\n const termWidth = this.renderWidth;\n const maxLineWidth = termWidth - 4 - BOX_INDENT * 2 - 2; // -2 for \"│ \" border prefix\n const lines: string[] = [];\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!;\n if (lines.length >= maxLines) {\n const remaining = keys.length - i;\n lines.push(theme.fg('muted', ` ... ${remaining} more`));\n break;\n }\n const raw = argsObj[key];\n let val: string;\n if (typeof raw === 'string') {\n const strLines = raw.split('\\n');\n if (strLines.length > 1) {\n val = strLines[0]!.slice(0, maxValueLen) + theme.fg('muted', ` (${strLines.length} lines)`);\n } else {\n val = raw.length > maxValueLen ? raw.slice(0, maxValueLen) + '…' : raw;\n }\n val = `\"${val}\"`;\n } else if (raw === undefined) {\n continue;\n } else if (Array.isArray(raw)) {\n val = `[${raw.length} items]`;\n } else if (typeof raw === 'object' && raw !== null) {\n const objKeys = Object.keys(raw as Record<string, unknown>);\n val = `{${objKeys.slice(0, 3).join(', ')}${objKeys.length > 3 ? ', …' : ''}}`;\n } else {\n val = String(raw);\n }\n const line = truncateAnsi(` ${theme.fg('muted', key + '=')}${val}`, maxLineWidth);\n lines.push(line);\n }\n return lines;\n }\n\n private formatPlainArgsSummary(): string {\n return this.stripAnsi(this.formatArgsSummary());\n }\n\n /**\n * Compact inline args summary for the footer line.\n * Shows key=value pairs truncated to fit on one line.\n */\n private formatArgsSummary(): string {\n if (!this.args || typeof this.args !== 'object') return '';\n const argsObj = this.args as Record<string, unknown>;\n const entries = Object.entries(argsObj).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return '';\n\n const termWidth = this.renderWidth;\n // Leave room for tool name, status indicator, borders\n const maxLen = Math.max(20, termWidth - this.toolName.length - 15 - BOX_INDENT * 2);\n const parts: string[] = [];\n let currentLen = 0;\n\n for (const [key, raw] of entries) {\n let val: string;\n if (typeof raw === 'string') {\n const firstLine = raw.split('\\n')[0]!;\n val = firstLine.length > 40 ? firstLine.slice(0, 40) + '…' : firstLine;\n val = `\"${val}\"`;\n } else if (Array.isArray(raw)) {\n val = `[${raw.length}]`;\n } else if (typeof raw === 'object' && raw !== null) {\n val = '{…}';\n } else {\n val = String(raw);\n }\n const part = `${key}=${val}`;\n if (currentLen + part.length + 2 > maxLen && parts.length > 0) {\n parts.push('…');\n break;\n }\n parts.push(part);\n currentLen += part.length + 2;\n }\n\n return ' ' + theme.fg('toolArgs', parts.join(', '));\n }\n\n private getStatusIndicator(): string {\n return this.isPartial\n ? theme.fg('muted', ' ⋯')\n : this.isErrorResult()\n ? theme.fg('error', ' ✗')\n : theme.fg('success', ' ✓');\n }\n\n private getDurationSuffix(): string {\n if (this.isPartial) return '';\n const ms = Date.now() - this.startTime;\n if (ms < 1000) return theme.fg('muted', ` ${ms}ms`);\n return theme.fg('muted', ` ${(ms / 1000).toFixed(1)}s`);\n }\n\n private getFormattedOutput(): string {\n if (!this.result) return '';\n\n const textContent = this.result.content\n .filter(c => c.type === 'text' && c.text)\n .map(c => c.text!)\n .join('\\n');\n\n if (!textContent) return '';\n\n const { content } = extractContent(textContent);\n // Remove excessive blank lines while preserving intentional formatting\n return content.trim().replace(/\\n\\s*\\n\\s*\\n/g, '\\n\\n');\n }\n\n /**\n * Render an error result using the enhanced error display component\n */\n private renderErrorResult(header: string): void {\n if (!this.result) return;\n\n // First add the header\n this.contentBox.addChild(new Text(header, 0, 0));\n\n // Extract error text from result\n const errorText = this.result.content\n .filter(c => c.type === 'text' && c.text)\n .map(c => c.text!)\n .join('\\n');\n\n if (!errorText) return;\n\n // Check if this is a validation error\n const isValidationError =\n errorText.toLowerCase().includes('validation') ||\n errorText.toLowerCase().includes('required parameter') ||\n errorText.toLowerCase().includes('missing required') ||\n errorText.match(/at \"\\w+\"/i) || // Zod-style errors\n (errorText.includes('Expected') && errorText.includes('Received'));\n\n if (isValidationError) {\n // Use specialized validation error component\n const validationErrors = parseValidationErrors(errorText);\n const validationDisplay = new ToolValidationErrorComponent(\n {\n toolName: this.toolName,\n errors: validationErrors,\n args: this.args,\n },\n this.ui,\n );\n this.contentBox.addChild(validationDisplay);\n return;\n }\n\n // Try to parse as an error object\n let error: Error | string = errorText;\n try {\n const { content } = extractContent(errorText);\n error = content;\n const parsed = parseErrorFromContent(content);\n if (parsed) error = parsed;\n } catch {\n // Keep as string\n }\n\n // Create error display component\n const errorDisplay = new ErrorDisplayComponent(\n error,\n {\n showStack: true,\n showContext: true,\n expanded: this.expanded,\n },\n this.ui,\n );\n\n this.contentBox.addChild(errorDisplay);\n }\n}\n\n/** Map file extensions to highlight.js language names */\nfunction getLanguageFromPath(path: string): string | undefined {\n const ext = path.split('.').pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n json: 'json',\n md: 'markdown',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n go: 'go',\n java: 'java',\n kt: 'kotlin',\n swift: 'swift',\n c: 'c',\n cpp: 'cpp',\n h: 'c',\n hpp: 'cpp',\n cs: 'csharp',\n php: 'php',\n sh: 'bash',\n bash: 'bash',\n zsh: 'bash',\n fish: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n toml: 'ini',\n ini: 'ini',\n xml: 'xml',\n html: 'html',\n htm: 'html',\n css: 'css',\n scss: 'scss',\n sass: 'scss',\n less: 'less',\n sql: 'sql',\n graphql: 'graphql',\n gql: 'graphql',\n dockerfile: 'dockerfile',\n makefile: 'makefile',\n cmake: 'cmake',\n vue: 'vue',\n svelte: 'xml',\n };\n return ext ? langMap[ext] : undefined;\n}\n\n/** Strip line number formatting (cat -n or workspace →) from view-style output */\nfunction getPlainCodeFromViewOutput(content: string, startLine?: number): string {\n let lines = content.split('\\n').map(line => line.trimEnd());\n // Remove known headers:\n // - \"[Truncated N tokens]\" from token truncation\n // - \"Here's the result of running `cat -n`...\" from view tool\n // - \"/path/to/file (NNN bytes)\" or \"/path/to/file (lines N-M of T, NNN bytes)\" from workspace read_file\n while (\n lines.length > 0 &&\n (lines[0]!.includes(\"Here's the result of running\") ||\n lines[0]!.match(/^\\[Truncated \\d+ tokens\\]$/) ||\n lines[0]!.match(/^.*\\(\\d+ bytes\\)$/) ||\n lines[0]!.match(/^.*\\(lines \\d+-\\d+ of \\d+, \\d+ bytes\\)$/))\n ) {\n lines = lines.slice(1);\n }\n\n // Strip line numbers - we know they're sequential starting from startLine\n // Supports two formats:\n // view tool: \" 123\\tcode\" (tab separator)\n // workspace read_file: \" 123→code\" (arrow separator)\n // Separator is optional because trimEnd() strips trailing tabs on blank lines\n let expectedLineNum = startLine ?? 1;\n const codeLines = lines.map(line => {\n const numStr = String(expectedLineNum);\n const match = line.match(/^(\\s*)(\\d+)[\\t→]?(.*)$/);\n if (match && match[2] === numStr) {\n expectedLineNum++;\n return match[3]; // Return just the code part after the separator\n }\n return line;\n });\n\n // Remove trailing empty lines\n while (codeLines.length > 0 && codeLines[codeLines.length - 1] === '') {\n codeLines.pop();\n }\n\n return codeLines.join('\\n');\n}\n\n/** Strip line number formatting (cat -n or workspace →) and apply syntax highlighting */\nfunction highlightCode(content: string, path: string, startLine?: number): string {\n const code = getPlainCodeFromViewOutput(content, startLine);\n try {\n return highlight(code, {\n language: getLanguageFromPath(path),\n ignoreIllegals: true,\n theme: CODE_HIGHLIGHT_THEME,\n });\n } catch {\n return code;\n }\n}\n/** Parse a `Name: message\\n at ...` error string into an Error object.\n * Returns null if the content does not look like a JavaScript Error.\n * Preserves the behaviour of the original `/^([A-Z][a-zA-Z]*Error):\\s*(.+)$/m`\n * pattern (same captures for well-formed inputs) while using bounded\n * quantifiers and `[ \\t]` separators to avoid the polynomial backtracking\n * CodeQL flagged on pathological inputs.\n * Exported for unit testing.\n */\nexport function parseErrorFromContent(content: string): Error | null {\n const errorMatch = content.match(/^([A-Z][A-Za-z]{0,64}Error):[ \\t]*(.{1,8192})$/m);\n if (!errorMatch) return null;\n const err = new Error(errorMatch[2]!);\n err.name = errorMatch[1]!;\n // Stack frames are always space/tab-indented — never vertical whitespace.\n const stackMatch = content.match(/\\n[ \\t]+at[ \\t]+.+/g);\n if (stackMatch) {\n err.stack = `${err.name}: ${err.message}\\n${stackMatch.join('\\n')}`;\n }\n return err;\n}\n","/**\n * Component that renders a user message with a thin border that fits the content.\n */\n\nimport { Container, Markdown, Text, truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';\nimport type { MarkdownTheme } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT_STR, getMarkdownTheme, mastra, tintHex, theme } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\n/**\n * Strip ANSI escape sequences from a string.\n */\nfunction stripAnsi(s: string): string {\n return s.replace(/\\x1b\\[[0-9;]*m/g, '');\n}\n\n/**\n * A renderable wrapper that adds a thin box-drawing border sized to content.\n */\nclass BorderedBox {\n private child: { render(width: number): string[]; invalidate?(): void };\n private pending: boolean;\n private borderColor?: string;\n private label?: string;\n\n constructor(\n child: { render(width: number): string[]; invalidate?(): void },\n options: { pending?: boolean; borderColor?: string; label?: string } = {},\n ) {\n this.child = child;\n this.pending = options.pending ?? false;\n this.borderColor = options.borderColor;\n this.label = options.label;\n }\n\n invalidate() {\n this.child.invalidate?.();\n }\n\n render(width: number): string[] {\n const borderColor = (s: string) =>\n this.borderColor\n ? chalk.hex(this.borderColor)(s)\n : this.pending\n ? chalk.hex(theme.getTheme().dim)(s)\n : chalk.hex(tintHex(mastra.green, 1))(s);\n\n // Border uses 4 chars: \"│ \" (2) on left + \" │\" (2) on right\n // Plus 2 for the \"› \" prompt prefix on the first line\n // Plus BOX_INDENT_STR.length for the left indent\n // Use the tightest constraint (first line with prompt) for Markdown width\n const maxInnerWidth = Math.max(1, width - 6 - 2 - BOX_INDENT_STR.length - 1);\n const childLines = this.child.render(maxInnerWidth);\n\n if (childLines.length === 0) {\n return [];\n }\n\n // Trim trailing whitespace padding that Markdown adds, and measure true content width\n const trimmedLines: string[] = [];\n let maxContentWidth = 0;\n for (const line of childLines) {\n // Markdown appends plain spaces to pad to full width — trim them\n const trimmed = line.replace(/\\s+$/, '');\n trimmedLines.push(trimmed);\n const w = visibleWidth(stripAnsi(trimmed));\n if (w > maxContentWidth) maxContentWidth = w;\n }\n\n // Cap content width so the box never exceeds the render width\n const maxAllowedContent = maxInnerWidth;\n maxContentWidth = Math.min(maxContentWidth, maxAllowedContent);\n\n // Box inner width = content width + prompt prefix (the \"│ \" and \" │\" add the padding)\n let boxInner = maxContentWidth + 2;\n // When a label is present, ensure the box is wide enough so the top border\n // (╭ label ──...──╮) doesn't exceed the content/bottom border width.\n if (this.label) {\n const labelOverhead = ` ${this.label} `.length + 2; // ╭ + label + ╮\n const neededBoxWidth = Math.max(boxInner + 4, labelOverhead);\n boxInner = neededBoxWidth - 4;\n }\n // Total box width: \"│\" + \" \" + content + \" \" + \"│\" = boxInner + 4\n const boxWidth = boxInner + 4;\n\n const lines: string[] = [];\n\n const promptPrefix = chalk.hex(tintHex(mastra.green, 1))('»') + ' ';\n const promptWidth = 2;\n\n // Top border: ╭──...──╮ or ╭ label ──...──╮\n if (this.label) {\n const labelText = ` ${this.label} `;\n const labelLen = labelText.length;\n const remaining = Math.max(0, boxWidth - 2 - labelLen);\n lines.push(\n borderColor('╭') + chalk.hex(theme.getTheme().dim)(labelText) + borderColor(`${'─'.repeat(remaining)}╮`),\n );\n } else {\n lines.push(borderColor(`╭${'─'.repeat(boxWidth - 2)}╮`));\n }\n\n // Content lines with side borders, first line gets \"> \" prefix\n for (let i = 0; i < trimmedLines.length; i++) {\n let trimmed = trimmedLines[i]!;\n let vis = visibleWidth(stripAnsi(trimmed));\n // Truncate content that exceeds the available inner width\n const lineMaxWidth = i === 0 ? boxInner - promptWidth : boxInner;\n if (vis > lineMaxWidth) {\n trimmed = truncateToWidth(trimmed, lineMaxWidth);\n vis = visibleWidth(stripAnsi(trimmed));\n }\n if (i === 0) {\n const padNeeded = Math.max(0, boxInner - vis - promptWidth);\n lines.push(borderColor('│') + ' ' + promptPrefix + trimmed + ' '.repeat(padNeeded) + ' ' + borderColor('│'));\n } else {\n const padNeeded = Math.max(0, boxInner - vis);\n lines.push(borderColor('│') + ' ' + trimmed + ' '.repeat(padNeeded) + ' ' + borderColor('│'));\n }\n }\n\n // Bottom border: ╰──...──╯\n lines.push(borderColor(`╰${'─'.repeat(boxWidth - 2)}╯`));\n\n return lines.map(l => BOX_INDENT_STR + l);\n }\n}\n\nexport class UserMessageComponent extends Container {\n constructor(\n text: string,\n markdownTheme: MarkdownTheme = getMarkdownTheme(),\n options: { pending?: boolean; borderColor?: string; label?: string } = {},\n ) {\n super();\n\n const md = new Markdown(text, 0, 0, markdownTheme, {\n color: (text: string) => (options.pending ? theme.fg('dim', text) : theme.fg('text', text)),\n italic: false,\n });\n\n this.addChild(\n new BorderedBox(md, { pending: options.pending, borderColor: options.borderColor, label: options.label }),\n );\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'user-message';\n }\n}\n\nexport class PendingUserMessageComponent extends Container {\n constructor(text: string, imageCount = 0) {\n super();\n\n const prefix = imageCount > 0 ? `[${imageCount} image${imageCount > 1 ? 's' : ''}] ` : '';\n const displayText = `${prefix}${text.replace(/\\[image\\]\\s*/g, '').trim()}`.trim();\n this.addChild(new Text(theme.fg('dim', `↳ ${displayText || 'Message'} pending…`), BOX_INDENT_STR.length, 0));\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'user-message';\n }\n}\n","/**\n * Tool approval dialog component.\n * Shows tool details and prompts user to approve or decline execution.\n *\n * Keyboard shortcuts:\n * y — approve this one call\n * n / Esc — decline this call\n * a — always allow this category for the session\n * Y — switch to YOLO mode (approve all)\n */\nimport { Box, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable } from '@earendil-works/pi-tui';\nimport { safeStringify } from '@mastra/core/utils';\nimport chalk from 'chalk';\nimport { decodePrintableShortcut } from '../key-input.js';\nimport { theme } from '../theme.js';\n\nexport type ApprovalAction =\n | { type: 'approve' }\n | { type: 'decline' }\n | { type: 'always_allow_category' }\n | { type: 'yolo' };\n\nexport interface ToolApprovalDialogOptions {\n toolCallId: string;\n toolName: string;\n args: unknown;\n /** Human-readable category label, e.g. \"Edit\" or \"Execute\" */\n categoryLabel?: string;\n onAction: (action: ApprovalAction) => void;\n}\n\nexport class ToolApprovalDialogComponent extends Box implements Focusable {\n private toolName: string;\n private args: unknown;\n private categoryLabel: string | undefined;\n private onAction: (action: ApprovalAction) => void;\n private resolved = false;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(options: ToolApprovalDialogOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.toolName = options.toolName;\n this.args = options.args;\n this.categoryLabel = options.categoryLabel;\n this.onAction = options.onAction;\n\n this.buildUI();\n }\n\n private buildUI(): void {\n // Title\n this.addChild(new Text(theme.fg('warning', '⚠ Tool Approval Required'), 0, 0));\n this.addChild(new Spacer(1));\n\n // Tool name\n this.addChild(new Text(theme.fg('accent', `Tool: `) + theme.fg('text', this.toolName), 0, 0));\n if (this.categoryLabel) {\n this.addChild(new Text(theme.fg('accent', `Category: `) + theme.fg('text', this.categoryLabel), 0, 0));\n }\n this.addChild(new Spacer(1));\n\n // Arguments (formatted)\n this.addChild(new Text(theme.fg('muted', 'Arguments:'), 0, 0));\n const argsText = this.formatArgs(this.args);\n for (const line of argsText.split('\\n').slice(0, 10)) {\n this.addChild(new Text(theme.fg('text', ' ' + line), 0, 0));\n }\n if (argsText.split('\\n').length > 10) {\n this.addChild(new Text(theme.fg('muted', ' ... (truncated)'), 0, 0));\n }\n\n this.addChild(new Spacer(1));\n // Prompt text with keyboard shortcuts\n const categoryHint = this.categoryLabel\n ? `lways allow ${this.categoryLabel.toLowerCase()}`\n : 'lways allow category';\n const dimColor = chalk.hex(theme.getTheme().dim);\n const key = chalk.hex(theme.getTheme().text).bold;\n this.addChild(\n new Text(\n theme.fg('accent', 'Allow? ') +\n key('y') +\n dimColor('es ') +\n key('n') +\n dimColor('o ') +\n key('a') +\n dimColor(categoryHint + ' ') +\n key('Y') +\n dimColor('olo'),\n 0,\n 0,\n ),\n );\n }\n\n private formatArgs(args: unknown): string {\n if (args === null || args === undefined) {\n return '(none)';\n }\n\n if (typeof args !== 'object') {\n return String(args);\n }\n\n const entries = Object.entries(args as Record<string, unknown>);\n if (entries.length === 0) return '(none)';\n\n const lines: string[] = [];\n for (const [key, value] of entries) {\n let str: string;\n if (typeof value === 'string') {\n str = value;\n } else {\n str = safeStringify(value);\n }\n const maxLen = 120;\n const firstLine = str.split('\\n')[0] ?? '';\n const lineCount = typeof value === 'string' ? str.split('\\n').length : 0;\n const suffix = lineCount > 1 ? ` (${lineCount} lines)` : '';\n const display = firstLine.length > maxLen ? firstLine.slice(0, maxLen) + '…' : firstLine;\n lines.push(`${key}: ${display}${suffix}`);\n }\n return lines.join('\\n');\n }\n\n private emit(action: ApprovalAction): void {\n if (this.resolved) return;\n this.resolved = true;\n this.onAction(action);\n }\n\n handleInput(data: string): void {\n if (this.resolved) return;\n const kb = getKeybindings();\n\n // Escape to decline\n if (kb.matches(data, 'tui.select.cancel')) {\n this.emit({ type: 'decline' });\n return;\n }\n\n switch (decodePrintableShortcut(data)) {\n case 'y':\n this.emit({ type: 'approve' });\n break;\n case 'n':\n this.emit({ type: 'decline' });\n break;\n case 'a':\n this.emit({ type: 'always_allow_category' });\n break;\n case 'Y':\n this.emit({ type: 'yolo' });\n break;\n }\n }\n\n render(maxWidth: number): string[] {\n return super.render(maxWidth);\n }\n}\n","export const DEFAULT_RENDER_COALESCE_MS = 80;\n\nexport class RenderScheduler {\n private timer: ReturnType<typeof setTimeout> | undefined;\n private lastRenderAt = 0;\n private pending = false;\n private disposed = false;\n\n constructor(\n private readonly render: () => void,\n private readonly intervalMs = DEFAULT_RENDER_COALESCE_MS,\n private readonly now = () => Date.now(),\n ) {}\n\n request(): void {\n if (this.disposed || this.pending) return;\n\n const elapsed = this.now() - this.lastRenderAt;\n const delay = Math.max(0, this.intervalMs - elapsed);\n this.pending = true;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.run();\n }, delay);\n }\n\n flush(): void {\n if (this.disposed) return;\n\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pending = false;\n this.run();\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pending = false;\n }\n\n private run(): void {\n this.pending = false;\n if (this.disposed) return;\n this.lastRenderAt = this.now();\n this.render();\n }\n}\n\nexport interface RenderableState {\n ui: { requestRender?: () => void };\n renderScheduler?: RenderScheduler;\n}\n\nexport function requestRender(state: RenderableState): void {\n if (state.renderScheduler) {\n state.renderScheduler.request();\n return;\n }\n state.ui.requestRender?.();\n}\n\nexport function flushRender(state: RenderableState): void {\n if (state.renderScheduler) {\n state.renderScheduler.flush();\n return;\n }\n state.ui.requestRender?.();\n}\n","/**\n * Event handlers for tool execution events:\n * tool_start, tool_approval_required, tool_update, shell_output,\n * tool_input_start, tool_input_delta, tool_input_end, tool_end.\n *\n * Also includes formatToolResult helper.\n */\n\nimport { getToolCategory, TOOL_CATEGORIES } from '@mastra/code-sdk/permissions';\nimport type { TaskItemInput } from '@mastra/core/signals';\nimport { safeStringify } from '@mastra/core/utils';\nimport { parse as parseJsonRiver } from 'jsonriver';\n\nimport { reconcileChatBoundarySpacers } from '../chat-boundary-reconciliation.js';\nimport { AskQuestionInlineComponent } from '../components/ask-question-inline.js';\nimport { AssistantMessageComponent } from '../components/assistant-message.js';\nimport { PlanApprovalInlineComponent } from '../components/plan-approval-inline.js';\nimport { SubagentExecutionComponent } from '../components/subagent-execution.js';\nimport { ToolApprovalDialogComponent } from '../components/tool-approval-dialog.js';\nimport type { ApprovalAction } from '../components/tool-approval-dialog.js';\nimport { ToolExecutionComponentEnhanced } from '../components/tool-execution-enhanced.js';\nimport type { ToolResult } from '../components/tool-execution-enhanced.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { DEFAULT_RENDER_COALESCE_MS, requestRender, flushRender } from '../render-scheduler.js';\nimport { sanitizeAnsiForRendering } from '../sanitize-ansi.js';\nimport { getMarkdownTheme } from '../theme.js';\n\nimport type { EventHandlerContext } from './types.js';\n\nfunction getCurrentModeColor(ctx: EventHandlerContext): string | undefined {\n const color = ctx.state.session?.mode?.resolve?.()?.metadata?.color;\n return typeof color === 'string' ? color : undefined;\n}\n\nexport function isTaskMutationTool(toolName: string): boolean {\n return toolName === 'task_write' || toolName === 'task_update' || toolName === 'task_complete';\n}\n\nfunction applyQuietDisplayForNewTool(ctx: EventHandlerContext, component: ToolExecutionComponentEnhanced): void {\n if (!ctx.state.quietMode) return;\n\n component.setCompactToolModeColor(getCurrentModeColor(ctx));\n component.setQuietModeDisplay('quiet');\n component.setQuietPreviewLineLimit(ctx.state.quietModeMaxToolPreviewLines);\n}\n\nfunction reconcileToolBoundaries(ctx: EventHandlerContext): void {\n reconcileChatBoundarySpacers(ctx.state.chatContainer);\n}\n\nconst pluginSubagentToolCallIds = new Set<string>();\n\ninterface PendingShellOutput {\n output: string;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst pendingShellOutputs = new Map<string, PendingShellOutput>();\n\nexport function clearPendingShellOutputs(): void {\n for (const pending of pendingShellOutputs.values()) {\n clearTimeout(pending.timer);\n }\n pendingShellOutputs.clear();\n}\n\ntype JsonObject = Record<string, unknown>;\n\nclass AsyncStringQueue implements AsyncIterable<string> {\n #chunks: string[] = [];\n #waiting: ((result: IteratorResult<string>) => void) | undefined;\n #closed = false;\n\n push(chunk: string): void {\n if (this.#closed) return;\n const waiting = this.#waiting;\n if (waiting) {\n this.#waiting = undefined;\n waiting({ value: chunk, done: false });\n return;\n }\n this.#chunks.push(chunk);\n }\n\n close(): void {\n this.#closed = true;\n const waiting = this.#waiting;\n if (waiting) {\n this.#waiting = undefined;\n waiting({ value: undefined, done: true });\n }\n }\n\n [Symbol.asyncIterator](): AsyncIterator<string> {\n return {\n next: () => {\n const chunk = this.#chunks.shift();\n if (chunk !== undefined) return Promise.resolve({ value: chunk, done: false });\n if (this.#closed) return Promise.resolve({ value: undefined, done: true });\n return new Promise(resolve => {\n this.#waiting = resolve;\n });\n },\n };\n }\n}\n\ninterface ToolInputParserState {\n queue: AsyncStringQueue;\n iterator: AsyncIterableIterator<unknown>;\n latestArgs?: JsonObject;\n applyTimer?: ReturnType<typeof setTimeout>;\n closed: boolean;\n}\n\nconst toolInputParsers = new Map<string, ToolInputParserState>();\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isTaskStatus(value: unknown): value is TaskItemInput['status'] {\n return value === 'pending' || value === 'in_progress' || value === 'completed';\n}\n\nfunction isRenderableTask(value: unknown): value is TaskItemInput {\n if (!isJsonObject(value) || !isTaskStatus(value.status)) return false;\n if (typeof value.content !== 'string' || value.content.length === 0) return false;\n if (value.status === 'in_progress' && (typeof value.activeForm !== 'string' || value.activeForm.length === 0)) {\n return false;\n }\n return true;\n}\n\nfunction getRenderableTasks(value: unknown): TaskItemInput[] {\n if (!Array.isArray(value)) return [];\n return value.filter(isRenderableTask);\n}\n\nfunction createToolInputParser(toolCallId: string): ToolInputParserState {\n const queue = new AsyncStringQueue();\n const state: ToolInputParserState = {\n queue,\n iterator: parseJsonRiver(queue) as AsyncIterableIterator<unknown>,\n closed: false,\n };\n toolInputParsers.set(toolCallId, state);\n return state;\n}\n\nfunction closeToolInputParser(toolCallId: string): void {\n const parser = toolInputParsers.get(toolCallId);\n if (!parser) return;\n parser.closed = true;\n if (parser.applyTimer) {\n clearTimeout(parser.applyTimer);\n parser.applyTimer = undefined;\n }\n parser.queue.close();\n toolInputParsers.delete(toolCallId);\n}\n\nexport function clearToolInputParsers(): void {\n for (const toolCallId of toolInputParsers.keys()) {\n closeToolInputParser(toolCallId);\n }\n}\n\ntype SubagentProgressEvent =\n | { event: 'text'; text: string }\n | { event: 'tool_start'; toolName: string; args?: unknown }\n | { event: 'tool_end'; toolName: string; result?: unknown; isError?: boolean }\n | { event: 'finish'; isError?: boolean; durationMs?: number; result?: string };\n\nfunction isSubagentProgressEvent(value: unknown): value is SubagentProgressEvent {\n if (!value || typeof value !== 'object') return false;\n const event = (value as Record<string, unknown>).event;\n return event === 'text' || event === 'tool_start' || event === 'tool_end' || event === 'finish';\n}\n\nfunction getTaskFromArgs(args: unknown, fallback: string): string {\n if (args && typeof args === 'object') {\n const question = (args as Record<string, unknown>).question;\n if (typeof question === 'string' && question.trim()) return question;\n const task = (args as Record<string, unknown>).task;\n if (typeof task === 'string' && task.trim()) return task;\n }\n return fallback;\n}\n\nexport function createStaticSubagentComponent(\n ctx: EventHandlerContext,\n toolCallId: string,\n toolName: string,\n args: unknown,\n): SubagentExecutionComponent | undefined {\n const renderConfig = ctx.state.pluginManager?.getToolRenderConfig(toolName);\n if (renderConfig?.type !== 'subagent') return undefined;\n\n const { state } = ctx;\n const existing = state.pendingSubagents.get(toolCallId);\n if (existing) {\n existing.setTask(getTaskFromArgs(args, toolName));\n return existing;\n }\n\n const component = new SubagentExecutionComponent(\n renderConfig.agentType ?? 'plugin',\n getTaskFromArgs(args, toolName),\n state.ui,\n renderConfig.modelId,\n {\n collapseOnComplete: false,\n expandOnComplete: state.quietMode,\n forked: renderConfig.forked,\n label: renderConfig.label,\n maxActivityLines: renderConfig.maxActivityLines,\n collapsedLines: renderConfig.collapsedLines,\n colors: renderConfig.colors,\n icons: renderConfig.icons,\n },\n );\n state.pendingSubagents.set(toolCallId, component);\n pluginSubagentToolCallIds.add(toolCallId);\n state.allToolComponents.push(component as any);\n ctx.addChildBeforeFollowUps(component);\n\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n\n reconcileToolBoundaries(ctx);\n flushRender(state);\n return component;\n}\n\nfunction handleSubagentProgress(\n ctx: EventHandlerContext,\n toolCallId: string,\n progress: SubagentProgressEvent,\n): boolean {\n const { state } = ctx;\n const component = state.pendingSubagents.get(toolCallId);\n if (!component || !pluginSubagentToolCallIds.has(toolCallId)) return false;\n\n switch (progress.event) {\n case 'text':\n component.setText(progress.text);\n break;\n case 'tool_start':\n component.addToolStart(progress.toolName, progress.args);\n break;\n case 'tool_end':\n component.addToolEnd(progress.toolName, progress.result, progress.isError ?? false);\n break;\n case 'finish':\n component.finish(progress.isError ?? false, progress.durationMs ?? 0, progress.result);\n break;\n }\n\n reconcileToolBoundaries(ctx);\n requestRender(state);\n return true;\n}\n\nfunction insertTaskToolErrorComponent(ctx: EventHandlerContext, component: unknown): void {\n const { state } = ctx;\n if (state.streamingComponent) {\n const insertIndex = state.chatContainer.children.indexOf(state.streamingComponent as never);\n if (insertIndex >= 0) {\n (state.chatContainer.children as unknown[]).splice(insertIndex, 0, component);\n state.chatContainer.invalidate();\n return;\n }\n }\n ctx.addChildBeforeFollowUps(component as never);\n}\n\nfunction ensureSubmitPlanComponent(\n ctx: EventHandlerContext,\n toolCallId: string,\n args?: unknown,\n): PlanApprovalInlineComponent {\n const { state } = ctx;\n let component = state.pendingSubmitPlanComponents.get(toolCallId);\n if (!component) {\n component = PlanApprovalInlineComponent.createStreaming(state.ui);\n state.pendingSubmitPlanComponents.set(toolCallId, component);\n state.lastSubmitPlanComponent = component;\n ctx.addChildBeforeFollowUps(component);\n\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n }\n component.updateArgs(args);\n reconcileToolBoundaries(ctx);\n return component;\n}\n\n/**\n * Format a tool result for display.\n * Handles objects, strings, and other types.\n * Extracts content from common tool return structures like { content: \"...\", isError: false }\n */\nfunction isToolResultError(result: unknown): boolean {\n return typeof result === 'object' && result !== null && (result as Record<string, unknown>).isError === true;\n}\n\nexport function formatToolResult(result: unknown): string {\n if (result === null || result === undefined) {\n return '';\n }\n if (typeof result === 'string') {\n return sanitizeAnsiForRendering(result);\n }\n if (typeof result === 'object') {\n const obj = result as Record<string, unknown>;\n // Handle common tool return format: { content: \"...\", isError: boolean }\n if ('content' in obj && typeof obj.content === 'string') {\n return sanitizeAnsiForRendering(obj.content);\n }\n // Handle content array format: { content: [{ type: \"text\", text: \"...\" }] }\n if ('content' in obj && Array.isArray(obj.content)) {\n const textParts = obj.content\n .filter(\n (part: unknown) =>\n typeof part === 'object' && part !== null && (part as Record<string, unknown>).type === 'text',\n )\n .map((part: unknown) => (part as Record<string, unknown>).text || '');\n if (textParts.length > 0) {\n return sanitizeAnsiForRendering(textParts.join('\\n'));\n }\n }\n try {\n return sanitizeAnsiForRendering(safeStringify(result, 2));\n } catch {\n return sanitizeAnsiForRendering(String(result));\n }\n }\n return sanitizeAnsiForRendering(String(result));\n}\n\nexport function handleToolApprovalRequired(\n ctx: EventHandlerContext,\n toolCallId: string,\n toolName: string,\n args: unknown,\n): void {\n const { state } = ctx;\n // Compute category label for the dialog\n const category = getToolCategory(toolName);\n const categoryLabel = category ? TOOL_CATEGORIES[category]?.label : undefined;\n\n // Send notification to alert the user\n ctx.notify('tool_approval', `Approve ${toolName}?`);\n\n const firePermissionResult = (decision: 'approved' | 'declined' | 'dismissed' | 'auto_approved') => {\n state.hookManager?.runPermissionResult('tool_approval', toolCallId, toolName, decision, args).catch(() => {});\n };\n\n const dialog = new ToolApprovalDialogComponent({\n toolCallId,\n toolName,\n args,\n categoryLabel,\n onAction: (action: ApprovalAction) => {\n state.ui.hideOverlay();\n state.pendingApprovalDismiss = null;\n if (action.type === 'approve') {\n firePermissionResult('approved');\n state.session.respondToToolApproval({ decision: 'approve' });\n } else if (action.type === 'always_allow_category') {\n firePermissionResult('approved');\n state.session.respondToToolApproval({ decision: 'always_allow_category' });\n } else if (action.type === 'yolo') {\n firePermissionResult('auto_approved');\n void state.session.state.set({ yolo: true } as any);\n state.session.respondToToolApproval({ decision: 'approve' });\n } else {\n firePermissionResult('declined');\n state.session.respondToToolApproval({ decision: 'decline' });\n }\n },\n });\n\n // Set up dismissal to decline\n state.pendingApprovalDismiss = declineContext => {\n state.ui.hideOverlay();\n state.pendingApprovalDismiss = null;\n firePermissionResult('dismissed');\n state.session.respondToToolApproval({ decision: 'decline', declineContext });\n };\n\n // Show the dialog as an overlay\n showModalOverlay(state.ui, dialog, { widthPercent: 0.7 });\n dialog.focused = true;\n flushRender(state);\n}\n\nexport function handleToolStart(ctx: EventHandlerContext, toolCallId: string, toolName: string, args: unknown): void {\n const { state } = ctx;\n // Component may already exist if created early by handleToolInputStart\n const existingComponent = state.pendingTools.get(toolCallId);\n const existingSubmitPlanComponent = state.pendingSubmitPlanComponents?.get(toolCallId);\n\n if (state.pendingSubagents.has(toolCallId) && pluginSubagentToolCallIds.has(toolCallId)) {\n createStaticSubagentComponent(ctx, toolCallId, toolName, args);\n return;\n }\n\n if (existingComponent) {\n // Component was created during input streaming — update with final args\n existingComponent.updateArgs(args);\n reconcileToolBoundaries(ctx);\n } else if (existingSubmitPlanComponent) {\n existingSubmitPlanComponent.updateArgs(args);\n } else if (!state.seenToolCallIds.has(toolCallId)) {\n state.seenToolCallIds.add(toolCallId);\n\n // Skip creating the regular tool component for subagent calls\n // The SubagentExecutionComponent will handle all the rendering\n if (toolName === 'subagent') {\n return;\n }\n\n if (createStaticSubagentComponent(ctx, toolCallId, toolName, args)) {\n return;\n }\n\n // Skip creating regular component for ask_user — it uses AskQuestionInlineComponent\n // (normally created by handleToolInputStart, but handleToolStart may fire first)\n if (toolName === 'ask_user') {\n return;\n }\n\n if (toolName === 'submit_plan') {\n ensureSubmitPlanComponent(ctx, toolCallId, args);\n flushRender(state);\n return;\n }\n\n if (isTaskMutationTool(toolName)) {\n state.taskToolInsertIndex = state.chatContainer.children.length;\n const component = new ToolExecutionComponentEnhanced(\n toolName,\n args,\n { showImages: false, collapsedByDefault: !state.toolOutputExpanded },\n state.ui,\n );\n component.setExpanded(state.toolOutputExpanded);\n state.pendingTools.set(toolCallId, component);\n state.pendingTaskToolIds?.add(toolCallId);\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n flushRender(state);\n return;\n }\n\n const component = new ToolExecutionComponentEnhanced(\n toolName,\n args,\n { showImages: false, collapsedByDefault: !state.toolOutputExpanded },\n state.ui,\n );\n component.setExpanded(state.toolOutputExpanded);\n applyQuietDisplayForNewTool(ctx, component);\n ctx.addChildBeforeFollowUps(component);\n state.pendingTools.set(toolCallId, component);\n state.allToolComponents.push(component);\n reconcileToolBoundaries(ctx);\n\n // Create a new post-tool AssistantMessageComponent so pre-tool text is preserved\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n\n flushRender(state);\n }\n\n // File modification tracking is handled by the AgentController display state\n}\n\nexport function handleToolUpdate(ctx: EventHandlerContext, toolCallId: string, partialResult: unknown): void {\n if (isSubagentProgressEvent(partialResult) && handleSubagentProgress(ctx, toolCallId, partialResult)) {\n return;\n }\n\n const { state } = ctx;\n const component = state.pendingTools.get(toolCallId);\n if (component) {\n const result: ToolResult = {\n content: [{ type: 'text', text: formatToolResult(partialResult) }],\n isError: false,\n };\n component.updateResult(result, true);\n reconcileToolBoundaries(ctx);\n requestRender(state);\n }\n}\n\n/**\n * Handle streaming shell output from execute_command tool.\n */\nfunction flushPendingShellOutput(ctx: EventHandlerContext, toolCallId: string): void {\n const pending = pendingShellOutputs.get(toolCallId);\n if (!pending) return;\n pendingShellOutputs.delete(toolCallId);\n clearTimeout(pending.timer);\n\n const { state } = ctx;\n const component = state.pendingTools.get(toolCallId);\n if (component?.appendStreamingOutput) {\n component.appendStreamingOutput(pending.output);\n reconcileToolBoundaries(ctx);\n requestRender(state);\n }\n}\n\n/**\n * Handle streaming shell output from execute_command tool.\n */\nexport function handleShellOutput(\n ctx: EventHandlerContext,\n toolCallId: string,\n output: string,\n _stream: 'stdout' | 'stderr',\n): void {\n const pending = pendingShellOutputs.get(toolCallId);\n if (pending) {\n pending.output += output;\n return;\n }\n\n pendingShellOutputs.set(toolCallId, {\n output,\n timer: setTimeout(() => flushPendingShellOutput(ctx, toolCallId), DEFAULT_RENDER_COALESCE_MS),\n });\n}\n\n/**\n * Handle the start of streaming tool call input arguments.\n * Creates the tool component early so partial args can render as they arrive.\n */\nexport function handleToolInputStart(ctx: EventHandlerContext, toolCallId: string, toolName: string): void {\n const { state } = ctx;\n closeToolInputParser(toolCallId);\n const parser = createToolInputParser(toolCallId);\n void processToolInputParser(ctx, toolCallId, parser);\n\n // Mark as seen so handleMessageUpdate doesn't create a duplicate component\n if (!state.seenToolCallIds.has(toolCallId)) {\n state.seenToolCallIds.add(toolCallId);\n }\n\n if (state.pendingTools.has(toolCallId)) {\n if (isTaskMutationTool(toolName)) {\n state.pendingTaskToolIds?.add(toolCallId);\n }\n return;\n }\n\n // Create the component early so deltas can update it\n // Skip for subagent (handled by SubagentExecutionComponent),\n // task tools (they stream to or update the pinned TaskProgressComponent),\n // and ask_user (uses AskQuestionInlineComponent)\n if (toolName === 'submit_plan') {\n ensureSubmitPlanComponent(ctx, toolCallId);\n flushRender(state);\n } else if (toolName === 'ask_user') {\n if (state.goalManager?.isActive()) {\n return;\n }\n\n const askComponent = AskQuestionInlineComponent.createStreaming(state.ui);\n ctx.addChildBeforeFollowUps(askComponent);\n state.lastAskUserComponent = askComponent;\n state.pendingAskUserComponents.set(toolCallId, askComponent);\n\n // Create a new post-tool AssistantMessageComponent so pre-tool text is preserved\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n\n flushRender(state);\n } else if (isTaskMutationTool(toolName)) {\n // Record position so task_updated can place inline completed/cleared display here\n state.taskToolInsertIndex = state.chatContainer.children.length;\n const component = new ToolExecutionComponentEnhanced(\n toolName,\n {},\n { showImages: false, collapsedByDefault: !state.toolOutputExpanded },\n state.ui,\n );\n component.setExpanded(state.toolOutputExpanded);\n state.pendingTools.set(toolCallId, component);\n state.pendingTaskToolIds?.add(toolCallId);\n\n // Create a new post-tool AssistantMessageComponent so pre-tool text is preserved\n // (even though task_write doesn't render a tool component inline, we still need\n // to split the streaming component so getTrailingContentParts doesn't overwrite it)\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n flushRender(state);\n } else if (toolName !== 'subagent') {\n if (createStaticSubagentComponent(ctx, toolCallId, toolName, {})) {\n return;\n }\n\n const component = new ToolExecutionComponentEnhanced(\n toolName,\n {},\n { showImages: false, collapsedByDefault: !state.toolOutputExpanded },\n state.ui,\n );\n component.setExpanded(state.toolOutputExpanded);\n applyQuietDisplayForNewTool(ctx, component);\n ctx.addChildBeforeFollowUps(component);\n state.pendingTools.set(toolCallId, component);\n state.allToolComponents.push(component);\n reconcileToolBoundaries(ctx);\n\n // Create a new post-tool AssistantMessageComponent so pre-tool text is preserved\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n\n flushRender(state);\n }\n}\n\n/**\n * Apply the latest progressive JSON object from the stateful tool-input parser.\n */\nfunction applyParsedToolArgs(\n ctx: EventHandlerContext,\n toolCallId: string,\n toolName: string,\n partialArgs: JsonObject,\n): void {\n const { state } = ctx;\n\n const component = state.pendingTools.get(toolCallId);\n if (component) {\n component.updateArgs(partialArgs, false);\n reconcileToolBoundaries(ctx);\n component.refresh?.();\n }\n\n if (toolName === 'ask_user') {\n const askComponent = state.pendingAskUserComponents.get(toolCallId);\n if (askComponent) {\n try {\n askComponent.updateArgs(partialArgs);\n } catch {\n // Don't crash on malformed partial args\n }\n }\n }\n\n if (toolName === 'submit_plan') {\n const planComponent = state.pendingSubmitPlanComponents?.get(toolCallId);\n if (planComponent) {\n planComponent.updateArgs(partialArgs);\n }\n }\n\n if (toolName === 'task_write' && state.taskProgress) {\n const tasks = getRenderableTasks(partialArgs.tasks);\n if (tasks.length > 0) {\n const existing = state.taskProgress.getTasks();\n const allExistingDone = existing.length === 0 || existing.every(t => t.status === 'completed');\n if (allExistingDone) {\n // Old list is done — start fresh, stream new items immediately\n state.taskProgress.updateTasks(tasks);\n } else if (tasks.length > 1) {\n // Merge only completed items (exclude the last still-streaming one)\n const merged = [...existing];\n for (const task of tasks.slice(0, -1)) {\n const idx = task.id\n ? merged.findIndex(t => t.id === task.id)\n : merged.findIndex(t => !t.id && t.content === task.content);\n if (idx >= 0) {\n merged[idx] = task;\n } else {\n merged.push(task);\n }\n }\n state.taskProgress.updateTasks(merged);\n }\n }\n }\n\n requestRender(state);\n}\n\nfunction flushLatestParsedToolArgs(ctx: EventHandlerContext, toolCallId: string): void {\n const parser = toolInputParsers.get(toolCallId);\n if (!parser || parser.closed || !parser.latestArgs) return;\n\n const buffer = ctx.state.session.displayState.get().toolInputBuffers.get(toolCallId);\n if (!buffer) return;\n applyParsedToolArgs(ctx, toolCallId, buffer.toolName, parser.latestArgs);\n}\n\nfunction scheduleParsedToolArgsApply(ctx: EventHandlerContext, toolCallId: string, parser: ToolInputParserState): void {\n if (parser.applyTimer) return;\n parser.applyTimer = setTimeout(() => {\n parser.applyTimer = undefined;\n flushLatestParsedToolArgs(ctx, toolCallId);\n }, DEFAULT_RENDER_COALESCE_MS);\n}\n\nasync function processToolInputParser(\n ctx: EventHandlerContext,\n toolCallId: string,\n parser: ToolInputParserState,\n): Promise<void> {\n try {\n while (!parser.closed) {\n const next = await parser.iterator.next();\n if (next.done) return;\n if (!isJsonObject(next.value)) continue;\n\n parser.latestArgs = next.value;\n if (parser.closed) return;\n scheduleParsedToolArgsApply(ctx, toolCallId, parser);\n }\n } catch {\n closeToolInputParser(toolCallId);\n }\n}\n\n/**\n * Handle an incremental delta of tool call input arguments.\n * Feeds only the incoming JSON fragment to the stateful parser.\n */\nexport function handleToolInputDelta(ctx: EventHandlerContext, toolCallId: string, argsTextDelta: string): void {\n const buffer = ctx.state.session.displayState.get().toolInputBuffers.get(toolCallId);\n if (buffer === undefined) return;\n\n let parser = toolInputParsers.get(toolCallId);\n if (!parser) {\n parser = createToolInputParser(toolCallId);\n void processToolInputParser(ctx, toolCallId, parser);\n }\n\n parser.queue.push(argsTextDelta);\n}\n\n/**\n * Clean up the input buffer when tool input streaming ends.\n */\nexport function handleToolInputEnd(ctx: EventHandlerContext, toolCallId: string): void {\n flushLatestParsedToolArgs(ctx, toolCallId);\n closeToolInputParser(toolCallId);\n}\n\nexport function handleToolEnd(ctx: EventHandlerContext, toolCallId: string, result: unknown, isError: boolean): void {\n flushPendingShellOutput(ctx, toolCallId);\n const { state } = ctx;\n // If this is a subagent tool, store the result in the SubagentExecutionComponent\n const subagentComponent = state.pendingSubagents.get(toolCallId);\n if (subagentComponent) {\n const resultText = formatToolResult(result);\n if (pluginSubagentToolCallIds.has(toolCallId)) {\n subagentComponent.finish(isError, 0, resultText);\n state.pendingSubagents.delete(toolCallId);\n pluginSubagentToolCallIds.delete(toolCallId);\n flushRender(state);\n } else {\n // We'll need to wait for subagent_end to set this\n // Store it temporarily\n (subagentComponent as any)._pendingResult = resultText;\n }\n }\n\n // File modification tracking is handled by the AgentController display state\n\n // Clean up ask_user component tracking\n state.pendingAskUserComponents.delete(toolCallId);\n\n if (state.pendingSubmitPlanComponents?.has(toolCallId)) {\n // submit_plan renders through PlanApprovalInlineComponent, not the generic tool box.\n return;\n }\n\n const component = state.pendingTools.get(toolCallId);\n if (component) {\n const isPendingTaskTool = state.pendingTaskToolIds?.has(toolCallId) ?? false;\n const effectiveIsError = isError || isToolResultError(result);\n if (isPendingTaskTool && effectiveIsError) {\n insertTaskToolErrorComponent(ctx, component);\n state.allToolComponents.push(component);\n }\n\n const toolResult: ToolResult = {\n content: [{ type: 'text', text: formatToolResult(result) }],\n isError: effectiveIsError,\n };\n component.updateResult(toolResult, false);\n reconcileToolBoundaries(ctx);\n\n state.pendingTools.delete(toolCallId);\n state.pendingTaskToolIds?.delete(toolCallId);\n flushRender(state);\n }\n}\n","/**\n * Message rendering helpers extracted from MastraTUI.\n *\n * Pure functions that operate on TUIState — no class dependency.\n */\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport type { Component } from '@earendil-works/pi-tui';\nimport { readPlanFile, resolvePlanPath } from '@mastra/code-sdk/utils/plans';\nimport type { MastraDBMessage } from '@mastra/core/agent-controller';\nimport { parseSubagentMeta } from '@mastra/core/agent-controller';\nimport type { TaskItemInput, TaskItemSnapshot } from '@mastra/core/signals';\nimport { assignTaskIds } from '@mastra/core/signals';\nimport type { GoalEvaluationPayload } from '@mastra/core/stream';\nimport { TASKS_STATE_ID } from '@mastra/core/tools';\nimport {\n insertChatComponentWithBoundarySpacing,\n reconcileChatBoundarySpacers,\n} from './chat-boundary-reconciliation.js';\nimport { AskQuestionInlineComponent } from './components/ask-question-inline.js';\nimport { AssistantMessageComponent } from './components/assistant-message.js';\nimport type { ChatSpacingKind } from './components/chat-spacing.js';\nimport { JudgeDisplayComponent } from './components/judge-display.js';\nimport { NotificationSummaryComponent } from './components/notification-summary.js';\nimport { NotificationComponent } from './components/notification.js';\nimport { OMMarkerComponent } from './components/om-marker.js';\nimport { OMOutputComponent } from './components/om-output.js';\nimport { PlanResultComponent } from './components/plan-approval-inline.js';\nimport { ReactiveSignalComponent } from './components/reactive-signal.js';\nimport { SlashCommandComponent } from './components/slash-command.js';\nimport { StateSignalComponent } from './components/state-signal.js';\nimport { SubagentExecutionComponent } from './components/subagent-execution.js';\nimport { SystemReminderComponent } from './components/system-reminder.js';\nimport { formatTaskProgressLine } from './components/task-progress.js';\nimport { TemporalGapComponent } from './components/temporal-gap.js';\nimport { ToolExecutionComponentEnhanced } from './components/tool-execution-enhanced.js';\nimport { PendingUserMessageComponent, UserMessageComponent } from './components/user-message.js';\nimport {\n getAssistantRenderParts,\n getMessageText,\n getNotificationSummaryView,\n getNotificationView,\n getReactiveSignalView,\n getReminderView,\n getSignalKind,\n getStateSignalView,\n getUserSignalView,\n isSignalMessage,\n} from './db-message-parts.js';\nimport type { AssistantRenderPart } from './db-message-parts.js';\nimport { formatToolResult, isTaskMutationTool } from './handlers/tool.js';\nimport type { TUIState } from './state.js';\nimport { BOX_INDENT, getMarkdownTheme, theme } from './theme.js';\n\n// Re-export so existing consumers can still import from here\nexport { formatToolResult };\n\nconst WHILE_ACTIVE_USER_MESSAGE_LABEL = 'steer';\n// These are internal control-plane signals handled by GithubSignals. The user-visible\n// result is rendered by github-sync-status, so showing these would duplicate the UI.\nconst HIDDEN_REACTIVE_SIGNAL_TAGS = new Set(['github-subscribe-pr', 'github-unsubscribe-pr']);\nconst GOAL_STATE_SIGNAL_ID = 'goal';\n\nfunction shouldRenderReactiveSignal(tagName: string): boolean {\n return !HIDDEN_REACTIVE_SIGNAL_TAGS.has(tagName);\n}\n\nfunction getUserMessageLabel(message: MastraDBMessage, fallbackLabel?: string): string | undefined {\n const signalAttributes = (message.content?.metadata?.signal as { attributes?: Record<string, unknown> } | undefined)\n ?.attributes;\n if (signalAttributes?.delivery === 'while-active') return WHILE_ACTIVE_USER_MESSAGE_LABEL;\n return fallbackLabel;\n}\n\nfunction getPendingUserMessageLabel(isInterjection?: boolean): string | undefined {\n return isInterjection ? WHILE_ACTIVE_USER_MESSAGE_LABEL : undefined;\n}\n\nfunction getCurrentModeColor(state: TUIState): string | undefined {\n const color = state.session.mode.resolve().metadata?.color;\n return typeof color === 'string' ? color : undefined;\n}\n\nfunction getTaskFromToolArgs(args: unknown, fallback: string): string {\n if (args && typeof args === 'object') {\n const question = (args as Record<string, unknown>).question;\n if (typeof question === 'string' && question.trim()) return question;\n const task = (args as Record<string, unknown>).task;\n if (typeof task === 'string' && task.trim()) return task;\n }\n return fallback;\n}\n\n// =============================================================================\n// renderClearedTasksInline\n// =============================================================================\n\nclass TaskHistoryComponent extends Container {\n getChatSpacingKind(): ChatSpacingKind {\n return 'task';\n }\n}\n\nfunction insertTaskHistoryComponent(state: TUIState, component: Component, insertIndex: number): void {\n insertChatComponentWithBoundarySpacing(\n state.chatContainer,\n component,\n insertIndex >= 0 ? insertIndex : state.chatContainer.children.length,\n );\n}\n\n/**\n * Render inline display when tasks are cleared.\n */\nexport function renderClearedTasksInline(state: TUIState, clearedTasks: TaskItemSnapshot[], insertIndex = -1): void {\n const container = new TaskHistoryComponent();\n const count = clearedTasks.length;\n const label = count === 1 ? 'Task' : 'Tasks';\n container.addChild(new Text(theme.fg('accent', `${label} cleared`), BOX_INDENT, 0));\n for (const task of clearedTasks) {\n container.addChild(new Text(formatTaskProgressLine(task, ' '), BOX_INDENT, 0));\n }\n insertTaskHistoryComponent(state, container, insertIndex);\n}\n\nexport function renderCompletedTasksInline(\n state: TUIState,\n completedTasks: TaskItemSnapshot[],\n insertIndex = -1,\n): void {\n const container = new TaskHistoryComponent();\n const count = completedTasks.length;\n container.addChild(\n new Text(`${theme.fg('accent', 'Tasks')} ${theme.fg('dim', `[${count}/${count} completed]`)}`, BOX_INDENT, 0),\n );\n for (const task of completedTasks) {\n container.addChild(new Text(formatTaskProgressLine(task, ' '), BOX_INDENT, 0));\n }\n insertTaskHistoryComponent(state, container, insertIndex);\n}\n\nfunction getTaskKey(task: TaskItemSnapshot): string {\n return task.id || task.content;\n}\n\nexport function renderTaskDeltaInline(\n state: TUIState,\n previousTasks: TaskItemSnapshot[],\n nextTasks: TaskItemSnapshot[],\n insertIndex = -1,\n): boolean {\n const previousByKey = new Map(previousTasks.map(task => [getTaskKey(task), task]));\n const addedTasks = nextTasks.filter(task => !previousByKey.has(getTaskKey(task)));\n const inProgressTasks = nextTasks.filter(task => {\n const previous = previousByKey.get(getTaskKey(task));\n return task.status === 'in_progress' && previous?.status !== 'in_progress';\n });\n const completedTasks = nextTasks.filter(task => {\n const previous = previousByKey.get(getTaskKey(task));\n return task.status === 'completed' && previous?.status !== 'completed';\n });\n\n if (addedTasks.length === 0 && inProgressTasks.length === 0 && completedTasks.length === 0) return false;\n\n const changedTaskKeys = new Set([...addedTasks, ...inProgressTasks, ...completedTasks].map(getTaskKey));\n const changedTasks = nextTasks.filter(task => changedTaskKeys.has(getTaskKey(task)));\n\n const container = new TaskHistoryComponent();\n container.addChild(new Text(theme.fg('accent', 'Tasks'), BOX_INDENT, 0));\n\n for (const task of changedTasks) {\n container.addChild(new Text(formatTaskProgressLine(task, ' '), BOX_INDENT, 0));\n }\n\n insertTaskHistoryComponent(state, container, insertIndex);\n return true;\n}\n\nfunction renderTaskTransitionFromHistory(\n state: TUIState,\n previousTasks: TaskItemSnapshot[],\n nextTasks: TaskItemSnapshot[],\n): { tasks: TaskItemSnapshot[]; replacedWithInline: boolean } {\n if (nextTasks.length > 0 && nextTasks.every(t => t.status === 'completed')) {\n renderCompletedTasksInline(state, nextTasks);\n return { tasks: nextTasks, replacedWithInline: true };\n }\n\n if (nextTasks.length === 0) {\n if (previousTasks.length > 0) {\n renderClearedTasksInline(state, previousTasks);\n return { tasks: [], replacedWithInline: true };\n }\n return { tasks: [], replacedWithInline: false };\n }\n\n renderTaskDeltaInline(state, previousTasks, nextTasks);\n return { tasks: nextTasks, replacedWithInline: true };\n}\n\n// =============================================================================\n// addUserMessage\n// =============================================================================\n\nfunction createReminderComponent(\n reminderType: string | undefined,\n options: {\n message?: string;\n path?: string;\n gapText?: string;\n goalMaxTurns?: number;\n judgeModelId?: string;\n },\n): SystemReminderComponent | TemporalGapComponent {\n if (reminderType === 'temporal-gap') {\n return new TemporalGapComponent({\n message: options.message,\n gapText: options.gapText,\n });\n }\n\n return new SystemReminderComponent({\n message: options.message,\n reminderType,\n path: options.path,\n goalMaxTurns: options.goalMaxTurns,\n judgeModelId: options.judgeModelId,\n });\n}\n\nfunction addChildBeforeFollowUps(state: TUIState, child: Component): void {\n const pendingSignalComponents = state.pendingSignalMessageComponentsById?.values() ?? [];\n const firstPinned = [...state.followUpComponents, ...pendingSignalComponents].find(pinned =>\n state.chatContainer.children.includes(('component' in pinned ? pinned.component : pinned) as never),\n );\n\n if (firstPinned) {\n const component = 'component' in firstPinned ? firstPinned.component : firstPinned;\n const idx = state.chatContainer.children.indexOf(component as never);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(state.chatContainer, child, idx);\n return;\n }\n }\n\n insertChatComponentWithBoundarySpacing(state.chatContainer, child);\n}\n\nexport function addChildBeforeMessageOrFollowUps(state: TUIState, child: Component, precedesMessageId?: string): void {\n if (precedesMessageId) {\n const anchor = state.messageComponentsById.get(precedesMessageId);\n if (anchor) {\n const idx = state.chatContainer.children.indexOf(anchor as never);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(state.chatContainer, child, idx);\n return;\n }\n }\n }\n\n addChildBeforeFollowUps(state, child);\n}\n\n/**\n * Add a user message to the chat container.\n */\nexport function addPendingUserMessage(\n state: TUIState,\n messageId: string,\n text: string,\n images?: Array<{ data: string; mimeType: string }>,\n options?: { isInterjection?: boolean },\n): void {\n const existing = state.pendingSignalMessageComponentsById.get(messageId);\n if (existing) {\n state.chatContainer.removeChild(existing.component as never);\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n\n const component = new PendingUserMessageComponent(text, images?.length ?? 0);\n state.pendingSignalMessageComponentsById.set(messageId, {\n component,\n text,\n images,\n isInterjection: options?.isInterjection,\n });\n state.chatContainer.addChild(component);\n reconcileChatBoundarySpacers(state.chatContainer);\n state.ui.requestRender();\n}\n\nexport function confirmPendingUserMessage(\n state: TUIState,\n messageId: string,\n text: string,\n attachments?: { imageCount: number; fileCount: number },\n): void {\n const pending = state.pendingSignalMessageComponentsById.get(messageId);\n if (!pending) return;\n\n if (state.streamingComponent && state.session.displayState.get().isRunning) {\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n }\n\n replacePendingUserMessage(state, messageId, text, attachments);\n}\n\nfunction replacePendingUserMessage(\n state: TUIState,\n messageId: string,\n text: string,\n attachments?: { imageCount: number; fileCount: number },\n): void {\n const pending = state.pendingSignalMessageComponentsById.get(messageId);\n if (!pending) return;\n\n const prefix = formatAttachmentPrefix(\n attachments?.imageCount ?? pending.images?.length ?? 0,\n attachments?.fileCount ?? 0,\n );\n const label = getPendingUserMessageLabel(pending.isInterjection);\n const confirmed = new UserMessageComponent(prefix + text, getMarkdownTheme(), {\n ...(label ? { label } : {}),\n });\n const idx = state.chatContainer.children.indexOf(pending.component as never);\n if (idx >= 0) {\n (state.chatContainer.children as unknown[]).splice(idx, 1, confirmed);\n reconcileChatBoundarySpacers(state.chatContainer);\n } else {\n addChildBeforeFollowUps(state, confirmed);\n }\n state.pendingSignalMessageComponentsById.delete(messageId);\n state.messageComponentsById.set(messageId, confirmed);\n state.ui.requestRender();\n}\n\nexport function removePendingUserMessage(state: TUIState, messageId: string): void {\n const pending = state.pendingSignalMessageComponentsById.get(messageId);\n if (!pending) return;\n state.chatContainer.removeChild(pending.component as never);\n state.pendingSignalMessageComponentsById.delete(messageId);\n state.ui.requestRender();\n}\n\nexport function removeUserMessage(state: TUIState, messageId: string): void {\n const component = state.messageComponentsById.get(messageId);\n if (!component) return;\n state.chatContainer.removeChild(component as never);\n state.messageComponentsById.delete(messageId);\n reconcileChatBoundarySpacers(state.chatContainer);\n state.ui.requestRender();\n}\n\nexport function clearPendingUserMessages(state: TUIState): void {\n for (const pending of state.pendingSignalMessageComponentsById.values()) {\n state.chatContainer.removeChild(pending.component as never);\n }\n state.pendingSignalMessageComponentsById.clear();\n state.ui.requestRender();\n}\n\nfunction confirmMatchingPendingUserMessage(\n state: TUIState,\n messageId: string,\n text: string,\n attachments: { imageCount: number; fileCount: number },\n): boolean {\n const normalizedText = text.trim();\n for (const [pendingId, pending] of state.pendingSignalMessageComponentsById) {\n if (pending.text.trim() !== normalizedText) continue;\n\n const label = getPendingUserMessageLabel(pending.isInterjection);\n const confirmed = new UserMessageComponent(\n formatAttachmentPrefix(attachments.imageCount, attachments.fileCount) + text,\n getMarkdownTheme(),\n {\n ...(label ? { label } : {}),\n },\n );\n const idx = state.chatContainer.children.indexOf(pending.component as never);\n if (idx >= 0) {\n (state.chatContainer.children as unknown[]).splice(idx, 1, confirmed);\n reconcileChatBoundarySpacers(state.chatContainer);\n } else {\n addChildBeforeFollowUps(state, confirmed);\n }\n state.pendingSignalMessageComponentsById.delete(pendingId);\n state.messageComponentsById.set(messageId, confirmed);\n state.ui.requestRender();\n return true;\n }\n return false;\n}\n\nfunction unescapeSkillBoundary(text: string): string {\n return text.replaceAll('&lt;/skill&gt;', '</skill>');\n}\n\nfunction getUserContentParts(\n message: MastraDBMessage,\n): Array<{ type?: string; mimeType?: string; mediaType?: string }> {\n const content = message.content;\n if (typeof content === 'string' || !content?.parts) return [];\n return content.parts as Array<{ type?: string; mimeType?: string; mediaType?: string }>;\n}\n\n/**\n * DB-native user attachments are persisted as `file` parts; images are `file`\n * parts whose media type is `image/*`. Distinguish them so the TUI can show\n * separate image and file counts.\n */\nfunction isImagePart(part: { type?: string; mimeType?: string; mediaType?: string }): boolean {\n if (part.type === 'image') return true;\n if (part.type !== 'file') return false;\n const media = part.mediaType ?? part.mimeType ?? '';\n return media.startsWith('image/');\n}\n\nfunction formatAttachmentPrefix(imageCount: number, fileCount: number): string {\n const labels = [\n imageCount > 0 ? `[${imageCount} image${imageCount > 1 ? 's' : ''}]` : '',\n fileCount > 0 ? `[${fileCount} file${fileCount > 1 ? 's' : ''}]` : '',\n ].filter(Boolean);\n return labels.length > 0 ? `${labels.join(' ')} ` : '';\n}\n\n/**\n * Render a `role: 'signal'` message into its dedicated TUI component (reminder,\n * judge, state, reactive, notification, notification-summary). Returns true when\n * the signal was fully handled; returns false for `user`-kind signals so the\n * caller renders it through the shared user-message component path.\n */\nexport function renderSignalMessage(state: TUIState, message: MastraDBMessage): boolean {\n const kind = getSignalKind(message);\n\n if (kind === 'reminder') {\n const reminder = getReminderView(message);\n\n if (reminder.reminderType === 'goal-judge') {\n // Goal-judge reminders with an evaluation payload render the judge result.\n // Bare goal-judge continuation reminders (\"[Goal attempt N/M] Continue…\")\n // are suppressed because the goal/judge UI already surfaces that state.\n if (reminder.goalEvaluation) {\n const goalEvaluation = reminder.goalEvaluation as GoalEvaluationPayload;\n const judgeComponent = new JudgeDisplayComponent(null, goalEvaluation.iteration, goalEvaluation.maxRuns);\n judgeComponent.setEvaluation(goalEvaluation);\n addChildBeforeMessageOrFollowUps(state, judgeComponent, reminder.precedesMessageId);\n state.messageComponentsById.set(message.id, judgeComponent);\n state.ui.requestRender();\n }\n return true;\n }\n\n const reminderComponent = createReminderComponent(reminder.reminderType, {\n message: reminder.message,\n path: reminder.path,\n gapText: reminder.gapText,\n goalMaxTurns: reminder.goalMaxTurns,\n judgeModelId: reminder.judgeModelId,\n });\n reminderComponent.setExpanded(state.toolOutputExpanded);\n state.allSystemReminderComponents.push(reminderComponent);\n\n // If the reminder anchors before a user message that has not been rendered\n // yet (its id is not mapped), fall back to inserting it before the latest\n // rendered user message so temporal-gap markers stay above the run they\n // precede.\n if (reminder.precedesMessageId && !state.messageComponentsById.has(reminder.precedesMessageId)) {\n const latestUserComponent = [...state.chatContainer.children]\n .reverse()\n .find(child => child instanceof UserMessageComponent);\n if (latestUserComponent) {\n const idx = state.chatContainer.children.indexOf(latestUserComponent as never);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(state.chatContainer, reminderComponent, idx);\n state.ui.requestRender();\n return true;\n }\n }\n }\n\n if (!reminder.precedesMessageId && state.streamingComponent) {\n const idx = state.chatContainer.children.indexOf(state.streamingComponent as never);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(state.chatContainer, reminderComponent, idx);\n state.ui.requestRender();\n return true;\n }\n }\n\n addChildBeforeMessageOrFollowUps(state, reminderComponent, reminder.precedesMessageId);\n state.ui.requestRender();\n return true;\n }\n\n if (kind === 'state') {\n const stateSignal = getStateSignalView(message);\n\n // The `tasks` state signal is rendered by the pinned task list UI (replayed\n // from task tool history), so skip its raw <current-task-list> snapshot here.\n // The `goal` state signal is surfaced by the goal/judge UI, so likewise skip\n // its raw <current-objective> snapshot.\n if (stateSignal.stateId === TASKS_STATE_ID || stateSignal.stateId === GOAL_STATE_SIGNAL_ID) {\n return true;\n }\n\n const component = new StateSignalComponent({\n stateId: stateSignal.stateId,\n mode: stateSignal.mode,\n version: stateSignal.version,\n message: stateSignal.message,\n });\n addChildBeforeFollowUps(state, component);\n state.messageComponentsById.set(message.id, component);\n state.ui.requestRender();\n return true;\n }\n\n if (kind === 'reactive') {\n const reactive = getReactiveSignalView(message);\n if (!reactive.tagName || !shouldRenderReactiveSignal(reactive.tagName)) return true;\n const component = new ReactiveSignalComponent({\n tagName: reactive.tagName,\n message: reactive.message,\n });\n addChildBeforeFollowUps(state, component);\n state.messageComponentsById.set(message.id, component);\n state.ui.requestRender();\n return true;\n }\n\n if (kind === 'notification') {\n const notification = getNotificationView(message);\n const component = new NotificationComponent({\n message: notification.message,\n source: notification.source,\n kind: notification.kind,\n priority: notification.priority,\n status: notification.status,\n });\n addChildBeforeFollowUps(state, component);\n state.messageComponentsById.set(message.id, component);\n state.ui.requestRender();\n return true;\n }\n\n if (kind === 'notification-summary') {\n const summary = getNotificationSummaryView(message);\n const component = new NotificationSummaryComponent({\n message: summary.message,\n pending: summary.pending,\n bySource: summary.bySource,\n });\n addChildBeforeFollowUps(state, component);\n state.messageComponentsById.set(message.id, component);\n state.ui.requestRender();\n return true;\n }\n\n // kind === 'user': fall through to shared user-message text rendering.\n return false;\n}\n\nexport function addUserMessage(state: TUIState, message: MastraDBMessage, options?: { label?: string }): void {\n if (state.messageComponentsById.has(message.id)) {\n return;\n }\n\n let textContent: string;\n let imageCount: number;\n let fileCount: number;\n if (isSignalMessage(message)) {\n if (renderSignalMessage(state, message)) return;\n const userSignal = getUserSignalView(message);\n textContent = userSignal.message;\n imageCount = userSignal.imageCount;\n fileCount = userSignal.fileCount;\n } else {\n const parts = getUserContentParts(message);\n textContent = getMessageText(message);\n imageCount = parts.filter(part => isImagePart(part)).length;\n fileCount = parts.filter(part => part.type === 'file' && !isImagePart(part)).length;\n }\n\n // Strip [image] markers from text since we show count separately\n const displayText = imageCount > 0 ? textContent.replace(/\\[image\\]\\s*/g, '').trim() : textContent.trim();\n const exactDisplayText = displayText.trim();\n\n const slashCommandMatch = exactDisplayText.match(/^<slash-command\\s+name=\"([^\"]*)\">([\\s\\S]*?)<\\/slash-command>$/);\n if (slashCommandMatch) {\n const commandName = slashCommandMatch[1]!;\n const commandContent = slashCommandMatch[2]!.trim();\n const pending = state.pendingSignalMessageComponentsById.get(message.id);\n if (pending) {\n state.chatContainer.removeChild(pending.component as never);\n state.pendingSignalMessageComponentsById.delete(message.id);\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n const existingSlashComp = state.allSlashCommandComponents.find(\n component =>\n component.matches(commandName, commandContent) && state.chatContainer.children.includes(component as never),\n );\n if (existingSlashComp) {\n state.messageComponentsById.set(message.id, existingSlashComp);\n state.ui.requestRender();\n return;\n }\n\n const slashComp = new SlashCommandComponent(commandName, commandContent);\n state.allSlashCommandComponents.push(slashComp);\n insertChatComponentWithBoundarySpacing(state.chatContainer, slashComp);\n state.ui.requestRender();\n return;\n }\n\n const skillMatch = exactDisplayText.match(/^<skill\\s+name=\"([^\"]*)\">([\\s\\S]*?)<\\/skill>$/);\n if (skillMatch) {\n const commandName = `skill/${skillMatch[1]!}`;\n const skillContent = unescapeSkillBoundary(skillMatch[2]!.trim());\n const pending = state.pendingSignalMessageComponentsById.get(message.id);\n if (pending) {\n state.chatContainer.removeChild(pending.component as never);\n state.pendingSignalMessageComponentsById.delete(message.id);\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n const existingSkillComp = state.allSlashCommandComponents.find(\n component =>\n component.matches(commandName, skillContent) && state.chatContainer.children.includes(component as never),\n );\n if (existingSkillComp) {\n state.messageComponentsById.set(message.id, existingSkillComp);\n state.ui.requestRender();\n return;\n }\n\n const skillComp = new SlashCommandComponent(commandName, skillContent);\n state.allSlashCommandComponents.push(skillComp);\n insertChatComponentWithBoundarySpacing(state.chatContainer, skillComp);\n state.ui.requestRender();\n return;\n }\n\n const attachments = { imageCount, fileCount };\n if (state.pendingSignalMessageComponentsById.has(message.id)) {\n confirmPendingUserMessage(state, message.id, displayText, attachments);\n return;\n }\n\n if (confirmMatchingPendingUserMessage(state, message.id, displayText, attachments)) {\n return;\n }\n\n // Suppress subscription echo of locally-rendered queued messages (Ctrl+F queue).\n // drainQueuedAction already rendered the message with a local ID; the subscription\n // echoes it back with a different signal ID which would otherwise create a duplicate.\n const dedupKey = displayText.trim();\n const pendingEchoCounts = state.firedQueuedMessageTexts;\n const dedupCount = pendingEchoCounts?.get(dedupKey) ?? 0;\n if (dedupCount > 0) {\n if (dedupCount === 1) pendingEchoCounts!.delete(dedupKey);\n else pendingEchoCounts!.set(dedupKey, dedupCount - 1);\n return;\n }\n\n const legacyReminderMatch = exactDisplayText.match(\n /^<system-reminder(?<attrs>\\s+[^>]*)?>(?<body>[\\s\\S]*?)<\\/system-reminder>$/,\n );\n if (legacyReminderMatch?.groups?.body) {\n const attrs = legacyReminderMatch.groups.attrs ?? '';\n const reminderType = attrs.match(/\\stype=\"([^\"]+)\"/)?.[1];\n const path = attrs.match(/\\spath=\"([^\"]+)\"/)?.[1];\n const precedesMessageId = attrs.match(/\\sprecedesMessageId=\"([^\"]+)\"/)?.[1];\n const reminderText = unescapeSystemReminderText(legacyReminderMatch.groups.body.trim());\n const reminderComponent = createReminderComponent(reminderType, {\n message: reminderText,\n path,\n gapText: reminderType === 'temporal-gap' ? reminderText.split(' — ')[0]?.trim() : undefined,\n });\n reminderComponent.setExpanded(state.toolOutputExpanded);\n state.allSystemReminderComponents.push(reminderComponent);\n\n addChildBeforeMessageOrFollowUps(state, reminderComponent, precedesMessageId);\n state.ui.requestRender();\n return;\n }\n\n const prefix = formatAttachmentPrefix(imageCount, fileCount);\n if (displayText || prefix) {\n const label = getUserMessageLabel(message, options?.label);\n const userComponent = new UserMessageComponent(prefix + displayText, getMarkdownTheme(), {\n ...(label ? { label } : {}),\n });\n\n state.messageComponentsById.set(message.id, userComponent);\n\n if (state.streamingComponent && state.session.displayState.get().isRunning) {\n state.chatContainer.addChild(userComponent);\n state.followUpComponents.push(userComponent);\n reconcileChatBoundarySpacers(state.chatContainer);\n return;\n }\n\n addChildBeforeFollowUps(state, userComponent);\n }\n}\n\nfunction getTaskResultTasks(result: unknown): TaskItemInput[] | undefined {\n if (typeof result !== 'object' || result === null || !('tasks' in result)) return undefined;\n const tasks = (result as { tasks?: unknown }).tasks;\n return Array.isArray(tasks) ? (tasks as TaskItemInput[]) : undefined;\n}\n\nfunction areTasksEqual(left: readonly TaskItemSnapshot[] | undefined, right: readonly TaskItemSnapshot[]): boolean {\n if (!left || left.length !== right.length) return false;\n return left.every((task, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n task.id === other.id &&\n task.content === other.content &&\n task.status === other.status &&\n task.activeForm === other.activeForm\n );\n });\n}\n\nfunction applyTaskPatchFallback(\n tasks: TaskItemSnapshot[],\n args: unknown,\n status?: TaskItemSnapshot['status'],\n): TaskItemSnapshot[] {\n if (\n typeof args !== 'object' ||\n args === null ||\n !('id' in args) ||\n typeof (args as { id?: unknown }).id !== 'string'\n ) {\n return tasks;\n }\n\n const patch = args as { id: string; content?: string; status?: TaskItemSnapshot['status']; activeForm?: string };\n return tasks.map(task => (task.id === patch.id ? { ...task, ...patch, ...(status ? { status } : {}) } : task));\n}\n\nfunction applyTaskToolResult(\n tasks: TaskItemSnapshot[],\n toolName: string,\n args: unknown,\n result: unknown,\n isError: boolean,\n): TaskItemSnapshot[] {\n if (isError) return tasks;\n\n if (toolName === 'task_write') {\n const resultTasks = getTaskResultTasks(result);\n const inputTasks = (args as { tasks?: TaskItemInput[] } | undefined)?.tasks;\n const rawTasks = resultTasks ?? inputTasks;\n const nextTasks = rawTasks ? assignTaskIds(rawTasks, tasks) : undefined;\n return nextTasks ? [...nextTasks] : [];\n }\n\n if (toolName === 'task_update' || toolName === 'task_complete') {\n const resultTasks = getTaskResultTasks(result);\n // Current task patch tools return structured task snapshots. Keep this\n // fallback only for early persisted histories created before that snapshot\n // field existed.\n return resultTasks\n ? assignTaskIds(resultTasks, tasks)\n : applyTaskPatchFallback(tasks, args, toolName === 'task_complete' ? 'completed' : undefined);\n }\n\n if (toolName === 'task_check') {\n const resultTasks = getTaskResultTasks(result);\n return resultTasks ? assignTaskIds(resultTasks, tasks) : tasks;\n }\n\n return tasks;\n}\n\n// =============================================================================\n// renderExistingMessages\n// =============================================================================\n\nconst STARTUP_MESSAGE_WINDOW_SIZE = 200;\n\n/**\n * Build a partial assistant `MastraDBMessage` carrying only the accumulated\n * text/thinking render parts, so the interleaving history replay can flush a\n * standalone `AssistantMessageComponent` before each tool/OM boundary.\n *\n * Terminal metadata (`stopReason`/`errorMessage`) is stripped from all but the\n * final slice so an aborted/errored message shows its terminal line once at\n * the end instead of after every accumulated text slice.\n */\nfunction buildAssistantSlice(\n message: MastraDBMessage,\n parts: Array<Extract<AssistantRenderPart, { kind: 'text' | 'thinking' }>>,\n options?: { includeTerminalMetadata?: boolean },\n): MastraDBMessage {\n const sliceParts = parts.map(part =>\n part.kind === 'thinking'\n ? { type: 'reasoning' as const, reasoning: part.text }\n : { type: 'text' as const, text: part.text },\n );\n const baseContent = typeof message.content === 'string' ? { format: 2 } : message.content;\n let metadata = (baseContent as { metadata?: Record<string, unknown> }).metadata;\n if (!options?.includeTerminalMetadata && metadata) {\n const { stopReason: _stopReason, errorMessage: _errorMessage, ...rest } = metadata;\n metadata = rest;\n }\n return {\n ...message,\n content: {\n ...baseContent,\n format: 2,\n parts: sliceParts as MastraDBMessage['content']['parts'],\n ...(metadata !== undefined ? { metadata } : {}),\n },\n } as MastraDBMessage;\n}\n\n/** Whether a message carries terminal metadata that renders a trailing abort/error line. */\nfunction hasTerminalMetadata(message: MastraDBMessage): boolean {\n if (typeof message.content === 'string') return false;\n const stopReason = (message.content.metadata as { stopReason?: string } | undefined)?.stopReason;\n return stopReason === 'aborted' || stopReason === 'error';\n}\n\nfunction getLatestMessageTimestamp(messages: MastraDBMessage[]): number | undefined {\n let latest: number | undefined;\n for (const message of messages) {\n const time = new Date(message.createdAt).getTime();\n if (Number.isNaN(time)) continue;\n latest = latest === undefined ? time : Math.max(latest, time);\n }\n return latest;\n}\n\n/**\n * Re-render all existing messages from the controller thread into the chat container.\n * Called on thread switch and initial load.\n */\nexport async function renderExistingMessages(state: TUIState): Promise<void> {\n const messages = await state.session.thread.listActiveMessages({ limit: STARTUP_MESSAGE_WINDOW_SIZE });\n state.lastRenderedMessageAt = getLatestMessageTimestamp(messages);\n\n state.chatContainer.clear();\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n state.allToolComponents = [];\n state.allSlashCommandComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.pendingSignalMessageComponentsById.clear();\n state.allShellComponents = [];\n\n // Local accumulator for detecting task clears during visible history reconstruction.\n // Startup only replays task state from the bounded message window. If no task\n // snapshot exists in that window, keep the existing display-state snapshot.\n let previousTasksAcc: TaskItemSnapshot[] = [];\n let hasReplayedTaskState = false;\n\n for (const message of messages) {\n if (message.role === 'user' || message.role === 'signal') {\n addUserMessage(state, message);\n } else if (message.role === 'assistant') {\n // Render content in order - interleaving text and tool calls\n // Accumulate text/thinking until we hit a tool call, then render both\n let accumulatedParts: Array<Extract<AssistantRenderPart, { kind: 'text' | 'thinking' }>> = [];\n\n const flushAccumulated = (isFinal = false): void => {\n // The final flush still renders when there is no trailing text but the\n // message carries terminal metadata, so the abort/error line shows once.\n if (accumulatedParts.length === 0 && !(isFinal && hasTerminalMetadata(message))) return;\n const textMessage = buildAssistantSlice(message, accumulatedParts, { includeTerminalMetadata: isFinal });\n const textComponent = new AssistantMessageComponent(textMessage, state.hideThinkingBlock, getMarkdownTheme());\n state.chatContainer.addChild(textComponent);\n accumulatedParts = [];\n };\n\n for (const part of getAssistantRenderParts(message)) {\n if (part.kind === 'text' || part.kind === 'thinking') {\n accumulatedParts.push(part);\n } else if (part.kind === 'tool') {\n // Render accumulated text first if any\n flushAccumulated();\n\n const toolName = part.toolName;\n const toolArgs = part.args;\n const hasResult = part.hasResult;\n const resultValue = part.result;\n const resultIsError = part.isError;\n\n // Render subagent tool calls with dedicated component\n if (toolName === 'subagent') {\n const subArgs = toolArgs as\n | {\n agentType?: string;\n task?: string;\n modelId?: string;\n forked?: boolean;\n }\n | undefined;\n const rawResult = hasResult ? formatToolResult(resultValue) : undefined;\n const isErr = hasResult && resultIsError;\n\n // Parse embedded metadata for model ID, duration, tool calls\n const meta = rawResult ? parseSubagentMeta(rawResult) : null;\n const resultText = meta?.text ?? rawResult;\n const currentModelId = state.session.model.get() || undefined;\n const modelId = meta?.modelId ?? subArgs?.modelId ?? (subArgs?.forked ? currentModelId : undefined);\n const durationMs = meta?.durationMs ?? 0;\n\n const subComponent = new SubagentExecutionComponent(\n subArgs?.agentType ?? 'unknown',\n subArgs?.task ?? '',\n state.ui,\n modelId,\n { collapseOnComplete: false, expandOnComplete: state.quietMode, forked: subArgs?.forked },\n );\n // Populate tool calls from metadata\n if (meta?.toolCalls) {\n for (const tc of meta.toolCalls) {\n subComponent.addToolStart(tc.name, {});\n subComponent.addToolEnd(tc.name, '', tc.isError);\n }\n }\n // Mark as finished with result\n subComponent.finish(isErr ?? false, durationMs, resultText);\n insertChatComponentWithBoundarySpacing(state.chatContainer, subComponent);\n state.allToolComponents.push(subComponent as any);\n continue;\n }\n\n // Render ask_user with the proper question component\n if (toolName === 'ask_user' && hasResult) {\n const askArgs = toolArgs as\n | { question?: string; options?: Array<{ label: string; description?: string }> }\n | undefined;\n const answer = typeof resultValue === 'string' ? resultValue : formatToolResult(resultValue);\n const cancelled = answer === '(skipped)';\n if (askArgs?.question) {\n const askComponent = AskQuestionInlineComponent.fromHistory(\n askArgs.question,\n askArgs.options,\n answer,\n cancelled,\n );\n state.chatContainer.addChild(askComponent);\n continue;\n }\n }\n\n const pluginRenderConfig = state.pluginManager?.getToolRenderConfig(toolName);\n if (pluginRenderConfig?.type === 'subagent') {\n const rawResult = hasResult ? formatToolResult(resultValue) : undefined;\n const isErr = hasResult && resultIsError;\n const subComponent = new SubagentExecutionComponent(\n pluginRenderConfig.agentType ?? 'plugin',\n getTaskFromToolArgs(toolArgs, toolName),\n state.ui,\n pluginRenderConfig.modelId,\n {\n collapseOnComplete: false,\n expandOnComplete: state.quietMode,\n forked: pluginRenderConfig.forked,\n label: pluginRenderConfig.label,\n maxActivityLines: pluginRenderConfig.maxActivityLines,\n collapsedLines: pluginRenderConfig.collapsedLines,\n colors: pluginRenderConfig.colors,\n icons: pluginRenderConfig.icons,\n },\n );\n subComponent.finish(isErr ?? false, 0, rawResult);\n insertChatComponentWithBoundarySpacing(state.chatContainer, subComponent);\n state.allToolComponents.push(subComponent as any);\n continue;\n }\n\n // Render the tool call\n const toolComponent = new ToolExecutionComponentEnhanced(\n toolName,\n toolArgs,\n {\n showImages: false,\n collapsedByDefault: !state.toolOutputExpanded,\n },\n state.ui,\n );\n\n if (hasResult) {\n toolComponent.updateResult(\n {\n content: [\n {\n type: 'text',\n text: formatToolResult(resultValue),\n },\n ],\n isError: resultIsError,\n },\n false,\n );\n }\n\n // Successful task transition tools render through the pinned task UI,\n // not as regular tool result boxes.\n let replacedWithInline = false;\n if (isTaskMutationTool(toolName) && hasResult && !resultIsError) {\n hasReplayedTaskState = true;\n const nextTasks = applyTaskToolResult(previousTasksAcc, toolName, toolArgs, resultValue, resultIsError);\n const transition = renderTaskTransitionFromHistory(state, previousTasksAcc, nextTasks);\n previousTasksAcc = transition.tasks;\n replacedWithInline = transition.replacedWithInline;\n }\n\n if (toolName === 'task_check' && hasResult && !resultIsError) {\n const resultTasks = getTaskResultTasks(resultValue);\n if (resultTasks) {\n hasReplayedTaskState = true;\n previousTasksAcc = assignTaskIds(resultTasks, previousTasksAcc);\n }\n }\n\n // If this was submit_plan, show the plan with approval status\n if (toolName === 'submit_plan' && hasResult) {\n const args = toolArgs as { path?: string } | undefined;\n // Result could be a string or an object with content property\n let resultText = '';\n let submittedPlan: { title?: string; path?: string; plan?: string } | undefined;\n if (typeof resultValue === 'string') {\n resultText = resultValue;\n } else if (typeof resultValue === 'object' && resultValue !== null) {\n if ('content' in resultValue && typeof (resultValue as any).content === 'string') {\n resultText = (resultValue as any).content;\n }\n if ('submittedPlan' in resultValue && typeof (resultValue as any).submittedPlan === 'object') {\n submittedPlan = (resultValue as any).submittedPlan;\n }\n }\n // The approved result starts with \"Plan approved.\" while rejected\n // results start with \"Plan was not approved\" — a naive `includes`\n // would match both since \"not approved\" still contains \"approved\".\n const isApproved = resultText.startsWith('Plan approved');\n // Extract feedback if rejected with inline feedback\n let feedback: string | undefined;\n if (!isApproved && resultText.includes('not approved')) {\n const feedbackMatch = resultText.match(/User feedback:\\s*(.+?)(?:\\n|$)/);\n // Use extracted feedback or a generic marker so PlanResultComponent\n // renders \"Changes requested\" (it checks truthiness of feedback).\n feedback = feedbackMatch?.[1] || 'Revision requested';\n }\n\n const submittedPath = submittedPlan?.path || args?.path;\n if (submittedPath) {\n // Prefer the submitted plan snapshot persisted in the tool result.\n // Older history entries may not have it, so fall back to reading the\n // submitted file from disk.\n const sessionState = state.session.state.get() as any;\n const projectPath = sessionState?.projectPath as string | undefined;\n const recoverAbsPath = !submittedPlan?.plan\n ? resolvePlanPath(projectPath ?? process.cwd(), submittedPath)\n : undefined;\n const recovered = recoverAbsPath ? await readPlanFile(recoverAbsPath) : undefined;\n const planBody = submittedPlan?.plan ?? recovered?.plan ?? '';\n const planTitle = submittedPlan?.title || recovered?.title || 'Implementation Plan';\n const planResult = new PlanResultComponent({\n title: planTitle,\n plan: planBody,\n planFilename: submittedPath,\n isApproved,\n feedback,\n });\n state.chatContainer.addChild(planResult);\n replacedWithInline = true;\n // Restore previousPlanSnapshot (keyed by submitted path) so that if the\n // agent resubmits after a restart, the diff can be computed against\n // the last submitted plan body, not whatever the mutable file now contains.\n state.previousPlanSnapshot = { path: submittedPath, plan: planBody };\n }\n }\n\n if (!replacedWithInline) {\n if (state.quietMode) {\n toolComponent.setCompactToolModeColor(getCurrentModeColor(state));\n toolComponent.setQuietModeDisplay('quiet');\n toolComponent.setQuietPreviewLineLimit(state.quietModeMaxToolPreviewLines);\n }\n state.chatContainer.addChild(toolComponent);\n state.allToolComponents.push(toolComponent);\n } else {\n }\n } else if (part.kind === 'om') {\n // Skip start markers in history — only show completed/failed results\n if (part.event === 'start') continue;\n\n // Render accumulated text first if any\n flushAccumulated();\n\n const omData = part.data as Record<string, any>;\n\n if (part.event === 'end') {\n // Render bordered output box with marker info in footer\n const isReflection = part.operationType === 'reflection';\n const outputComponent = new OMOutputComponent({\n type: isReflection ? 'reflection' : 'observation',\n observations: omData.observations ?? '',\n currentTask: omData.currentTask,\n suggestedResponse: omData.suggestedResponse,\n durationMs: omData.durationMs,\n tokensObserved: omData.tokensObserved,\n observationTokens: omData.observationTokens,\n compressedTokens: isReflection ? omData.observationTokens : undefined,\n });\n state.chatContainer.addChild(outputComponent);\n } else if (part.event === 'failed') {\n // Failed marker\n state.chatContainer.addChild(\n new OMMarkerComponent({\n type: 'om_observation_failed',\n error: typeof omData.error === 'string' ? omData.error : 'observation failed',\n tokensAttempted: typeof omData.tokensAttempted === 'number' ? omData.tokensAttempted : undefined,\n operationType: omData.operationType,\n }),\n );\n } else if (part.event === 'thread-title') {\n if (state.quietMode) continue;\n // Render thread title update marker in history\n state.chatContainer.addChild(\n new OMMarkerComponent({\n type: 'om_thread_title_updated',\n newTitle: omData.newTitle,\n oldTitle: omData.oldTitle,\n }),\n );\n }\n }\n // Skip tool result parts - they are folded into the tool-invocation part above\n }\n\n // Render any remaining text after the last tool call\n flushAccumulated(true);\n }\n }\n\n // Restore or clear the pinned task list from history replay when the bounded\n // window contains a task snapshot. Otherwise, keep the existing display-state\n // snapshot instead of clobbering older tasks that are outside the render window.\n if (hasReplayedTaskState) {\n if (state.taskProgress) {\n state.taskProgress.updateTasks(previousTasksAcc);\n }\n const currentTasks = (state.session.state.get() as { tasks?: TaskItemSnapshot[] } | undefined)?.tasks;\n if (!areTasksEqual(currentTasks, previousTasksAcc)) {\n try {\n await state.session.state.set({ tasks: previousTasksAcc });\n } catch {\n // Custom controller state schemas may not accept TUI replayed task state.\n // Keep the reconstructed task list local to display state in that case.\n }\n }\n state.session.displayState.restoreTasks(previousTasksAcc);\n }\n\n reconcileChatBoundarySpacers(state.chatContainer);\n state.ui.requestRender();\n}\n\nfunction unescapeSystemReminderText(text: string): string {\n return text.replaceAll('&lt;', '<').replaceAll('&gt;', '>').replaceAll('&amp;', '&');\n}\n","import { addPendingUserMessage, removePendingUserMessage } from '../render-messages.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport function isCurrentThreadActive(ctx: SlashCommandContext): boolean {\n return ctx.state.session?.stream?.isActive?.() ?? ctx.state.session?.displayState?.get?.().isRunning ?? false;\n}\n\nexport async function sendSlashCommandMessage(\n ctx: SlashCommandContext,\n displayText: string,\n content: string,\n options: { renderIdleUserMessage?: boolean } = {},\n): Promise<void> {\n if (ctx.state.pendingNewThread) {\n await ctx.state.session.thread.create();\n ctx.state.pendingNewThread = false;\n }\n\n if (isCurrentThreadActive(ctx)) {\n const signal = ctx.state.session.sendSignal({ content });\n addPendingUserMessage(ctx.state, signal.id, displayText);\n try {\n await signal.accepted;\n } catch (error) {\n removePendingUserMessage(ctx.state, signal.id);\n throw error;\n }\n return;\n }\n\n if (options.renderIdleUserMessage ?? true) {\n ctx.addUserMessage({\n id: `user-${Date.now()}`,\n role: 'user',\n content: { format: 2, parts: [{ type: 'text', text: displayText }] },\n createdAt: new Date(),\n });\n ctx.state.ui.requestRender();\n }\n await ctx.state.session.sendMessage({ content });\n}\n","import type { SkillMetadata } from '@mastra/core/workspace';\n\n/**\n * Whether a skill should be invocable directly by the user via /skill/<name>\n * and surfaced in the /skills listing and autocomplete. Defaults to true.\n * Skills opt out by setting `user-invocable: false` in SKILL.md frontmatter.\n */\nexport function isUserInvocable(skill: Pick<SkillMetadata, 'user-invocable'>): boolean {\n return skill['user-invocable'] !== false;\n}\n","import { formatSkillActivation } from '@mastra/core/workspace';\nimport { insertChatComponentWithBoundarySpacing } from '../chat-boundary-reconciliation.js';\nimport { SlashCommandComponent } from '../components/slash-command.js';\nimport { isCurrentThreadActive, sendSlashCommandMessage } from './send-slash-command-message.js';\nimport { isUserInvocable } from './skill-filters.js';\nimport type { SlashCommandContext } from './types.js';\n\n// Keep the renderer's non-greedy `<skill>...</skill>` regex from terminating\n// on a literal closing tag inside the body. Other characters pass through.\nfunction escapeSkillBoundary(value: string): string {\n return value.replaceAll('</skill>', '&lt;/skill&gt;');\n}\n\nasync function resolveWorkspace(ctx: SlashCommandContext) {\n let workspace = ctx.getResolvedWorkspace();\n if (!workspace && ctx.controller.hasWorkspace()) {\n workspace = await ctx.controller.resolveWorkspace({ session: ctx.state.session });\n }\n return workspace;\n}\n\nexport async function handleSkillsCommand(ctx: SlashCommandContext): Promise<void> {\n // Eagerly resolve workspace if not yet cached (e.g. /skills called before first message)\n let workspace;\n try {\n workspace = await resolveWorkspace(ctx);\n } catch (error) {\n ctx.showError(`Failed to resolve workspace: ${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n\n if (!workspace?.skills) {\n ctx.showInfo(\n 'No skills configured.\\n\\n' +\n 'Add skills to any of these locations:\\n' +\n ' .mastracode/skills/ (project-local)\\n' +\n ' .claude/skills/ (project-local)\\n' +\n ' .agents/skills/ (project-local)\\n' +\n ' ~/.mastracode/skills/ (global)\\n' +\n ' ~/.claude/skills/ (global)\\n' +\n ' ~/.agents/skills/ (global)\\n\\n' +\n 'Each skill is a folder with a SKILL.md file.\\n' +\n 'Install skills: npx add-skill <github-url>',\n );\n return;\n }\n\n try {\n const allSkills = await workspace.skills!.list();\n const skills = allSkills.filter(isUserInvocable);\n\n if (skills.length === 0) {\n ctx.showInfo(\n 'No user-invokable skills found in configured directories.\\n\\n' +\n 'Each skill needs a SKILL.md file with YAML frontmatter.\\n' +\n 'Skills with `user-invocable: false` are hidden from this list.\\n' +\n 'Install skills: npx add-skill <github-url>',\n );\n return;\n }\n\n const skillLines = skills.map(skill => {\n const desc = skill.description\n ? ` - ${skill.description.length > 60 ? skill.description.slice(0, 57) + '...' : skill.description}`\n : '';\n return ` ${skill.name}${desc}`;\n });\n\n ctx.showInfo(\n `Skills (${skills.length}):\\n${skillLines.join('\\n')}\\n\\n` +\n 'Skills are automatically activated by the agent when relevant.',\n );\n } catch (error) {\n ctx.showError(`Failed to list skills: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nexport async function handleSkillCommand(ctx: SlashCommandContext, skillName: string, args: string[]): Promise<void> {\n const normalizedSkillName = skillName.trim();\n if (!normalizedSkillName) {\n ctx.showError('Usage: /skill/<name>');\n return;\n }\n\n let workspace;\n try {\n workspace = await resolveWorkspace(ctx);\n } catch (error) {\n ctx.showError(`Failed to resolve workspace: ${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n\n if (!workspace?.skills) {\n ctx.showError('No skills configured.');\n return;\n }\n\n try {\n const skill = await workspace.skills.get(normalizedSkillName);\n if (!skill || !isUserInvocable(skill)) {\n const skills = (await workspace.skills.list()).filter(isUserInvocable);\n const available = skills.length ? ` Available skills: ${skills.map(s => s.name).join(', ')}` : '';\n ctx.showError(`Skill not found: ${normalizedSkillName}.${available}`);\n return;\n }\n\n const trimmedArgs = args.join(' ').trim();\n const content = `${formatSkillActivation(skill)}${trimmedArgs ? `\\n\\nARGUMENTS: ${trimmedArgs}` : ''}`.trim();\n if (!content) {\n ctx.showInfo(`Activated /skill/${skill.name} (no instructions)`);\n return;\n }\n\n if (!isCurrentThreadActive(ctx)) {\n const component = new SlashCommandComponent(`skill/${skill.name}`, content);\n ctx.state.allSlashCommandComponents.push(component);\n insertChatComponentWithBoundarySpacing(ctx.state.chatContainer, component);\n ctx.state.ui.requestRender();\n }\n\n const displayText = `/skill/${skill.name}${trimmedArgs ? ` ${trimmedArgs}` : ''}`;\n await sendSlashCommandMessage(\n ctx,\n displayText,\n `<skill name=\"${skill.name}\">\\n${escapeSkillBoundary(content)}\\n</skill>`,\n {\n renderIdleUserMessage: false,\n },\n );\n } catch (error) {\n ctx.showError(\n `Error executing /skill/${normalizedSkillName}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport async function handleNewCommand(ctx: SlashCommandContext): Promise<void> {\n const { state } = ctx;\n\n // Detach from the old thread's event stream so cross-process events\n // don't leak into the new conversation. Unlike bare abort(), this also\n // unsubscribes from the PubSub topic — preventing another mc instance\n // on the same thread from pushing output into this TUI.\n state.session.thread.detachFromCurrent();\n\n state.pendingNewThread = true;\n state.chatContainer.clear();\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n state.allToolComponents = [];\n state.allSlashCommandComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.allShellComponents = [];\n // Clear file tracking in display state (thread_created will also reset this)\n state.session.displayState.get().modifiedFiles.clear();\n // Clear per-thread ephemeral state from the global controller state\n await state.session.state.set({ tasks: [], activePlan: null, sandboxAllowedPaths: [] });\n state.previousPlanSnapshot = undefined;\n if (state.taskProgress) {\n state.taskProgress.updateTasks([]);\n }\n state.taskToolInsertIndex = -1;\n\n ctx.updateStatusLine();\n state.ui.requestRender();\n ctx.showInfo('Ready for new conversation');\n}\n","import { askModalQuestion } from '../modal-question.js';\nimport type { TUIState } from '../state.js';\nimport type { SlashCommandContext } from './types.js';\n\n/** Minimal interface accepted by resetUIAfterClone so it works from both\n * slash-command handlers (SlashCommandContext) and the MastraTUI class. */\ninterface CloneResetContext {\n state: TUIState;\n updateStatusLine: () => void;\n renderExistingMessages: () => Promise<void>;\n showInfo: (message: string) => void;\n}\n\n/**\n * Confirm whether the user wants to clone a thread. Returns true if\n * confirmed, false on cancel or \"No\".\n */\nexport async function confirmClone(state: TUIState, threadLabel?: string): Promise<boolean> {\n const label = threadLabel ? `Clone thread \"${threadLabel}\"?` : 'Clone the current thread?';\n const answer = await askModalQuestion(state.ui, {\n question: label,\n options: [\n { label: 'Yes', description: 'Clone this thread' },\n { label: 'No', description: 'Cancel' },\n ],\n });\n return answer === 'Yes';\n}\n\n/**\n * Prompt for an optional clone name. Returns the trimmed name, or null\n * if the user presses Esc or submits an empty string.\n */\nexport async function askCloneName(state: TUIState): Promise<string | null> {\n const answer = await askModalQuestion(state.ui, { question: 'Give the cloned thread a name? (Esc to skip)' });\n const trimmed = answer?.trim() ?? '';\n return trimmed.length > 0 ? trimmed : null;\n}\n\n/**\n * Shared post-clone UI reset: clears chat, tools, tasks, re-renders messages,\n * and shows an info banner. Every clone path should call this after\n * `controller.session.thread.clone()` succeeds.\n */\nexport async function resetUIAfterClone(ctx: CloneResetContext, clonedTitle: string): Promise<void> {\n const { state } = ctx;\n state.chatContainer.clear();\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n state.allToolComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.allShellComponents = [];\n state.session.displayState.clearModifiedFiles();\n // Clear per-thread ephemeral state from the global controller state\n await state.session.state.set({ tasks: [], activePlan: null, sandboxAllowedPaths: [] });\n state.previousPlanSnapshot = undefined;\n if (state.taskProgress) {\n state.taskProgress.updateTasks([]);\n }\n state.taskToolInsertIndex = -1;\n\n ctx.updateStatusLine();\n await ctx.renderExistingMessages();\n state.ui.requestRender();\n ctx.showInfo(`Cloned thread: ${clonedTitle}`);\n}\n\nexport async function handleCloneCommand(ctx: SlashCommandContext): Promise<void> {\n const { state } = ctx;\n\n const currentThreadId = state.session.thread.getId();\n if (!currentThreadId) {\n ctx.showInfo('No active thread to clone');\n return;\n }\n\n // Step 1: Confirm / Cancel\n if (!(await confirmClone(state))) return;\n\n // Step 2: Optional rename\n const customTitle = await askCloneName(state);\n\n try {\n const clonedThread = await state.session.thread.clone({\n sourceThreadId: currentThreadId,\n ...(customTitle ? { title: customTitle } : {}),\n });\n\n await resetUIAfterClone(ctx, clonedThread.title || clonedThread.id);\n } catch (error) {\n ctx.showError(`Failed to clone thread: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport async function handleResourceCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const { state, controller } = ctx;\n const { session } = state;\n const sub = args[0]?.trim();\n const current = session.identity.getResourceId();\n const defaultId = session.identity.getDefaultResourceId();\n\n if (!sub) {\n const knownIds = await controller.getKnownResourceIds(session);\n const isOverridden = current !== defaultId;\n const lines = [\n `Current: ${current}${isOverridden ? ` (auto-detected: ${defaultId})` : ''}`,\n '',\n 'Known resource IDs:',\n ...knownIds.map((id: string) => ` ${id === current ? '* ' : ' '}${id}`),\n '',\n 'Usage:',\n ' /resource - Show current resource and known IDs',\n ' /resource <id> - Switch to a resource ID (resumes latest thread)',\n ' /resource reset - Reset to auto-detected ID',\n ];\n ctx.showInfo(lines.join('\\n'));\n return;\n }\n\n const newId = sub === 'reset' ? defaultId : args.join(' ').trim();\n\n if (newId === current) {\n ctx.showInfo(`Already on resource: ${current}`);\n return;\n }\n\n await controller.setResourceId(session, { resourceId: newId });\n\n // Try to resume the most recent thread for this resource\n const threads = await session.thread.list();\n const latest = [...threads].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())[0];\n\n if (latest) {\n await session.thread.switch({ threadId: latest.id, emitEvent: false });\n state.chatContainer.clear();\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n state.allToolComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.allShellComponents = [];\n state.pendingNewThread = false;\n await ctx.renderExistingMessages();\n ctx.showInfo(\n sub === 'reset'\n ? `Resource ID reset to: ${defaultId} — resumed thread: ${latest.title || latest.id}`\n : `Switched to resource: ${newId} — resumed thread: ${latest.title || latest.id}`,\n );\n } else {\n state.chatContainer.clear();\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n state.allToolComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.allShellComponents = [];\n state.pendingNewThread = true;\n ctx.showInfo(\n sub === 'reset'\n ? `Resource ID reset to: ${defaultId} (no existing threads, a new one will be created)`\n : `Switched to resource: ${newId} (no existing threads, a new one will be created)`,\n );\n }\n\n ctx.updateStatusLine();\n state.ui.requestRender();\n}\n","/**\n * Component that renders git diff output with syntax highlighting.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { BOX_INDENT, theme, mastra } from '../theme.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\n\nfunction colorizeDiffLine(line: string): string {\n const t = theme.getTheme();\n const addedColor = chalk.hex(t.success);\n const hunkHeaderColor = chalk.hex(t.toolBorderPending);\n const fileHeaderColor = chalk.bold.hex(t.accent);\n const removedColor = chalk.hex(mastra.red);\n const metaColor = chalk.hex(mastra.mainGray);\n\n // Unified diff headers\n if (line.startsWith('+++') || line.startsWith('---')) {\n return fileHeaderColor(line);\n }\n\n // Added lines\n if (line.startsWith('+')) {\n return addedColor(line);\n }\n\n // Removed lines\n if (line.startsWith('-')) {\n return removedColor(line);\n }\n\n // Hunk headers\n if (line.startsWith('@@')) {\n // Parse the @@ -start,count +start,count @@ format\n const match = line.match(/^(@@ .+? @@)(.*)/);\n if (match) {\n return hunkHeaderColor(match[1]) + metaColor(match[2] || '');\n }\n return hunkHeaderColor(line);\n }\n\n // Binary files, rename markers, etc.\n if (\n line.startsWith('diff ') ||\n line.startsWith('index ') ||\n line.startsWith('new file') ||\n line.startsWith('deleted file') ||\n line.startsWith('similarity index') ||\n line.startsWith('rename ')\n ) {\n return metaColor(line);\n }\n\n return metaColor(line);\n}\n\nexport class DiffOutputComponent extends Container {\n constructor(command: string, diffOutput: string) {\n super();\n\n // Command header\n this.addChild(\n new Text(\n `${theme.fg('success', '✓')} ${theme.bold(theme.fg('muted', '$'))} ${theme.fg('text', command)}`,\n BOX_INDENT,\n 0,\n ),\n );\n\n const output = diffOutput.trimEnd();\n if (output) {\n const lines = output.split('\\n');\n for (const line of lines) {\n this.addChild(new Text(` ${colorizeDiffLine(line)}`, BOX_INDENT, 0));\n }\n }\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n","import { DiffOutputComponent } from '../components/diff-output.js';\nimport { theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handleDiffCommand(ctx: SlashCommandContext, filePath?: string): Promise<void> {\n const { state } = ctx;\n\n if (filePath) {\n try {\n const { execa } = await import('execa');\n const result = await execa('git', ['diff', filePath], {\n cwd: process.cwd(),\n reject: false,\n });\n\n if (!result.stdout.trim()) {\n const staged = await execa('git', ['diff', '--cached', filePath], {\n cwd: process.cwd(),\n reject: false,\n });\n if (!staged.stdout.trim()) {\n ctx.showInfo(`No changes detected for: ${filePath}`);\n return;\n }\n const component = new DiffOutputComponent(`git diff --cached ${filePath}`, staged.stdout);\n state.chatContainer.addChild(component);\n state.ui.requestRender();\n return;\n }\n\n const component = new DiffOutputComponent(`git diff ${filePath}`, result.stdout);\n state.chatContainer.addChild(component);\n state.ui.requestRender();\n } catch (error) {\n ctx.showError(error instanceof Error ? error.message : 'Failed to get diff');\n }\n return;\n }\n\n // No path specified — show summary of all tracked modified files\n // Read from AgentController display state (canonical source for file modifications)\n const modifiedFiles = state.session.displayState.get().modifiedFiles;\n if (modifiedFiles.size === 0) {\n try {\n const { execa } = await import('execa');\n const result = await execa('git', ['diff', '--stat'], {\n cwd: process.cwd(),\n reject: false,\n });\n const staged = await execa('git', ['diff', '--cached', '--stat'], {\n cwd: process.cwd(),\n reject: false,\n });\n\n const output = [result.stdout, staged.stdout].filter(Boolean).join('\\n');\n if (output.trim()) {\n const component = new DiffOutputComponent('git diff --stat', output);\n state.chatContainer.addChild(component);\n state.ui.requestRender();\n } else {\n ctx.showInfo('No file changes detected in this session or working tree.');\n }\n } catch {\n ctx.showInfo('No file changes tracked in this session.');\n }\n return;\n }\n\n const lines: string[] = [`Modified files (${modifiedFiles.size}):`];\n for (const [fp, info] of modifiedFiles) {\n const opCounts = new Map<string, number>();\n for (const op of info.operations) {\n opCounts.set(op, (opCounts.get(op) || 0) + 1);\n }\n const ops = Array.from(opCounts.entries())\n .map(([op, count]) => (count > 1 ? `${op}×${count}` : op))\n .join(', ');\n lines.push(` ${theme.fg('path', fp)} ${theme.fg('muted', `(${ops})`)}`);\n }\n lines.push('');\n lines.push(theme.fg('muted', 'Use /diff <path> to see the git diff for a specific file.'));\n\n ctx.showInfo(lines.join('\\n'));\n}\n","/**\n * Thread selector component for switching between conversation threads.\n * Uses pi-tui overlay pattern with search and navigation.\n */\n\nimport { Box, Container, fuzzyFilter, getKeybindings, Input, matchesKey, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, TUI } from '@earendil-works/pi-tui';\nimport type { AgentControllerThread } from '@mastra/core/agent-controller';\nimport { theme } from '../theme.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ThreadSelectorOptions {\n tui: TUI;\n threads: AgentControllerThread[];\n currentThreadId: string | null;\n /** Current resource ID — threads from this resource sort to the top */\n currentResourceId?: string;\n /** Current project root path — threads tagged with this directory sort above other same-resource threads */\n currentProjectPath?: string;\n onSelect: (thread: AgentControllerThread) => void;\n onCancel: () => void;\n /** Called when user presses Tab to clone the selected thread */\n onClone?: (thread: AgentControllerThread) => void;\n /** Function to fetch message previews for currently visible threads */\n getMessagePreviews?: (threadIds: string[]) => Promise<Map<string, string>>;\n initialMessagePreviews?: Map<string, string>;\n initialAttemptedPreviewThreadIds?: Set<string>;\n onMessagePreviewsLoaded?: (previews: Map<string, string>, attemptedThreadIds: Set<string>) => void;\n}\n\nconst MAX_VISIBLE_THREADS = 12;\nconst INITIAL_PREVIEW_LOAD_COUNT = 24;\nconst PREVIEW_BATCH_SIZE = 2;\nconst INITIAL_PREVIEW_LOAD_DELAY_MS = 150;\nconst INTERACTION_PREVIEW_LOAD_DELAY_MS = 250;\nconst FOLLOW_UP_PREVIEW_LOAD_DELAY_MS = 50;\n\n// =============================================================================\n// ThreadSelectorComponent\n// =============================================================================\n\nexport class ThreadSelectorComponent extends Box implements Focusable {\n private searchInput!: Input;\n private listContainer!: Container;\n private allThreads: AgentControllerThread[];\n private filteredThreads: AgentControllerThread[];\n private selectedIndex = 0;\n private currentThreadId: string | null;\n private currentResourceId: string | undefined;\n private currentProjectPath: string | undefined;\n private onSelectCallback: (thread: AgentControllerThread) => void;\n private onCancelCallback: () => void;\n private onCloneCallback: ((thread: AgentControllerThread) => void) | undefined;\n private tui: TUI;\n private getMessagePreviews: ((threadIds: string[]) => Promise<Map<string, string>>) | undefined;\n private onMessagePreviewsLoaded:\n | ((previews: Map<string, string>, attemptedThreadIds: Set<string>) => void)\n | undefined;\n private messagePreviews: Map<string, string>;\n private attemptedPreviewThreadIds: Set<string>;\n private loadingPreviewThreadIds: Set<string> = new Set();\n private previewLoadVersion = 0;\n private previewLoadTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n this.searchInput.focused = value;\n }\n\n constructor(options: ThreadSelectorOptions) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.tui = options.tui;\n this.currentResourceId = options.currentResourceId;\n this.currentProjectPath = options.currentProjectPath;\n this.allThreads = this.sortThreads(options.threads, options.currentThreadId);\n this.currentThreadId = options.currentThreadId;\n this.onSelectCallback = options.onSelect;\n this.onCancelCallback = options.onCancel;\n this.onCloneCallback = options.onClone;\n this.getMessagePreviews = options.getMessagePreviews;\n this.onMessagePreviewsLoaded = options.onMessagePreviewsLoaded;\n this.messagePreviews = new Map(options.initialMessagePreviews ?? []);\n this.attemptedPreviewThreadIds = new Set(options.initialAttemptedPreviewThreadIds ?? []);\n this.filteredThreads = this.allThreads;\n\n this.buildUI();\n this.scheduleMessagePreviewLoad({ initialLoad: true });\n }\n\n private getVisibleRange(): { startIndex: number; endIndex: number } {\n const startIndex = Math.max(\n 0,\n Math.min(\n this.selectedIndex - Math.floor(MAX_VISIBLE_THREADS / 2),\n this.filteredThreads.length - MAX_VISIBLE_THREADS,\n ),\n );\n const endIndex = Math.min(startIndex + MAX_VISIBLE_THREADS, this.filteredThreads.length);\n return { startIndex, endIndex };\n }\n\n private getVisibleThreads(): AgentControllerThread[] {\n const { startIndex, endIndex } = this.getVisibleRange();\n return this.filteredThreads.slice(startIndex, endIndex);\n }\n\n private getPreviewCandidates(initialLoad: boolean): AgentControllerThread[] {\n const initialThreads = initialLoad ? this.filteredThreads.slice(0, INITIAL_PREVIEW_LOAD_COUNT) : [];\n const combinedThreads = [...initialThreads, ...this.getVisibleThreads()];\n const uniqueThreads = combinedThreads.filter(\n (thread, index, threads) => threads.findIndex(t => t.id === thread.id) === index,\n );\n\n const prioritizedThreads = uniqueThreads.filter(\n thread =>\n thread.resourceId === this.currentResourceId &&\n typeof thread.metadata?.projectPath === 'string' &&\n thread.metadata.projectPath === this.currentProjectPath,\n );\n const remainingThreads = uniqueThreads.filter(thread => !prioritizedThreads.some(t => t.id === thread.id));\n\n return [...prioritizedThreads, ...remainingThreads].filter(\n thread =>\n !this.messagePreviews.has(thread.id) &&\n !this.attemptedPreviewThreadIds.has(thread.id) &&\n !this.loadingPreviewThreadIds.has(thread.id),\n );\n }\n\n private scheduleMessagePreviewLoad({\n initialLoad = false,\n delayMs,\n }: { initialLoad?: boolean; delayMs?: number } = {}): void {\n const previewDelayMs = delayMs ?? (initialLoad ? INITIAL_PREVIEW_LOAD_DELAY_MS : FOLLOW_UP_PREVIEW_LOAD_DELAY_MS);\n\n if (this.previewLoadTimeout) {\n clearTimeout(this.previewLoadTimeout);\n }\n\n this.previewLoadTimeout = setTimeout(() => {\n this.previewLoadTimeout = null;\n void this.loadMessagePreviews({ initialLoad });\n }, previewDelayMs);\n }\n\n private async loadMessagePreviews({ initialLoad = false }: { initialLoad?: boolean } = {}): Promise<void> {\n if (!this.getMessagePreviews) return;\n\n const version = ++this.previewLoadVersion;\n const candidates = this.getPreviewCandidates(initialLoad);\n const threadIds = candidates.slice(0, PREVIEW_BATCH_SIZE).map(thread => thread.id);\n\n if (threadIds.length === 0) return;\n\n threadIds.forEach(threadId => this.loadingPreviewThreadIds.add(threadId));\n this.updateList();\n this.tui.requestRender();\n\n try {\n const previews = await this.getMessagePreviews(threadIds);\n if (version !== this.previewLoadVersion) return;\n\n threadIds.forEach(threadId => this.attemptedPreviewThreadIds.add(threadId));\n\n for (const [threadId, preview] of previews) {\n if (preview) {\n this.messagePreviews.set(threadId, preview);\n }\n }\n\n this.onMessagePreviewsLoaded?.(new Map(this.messagePreviews), new Set(this.attemptedPreviewThreadIds));\n } catch {\n // Ignore errors, previews will just be empty\n } finally {\n threadIds.forEach(threadId => this.loadingPreviewThreadIds.delete(threadId));\n }\n\n this.updateList();\n this.tui.requestRender();\n\n if (candidates.length > PREVIEW_BATCH_SIZE) {\n this.scheduleMessagePreviewLoad({ initialLoad, delayMs: FOLLOW_UP_PREVIEW_LOAD_DELAY_MS });\n }\n }\n\n private buildUI(): void {\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Select Thread')), 0, 0));\n this.addChild(new Spacer(1));\n const cloneHint = this.onCloneCallback ? ' • Tab clone active thread' : '';\n this.addChild(\n new Text(theme.fg('muted', `Type to search • ↑↓ navigate • Enter select${cloneHint} • Esc cancel`), 0, 0),\n );\n this.addChild(new Spacer(1));\n\n this.searchInput = new Input();\n this.searchInput.onSubmit = () => {\n const selected = this.filteredThreads[this.selectedIndex];\n if (selected) {\n this.onSelectCallback(selected);\n }\n };\n this.addChild(this.searchInput);\n this.addChild(new Spacer(1));\n\n this.listContainer = new Container();\n this.addChild(this.listContainer);\n\n this.updateList();\n }\n\n private sortThreads(threads: AgentControllerThread[], currentThreadId: string | null): AgentControllerThread[] {\n const sorted = [...threads];\n const resId = this.currentResourceId;\n const projPath = this.currentProjectPath;\n sorted.sort((a, b) => {\n // Current thread first\n if (a.id === currentThreadId) return -1;\n if (b.id === currentThreadId) return 1;\n // Current resource threads before other resources\n if (resId) {\n const aLocal = a.resourceId === resId;\n const bLocal = b.resourceId === resId;\n if (aLocal && !bLocal) return -1;\n if (!aLocal && bLocal) return 1;\n }\n // Within the same resource, threads tagged with the current directory first\n if (projPath && a.resourceId === b.resourceId) {\n const aDir = typeof a.metadata?.projectPath === 'string' && a.metadata.projectPath === projPath;\n const bDir = typeof b.metadata?.projectPath === 'string' && b.metadata.projectPath === projPath;\n if (aDir && !bDir) return -1;\n if (!aDir && bDir) return 1;\n }\n // Then by most recently updated\n return b.updatedAt.getTime() - a.updatedAt.getTime();\n });\n return sorted;\n }\n\n private filterThreads(query: string): void {\n this.filteredThreads = query\n ? fuzzyFilter(\n this.allThreads,\n query,\n t =>\n `${t.title ?? ''} ${t.resourceId} ${t.id} ${typeof t.metadata?.projectPath === 'string' ? t.metadata.projectPath : ''}`,\n )\n : this.allThreads;\n\n this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredThreads.length - 1));\n this.updateList();\n this.scheduleMessagePreviewLoad({ initialLoad: true });\n }\n\n private formatTimeAgo(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n }\n\n private updateList(): void {\n this.listContainer.clear();\n\n const startIndex = Math.max(\n 0,\n Math.min(\n this.selectedIndex - Math.floor(MAX_VISIBLE_THREADS / 2),\n this.filteredThreads.length - MAX_VISIBLE_THREADS,\n ),\n );\n const endIndex = Math.min(startIndex + MAX_VISIBLE_THREADS, this.filteredThreads.length);\n\n for (let i = startIndex; i < endIndex; i++) {\n const thread = this.filteredThreads[i];\n if (!thread) continue;\n\n const isSelected = i === this.selectedIndex;\n const isCurrent = thread.id === this.currentThreadId;\n const checkmark = isCurrent ? theme.fg('success', ' ✓') : '';\n const shortId = thread.id.slice(-6);\n const threadPath = thread.metadata?.projectPath as string | undefined;\n const pathTag = threadPath ? theme.fg('dim', ` [${threadPath.split('/').pop()}]`) : '';\n const displayId = `${thread.resourceId}/${shortId}`;\n const timeAgo = theme.fg('muted', ` (${this.formatTimeAgo(thread.updatedAt)})`);\n\n // Show thread title when available, except the default placeholder title.\n const displayTitle = thread.title && thread.title !== 'New Thread' ? thread.title : null;\n\n let line = '';\n if (isSelected) {\n line = theme.fg('accent', `→ ${displayId}`) + pathTag + timeAgo + checkmark;\n } else {\n line = ` ${displayId}` + pathTag + timeAgo + checkmark;\n }\n\n this.listContainer.addChild(new Text(line, 0, 0));\n\n if (displayTitle) {\n this.listContainer.addChild(new Text(` ${theme.fg('muted', displayTitle)}`, 0, 0));\n } else {\n const preview = this.messagePreviews.get(thread.id);\n if (preview) {\n this.listContainer.addChild(new Text(` ${theme.fg('dim', `\"${preview}\"`)}`, 0, 0));\n }\n }\n }\n\n if (startIndex > 0 || endIndex < this.filteredThreads.length) {\n const scrollInfo = theme.fg('muted', `(${this.selectedIndex + 1}/${this.filteredThreads.length})`);\n this.listContainer.addChild(new Text(scrollInfo, 0, 0));\n }\n\n if (this.filteredThreads.length === 0) {\n this.listContainer.addChild(new Text(theme.fg('muted', 'No matching threads'), 0, 0));\n }\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n if (kb.matches(keyData, 'tui.select.up')) {\n if (this.filteredThreads.length === 0) return;\n this.selectedIndex = this.selectedIndex === 0 ? this.filteredThreads.length - 1 : this.selectedIndex - 1;\n this.updateList();\n this.tui.requestRender();\n this.scheduleMessagePreviewLoad({ delayMs: INTERACTION_PREVIEW_LOAD_DELAY_MS });\n } else if (kb.matches(keyData, 'tui.select.down')) {\n if (this.filteredThreads.length === 0) return;\n this.selectedIndex = this.selectedIndex === this.filteredThreads.length - 1 ? 0 : this.selectedIndex + 1;\n this.updateList();\n this.tui.requestRender();\n this.scheduleMessagePreviewLoad({ delayMs: INTERACTION_PREVIEW_LOAD_DELAY_MS });\n } else if (kb.matches(keyData, 'tui.select.confirm')) {\n const selected = this.filteredThreads[this.selectedIndex];\n if (selected) {\n this.onSelectCallback(selected);\n }\n } else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancelCallback();\n } else if (matchesKey(keyData, 'tab') && this.onCloneCallback) {\n const selected = this.filteredThreads[this.selectedIndex];\n if (selected) {\n this.onCloneCallback(selected);\n }\n } else {\n this.searchInput.handleInput(keyData);\n this.filterThreads(this.searchInput.getValue());\n this.tui.requestRender();\n this.scheduleMessagePreviewLoad({ delayMs: INTERACTION_PREVIEW_LOAD_DELAY_MS });\n }\n }\n}\n","import { ThreadLockError } from '@mastra/code-sdk/utils/thread-lock';\nimport { ThreadSelectorComponent } from '../components/thread-selector.js';\nimport { askModalQuestion } from '../modal-question.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { askCloneName, confirmClone, resetUIAfterClone } from './clone.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport function showThreadLockPrompt(\n ctx: SlashCommandContext,\n threadTitle: string,\n ownerPid: number,\n lockedThreadId?: string,\n): void {\n ctx.analytics?.trackInteractivePrompt('thread_lock_prompt', {\n threadId: lockedThreadId ?? ctx.state.session.thread.getId(),\n resourceId: ctx.state.session.identity.getResourceId(),\n mode: ctx.state.session.mode.get(),\n });\n\n void (async () => {\n const answer = await askModalQuestion(ctx.state.ui, {\n question: `Thread \"${threadTitle}\" is locked by pid ${ownerPid}. What would you like to do?`,\n options: [\n { label: 'Switch thread', description: 'Pick a different thread' },\n { label: 'New thread', description: 'Start a fresh thread' },\n ...(lockedThreadId ? [{ label: 'Clone thread', description: 'Fork from this thread' }] : []),\n { label: 'Exit', description: 'Exit' },\n ],\n });\n\n if (answer === 'Switch thread') {\n await handleThreadsCommand(ctx);\n } else if (answer === 'Clone thread' && lockedThreadId) {\n try {\n const customTitle = await askCloneName(ctx.state);\n const clonedThread = await ctx.state.session.thread.clone({\n sourceThreadId: lockedThreadId,\n ...(customTitle ? { title: customTitle } : {}),\n });\n ctx.state.pendingNewThread = false;\n await resetUIAfterClone(ctx, clonedThread.title || clonedThread.id);\n } catch (error) {\n ctx.showError(`Failed to clone thread: ${error instanceof Error ? error.message : String(error)}`);\n }\n } else if (answer === 'New thread') {\n // pendingNewThread is already true from the caller\n } else {\n process.exit(0);\n }\n })();\n}\n\nexport async function handleThreadsCommand(ctx: SlashCommandContext): Promise<void> {\n const { state } = ctx;\n const threads = await state.session.thread.list({ allResources: true });\n const currentId = state.pendingNewThread ? null : state.session.thread.getId();\n const currentResourceId = state.session.identity.getResourceId();\n const threadById = new Map(threads.map(thread => [thread.id, thread] as const));\n\n for (const [threadId, cachedPreview] of [...state.threadPreviewCache.entries()]) {\n const thread = threadById.get(threadId);\n if (!thread || cachedPreview.updatedAt < thread.updatedAt.getTime()) {\n state.threadPreviewCache.delete(threadId);\n state.attemptedThreadPreviewIds.delete(threadId);\n }\n }\n\n for (const threadId of [...state.attemptedThreadPreviewIds]) {\n if (!threadById.has(threadId)) {\n state.attemptedThreadPreviewIds.delete(threadId);\n }\n }\n\n if (threads.length === 0) {\n ctx.showInfo('No threads yet. Send a message to create one.');\n return;\n }\n // console.log(cachedPreview);\n\n return new Promise(resolve => {\n const selector = new ThreadSelectorComponent({\n tui: state.ui,\n threads,\n currentThreadId: currentId,\n currentResourceId,\n currentProjectPath: state.projectInfo.rootPath,\n initialMessagePreviews: new Map(\n [...state.threadPreviewCache.entries()].map(\n ([threadId, cachedPreview]) => [threadId, cachedPreview.preview] as const,\n ),\n ),\n initialAttemptedPreviewThreadIds: state.attemptedThreadPreviewIds,\n onMessagePreviewsLoaded: (previews, attemptedThreadIds) => {\n state.threadPreviewCache = new Map(\n [...previews.entries()].flatMap(([threadId, preview]) => {\n const thread = threadById.get(threadId);\n return thread ? [[threadId, { preview, updatedAt: thread.updatedAt.getTime() }] as const] : [];\n }),\n );\n state.attemptedThreadPreviewIds = attemptedThreadIds;\n },\n getMessagePreviews: async (threadIds: string[]) => {\n return new Map(\n threadIds.flatMap(threadId => {\n const preview = state.threadPreviewCache.get(threadId)?.preview;\n return preview ? [[threadId, preview] as const] : [];\n }),\n );\n },\n onSelect: async thread => {\n state.ui.hideOverlay();\n\n if (thread.id === currentId) {\n ctx.showInfo(`Switched to: ${thread.title || thread.id}`);\n resolve();\n return;\n }\n\n if (thread.resourceId !== currentResourceId) {\n await state.controller.setResourceId(state.session, { resourceId: thread.resourceId });\n }\n try {\n await state.session.thread.switch({ threadId: thread.id });\n } catch (error) {\n if (error instanceof ThreadLockError) {\n showThreadLockPrompt(ctx, thread.title || thread.id, error.ownerPid, thread.id);\n } else {\n ctx.showError(`Failed to switch thread: ${error instanceof Error ? error.message : String(error)}`);\n }\n resolve();\n return;\n }\n state.pendingNewThread = false;\n\n state.chatContainer.clear();\n state.allToolComponents = [];\n state.allSystemReminderComponents = [];\n state.messageComponentsById.clear();\n state.allShellComponents = [];\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n await ctx.renderExistingMessages();\n\n ctx.showInfo(`Switched to: ${thread.title || thread.id}`);\n resolve();\n },\n onClone: async thread => {\n state.ui.hideOverlay();\n if (!(await confirmClone(state, thread.title || thread.id))) {\n resolve();\n return;\n }\n try {\n const customTitle = await askCloneName(state);\n const clonedThread = await state.session.thread.clone({\n sourceThreadId: thread.id,\n ...(customTitle ? { title: customTitle } : {}),\n });\n state.pendingNewThread = false;\n await resetUIAfterClone(ctx, clonedThread.title || clonedThread.id);\n } catch (error) {\n ctx.showError(`Failed to clone thread: ${error instanceof Error ? error.message : String(error)}`);\n }\n resolve();\n },\n onCancel: () => {\n state.ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(state.ui, selector, { widthPercent: 0.8, maxHeight: '60%' });\n selector.focused = true;\n });\n}\n","import type { SlashCommandContext } from './types.js';\n\nfunction formatDateWithLocal(date: Date): string {\n return `${date.toISOString()} [${date.toLocaleString()}]`;\n}\n\nexport async function handleThreadCommand(ctx: SlashCommandContext): Promise<void> {\n const { state } = ctx;\n const currentThreadId = state.session.thread.getId();\n const currentResourceId = state.session.identity.getResourceId();\n const isPendingNewThread = state.pendingNewThread;\n\n if (!currentThreadId) {\n const lines = ['No active thread.', `Resource: ${currentResourceId}`];\n\n if (isPendingNewThread) {\n lines.push('Pending new thread: yes');\n }\n\n ctx.showInfo(lines.join('\\n'));\n return;\n }\n\n const threads = await state.session.thread.list({ allResources: true });\n const thread = threads.find(t => t.id === currentThreadId);\n\n const cloneMetadata =\n thread?.metadata && typeof thread.metadata === 'object'\n ? (thread.metadata as { clone?: { sourceThreadId?: string; clonedAt?: Date | string } }).clone\n : undefined;\n\n const lines = [\n `Title: ${thread?.title?.trim() || '(untitled)'}`,\n `ID: ${currentThreadId}`,\n `Resource: ${thread?.resourceId ?? currentResourceId}`,\n ];\n\n if (thread) {\n lines.push(`Created: ${formatDateWithLocal(thread.createdAt)}`);\n lines.push(`Updated: ${formatDateWithLocal(thread.updatedAt)}`);\n }\n\n if (isPendingNewThread) {\n lines.push('Pending new thread: yes');\n }\n\n if (cloneMetadata?.sourceThreadId) {\n lines.push(`Forked from: ${cloneMetadata.sourceThreadId}`);\n if (cloneMetadata.clonedAt) {\n const clonedAt =\n cloneMetadata.clonedAt instanceof Date ? cloneMetadata.clonedAt : new Date(cloneMetadata.clonedAt);\n lines.push(`Forked at: ${formatDateWithLocal(clonedAt)}`);\n }\n }\n\n ctx.showInfo(lines.join('\\n'));\n}\n","import { askModalQuestion } from '../modal-question.js';\nimport { theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handleThreadTagDirCommand(ctx: SlashCommandContext): Promise<void> {\n const { state } = ctx;\n const threadId = state.session.thread.getId();\n if (!threadId && state.pendingNewThread) {\n ctx.showInfo('No active thread yet — send a message first.');\n return;\n }\n if (!threadId) {\n ctx.showInfo('No active thread.');\n return;\n }\n\n const projectPath = (state.session.state.get() as any)?.projectPath as string | undefined;\n if (!projectPath) {\n ctx.showInfo('Could not detect current project path.');\n return;\n }\n\n const dirName = projectPath.split('/').pop() || projectPath;\n\n const answer = await askModalQuestion(state.ui, {\n question: `Tag this thread with directory \"${dirName}\"?\\n ${theme.fg('dim', projectPath)}`,\n options: [{ label: 'Yes' }, { label: 'No' }],\n });\n if (answer?.toLowerCase().startsWith('y')) {\n await state.session.thread.setSetting({ key: 'projectPath', value: projectPath });\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { AskQuestionDialogComponent } from '../components/ask-question-dialog.js';\nimport { showModalOverlay } from '../overlay.js';\nimport type { SlashCommandContext } from './types.js';\n\nasync function sandboxAddPath(ctx: SlashCommandContext, rawPath: string): Promise<void> {\n const controllerWithState = ctx.state.session.state.get() as\n | {\n sandboxAllowedPaths?: string[];\n }\n | undefined;\n const currentPaths = controllerWithState?.sandboxAllowedPaths ?? [];\n const resolved = path.resolve(rawPath);\n\n if (currentPaths.includes(resolved)) {\n ctx.showInfo(`Path already allowed: ${resolved}`);\n return;\n }\n try {\n await fs.promises.access(resolved);\n } catch {\n ctx.showError(`Path does not exist: ${resolved}`);\n return;\n }\n const updated = [...currentPaths, resolved];\n await ctx.state.session.state.set({ sandboxAllowedPaths: updated } as any);\n await ctx.state.session.thread.setSetting({ key: 'sandboxAllowedPaths', value: updated });\n ctx.showInfo(`Added to sandbox: ${resolved}`);\n}\n\nasync function sandboxRemovePath(ctx: SlashCommandContext, rawPath: string, currentPaths: string[]): Promise<void> {\n const resolved = path.resolve(rawPath);\n const match = currentPaths.find(p => p === resolved || p === rawPath);\n if (!match) {\n ctx.showError(`Path not in allowed list: ${resolved}`);\n return;\n }\n const updated = currentPaths.filter(p => p !== match);\n await ctx.state.session.state.set({ sandboxAllowedPaths: updated } as any);\n await ctx.state.session.thread.setSetting({ key: 'sandboxAllowedPaths', value: updated });\n ctx.showInfo(`Removed from sandbox: ${match}`);\n}\n\nasync function showSandboxAddPrompt(ctx: SlashCommandContext): Promise<void> {\n return new Promise<void>(resolve => {\n const questionComponent = new AskQuestionDialogComponent({\n question: 'Enter path to allow',\n tui: ctx.state.ui,\n onSubmit: async answer => {\n ctx.state.ui.hideOverlay();\n await sandboxAddPath(ctx, answer);\n resolve();\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(ctx.state.ui, questionComponent, { maxHeight: '50%' });\n questionComponent.focused = true;\n });\n}\n\nexport async function handleSandboxCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const agentControllerState = ctx.state.session.state.get() as\n | {\n sandboxAllowedPaths?: string[];\n }\n | undefined;\n const currentPaths = agentControllerState?.sandboxAllowedPaths ?? [];\n\n const subcommand = args[0]?.toLowerCase();\n if (subcommand === 'add' && args.length > 1) {\n await sandboxAddPath(ctx, args.slice(1).join(' ').trim());\n return;\n }\n if (subcommand === 'remove' && args.length > 1) {\n await sandboxRemovePath(ctx, args.slice(1).join(' ').trim(), currentPaths);\n return;\n }\n\n const options: Array<{ label: string; description?: string }> = [\n { label: 'Add path', description: 'Allow access to another directory' },\n ];\n\n for (const p of currentPaths) {\n options.push({\n label: `Remove: ${p}`,\n description: p,\n });\n }\n\n const pathsSummary = currentPaths.length\n ? `${currentPaths.length} allowed path${currentPaths.length > 1 ? 's' : ''}`\n : 'no extra paths';\n\n return new Promise<void>(resolve => {\n const questionComponent = new AskQuestionDialogComponent({\n question: `Sandbox settings (${pathsSummary})`,\n options,\n tui: ctx.state.ui,\n onSubmit: async answer => {\n ctx.state.ui.hideOverlay();\n if (answer === 'Add path') {\n await showSandboxAddPrompt(ctx);\n } else if (answer.startsWith('Remove: ')) {\n const targetPath = answer.replace('Remove: ', '');\n if (currentPaths.includes(targetPath)) {\n await sandboxRemovePath(ctx, targetPath, currentPaths);\n }\n }\n resolve();\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(ctx.state.ui, questionComponent, { maxHeight: '60%' });\n questionComponent.focused = true;\n });\n}\n","import chalk from 'chalk';\nimport { getThemeMode } from '../theme.js';\n\nconst GRADIENT_WIDTH = 30; // Width of the bright spot as percentage of total text\nconst BASE_COLOR = [22, 200, 88]; // Brand green #16c858\nfunction getMinBrightness(): number {\n return getThemeMode() === 'dark' ? 0.45 : 0.55;\n}\n\n/**\n * Parse a hex color string to [r, g, b].\n */\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace('#', '');\n return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];\n}\n\n/** Idle brightness target for fade-out interpolation */\nconst IDLE_BRIGHTNESS = 0.8;\n\n/**\n * Applies a sweeping gradient animation to a plain text string.\n * A bright spot moves left-to-right across the text.\n *\n * @param text - Plain text to colorize (no ANSI codes)\n * @param offset - Current animation offset (0-1, wraps around)\n * @param color - Optional hex color override (defaults to green accent)\n * @param fadeProgress - 0 = full animation, 1 = fully idle (flattens gradient)\n * @returns Chalk-colored string\n */\nexport function applyGradientSweep(text: string, offset: number, color?: string, fadeProgress = 0): string {\n const chars = [...text];\n const totalChars = chars.length;\n if (totalChars === 0) return text;\n\n const baseColor = color ? hexToRgb(color) : BASE_COLOR;\n const gradientCenter = (offset % 1) * 100;\n const halfGradient = GRADIENT_WIDTH / 2;\n const minBrightness = getMinBrightness();\n const brightnessRange = 1 - minBrightness;\n\n // Batch consecutive chars with same RGB to reduce chalk.rgb() calls\n let result = '';\n let batchChars = '';\n let batchR = -1,\n batchG = -1,\n batchB = -1;\n\n for (let i = 0; i < totalChars; i++) {\n const char = chars[i]!;\n if (char === ' ') {\n // Flush current batch before space\n if (batchChars) {\n result += chalk.rgb(batchR, batchG, batchB)(batchChars);\n batchChars = '';\n }\n result += ' ';\n continue;\n }\n\n const charPosition = (i / totalChars) * 100;\n let distance = Math.abs(charPosition - gradientCenter);\n if (distance > 50) distance = 100 - distance;\n\n const normalizedDistance = Math.min(distance / halfGradient, 1);\n const animBrightness = minBrightness + brightnessRange * (1 - normalizedDistance);\n const brightness = animBrightness + (IDLE_BRIGHTNESS - animBrightness) * fadeProgress;\n\n const r = Math.floor(baseColor[0]! * brightness);\n const g = Math.floor(baseColor[1]! * brightness);\n const b = Math.floor(baseColor[2]! * brightness);\n\n // If same color as current batch, append; otherwise flush and start new batch\n if (r === batchR && g === batchG && b === batchB) {\n batchChars += char;\n } else {\n if (batchChars) {\n result += chalk.rgb(batchR, batchG, batchB)(batchChars);\n }\n batchChars = char;\n batchR = r;\n batchG = g;\n batchB = b;\n }\n }\n\n if (batchChars) {\n result += chalk.rgb(batchR, batchG, batchB)(batchChars);\n }\n\n return result;\n}\n\n/**\n * Manages the gradient sweep animation state.\n * Call `start()` when agent begins working, `stop()` when idle.\n * On each tick, call `getOffset()` to get the current sweep position.\n */\nexport class GradientAnimator {\n private offset = 0;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private onTick: () => void;\n private _isFadingOut = false;\n private _isFadingIn = false;\n private _fadeProgress = 0; // 0 = full animation, 1 = fully idle\n\n constructor(onTick: () => void) {\n this.onTick = onTick;\n }\n\n start(): void {\n if (this.intervalId && !this._isFadingOut) return;\n // Cancel any ongoing fade-out\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n this._isFadingOut = false;\n this._isFadingIn = true;\n this._fadeProgress = 1; // Start from idle, fade toward full animation\n this.offset = 0;\n this.intervalId = setInterval(() => {\n this.offset += 0.03; // Speed: full sweep in ~55 ticks\n if (this._isFadingIn) {\n this._fadeProgress -= 0.06; // ~17 steps over ~500ms\n if (this._fadeProgress <= 0) {\n this._fadeProgress = 0;\n this._isFadingIn = false;\n }\n }\n this.onTick();\n }, 80);\n }\n\n /**\n * Smoothly fade the gradient to idle state over ~500ms.\n */\n fadeOut(): void {\n if (!this.intervalId) return;\n if (this._isFadingOut) return;\n this._isFadingOut = true;\n this._isFadingIn = false;\n this._fadeProgress = 0;\n // Replace the animation interval with a fade interval\n clearInterval(this.intervalId);\n this.intervalId = setInterval(() => {\n this._fadeProgress += 0.08; // ~12 steps over ~500ms\n if (this._fadeProgress >= 1) {\n this._fadeProgress = 1;\n this.stop();\n }\n this.onTick();\n }, 40);\n }\n\n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n this._isFadingOut = false;\n this._isFadingIn = false;\n this._fadeProgress = 0;\n this.offset = 0;\n }\n\n getOffset(): number {\n return this.offset;\n }\n\n /** 0 = full animation, 1 = fully idle. Use to interpolate colors. */\n getFadeProgress(): number {\n return this._fadeProgress;\n }\n\n isFadingOut(): boolean {\n return this._isFadingOut;\n }\n\n isFadingIn(): boolean {\n return this._isFadingIn;\n }\n\n isRunning(): boolean {\n return this.intervalId !== null;\n }\n}\n","/**\n * Observational Memory progress indicator component.\n * Shows when OM is observing or reflecting on conversation history.\n */\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport { defaultOMProgressState } from '@mastra/core/agent-controller';\nimport type { OMBufferedStatus, OMProgressState, OMStatus } from '@mastra/core/agent-controller';\nimport chalk from 'chalk';\nimport { theme, mastra } from '../theme.js';\n\n// Re-export types from core for backward compatibility\nexport type { OMBufferedStatus, OMProgressState, OMStatus };\nexport { defaultOMProgressState };\n\n/**\n * Component that displays OM progress in the status line area.\n * Shows a compact indicator when observation/reflection is happening.\n */\nexport class OMProgressComponent extends Container {\n private state: OMProgressState = defaultOMProgressState();\n private statusText: Text;\n\n constructor() {\n super();\n this.statusText = new Text('');\n this.children.push(this.statusText);\n }\n\n updateProgress(progress: {\n pendingTokens: number;\n threshold: number;\n thresholdPercent: number;\n observationTokens: number;\n reflectionThreshold: number;\n reflectionThresholdPercent: number;\n }): void {\n this.state.pendingTokens = progress.pendingTokens;\n this.state.threshold = progress.threshold;\n this.state.thresholdPercent = progress.thresholdPercent;\n this.state.observationTokens = progress.observationTokens;\n this.state.reflectionThreshold = progress.reflectionThreshold;\n this.state.reflectionThresholdPercent = progress.reflectionThresholdPercent;\n this.updateDisplay();\n }\n\n startObservation(cycleId: string, _tokensToObserve: number): void {\n this.state.status = 'observing';\n this.state.cycleId = cycleId;\n this.state.startTime = Date.now();\n this.updateDisplay();\n }\n\n endObservation(): void {\n this.state.status = 'idle';\n this.state.cycleId = undefined;\n this.state.startTime = undefined;\n this.updateDisplay();\n }\n\n startReflection(cycleId: string): void {\n this.state.status = 'reflecting';\n this.state.cycleId = cycleId;\n this.state.startTime = Date.now();\n this.updateDisplay();\n }\n\n endReflection(): void {\n this.state.status = 'idle';\n this.state.cycleId = undefined;\n this.state.startTime = undefined;\n this.updateDisplay();\n }\n\n failOperation(): void {\n this.state.status = 'idle';\n this.state.cycleId = undefined;\n this.state.startTime = undefined;\n this.updateDisplay();\n }\n\n getStatus(): OMStatus {\n return this.state.status;\n }\n\n private updateDisplay(): void {\n if (this.state.status === 'idle') {\n // Show threshold progress when idle (if any pending tokens)\n if (this.state.thresholdPercent > 0) {\n const percent = Math.round(this.state.thresholdPercent);\n const bar = this.renderProgressBar(percent, 10);\n this.statusText.setText(theme.fg('muted', `OM ${bar} ${percent}%`));\n } else {\n this.statusText.setText('');\n }\n } else if (this.state.status === 'observing') {\n const elapsed = this.state.startTime ? Math.round((Date.now() - this.state.startTime) / 1000) : 0;\n const spinner = this.getSpinner();\n this.statusText.setText(chalk.hex(mastra.orange)(`${spinner} Observing... ${elapsed}s`));\n } else if (this.state.status === 'reflecting') {\n const elapsed = this.state.startTime ? Math.round((Date.now() - this.state.startTime) / 1000) : 0;\n const spinner = this.getSpinner();\n this.statusText.setText(chalk.hex(mastra.pink)(`${spinner} Reflecting... ${elapsed}s`));\n }\n }\n\n private renderProgressBar(percent: number, width: number): string {\n const filled = Math.min(width, Math.round((percent / 100) * width));\n const empty = width - filled;\n const bar = '━'.repeat(filled) + '─'.repeat(empty);\n\n // Color based on threshold proximity — Mastra brand colors\n if (percent >= 90) {\n return chalk.hex(mastra.red)(bar); // Mastra red\n } else if (percent >= 70) {\n return chalk.hex(mastra.orange)(bar); // Mastra orange\n } else {\n return chalk.hex(mastra.darkGray)(bar); // Mastra dark gray\n }\n }\n private spinnerFrame = 0;\n private getSpinner(): string {\n const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n this.spinnerFrame = (this.spinnerFrame + 1) % frames.length;\n return frames[this.spinnerFrame]!;\n }\n\n render(maxWidth: number): string[] {\n this.updateDisplay();\n return this.statusText.render(maxWidth);\n }\n}\n\n/** Format token count without k suffix (e.g., 7234 -> \"7.2\", 200 -> \"0.2\", 0 -> \"0\") */\nfunction formatTokensValue(n: number): string {\n if (n === 0) return '0';\n const k = n / 1000;\n const s = k.toFixed(1);\n return s.endsWith('.0') ? s.slice(0, -2) : s;\n}\n\n/** Format token threshold with k suffix (e.g., 30000 -> \"30k\", 40000 -> \"40k\") */\nfunction formatTokensThreshold(n: number): string {\n const k = n / 1000;\n const s = k.toFixed(1);\n return (s.endsWith('.0') ? s.slice(0, -2) : s) + 'k';\n}\n\ninterface OMContextIndicator {\n plain: string;\n styled: string;\n messageCells: number;\n memoryCells: number;\n unusedCells: number;\n}\n\ninterface OMContextIndicatorOptions {\n messages?: (segment: string) => string;\n memory?: (segment: string) => string;\n unused?: (segment: string) => string;\n showBar?: boolean;\n}\n\nexport function formatOMContextIndicator(\n state: OMProgressState,\n options: OMContextIndicatorOptions = {},\n): OMContextIndicator {\n const used = Math.max(0, state.pendingTokens) + Math.max(0, state.observationTokens);\n const capacity = Math.max(0, state.threshold) + Math.max(0, state.reflectionThreshold);\n const occupiedCells = capacity === 0 ? 0 : Math.max(0, Math.min(10, Math.round((used / capacity) * 10)));\n\n let messageCells = used === 0 ? 0 : Math.round((Math.max(0, state.pendingTokens) / used) * occupiedCells);\n if (state.pendingTokens > 0 && state.observationTokens > 0 && occupiedCells >= 2) {\n messageCells = Math.max(1, Math.min(occupiedCells - 1, messageCells));\n }\n const memoryCells = occupiedCells - messageCells;\n const unusedCells = 10 - occupiedCells;\n\n const messageSegment = '━'.repeat(messageCells);\n const unusedSegment = '━'.repeat(unusedCells);\n const memorySegment = '━'.repeat(memoryCells);\n const usedText = formatTokensValue(used);\n const capacityText = formatTokensThreshold(capacity);\n const fraction = `${usedText}/${capacityText}`;\n const messageSavings = Math.max(0, state.buffered.observations.projectedMessageRemoval);\n const reflectionSavings = Math.max(\n 0,\n state.buffered.reflection.inputObservationTokens - state.buffered.reflection.observationTokens,\n );\n const hasSavings = messageSavings + reflectionSavings > 0;\n const savingsSlot = hasSavings ? '↓ ' : ' ';\n\n const barPlain = options.showBar === false ? '' : `${memorySegment}${messageSegment}${unusedSegment} `;\n const plain = `${barPlain}${fraction}${savingsSlot}`;\n const styleMessages = options.messages ?? (segment => theme.fg('text', segment));\n const styleMemory = options.memory ?? (segment => theme.fg('dim', segment));\n const styleUnused = options.unused ?? (segment => theme.fg('muted', segment));\n const barStyled =\n options.showBar === false\n ? ''\n : styleMemory(memorySegment) + styleMessages(messageSegment) + styleUnused(unusedSegment) + ' ';\n const styled =\n barStyled +\n chalk.bold(theme.fg('text', usedText)) +\n theme.fg('thinkingText', `/${capacityText}`) +\n (hasSavings ? `${theme.fg('success', '↓')} ` : ' ');\n\n return { plain, styled, messageCells, memoryCells, unusedCells };\n}\n\n/** @deprecated Use formatOMContextIndicator for the unified context display. */\nexport function formatOMStatus(state: OMProgressState): string {\n const percent = Math.round(state.thresholdPercent);\n const fraction = `${formatTokensValue(state.pendingTokens)}/${formatTokensThreshold(state.threshold)}`;\n const value =\n percent >= 90\n ? chalk.hex(mastra.red)(fraction)\n : percent >= 70\n ? chalk.hex(mastra.orange)(fraction)\n : chalk.hex('#71717a')(fraction);\n const savings = state.buffered.observations.projectedMessageRemoval;\n const buffered = savings > 0 ? chalk.italic(theme.fg('muted', ` ↓${formatTokensThreshold(savings)}`)) : '';\n return chalk.hex(mastra.specialGray)('msg ') + value + buffered;\n}\n","const MINUTE_MS = 60_000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\n\nexport function formatStatusDuration(ms: number, opts: { includeSeconds?: boolean } = {}): string {\n const safeMs = Math.max(0, ms);\n const days = Math.floor(safeMs / DAY_MS);\n const hours = Math.floor((safeMs % DAY_MS) / HOUR_MS);\n const minutes = Math.floor((safeMs % HOUR_MS) / MINUTE_MS);\n const seconds = Math.floor((safeMs % MINUTE_MS) / 1000);\n\n if (days > 0) {\n return `${days}d${hours > 0 ? `${hours}hr` : ''}${minutes > 0 ? `${minutes}m` : ''}`;\n }\n if (hours > 0) {\n return `${hours}hr${minutes > 0 ? `${minutes}m` : ''}`;\n }\n if (opts.includeSeconds) {\n return minutes > 0 ? `${minutes}m${seconds}s` : `${Math.max(1, seconds)}s`;\n }\n return `${Math.max(1, minutes)}m`;\n}\n","/**\n * Status line rendering — builds the bottom-of-screen status bar\n * showing model, mode, memory progress, and project path.\n */\nimport { visibleWidth } from '@earendil-works/pi-tui';\nimport chalk from 'chalk';\nimport { applyGradientSweep } from './components/obi-loader.js';\nimport { formatOMContextIndicator } from './components/om-progress.js';\nimport type { GithubPrSubscriptionBadge, TUIState } from './state.js';\nimport { formatStatusDuration } from './status-duration.js';\nimport { theme, mastra, mastraBrand, tintHex, getTermWidth, extendedColors } from './theme.js';\n\n// Colors for OM modes — read from proxy at render time so they pick up contrast adaptation\nconst getObserverColor = () => mastra.orange;\nconst getReflectorColor = () => mastra.pink;\n\nfunction formatGithubPrLabel(\n state: TUIState,\n subscription: GithubPrSubscriptionBadge,\n): { plain: string; styled: string } {\n const label = `PR#${subscription.prNumber}`;\n const color = subscription.lastNotificationPriority === 'high' ? mastra.orange : extendedColors.skyBlue;\n if (state.githubPrPollingActive && state.githubPrGradientAnimator?.isRunning()) {\n return {\n plain: label,\n styled: applyGradientSweep(\n label,\n state.githubPrGradientAnimator.getOffset(),\n color,\n state.githubPrGradientAnimator.getFadeProgress(),\n ),\n };\n }\n return { plain: label, styled: chalk.hex(color)(label) };\n}\n\nfunction isGenericTitle(title: string): boolean {\n const lower = title.toLowerCase().trim();\n return (\n lower === 'new thread' ||\n lower.startsWith('new thread') ||\n lower.startsWith('clone of') ||\n lower.startsWith('untitled')\n );\n}\n\nfunction getGoalDurationMs(\n goal: { startedAt: string; activeStartedAt?: string; activeDurationMs?: number },\n now: number,\n): number {\n const activeStartedAt = goal.activeStartedAt ?? (goal.activeDurationMs === undefined ? goal.startedAt : undefined);\n const startedMs = activeStartedAt ? Date.parse(activeStartedAt) : NaN;\n const activeRunMs = Number.isFinite(startedMs) ? Math.max(0, now - startedMs) : 0;\n return (goal.activeDurationMs ?? 0) + activeRunMs;\n}\n\nfunction formatGoalDuration(goal: { startedAt: string; activeStartedAt?: string; activeDurationMs?: number }): string {\n const elapsedMinutes = Math.floor(getGoalDurationMs(goal, Date.now()) / 60_000);\n if (elapsedMinutes < 1) return '<1m';\n\n const days = Math.floor(elapsedMinutes / 1_440);\n const hours = Math.floor((elapsedMinutes % 1_440) / 60);\n const minutes = elapsedMinutes % 60;\n\n if (days > 0) return hours > 0 ? `${days}days${hours}hr` : `${days}days`;\n if (hours > 0) return minutes > 0 ? `${hours}hr${minutes}m` : `${hours}hr`;\n return `${minutes}m`;\n}\n\n/**\n * Update the status line at the bottom of the TUI.\n * Progressively reduces content to fit the terminal width.\n */\nexport function updateStatusLine(state: TUIState): void {\n if (!state.statusLine) return;\n const termWidth = getTermWidth();\n const SEP = ' '; // double-space separator between parts\n\n // --- Determine if we're showing observer/reflector instead of main mode ---\n const displayState = state.session.displayState.get();\n const omStatus = displayState.omProgress.status;\n const isJudging = Boolean(state.activeGoalJudge);\n const isObserving = omStatus === 'observing';\n const isReflecting = omStatus === 'reflecting';\n const showOMMode = !isJudging && (isObserving || isReflecting);\n\n // --- Mode badge ---\n let modeBadge = '';\n let modeBadgeWidth = 0;\n const modes = state.controller.listModes();\n const configuredMode = state.session.mode.resolve();\n const currentMode = modes.length > 1 ? configuredMode : undefined;\n const judgeModeColor = mastra.blue;\n // Use judge color for goal judge activity, OM color for OM activity, otherwise mode color\n const currentModeColor = currentMode?.metadata?.color;\n const mainModeColor = typeof currentModeColor === 'string' ? currentModeColor : undefined;\n const configuredModeColor = configuredMode?.metadata?.color;\n const contextIndicatorColor = typeof configuredModeColor === 'string' ? configuredModeColor : mastra.green;\n const modeColor = isJudging\n ? judgeModeColor\n : showOMMode\n ? isObserving\n ? getObserverColor()\n : getReflectorColor()\n : mainModeColor;\n // Tinted near-black background from mode color (shared between badge and model ID)\n const tintBg = modeColor ? tintHex(modeColor, 0.15) : undefined;\n // Badge name: use judge/OM mode name for background activity, otherwise main mode name\n const badgeName = isJudging\n ? 'judge'\n : showOMMode\n ? isObserving\n ? 'observe'\n : 'reflect'\n : currentMode\n ? currentMode.name || currentMode.id || 'unknown'\n : undefined;\n if (badgeName && modeColor) {\n const [mcr, mcg, mcb] = [\n parseInt(modeColor.slice(1, 3), 16),\n parseInt(modeColor.slice(3, 5), 16),\n parseInt(modeColor.slice(5, 7), 16),\n ];\n // Pulse the badge bg brightness opposite to the gradient sweep\n let badgeBrightness = 0.9;\n if (state.gradientAnimator?.isRunning()) {\n const fade = state.gradientAnimator.getFadeProgress();\n const easedFade = fade * fade * (3 - 2 * fade); // smoothstep\n const offset = state.gradientAnimator.getOffset() % 1;\n // Inverted phase (+ PI), range 0.65-0.95\n const animBrightness = 0.65 + 0.3 * (0.5 + 0.5 * Math.sin(offset * Math.PI * 2 + Math.PI));\n // Interpolate toward idle (0.9) as fade progresses\n badgeBrightness = animBrightness + (0.9 - animBrightness) * easedFade;\n }\n const mr = Math.floor(mcr * badgeBrightness);\n const mg = Math.floor(mcg * badgeBrightness);\n const mb = Math.floor(mcb * badgeBrightness);\n const rightHalf = tintBg ? chalk.rgb(mr, mg, mb).bgHex(tintBg)('▌') : chalk.rgb(mr, mg, mb)('▌');\n modeBadge =\n chalk.rgb(mr, mg, mb)('▐') + chalk.bgRgb(mr, mg, mb).hex('#000000').bold(badgeName.toLowerCase()) + rightHalf;\n modeBadgeWidth = badgeName.length + 2;\n } else if (badgeName) {\n modeBadge = ' ' + theme.fg('dim', badgeName) + ' ';\n modeBadgeWidth = badgeName.length + 2;\n }\n\n // --- Collect raw data ---\n // Show judge/OM model during background activity, otherwise main model\n const rawModelId =\n (isJudging\n ? state.activeGoalJudge?.modelId\n : showOMMode\n ? isObserving\n ? state.session.om.observer.modelId()\n : state.session.om.reflector.modelId()\n : state.session.model.get()) ?? '';\n // Rewrite Fireworks AI long paths: fireworks-ai/accounts/fireworks/models/<name> → fireworks/<name>\n let fullModelId = rawModelId.startsWith('fireworks-ai/accounts/fireworks/models/')\n ? 'fireworks/' + rawModelId.slice('fireworks-ai/accounts/fireworks/models/'.length)\n : rawModelId;\n // Rewrite version separators where 'p' stands for '.': e.g. kimi-k2p6 → kimi-k2.6, minimax-m2p7 → minimax-m2.7\n fullModelId = fullModelId.replace(/\\b([a-z]+-[a-z])(\\d+)p(\\d+)\\b/g, '$1$2.$3');\n const compactModelId = (modelId: string): string => {\n const parts = modelId.split('/');\n if (parts.length >= 3) {\n return `${parts[0]}/${parts.at(-1)!}`;\n }\n if (parts.length === 2) {\n return parts[1] ?? modelId;\n }\n return modelId;\n };\n\n // e.g. \"anthropic/claude-sonnet-4-20250514\" → \"claude-sonnet-4-20250514\"\n // e.g. \"mastra/anthropic/claude-opus-4.6\" → \"mastra/claude-opus-4.6\"\n const shortModelId = compactModelId(fullModelId);\n // e.g. \"claude-opus-4-6\" → \"opus 4.6\", \"mastra/anthropic/claude-opus-4.6\" → \"mastra/claude-opus-4.6\"\n const tinyModelId = shortModelId.includes('/')\n ? shortModelId\n : shortModelId.replace(/^claude-/, '').replace(/^(\\w+)-(\\d+)-(\\d{1,2})$/, '$1 $2.$3');\n\n const branch = state.projectInfo.gitBranch;\n const threadTitle =\n state.currentThreadTitle && !isGenericTitle(state.currentThreadTitle) ? state.currentThreadTitle : null;\n const activeGithubPr = state.activeGithubPrSubscriptions[0];\n const githubPrLabel = activeGithubPr ? formatGithubPrLabel(state, activeGithubPr) : null;\n const centerText = threadTitle || branch || (githubPrLabel ? '' : null);\n const centerTextShort =\n centerText && centerText.length > 24 ? centerText.slice(0, 12) + '..' + centerText.slice(-8) : centerText;\n const now = Date.now();\n const queuedCount = state.pendingQueuedActions.length + state.session.followUps.count();\n const queuedLabel = queuedCount > 0 ? `${queuedCount} queued` : null;\n const goalState = state.goalManager?.getGoal();\n const goalDuration = !isJudging && goalState?.status === 'active' ? formatGoalDuration(goalState) : null;\n const goalMatchesActiveRun =\n goalState?.status === 'active' &&\n goalDuration !== null &&\n state.agentRunStartedAt !== undefined &&\n Math.floor(getGoalDurationMs(goalState, now) / 60_000) === Math.floor((now - state.agentRunStartedAt) / 60_000);\n const goalLabel = goalDuration ? (goalMatchesActiveRun ? 'goal' : `goal ${goalDuration}`) : null;\n const formatDirPart = (value: string) => {\n const separator = githubPrLabel && value ? ' ' : '';\n return {\n plain: githubPrLabel ? `${githubPrLabel.plain}${separator}${value}` : value,\n styled: githubPrLabel\n ? `${githubPrLabel.styled}${separator}${theme.fg('thinkingText', value)}`\n : theme.fg('thinkingText', value),\n };\n };\n\n // --- Helper to style the model ID ---\n const modelTrail = tintBg ? chalk.hex(tintBg)('▌') : '';\n const styleModelId = (id: string): string => {\n if (!state.modelAuthStatus.hasAuth) {\n const envVar = state.modelAuthStatus.apiKeyEnvVar;\n return theme.fg('dim', id) + theme.fg('error', ' ✗') + theme.fg('muted', envVar ? ` (${envVar})` : ' (no key)');\n }\n\n if (state.gradientAnimator?.isRunning() && modeColor) {\n const fade = state.gradientAnimator.getFadeProgress();\n const easedFade = fade * fade * (3 - 2 * fade); // smoothstep\n const text = applyGradientSweep(id, state.gradientAnimator.getOffset(), modeColor, easedFade);\n const styled = chalk.italic(text);\n const bg = tintBg ? chalk.bgHex(tintBg)(styled) : styled;\n return bg + modelTrail;\n }\n if (modeColor) {\n // Use same idle brightness as gradient animation convergence (0.8)\n // so there's no color jump when animation stops\n const [cr, cg, cb] = [\n parseInt(modeColor.slice(1, 3), 16),\n parseInt(modeColor.slice(3, 5), 16),\n parseInt(modeColor.slice(5, 7), 16),\n ];\n const idleBright = 0.8;\n const fgStyled = chalk\n .rgb(Math.floor(cr * idleBright), Math.floor(cg * idleBright), Math.floor(cb * idleBright))\n .bold.italic(id);\n const bg = tintBg ? chalk.bgHex(tintBg)(fgStyled) : fgStyled;\n return bg + modelTrail;\n }\n return chalk.hex(mastra.specialGray).bold.italic(id);\n };\n\n // --- Build line with progressive reduction ---\n // Strategy: progressively drop less-important elements to fit terminal width.\n // Each attempt assembles plain-text parts, measures, and if it fits, styles and renders.\n\n // Short badge: first letter only (e.g., \"build\" → \"b\", \"observe\" → \"o\")\n let shortModeBadge = '';\n let shortModeBadgeWidth = 0;\n if (badgeName && modeColor) {\n const shortName = badgeName.toLowerCase().charAt(0);\n const [mcr, mcg, mcb] = [\n parseInt(modeColor.slice(1, 3), 16),\n parseInt(modeColor.slice(3, 5), 16),\n parseInt(modeColor.slice(5, 7), 16),\n ];\n let sBadgeBrightness = 0.9;\n if (state.gradientAnimator?.isRunning()) {\n const fade = state.gradientAnimator.getFadeProgress();\n if (fade < 1) {\n const offset = state.gradientAnimator.getOffset() % 1;\n const animBrightness = 0.65 + 0.3 * (0.5 + 0.5 * Math.sin(offset * Math.PI * 2 + Math.PI));\n sBadgeBrightness = animBrightness + (0.9 - animBrightness) * fade;\n }\n }\n const sr = Math.floor(mcr * sBadgeBrightness);\n const sg = Math.floor(mcg * sBadgeBrightness);\n const sb = Math.floor(mcb * sBadgeBrightness);\n const shortRightHalf = tintBg ? chalk.rgb(sr, sg, sb).bgHex(tintBg)('▌') : chalk.rgb(sr, sg, sb)('▌');\n shortModeBadge =\n chalk.rgb(sr, sg, sb)('▐') + chalk.bgRgb(sr, sg, sb).hex('#000000').bold(shortName) + shortRightHalf;\n shortModeBadgeWidth = shortName.length + 2;\n } else if (badgeName) {\n const shortName = badgeName.toLowerCase().charAt(0);\n shortModeBadge = ' ' + theme.fg('dim', shortName) + ' ';\n shortModeBadgeWidth = shortName.length + 2;\n }\n\n const activeTimingLabel =\n state.agentRunStartedAt !== undefined\n ? formatStatusDuration(now - state.agentRunStartedAt, { includeSeconds: true })\n : '';\n const activeTimingIsStale =\n state.agentRunStartedAt !== undefined &&\n state.agentRunLastStreamPartAt !== undefined &&\n now - state.agentRunLastStreamPartAt > 3 * 60_000;\n const completedTimingLabel =\n !activeTimingLabel && state.lastAgentRunDurationMs !== undefined\n ? formatStatusDuration(state.lastAgentRunDurationMs, { includeSeconds: true })\n : '';\n const completedTimingIcon =\n state.lastAgentRunEndReason === 'error'\n ? '×'\n : completedTimingLabel && state.lastAgentRunEndReason !== 'aborted'\n ? '✓'\n : '';\n const timingLabel = activeTimingLabel || completedTimingLabel;\n\n const buildLine = (opts: {\n modelId: string;\n showOM?: boolean;\n showOMBar?: boolean;\n showDir: boolean;\n dir?: string | null;\n allowDirTruncation?: boolean;\n badge?: 'full' | 'short';\n showQueue?: boolean;\n }): { plain: string; styled: string } | null => {\n const parts: Array<{ plain: string; styled: string }> = [];\n // Model ID (always present) — styleModelId adds padding spaces\n const timingPlain = timingLabel ? ` ${timingLabel}${completedTimingIcon ? ` ${completedTimingIcon}` : ''}` : '';\n const timingColor = activeTimingIsStale\n ? theme.fg('error', timingLabel)\n : activeTimingLabel\n ? modeColor\n ? chalk.hex(modeColor)(timingLabel)\n : theme.fg('dim', timingLabel)\n : state.lastAgentRunEndReason === 'aborted'\n ? theme.fg('warning', timingLabel)\n : state.lastAgentRunEndReason === 'error'\n ? theme.fg('error', timingLabel)\n : theme.fg('success', timingLabel);\n const timingIconColor =\n state.lastAgentRunEndReason === 'aborted'\n ? 'warning'\n : state.lastAgentRunEndReason === 'error'\n ? 'error'\n : 'success';\n const timingStyled = timingLabel\n ? ` ${timingColor}${completedTimingIcon ? ` ${theme.fg(timingIconColor, completedTimingIcon)}` : ''}`\n : '';\n parts.push({\n plain: `${opts.modelId}${tintBg ? ' ' : ''}${timingPlain}`,\n styled: styleModelId(opts.modelId) + timingStyled,\n });\n const useBadge = opts.badge === 'short' ? shortModeBadge : modeBadge;\n const useBadgeWidth = opts.badge === 'short' ? shortModeBadgeWidth : modeBadgeWidth;\n const ds = displayState;\n const messageColor = contextIndicatorColor;\n const memoryColor = mastraBrand.blue;\n const unusedColor = '#3f3f46';\n const messageSegmentStyler =\n ds.bufferingMessages && state.gradientAnimator?.isRunning()\n ? (segment: string) =>\n applyGradientSweep(\n segment,\n state.gradientAnimator!.getOffset(),\n messageColor,\n state.gradientAnimator!.getFadeProgress(),\n )\n : (segment: string) => chalk.hex(messageColor)(segment);\n const memorySegmentStyler =\n ds.bufferingObservations && state.gradientAnimator?.isRunning()\n ? (segment: string) =>\n applyGradientSweep(\n segment,\n state.gradientAnimator!.getOffset(),\n memoryColor,\n state.gradientAnimator!.getFadeProgress(),\n )\n : (segment: string) => chalk.hex(memoryColor)(segment);\n const unusedSegmentStyler = (segment: string) => chalk.hex(unusedColor)(segment);\n const indicatorPart =\n !isJudging && opts.showOM !== false\n ? formatOMContextIndicator(ds.omProgress, {\n messages: messageSegmentStyler,\n memory: memorySegmentStyler,\n unused: unusedSegmentStyler,\n showBar: opts.showOMBar,\n })\n : null;\n if (opts.showQueue && goalLabel) {\n parts.push({\n plain: goalLabel,\n styled: theme.fg('success', goalLabel),\n });\n }\n if (opts.showQueue && queuedLabel) {\n parts.push({\n plain: queuedLabel,\n styled: theme.fg('warning', queuedLabel),\n });\n }\n const tpsLabel = state.tokensPerSec > 0 ? `${String(state.tokensPerSec).padStart(3)} t/s` : null;\n const tpsPart = tpsLabel\n ? {\n plain: tpsLabel,\n styled: theme.fg('text', tpsLabel),\n }\n : null;\n // Directory / branch / thread title (lowest priority on line 1)\n let dirText = opts.dir !== undefined ? opts.dir : opts.showDir ? centerText : null;\n\n // Measure width of everything except dir to know how much space remains.\n // Throughput and the context indicator are reserved at the far right even though they are appended after dir.\n const rightParts = indicatorPart ? [tpsPart, indicatorPart].filter(part => part !== null) : [];\n const nonDirParts = [...parts, ...rightParts];\n const nonDirWidth =\n useBadgeWidth + nonDirParts.reduce((sum, p, i) => sum + visibleWidth(p.plain) + (i > 0 ? SEP.length : 0), 0);\n\n if (dirText !== null) {\n const dirPart = formatDirPart(dirText);\n const availableForDir = termWidth - nonDirWidth - SEP.length - 1; // -1 buffer for ambiguous-width chars\n const dirWidth = visibleWidth(dirPart.plain);\n const prefixWidth = githubPrLabel ? visibleWidth(githubPrLabel.plain) + (dirText ? 1 : 0) : 0;\n const availableForText = availableForDir - prefixWidth;\n const MIN_TRUNCATED_DIR = 10; // don't show a tiny sliver\n if (dirWidth > availableForDir && opts.allowDirTruncation === false) {\n return null;\n }\n if (dirWidth > availableForDir && availableForText >= MIN_TRUNCATED_DIR) {\n dirText = availableForText > 1 ? dirText.slice(0, availableForText - 1) + '…' : null;\n } else if (dirWidth > availableForDir) {\n // Preserve a standalone PR label when there is no room for the title.\n dirText = githubPrLabel && visibleWidth(githubPrLabel.plain) <= availableForDir ? '' : null;\n }\n }\n\n if (dirText !== null) {\n parts.push(formatDirPart(dirText));\n }\n if (indicatorPart) {\n parts.push(...rightParts);\n } else if (tpsPart) {\n parts.push(tpsPart);\n }\n const totalPlain =\n useBadgeWidth + parts.reduce((sum, p, i) => sum + visibleWidth(p.plain) + (i > 0 ? SEP.length : 0), 0);\n\n if (totalPlain + 1 > termWidth) return null; // +1 buffer for ambiguous-width chars (▐▌)\n\n let styledLine: string;\n const hasDir = dirText !== null;\n if (indicatorPart && parts.length >= 2) {\n // Three groups: left (model + timing + goal), center (queue + dir/thread), right (throughput + context)\n const leftPartCount = opts.showQueue && goalLabel ? 2 : 1;\n const leftParts = parts.slice(0, leftPartCount);\n const centerParts = parts.slice(leftPartCount, -rightParts.length);\n const leftSeparatorPlain = timingLabel ? ' · ' : ' ';\n const leftSeparatorStyled = timingLabel ? ` ${theme.fg('success', '·')} ` : ' ';\n\n const leftWidth =\n useBadgeWidth +\n leftParts.reduce((sum, p, i) => sum + visibleWidth(p.plain) + (i > 0 ? leftSeparatorPlain.length : 0), 0);\n const centerWidth = centerParts.reduce((sum, p, i) => sum + visibleWidth(p.plain) + (i > 0 ? SEP.length : 0), 0);\n const rightWidth = rightParts.reduce((sum, p, i) => sum + visibleWidth(p.plain) + (i > 0 ? SEP.length : 0), 0);\n const totalContent = leftWidth + centerWidth + rightWidth;\n const freeSpace = termWidth - totalContent;\n const gapLeft = Math.floor(freeSpace / 2);\n const gapRight = freeSpace - gapLeft;\n\n styledLine =\n useBadge +\n leftParts.map(p => p.styled).join(leftSeparatorStyled) +\n ' '.repeat(Math.max(gapLeft, 1)) +\n centerParts.map(p => p.styled).join(SEP) +\n ' '.repeat(Math.max(gapRight, 1)) +\n rightParts.map(p => p.styled).join(SEP);\n } else if (hasDir && parts.length === 2) {\n // Just model + dir, right-align dir\n const mainStr = useBadge + parts[0]!.styled;\n const dirPart = parts[parts.length - 1]!;\n const gap = termWidth - totalPlain;\n styledLine = mainStr + ' '.repeat(gap + SEP.length) + dirPart.styled;\n } else {\n styledLine = useBadge + parts.map(p => p.styled).join(SEP);\n }\n return { plain: '', styled: styledLine };\n };\n // Try progressively more compact layouts.\n // Preserve status content before the context indicator, which is a visual summary.\n const result =\n buildLine({\n modelId: fullModelId,\n showDir: false,\n dir: centerText,\n allowDirTruncation: false,\n showQueue: true,\n }) ??\n buildLine({\n modelId: fullModelId,\n showOMBar: false,\n showDir: false,\n dir: centerText,\n allowDirTruncation: false,\n showQueue: true,\n }) ??\n buildLine({ modelId: fullModelId, showOMBar: false, showDir: false, dir: centerTextShort, showQueue: true }) ??\n buildLine({ modelId: fullModelId, showOMBar: false, showDir: false, showQueue: true }) ??\n buildLine({ modelId: tinyModelId, showOMBar: false, showDir: false, showQueue: true }) ??\n buildLine({ modelId: tinyModelId, showOMBar: false, showDir: false, badge: 'short', showQueue: true }) ??\n buildLine({ modelId: tinyModelId, showOM: false, showDir: false, badge: 'short', showQueue: true }) ??\n buildLine({ modelId: tinyModelId, showOM: false, showDir: false }) ??\n buildLine({ modelId: '', showOMBar: false, showDir: false, badge: 'short', showQueue: true }) ??\n buildLine({ modelId: '', showOM: false, showDir: false, badge: 'short' });\n\n state.statusLine.setText(result?.styled ?? shortModeBadge + styleModelId(tinyModelId));\n\n // Line 2: hidden — dir only shows on line 1 when it fits\n if (state.memoryStatusLine) {\n state.memoryStatusLine.setText('');\n }\n\n state.ui.requestRender();\n}\n","import { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SelectItem } from '@earendil-works/pi-tui';\n\nimport { setClipboardText } from '@mastra/code-sdk/clipboard/index';\nimport { removeCustomPackFromSettings } from '@mastra/code-sdk/onboarding/custom-packs';\nimport type { ModePack, ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/packs';\nimport { getAvailableModePacks } from '@mastra/code-sdk/onboarding/packs';\nimport {\n loadSettings,\n resolveThreadActiveModelPackId,\n saveSettings,\n THREAD_ACTIVE_MODEL_PACK_ID_KEY,\n} from '@mastra/code-sdk/onboarding/settings';\nimport type { GlobalSettings } from '@mastra/code-sdk/onboarding/settings';\nimport chalk from 'chalk';\nimport { AskQuestionDialogComponent } from '../components/ask-question-dialog.js';\nimport { ModelSelectorComponent } from '../components/model-selector.js';\nimport type { ModelItem } from '../components/model-selector.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { promptForApiKeyIfNeeded } from '../prompt-api-key.js';\nimport { updateStatusLine } from '../status-line.js';\nimport { getSelectListTheme, mastra, theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\n// Re-exported for existing importers/tests; the implementation lives in\n// onboarding/custom-packs.ts so non-TUI surfaces (web routes) can share it.\nexport { removeCustomPackFromSettings };\n\n// ---------------------------------------------------------------------------\n// Pack sharing — serialize/deserialize\n// ---------------------------------------------------------------------------\n\nconst SHARE_PREFIX = 'mastra-pack:';\n\ninterface SharedPackPayload {\n name: string;\n models: { build: string; plan: string; fast: string };\n}\n\nexport function serializePack(pack: ModePack): string {\n const payload: SharedPackPayload = {\n name: pack.name,\n models: { build: pack.models.build, plan: pack.models.plan, fast: pack.models.fast },\n };\n return SHARE_PREFIX + Buffer.from(JSON.stringify(payload), 'utf-8').toString('base64');\n}\n\nexport function deserializePack(input: string): ModePack | null {\n try {\n const trimmed = input.trim();\n if (!trimmed.startsWith(SHARE_PREFIX)) return null;\n const json = Buffer.from(trimmed.slice(SHARE_PREFIX.length), 'base64').toString('utf-8');\n const parsed = JSON.parse(json) as Record<string, unknown>;\n\n const name = typeof parsed.name === 'string' ? parsed.name.trim() : '';\n if (!name) return null;\n\n const models = parsed.models as Record<string, unknown> | undefined;\n if (!models || typeof models !== 'object') return null;\n\n const build = typeof models.build === 'string' ? models.build : '';\n const plan = typeof models.plan === 'string' ? models.plan : '';\n const fast = typeof models.fast === 'string' ? models.fast : '';\n if (!build || !plan || !fast) return null;\n\n return {\n id: `custom:${name}`,\n name,\n description: 'Imported custom pack',\n models: { build, plan, fast },\n };\n } catch {\n return null;\n }\n}\n\nasync function selectModel(\n ctx: SlashCommandContext,\n title: string,\n modeColor?: string,\n currentModelId?: string,\n): Promise<string | undefined> {\n const availableModels = await ctx.state.controller.listAvailableModels();\n if (availableModels.length === 0) return undefined;\n\n return new Promise<string | undefined>(resolve => {\n const selector = new ModelSelectorComponent({\n tui: ctx.state.ui,\n models: availableModels,\n currentModelId,\n title,\n titleColor: modeColor,\n onSelect: async (model: ModelItem) => {\n ctx.state.ui.hideOverlay();\n await promptForApiKeyIfNeeded(ctx.state.ui, model, ctx.authStorage);\n resolve(model.id);\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve(undefined);\n },\n });\n\n showModalOverlay(ctx.state.ui, selector, { maxHeight: '75%' });\n selector.focused = true;\n });\n}\n\nasync function askCustomPackName(ctx: SlashCommandContext, defaultName?: string): Promise<string | null> {\n return new Promise(resolve => {\n const question = new AskQuestionDialogComponent({\n question: 'Name this custom pack',\n tui: ctx.state.ui,\n onSubmit: answer => {\n ctx.state.ui.hideOverlay();\n const trimmed = answer.trim();\n resolve(trimmed.length > 0 ? trimmed : null);\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve(null);\n },\n });\n\n if (defaultName) {\n (question as any).input?.setValue?.(defaultName);\n }\n\n showModalOverlay(ctx.state.ui, question, { maxHeight: '50%' });\n question.focused = true;\n });\n}\n\nasync function askCustomPackAction(\n ctx: SlashCommandContext,\n pack: ModePack,\n): Promise<'activate' | 'edit' | 'share' | 'delete' | null> {\n const actions = [\n { id: 'activate', label: 'Activate', description: 'Use this pack as-is' },\n { id: 'edit', label: 'Edit', description: 'Update this pack' },\n { id: 'share', label: 'Share', description: 'Copy to clipboard' },\n { id: 'delete', label: 'Delete', description: 'Remove this custom pack' },\n ] as const;\n\n return new Promise(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', `Custom pack: ${pack.name}`)), 0, 0));\n container.addChild(new Spacer(1));\n\n const items: SelectItem[] = actions.map(action => ({\n value: action.id,\n label: ` ${action.label} ${theme.fg('dim', action.description)}`,\n }));\n\n const selectList = new SelectList(items, items.length, getSelectListTheme());\n const detailText = new Text('', 0, 0);\n const detailById: Record<string, string> = {\n activate: getPackDetail(pack),\n edit: theme.fg('dim', ' Edit one setting at a time (Rename, plan, build, fast).'),\n share: theme.fg('dim', ' Copy shareable config to clipboard. Paste it to import elsewhere.'),\n delete: theme.fg('error', ' Permanently removes this custom pack from settings.'),\n };\n\n const closeOverlay = () => {\n ctx.state.ui.hideOverlay();\n ctx.state.ui.requestRender();\n };\n\n selectList.onSelectionChange = item => {\n detailText.setText(detailById[item.value] ?? '');\n ctx.state.ui.requestRender();\n };\n\n selectList.onSelect = item => {\n closeOverlay();\n resolve(item.value as 'activate' | 'edit' | 'share' | 'delete');\n };\n\n selectList.onCancel = () => {\n closeOverlay();\n resolve(null);\n };\n\n detailText.setText(detailById['activate']!);\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(detailText);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc cancel'), 0, 0));\n (container as Box & { handleInput: (data: string) => void }).handleInput = (data: string) =>\n selectList.handleInput(data);\n\n showModalOverlay(ctx.state.ui, container, { maxHeight: '75%' });\n });\n}\n\nasync function askCustomPackEditTarget(\n ctx: SlashCommandContext,\n pack: ModePack,\n): Promise<'rename' | 'plan' | 'build' | 'fast' | 'save' | null> {\n return new Promise(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', `Edit custom pack: ${pack.name}`)), 0, 0));\n container.addChild(new Spacer(1));\n\n const selectList = new SelectList(\n [\n { value: 'rename', label: ` Rename → ${theme.fg('text', pack.name)}` },\n { value: 'plan', label: ` ${chalk.hex(mastra.purple)('plan')} → ${theme.fg('text', pack.models.plan)}` },\n { value: 'build', label: ` ${chalk.hex(mastra.green)('build')} → ${theme.fg('text', pack.models.build)}` },\n { value: 'fast', label: ` ${chalk.hex(mastra.orange)('fast')} → ${theme.fg('text', pack.models.fast)}` },\n { value: 'save', label: ` ${theme.fg('success', 'Save')}` },\n ],\n 5,\n getSelectListTheme(),\n );\n\n const closeOverlay = () => {\n ctx.state.ui.hideOverlay();\n ctx.state.ui.requestRender();\n };\n\n selectList.onSelect = item => {\n closeOverlay();\n resolve(item.value as 'rename' | 'plan' | 'build' | 'fast' | 'save');\n };\n\n selectList.onCancel = () => {\n closeOverlay();\n resolve(null);\n };\n\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc cancel'), 0, 0));\n (container as Box & { handleInput: (data: string) => void }).handleInput = (data: string) =>\n selectList.handleInput(data);\n\n showModalOverlay(ctx.state.ui, container, { maxHeight: '75%' });\n });\n}\n\nasync function runCustomFlow(\n ctx: SlashCommandContext,\n options?: { name?: string; models?: ModePack['models']; skipNamePrompt?: boolean },\n): Promise<ModePack | null> {\n const modes: Array<{ id: 'plan' | 'build' | 'fast'; label: string; metadata: { color: string } }> = [\n { id: 'plan', label: 'plan', metadata: { color: mastra.purple } },\n { id: 'build', label: 'build', metadata: { color: mastra.green } },\n { id: 'fast', label: 'fast', metadata: { color: mastra.orange } },\n ];\n\n const name = options?.skipNamePrompt\n ? options?.name\n : await askCustomPackName(ctx, options?.name && options.name !== 'Custom' ? options.name : undefined);\n if (!name) return null;\n\n const existing = options?.models ?? { build: '', plan: '', fast: '' };\n const models: Record<string, string> = {\n build: existing.build ?? '',\n plan: existing.plan ?? '',\n fast: existing.fast ?? '',\n };\n\n for (const mode of modes) {\n const modelId = await selectModel(\n ctx,\n `Select model for ${mode.label} mode`,\n mode.metadata.color,\n models[mode.id] || undefined,\n );\n if (!modelId) return null;\n models[mode.id] = modelId;\n }\n\n return {\n id: `custom:${name}`,\n name,\n description: 'Saved custom pack',\n models: models as ModePack['models'],\n };\n}\n\nasync function runCustomPackEditFlow(\n ctx: SlashCommandContext,\n pack: ModePack,\n): Promise<{ pack: ModePack; previousPackId?: string } | null> {\n let workingPack: ModePack = { ...pack, models: { ...pack.models } };\n let previousPackId: string | undefined;\n\n while (true) {\n const editTarget = await askCustomPackEditTarget(ctx, workingPack);\n if (!editTarget) return null;\n if (editTarget === 'save') return { pack: workingPack, previousPackId };\n\n if (editTarget === 'rename') {\n const renamed = await askCustomPackName(ctx, workingPack.name);\n if (!renamed) continue;\n const renamedPack: ModePack = {\n ...workingPack,\n id: `custom:${renamed}`,\n name: renamed,\n };\n if (renamedPack.id !== pack.id && !previousPackId) previousPackId = pack.id;\n workingPack = renamedPack;\n continue;\n }\n\n const modeColors: Record<'plan' | 'build' | 'fast', string> = {\n plan: mastra.purple,\n build: mastra.green,\n fast: mastra.orange,\n };\n\n const modelId = await selectModel(\n ctx,\n `Select model for ${editTarget} mode`,\n modeColors[editTarget],\n workingPack.models[editTarget],\n );\n if (!modelId) continue;\n\n workingPack = {\n ...workingPack,\n models: {\n ...workingPack.models,\n [editTarget]: modelId,\n },\n };\n }\n}\n\nexport function upsertCustomPackInSettings(\n settings: GlobalSettings,\n pack: ModePack,\n modeDefaults: Record<string, string>,\n previousPackId?: string,\n setActive = true,\n): void {\n if (!pack.id.startsWith('custom:')) return;\n\n if (previousPackId && previousPackId.startsWith('custom:') && previousPackId !== pack.id) {\n removeCustomPackFromSettings(settings, previousPackId);\n }\n\n const customName = pack.id.slice('custom:'.length);\n const entry = { name: customName, models: modeDefaults, createdAt: new Date().toISOString() };\n const idx = settings.customModelPacks.findIndex(p => p.name === customName);\n if (idx >= 0) {\n settings.customModelPacks[idx] = entry;\n } else {\n settings.customModelPacks.push(entry);\n }\n if (setActive) {\n settings.models.activeModelPackId = pack.id;\n settings.models.modeDefaults = modeDefaults;\n }\n}\n\nasync function applyPack(ctx: SlashCommandContext, pack: ModePack, previousPackId?: string): Promise<void> {\n const controller = ctx.state.controller;\n const modes = controller.listModes();\n\n for (const mode of modes) {\n const modelId = (pack.models as Record<string, string>)[mode.id];\n if (modelId) {\n (mode as any).defaultModelId = modelId;\n await ctx.state.session.thread.setSetting({ key: `modeModelId_${mode.id}`, value: modelId });\n }\n }\n\n const currentModeId = ctx.state.session.mode.get();\n const currentModeModel = (pack.models as Record<string, string>)[currentModeId];\n if (currentModeModel) {\n await ctx.state.session.model.switch({ modelId: currentModeModel });\n }\n\n const subagentModeMap: Record<string, string> = { explore: 'fast', plan: 'plan', execute: 'build' };\n for (const [agentType, modeId] of Object.entries(subagentModeMap)) {\n const saModelId = (pack.models as Record<string, string>)[modeId];\n if (saModelId) {\n await ctx.state.session.subagents.model.set({ modelId: saModelId, agentType });\n }\n }\n\n await ctx.state.session.thread.setSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY, value: pack.id });\n\n const s = loadSettings();\n const modeDefaults: Record<string, string> = {};\n for (const mode of modes) {\n const modelId = (pack.models as Record<string, string>)[mode.id];\n if (modelId) modeDefaults[mode.id] = modelId;\n }\n\n if (pack.id.startsWith('custom:')) {\n upsertCustomPackInSettings(s, pack, modeDefaults, previousPackId);\n } else {\n s.models.activeModelPackId = pack.id;\n s.models.modeDefaults = {};\n }\n\n s.models.subagentModels = {};\n\n const hasOpenAI = Object.values(pack.models).some(m => m.startsWith('openai/'));\n const currentThinking = ((ctx.state.session.state.get() as any)?.thinkingLevel ?? 'off') as string;\n if (hasOpenAI && currentThinking === 'off') {\n await ctx.state.session.state.set({ thinkingLevel: 'low' } as any);\n s.preferences.thinkingLevel = 'low';\n }\n\n saveSettings(s);\n updateStatusLine(ctx.state);\n}\n\nfunction getPackDetail(pack: ModePack): string {\n if (pack.id === 'custom') {\n return theme.fg('dim', ' Create a named custom pack and pick a model for each mode.');\n }\n return [\n ` ${chalk.hex(mastra.purple)('plan')} → ${theme.fg('text', pack.models.plan)}`,\n ` ${chalk.hex(mastra.green)('build')} → ${theme.fg('text', pack.models.build)}`,\n ` ${chalk.hex(mastra.orange)('fast')} → ${theme.fg('text', pack.models.fast)}`,\n ].join('\\n');\n}\n\nasync function saveCustomPackEdits(ctx: SlashCommandContext, pack: ModePack, previousPackId?: string): Promise<void> {\n const settings = loadSettings();\n const wasActive = previousPackId\n ? settings.models.activeModelPackId === previousPackId\n : settings.models.activeModelPackId === pack.id;\n const wasOnboarding = previousPackId\n ? settings.onboarding.modePackId === previousPackId\n : settings.onboarding.modePackId === pack.id;\n\n const modeDefaults: Record<string, string> = {\n plan: pack.models.plan,\n build: pack.models.build,\n fast: pack.models.fast,\n };\n\n upsertCustomPackInSettings(settings, pack, modeDefaults, previousPackId, false);\n\n if (wasActive) {\n settings.models.activeModelPackId = pack.id;\n }\n if (wasOnboarding) {\n settings.onboarding.modePackId = pack.id;\n }\n\n saveSettings(settings);\n\n if (previousPackId && previousPackId !== pack.id) {\n const threadId = ctx.state.session.thread.getId();\n const thread = threadId ? (await ctx.state.session.thread.list()).find(t => t.id === threadId) : undefined;\n const threadPackId = (thread?.metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY] as string | undefined) ?? null;\n if (threadPackId === previousPackId) {\n await ctx.state.session.thread.setSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY, value: pack.id });\n }\n }\n}\n\nasync function deleteCustomPack(ctx: SlashCommandContext, pack: ModePack): Promise<void> {\n if (!pack.id.startsWith('custom:')) return;\n\n const threadId = ctx.state.session.thread.getId();\n const thread = threadId ? (await ctx.state.session.thread.list()).find(t => t.id === threadId) : undefined;\n const threadPackId = (thread?.metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY] as string | undefined) ?? null;\n\n const settings = loadSettings();\n removeCustomPackFromSettings(settings, pack.id);\n saveSettings(settings);\n\n if (threadPackId === pack.id) {\n await ctx.state.session.thread.setSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY, value: null });\n }\n}\n\nfunction sharePack(ctx: SlashCommandContext, pack: ModePack): void {\n const serialized = serializePack(pack);\n const copied = setClipboardText(serialized);\n if (copied) {\n ctx.showInfo(`Copied ${pack.name} pack to clipboard`);\n } else {\n ctx.showInfo(`Share string for ${pack.name}:\\n${serialized}`);\n }\n}\n\nasync function askImportPackString(ctx: SlashCommandContext): Promise<string | null> {\n return new Promise(resolve => {\n const question = new AskQuestionDialogComponent({\n question: 'Paste the shared model pack string',\n tui: ctx.state.ui,\n onSubmit: answer => {\n ctx.state.ui.hideOverlay();\n const trimmed = answer.trim();\n resolve(trimmed.length > 0 ? trimmed : null);\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve(null);\n },\n });\n\n showModalOverlay(ctx.state.ui, question, { maxHeight: '50%' });\n question.focused = true;\n });\n}\n\nasync function askImportCollision(\n ctx: SlashCommandContext,\n existingName: string,\n): Promise<'overwrite' | 'rename' | 'cancel'> {\n const actions = [\n { id: 'overwrite', label: 'Overwrite', description: `Replace the existing \"${existingName}\" pack` },\n { id: 'rename', label: 'Rename', description: 'Choose a different name for the imported pack' },\n { id: 'cancel', label: 'Cancel', description: 'Abort import' },\n ] as const;\n\n return new Promise(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', `A pack named \"${existingName}\" already exists`)), 0, 0));\n container.addChild(new Spacer(1));\n\n const items: SelectItem[] = actions.map(a => ({\n value: a.id,\n label: ` ${a.label} ${theme.fg('dim', a.description)}`,\n }));\n\n const selectList = new SelectList(items, items.length, getSelectListTheme());\n\n const closeOverlay = () => {\n ctx.state.ui.hideOverlay();\n ctx.state.ui.requestRender();\n };\n\n selectList.onSelect = (selected: SelectItem) => {\n closeOverlay();\n resolve(selected.value as 'overwrite' | 'rename' | 'cancel');\n };\n\n selectList.onCancel = () => {\n closeOverlay();\n resolve('cancel');\n };\n\n container.addChild(selectList);\n (container as Box & { handleInput: (data: string) => void }).handleInput = (data: string) =>\n selectList.handleInput(data);\n\n showModalOverlay(ctx.state.ui, container, { maxHeight: '75%' });\n });\n}\n\nexport async function handleModelsPackCommand(ctx: SlashCommandContext): Promise<void> {\n const controller = ctx.state.controller;\n const models = await controller.listAvailableModels();\n\n const hasEnv = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (storageProviderId: string): ProviderAccessLevel => {\n const cred = ctx.authStorage?.get(storageProviderId);\n if (cred?.type === 'oauth') return 'oauth';\n if (cred?.type === 'api_key' && cred.key.trim().length > 0) return 'apikey';\n return false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai-codex'),\n cerebras: hasEnv('cerebras') ? ('apikey' as const) : false,\n google: hasEnv('google') ? ('apikey' as const) : false,\n deepseek: hasEnv('deepseek') ? ('apikey' as const) : false,\n 'github-copilot': accessLevel('github-copilot'),\n };\n // Include all other providers that have API keys configured\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider) && m.hasApiKey) {\n access[m.provider] = 'apikey';\n seen.add(m.provider);\n }\n }\n\n const settings = loadSettings();\n const packs = getAvailableModePacks(access, settings.customModelPacks);\n if (packs.length === 0) {\n ctx.showInfo('No model packs available. Configure provider auth first.');\n return;\n }\n\n const threadId = ctx.state.session.thread.getId();\n const thread = threadId ? (await ctx.state.session.thread.list()).find(t => t.id === threadId) : undefined;\n const currentPackId = resolveThreadActiveModelPackId(\n settings,\n packs,\n thread?.metadata as Record<string, unknown> | undefined,\n );\n\n const items: SelectItem[] = packs.map(p => ({\n value: p.id,\n label: ` ${p.name} ${theme.fg('dim', p.description)}${p.id === currentPackId ? theme.fg('dim', ' (current)') : ''}`,\n }));\n items.push({\n value: '__import__',\n label: ` Import Pack ${theme.fg('dim', 'Paste a shared pack config')}`,\n });\n\n return new Promise<void>(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', 'Switch model pack')), 0, 0));\n container.addChild(new Spacer(1));\n\n const selectList = new SelectList(items, items.length, getSelectListTheme());\n const detailText = new Text('', 0, 0);\n\n const closeOverlay = () => {\n ctx.state.ui.hideOverlay();\n ctx.state.ui.requestRender();\n };\n\n const updateDetail = (packId: string) => {\n if (packId === '__import__') {\n detailText.setText(theme.fg('dim', ' Paste a mastra-pack:... string from someone else to import their pack.'));\n ctx.state.ui.requestRender();\n return;\n }\n const pack = packs.find(p => p.id === packId);\n if (!pack) return;\n detailText.setText(getPackDetail(pack));\n ctx.state.ui.requestRender();\n };\n\n selectList.onSelect = async (item: SelectItem) => {\n closeOverlay();\n\n if (item.value === '__import__') {\n const importStr = await askImportPackString(ctx);\n if (!importStr) {\n resolve();\n return;\n }\n const imported = deserializePack(importStr);\n if (!imported) {\n ctx.showInfo('Invalid pack string. Expected a mastra-pack:... value.');\n resolve();\n return;\n }\n\n // Validate that the imported model IDs are available in this environment\n const availableModelIds = new Set(models.map(m => m.id));\n const unavailable = Object.entries(imported.models)\n .filter(([, modelId]) => !availableModelIds.has(modelId))\n .map(([mode, modelId]) => `${mode}: ${modelId}`);\n if (unavailable.length > 0) {\n ctx.showInfo(`Can't import — these models aren't available:\\n${unavailable.join('\\n')}`);\n resolve();\n return;\n }\n\n // Handle name collision with existing custom pack\n const s = loadSettings();\n const existing = s.customModelPacks.find(p => p.name === imported.name);\n if (existing) {\n const collision = await askImportCollision(ctx, imported.name);\n if (collision === 'cancel') {\n resolve();\n return;\n }\n if (collision === 'rename') {\n const newName = await askCustomPackName(ctx, imported.name);\n if (!newName) {\n resolve();\n return;\n }\n if (s.customModelPacks.some(p => p.name === newName)) {\n ctx.showInfo(`A custom pack named \"${newName}\" already exists. Rename or delete it first.`);\n resolve();\n return;\n }\n imported.name = newName;\n imported.id = `custom:${newName}`;\n }\n // collision === 'overwrite' falls through\n }\n\n await applyPack(ctx, imported);\n ctx.showInfo(`Imported and activated ${imported.name} pack`);\n resolve();\n return;\n }\n\n let pack: ModePack | null | undefined = packs.find(p => p.id === item.value);\n let previousPackId: string | undefined;\n if (!pack) {\n resolve();\n return;\n }\n\n if (pack.id === 'custom') {\n pack = await runCustomFlow(ctx);\n } else if (pack.id.startsWith('custom:')) {\n while (true) {\n const action = await askCustomPackAction(ctx, pack);\n if (action === null) {\n await handleModelsPackCommand(ctx);\n resolve();\n return;\n }\n\n if (action === 'delete') {\n await deleteCustomPack(ctx, pack);\n ctx.showInfo(`Deleted custom pack: ${pack.name}`);\n resolve();\n return;\n }\n\n if (action === 'share') {\n sharePack(ctx, pack);\n continue;\n }\n\n if (action === 'activate') {\n break;\n }\n\n const edited = await runCustomPackEditFlow(ctx, pack);\n if (!edited) {\n continue;\n }\n\n previousPackId = edited.previousPackId;\n pack = edited.pack;\n await saveCustomPackEdits(ctx, pack, previousPackId);\n previousPackId = undefined;\n ctx.showInfo(`Updated custom pack: ${pack.name}`);\n }\n }\n\n if (!pack) {\n resolve();\n return;\n }\n\n await applyPack(ctx, pack, previousPackId);\n ctx.showInfo(`Switched to ${pack.name} pack`);\n resolve();\n };\n\n selectList.onCancel = () => {\n closeOverlay();\n resolve();\n };\n\n selectList.onSelectionChange = (item: SelectItem) => {\n updateDetail(item.value);\n };\n\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(detailText);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc cancel'), 0, 0));\n\n const currentIdx = packs.findIndex(p => p.id === currentPackId);\n const initialIdx = currentIdx >= 0 ? currentIdx : 0;\n if (initialIdx > 0) selectList.setSelectedIndex(initialIdx);\n updateDetail(packs[initialIdx]!.id);\n (container as Box & { handleInput: (data: string) => void }).handleInput = (data: string) =>\n selectList.handleInput(data);\n\n showModalOverlay(ctx.state.ui, container, { maxHeight: '80%' });\n });\n}\n","import {\n removeCustomProviderFromSettings,\n upsertCustomProviderInSettings,\n} from '@mastra/code-sdk/onboarding/custom-providers';\nimport {\n getCustomProviderId,\n loadSettings,\n saveSettings,\n toCustomProviderModelId,\n} from '@mastra/code-sdk/onboarding/settings';\nimport type { GlobalSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { SlashCommandContext } from './types.js';\n\n// Re-exported for existing importers/tests; the implementations live in\n// onboarding/custom-providers.ts so non-TUI surfaces (web routes) can share them.\nexport { removeCustomProviderFromSettings, upsertCustomProviderInSettings };\n\nfunction isValidUrl(value: string): boolean {\n try {\n const parsed = new URL(value);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nexport function addModelToCustomProviderInSettings(\n settings: GlobalSettings,\n providerId: string,\n modelName: string,\n): boolean {\n const trimmed = modelName.trim();\n if (!trimmed) return false;\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) return false;\n provider.models = [...new Set([...provider.models, trimmed])];\n return true;\n}\n\nexport function removeModelFromCustomProviderInSettings(\n settings: GlobalSettings,\n providerId: string,\n modelName: string,\n): boolean {\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) return false;\n const before = provider.models.length;\n provider.models = provider.models.filter(model => model !== modelName);\n return provider.models.length < before;\n}\n\nasync function askText(\n ctx: SlashCommandContext,\n question: string,\n defaultValue?: string,\n allowEmptyInput = false,\n): Promise<string | null> {\n const answer = await askModalQuestion(ctx.state.ui, { question, defaultValue, allowEmptyInput });\n const trimmed = answer?.trim() ?? '';\n return trimmed.length > 0 ? trimmed : null;\n}\n\nasync function askOptionalText(\n ctx: SlashCommandContext,\n question: string,\n defaultValue?: string,\n): Promise<string | undefined> {\n const answer = await askText(ctx, `${question} (leave blank to skip)`, defaultValue, true);\n return answer?.trim() || undefined;\n}\n\nasync function askSelect(\n ctx: SlashCommandContext,\n question: string,\n options: Array<{ label: string; value: string; description?: string }>,\n): Promise<string | null> {\n const answer = await askModalQuestion(ctx.state.ui, {\n question,\n options: options.map(option => ({ label: option.label, description: option.description })),\n });\n const selected = options.find(option => option.label === answer);\n return selected?.value ?? null;\n}\n\nasync function createProviderFlow(ctx: SlashCommandContext): Promise<void> {\n const settings = loadSettings();\n const name = await askText(ctx, 'Custom provider name');\n if (!name) return;\n\n const providerId = getCustomProviderId(name);\n if (settings.customProviders.some(provider => getCustomProviderId(provider.name) === providerId)) {\n ctx.showError(`Provider already exists: ${name}`);\n return;\n }\n\n const url = await askText(ctx, 'Base URL (OpenAI-compatible endpoint)');\n if (!url) return;\n if (!isValidUrl(url)) {\n ctx.showError('Invalid URL. Use a full http(s) URL.');\n return;\n }\n\n const apiKey = await askOptionalText(ctx, 'API key');\n upsertCustomProviderInSettings(settings, { name, url, apiKey, models: [] });\n saveSettings(settings);\n ctx.showInfo(`Added custom provider: ${name}`);\n\n await manageProviderFlow(ctx, providerId);\n}\n\nasync function editProviderFlow(ctx: SlashCommandContext, providerId: string): Promise<void> {\n const settings = loadSettings();\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) {\n ctx.showError('Provider not found.');\n return;\n }\n\n const name = await askText(ctx, 'Provider name', provider.name);\n if (!name) return;\n const nextProviderId = getCustomProviderId(name);\n if (\n nextProviderId !== providerId &&\n settings.customProviders.some(entry => getCustomProviderId(entry.name) === nextProviderId)\n ) {\n ctx.showError(`Provider already exists: ${name}`);\n return;\n }\n\n const url = await askText(ctx, 'Base URL', provider.url);\n if (!url) return;\n if (!isValidUrl(url)) {\n ctx.showError('Invalid URL. Use a full http(s) URL.');\n return;\n }\n\n const apiKey = await askOptionalText(ctx, 'API key', provider.apiKey);\n upsertCustomProviderInSettings(\n settings,\n {\n ...provider,\n name,\n url,\n apiKey,\n },\n providerId,\n );\n saveSettings(settings);\n ctx.showInfo(`Updated custom provider: ${name}`);\n}\n\nasync function addProviderModelFlow(ctx: SlashCommandContext, providerId: string): Promise<void> {\n const settings = loadSettings();\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) {\n ctx.showError('Provider not found.');\n return;\n }\n\n const modelName = await askText(ctx, `Model ID for ${provider.name}`);\n if (!modelName) return;\n const added = addModelToCustomProviderInSettings(settings, providerId, modelName);\n if (!added) {\n ctx.showError('Unable to add model to provider.');\n return;\n }\n\n saveSettings(settings);\n ctx.showInfo(`Added model: ${toCustomProviderModelId(provider.name, modelName)}`);\n}\n\nasync function removeProviderModelFlow(ctx: SlashCommandContext, providerId: string): Promise<void> {\n const settings = loadSettings();\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) {\n ctx.showError('Provider not found.');\n return;\n }\n if (provider.models.length === 0) {\n ctx.showInfo(`No custom models configured for ${provider.name}.`);\n return;\n }\n\n const modelName = await askSelect(\n ctx,\n `Remove model from ${provider.name}`,\n provider.models.map(model => ({\n label: model,\n value: model,\n description: toCustomProviderModelId(provider.name, model),\n })),\n );\n\n if (!modelName) return;\n\n const removed = removeModelFromCustomProviderInSettings(settings, providerId, modelName);\n if (!removed) {\n ctx.showError('Unable to remove model from provider.');\n return;\n }\n\n saveSettings(settings);\n ctx.showInfo(`Removed model: ${toCustomProviderModelId(provider.name, modelName)}`);\n}\n\nasync function manageProviderFlow(ctx: SlashCommandContext, providerId: string): Promise<void> {\n const settings = loadSettings();\n const provider = settings.customProviders.find(entry => getCustomProviderId(entry.name) === providerId);\n if (!provider) {\n ctx.showError('Provider not found.');\n return;\n }\n\n const action = await askSelect(ctx, `Manage provider: ${provider.name}`, [\n { label: 'Add model', value: 'add-model', description: 'Attach a model ID to this provider' },\n { label: 'Remove model', value: 'remove-model', description: 'Remove a model ID from this provider' },\n { label: 'Edit provider', value: 'edit-provider', description: 'Rename, change URL, or update API key' },\n { label: 'Delete provider', value: 'delete-provider', description: 'Remove provider and all its model IDs' },\n ]);\n\n switch (action) {\n case 'add-model':\n await addProviderModelFlow(ctx, providerId);\n break;\n case 'remove-model':\n await removeProviderModelFlow(ctx, providerId);\n break;\n case 'edit-provider':\n await editProviderFlow(ctx, providerId);\n break;\n case 'delete-provider': {\n const confirm = await askSelect(ctx, `Delete ${provider.name}?`, [\n { label: 'Delete', value: 'delete', description: 'This cannot be undone' },\n ]);\n if (confirm !== 'delete') return;\n const latest = loadSettings();\n removeCustomProviderFromSettings(latest, providerId);\n saveSettings(latest);\n ctx.showInfo(`Deleted custom provider: ${provider.name}`);\n break;\n }\n default:\n break;\n }\n}\n\nexport async function handleCustomProvidersCommand(ctx: SlashCommandContext): Promise<void> {\n const settings = loadSettings();\n const providerOptions = settings.customProviders.map(provider => {\n const providerId = getCustomProviderId(provider.name);\n const modelCount = provider.models.length;\n return {\n label: provider.name,\n value: providerId,\n description: `${provider.url} · ${modelCount} model${modelCount === 1 ? '' : 's'} · ${provider.apiKey ? 'api key set' : 'no api key'}`,\n };\n });\n\n const action = await askSelect(ctx, 'Custom providers', [\n { label: 'Add provider', value: 'add-provider', description: 'Create an OpenAI-compatible provider' },\n ...providerOptions,\n ]);\n\n if (!action) return;\n if (action === 'add-provider') {\n await createProviderFlow(ctx);\n return;\n }\n\n await manageProviderFlow(ctx, action);\n}\n","import { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { ModelSelectorComponent } from '../components/model-selector.js';\nimport type { ModelItem } from '../components/model-selector.js';\nimport { askModalQuestion } from '../modal-question.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { promptForApiKeyIfNeeded } from '../prompt-api-key.js';\nimport type { SlashCommandContext } from './types.js';\n\nconst BUILT_IN_SUBAGENT_TYPES: Array<{ id: string; label: string; description: string }> = [\n {\n id: 'explore',\n label: 'Explore',\n description: 'Read-only codebase exploration',\n },\n {\n id: 'plan',\n label: 'Plan',\n description: 'Read-only analysis and planning',\n },\n {\n id: 'execute',\n label: 'Execute',\n description: 'Task execution with write access',\n },\n];\n\nasync function showSubagentModelListForScope(\n ctx: SlashCommandContext,\n scope: 'global' | 'thread',\n agentType: string,\n agentTypeLabel: string,\n): Promise<void> {\n const availableModels = await ctx.state.controller.listAvailableModels();\n\n if (availableModels.length === 0) {\n ctx.showInfo('No models available. Check your Mastra configuration.');\n return;\n }\n\n const currentSubagentModel = ctx.state.session.subagents.model.get({ agentType });\n const scopeLabel = scope === 'global' ? `${agentTypeLabel} · Global` : `${agentTypeLabel} · Thread`;\n\n return new Promise(resolve => {\n const selector = new ModelSelectorComponent({\n tui: ctx.state.ui,\n models: availableModels,\n currentModelId: currentSubagentModel ?? undefined,\n title: `Select subagent model (${scopeLabel})`,\n onSelect: async (model: ModelItem) => {\n ctx.state.ui.hideOverlay();\n await promptForApiKeyIfNeeded(ctx.state.ui, model, ctx.authStorage);\n try {\n await ctx.state.session.subagents.model.set({ modelId: model.id, agentType });\n if (scope === 'global') {\n const settings = loadSettings();\n settings.models.subagentModels[agentType] = model.id;\n saveSettings(settings);\n }\n ctx.showInfo(`Subagent model set for ${scopeLabel}: ${model.id}`);\n } catch (err) {\n ctx.showError(`Failed to set subagent model: ${err instanceof Error ? err.message : String(err)}`);\n }\n resolve();\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(ctx.state.ui, selector, { widthPercent: 0.8, maxHeight: '60%' });\n selector.focused = true;\n });\n}\n\nasync function showSubagentScopeThenList(\n ctx: SlashCommandContext,\n agentType: string,\n agentTypeLabel: string,\n): Promise<void> {\n const scopes = [\n {\n label: 'Thread default',\n description: `Default for ${agentTypeLabel} subagents in this thread`,\n scope: 'thread' as const,\n },\n {\n label: 'Global default',\n description: `Default for ${agentTypeLabel} subagents in all threads`,\n scope: 'global' as const,\n },\n ];\n\n const answer = await askModalQuestion(ctx.state.ui, {\n question: `Select scope for ${agentTypeLabel} subagents`,\n options: scopes.map(s => ({\n label: s.label,\n description: s.description,\n })),\n });\n\n try {\n const selected = scopes.find(s => s.label === answer);\n if (selected) {\n await showSubagentModelListForScope(ctx, selected.scope, agentType, agentTypeLabel);\n }\n } catch (err) {\n ctx.showError(`Subagent selection failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction getConfiguredSubagentTypes(\n ctx: SlashCommandContext,\n): Array<{ id: string; label: string; description: string }> {\n const controllerWithConfig = ctx.state.controller as unknown as {\n config?: {\n subagents?: Array<{ id: string; name: string; description: string }>;\n };\n };\n const configuredSubagents = controllerWithConfig.config?.subagents;\n\n return configuredSubagents && configuredSubagents.length > 0\n ? configuredSubagents.map(subagent => ({\n id: subagent.id,\n label: subagent.name,\n description: subagent.description,\n }))\n : BUILT_IN_SUBAGENT_TYPES;\n}\n\nexport async function handleSubagentsCommand(ctx: SlashCommandContext): Promise<void> {\n const agentTypes = getConfiguredSubagentTypes(ctx);\n\n const answer = await askModalQuestion(ctx.state.ui, {\n question: 'Select subagent type',\n options: agentTypes.map(t => ({\n label: t.label,\n description: t.description,\n })),\n });\n\n try {\n const selected = agentTypes.find(t => t.label === answer);\n if (selected) {\n await showSubagentScopeThenList(ctx, selected.id, selected.label);\n }\n } catch (err) {\n ctx.showError(`Subagent selection failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n","/**\n * Observational Memory settings component.\n * Uses pi-tui's SettingsList for a clean settings UI with\n * threshold configuration and model selection submenus.\n *\n * Changes apply immediately — Esc closes the panel.\n */\n\nimport { Box, Container, Input, SelectList, SettingsList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, SelectItem, SettingItem, TUI } from '@earendil-works/pi-tui';\nimport { theme, getSettingsListTheme, getSelectListTheme } from '../theme.js';\nimport { ModelSelectorComponent } from './model-selector.js';\nimport type { ModelItem } from './model-selector.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface OMSettingsConfig {\n observerModelId: string;\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n cavemanObservations: boolean;\n observeAttachments: 'auto' | boolean;\n}\n\nexport interface OMSettingsCallbacks {\n onObserverModelChange: (model: ModelItem) => void | Promise<void>;\n onReflectorModelChange: (model: ModelItem) => void | Promise<void>;\n onObservationThresholdChange: (value: number) => void;\n onReflectionThresholdChange: (value: number) => void;\n onCavemanObservationsChange: (enabled: boolean) => void;\n onObserveAttachmentsChange: (value: 'auto' | boolean) => void | Promise<void>;\n onClose: () => void;\n}\n\ninterface BooleanSubmenuLabels {\n onLabel?: string;\n offLabel?: string;\n onDescription?: string;\n offDescription?: string;\n}\n\n// =============================================================================\n// Threshold presets (in tokens)\n// =============================================================================\n\nconst OBSERVATION_THRESHOLDS = [5_000, 10_000, 15_000, 20_000, 30_000, 50_000, 75_000, 100_000];\n\nconst REFLECTION_THRESHOLDS = [10_000, 20_000, 30_000, 40_000, 60_000, 80_000, 100_000, 150_000];\n\nfunction formatTokens(n: number): string {\n if (n >= 1000) return `${(n / 1000).toFixed(0)}k`;\n return String(n);\n}\n\nfunction parseTokenInput(input: string): number | null {\n const trimmed = input.trim().toLowerCase();\n if (!trimmed) return null;\n\n // Match patterns like \"30k\", \"30\", \"30000\", \"1.5k\"\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)\\s*k?$/);\n if (!match) return null;\n\n const num = parseFloat(match[1]!);\n if (isNaN(num) || num <= 0) return null;\n\n // \"30k\" → 30,000\n if (trimmed.endsWith('k')) {\n return num * 1000;\n }\n // Small numbers (< 500) assumed to be in thousands: \"30\" → 30,000\n if (num < 500) {\n return num * 1000;\n }\n // Large numbers used as-is: \"30000\" → 30,000\n return num;\n}\n\n// =============================================================================\n// Threshold Input Submenu\n// =============================================================================\n\nclass ThresholdSubmenu extends Container {\n private input: Input;\n private selectList: SelectList;\n private onDone: (value: number) => void;\n private onBack: () => void;\n private inInputMode = true;\n\n constructor(\n title: string,\n currentValue: number,\n presets: number[],\n onDone: (value: number) => void,\n onBack: () => void,\n ) {\n super();\n this.onDone = onDone;\n this.onBack = onBack;\n\n this.addChild(new Text(theme.bold(theme.fg('accent', title)), 0, 0));\n this.addChild(new Spacer(1));\n\n // Input for custom value — type a number like 30 for 30k\n this.addChild(new Text(theme.fg('muted', ' _k tokens (type a number, e.g. 30 for 30k):'), 0, 0));\n this.input = new Input();\n this.addChild(this.input);\n this.addChild(new Spacer(1));\n\n // Preset list\n this.addChild(new Text(theme.fg('muted', ' Or pick a preset:'), 0, 0));\n\n const items: SelectItem[] = presets.map(p => ({\n value: String(p),\n label: ` ${formatTokens(p)} tokens`,\n }));\n\n this.selectList = new SelectList(items, Math.min(items.length, 8), getSelectListTheme());\n\n // Pre-select current value\n const currentIndex = presets.indexOf(currentValue);\n if (currentIndex !== -1) {\n this.selectList.setSelectedIndex(currentIndex);\n }\n\n this.selectList.onSelect = (item: SelectItem) => {\n this.onDone(parseInt(item.value, 10));\n };\n this.selectList.onCancel = onBack;\n\n this.addChild(this.selectList);\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('dim', ' Enter to confirm · ↓ for presets · Esc to go back'), 0, 0));\n }\n\n handleInput(data: string): void {\n if (this.inInputMode) {\n // Enter — submit the typed value\n if (data === '\\r' || data === '\\n') {\n const parsed = parseTokenInput(this.input.getValue());\n if (parsed) {\n this.onDone(parsed);\n }\n return;\n }\n\n // Escape\n if (data === '\\x1b' || data === '\\x1b\\x1b') {\n this.onBack();\n return;\n }\n\n // Down arrow — switch to preset list\n if (data === '\\x1b[B') {\n this.inInputMode = false;\n return;\n }\n\n // Delegate to input (numbers, backspace, etc.)\n this.input.handleInput(data);\n } else {\n // In preset list mode\n // Escape — go back (handled by selectList.onCancel)\n this.selectList.handleInput(data);\n }\n }\n}\n\n// =============================================================================\n// Boolean Submenu\n// =============================================================================\n\nclass BooleanSubmenu extends SelectList {\n constructor(\n currentValue: boolean,\n onSelect: (value: boolean) => void,\n onBack: () => void,\n labels?: BooleanSubmenuLabels,\n ) {\n const items: SelectItem[] = [\n { value: 'on', label: ` ${labels?.onLabel ?? 'On'}`, description: labels?.onDescription ?? '' },\n { value: 'off', label: ` ${labels?.offLabel ?? 'Off'}`, description: labels?.offDescription ?? '' },\n ];\n super(items, items.length, getSelectListTheme());\n\n this.setSelectedIndex(currentValue ? 0 : 1);\n\n this.onSelect = (item: SelectItem) => {\n onSelect(item.value === 'on');\n };\n this.onCancel = onBack;\n }\n}\n\n// =============================================================================\n// OM Settings Component\n// =============================================================================\n\nexport class OMSettingsComponent extends Box implements Focusable {\n private settingsList: SettingsList;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(config: OMSettingsConfig, callbacks: OMSettingsCallbacks, models: ModelItem[], tui: TUI) {\n super(2, 1, (text: string) => theme.bg('overlayBg', text));\n\n // Title\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Observational Memory Settings')), 0, 0));\n this.addChild(new Spacer(1));\n\n // Build settings items\n const items: SettingItem[] = [\n {\n id: 'observer-model',\n label: 'Observer model',\n description: 'Model used for observing and summarizing message history',\n currentValue: getShortModelName(config.observerModelId),\n submenu: (_currentValue, done) =>\n new ModelSelectorComponent({\n tui,\n models,\n currentModelId: config.observerModelId,\n title: 'Observer Model',\n onSelect: async model => {\n await callbacks.onObserverModelChange(model);\n config.observerModelId = model.id;\n done(getShortModelName(model.id));\n },\n onCancel: () => done(),\n }),\n },\n {\n id: 'reflector-model',\n label: 'Reflector model',\n description: 'Model used for compressing observations when they grow too large',\n currentValue: getShortModelName(config.reflectorModelId),\n submenu: (_currentValue, done) =>\n new ModelSelectorComponent({\n tui,\n models,\n currentModelId: config.reflectorModelId,\n title: 'Reflector Model',\n onSelect: async model => {\n await callbacks.onReflectorModelChange(model);\n config.reflectorModelId = model.id;\n done(getShortModelName(model.id));\n },\n onCancel: () => done(),\n }),\n },\n {\n id: 'obs-threshold',\n label: 'Messages before observation',\n description:\n 'Message tokens before the Observer runs. ' + 'More means a larger message window per observation.',\n currentValue: formatTokens(config.observationThreshold),\n submenu: (_currentValue, done) =>\n new ThresholdSubmenu(\n 'Messages Before Observation',\n config.observationThreshold,\n OBSERVATION_THRESHOLDS,\n value => {\n config.observationThreshold = value;\n callbacks.onObservationThresholdChange(value);\n done(formatTokens(value));\n },\n () => done(),\n ),\n },\n {\n id: 'ref-threshold',\n label: 'Observations before reflection',\n description:\n 'Accumulated observation tokens before the Reflector compresses them. ' +\n 'More means less frequent compression.',\n currentValue: formatTokens(config.reflectionThreshold),\n submenu: (_currentValue, done) =>\n new ThresholdSubmenu(\n 'Observations Before Reflection',\n config.reflectionThreshold,\n REFLECTION_THRESHOLDS,\n value => {\n config.reflectionThreshold = value;\n callbacks.onReflectionThresholdChange(value);\n done(formatTokens(value));\n },\n () => done(),\n ),\n },\n {\n id: 'caveman-observations',\n label: 'Caveman observations',\n description:\n 'Optional. Use terse caveman-style compression for observations and reflections ' +\n 'instead of standard prose. Off by default; turn on if you prefer the more compact style',\n currentValue: config.cavemanObservations ? 'On' : 'Off',\n submenu: (_currentValue, done) =>\n new BooleanSubmenu(\n config.cavemanObservations,\n value => {\n config.cavemanObservations = value;\n callbacks.onCavemanObservationsChange(value);\n done(value ? 'On' : 'Off');\n },\n () => done(),\n {\n onDescription: 'Caveman-style terse compression',\n offDescription: 'Standard prose observations',\n },\n ),\n },\n {\n id: 'observe-attachments',\n label: 'Observe attachments',\n description:\n 'Forward image and file attachments to the Observer LLM. ' + 'Auto checks model capabilities to decide',\n currentValue: formatAttachmentValue(config.observeAttachments),\n submenu: (_currentValue, done) => {\n const items: SelectItem[] = [\n { value: 'auto', label: ' Auto', description: 'Use model capabilities to decide' },\n { value: 'on', label: ' On', description: 'Always forward attachments' },\n { value: 'off', label: ' Off', description: 'Drop attachments (placeholder text only)' },\n ];\n const list = new SelectList(items, items.length, getSelectListTheme());\n const currentIndex = config.observeAttachments === 'auto' ? 0 : config.observeAttachments ? 1 : 2;\n list.setSelectedIndex(currentIndex);\n list.onSelect = async (item: SelectItem) => {\n const value: 'auto' | boolean = item.value === 'auto' ? 'auto' : item.value === 'on';\n try {\n await callbacks.onObserveAttachmentsChange(value);\n config.observeAttachments = value;\n done(formatAttachmentValue(value));\n } catch (error) {\n console.error('Failed to update observe attachments setting:', error);\n }\n };\n list.onCancel = () => done();\n return list;\n },\n },\n ];\n\n this.settingsList = new SettingsList(\n items,\n 11,\n getSettingsListTheme(),\n (_id, _newValue) => {\n // All changes handled via submenu callbacks\n },\n callbacks.onClose,\n );\n\n this.addChild(this.settingsList);\n }\n\n handleInput(data: string): void {\n this.settingsList.handleInput(data);\n }\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction getShortModelName(modelId: string): string {\n if (!modelId) return '(none)';\n const parts = modelId.split('/');\n return parts.length > 1 ? parts.slice(1).join('/') : modelId;\n}\n\nfunction formatAttachmentValue(value: 'auto' | boolean): string {\n if (value === 'auto') return 'Auto';\n return value ? 'On' : 'Off';\n}\n","import { applyOmRoleOverride, persistOmObserveAttachments } from '@mastra/code-sdk/onboarding/om-settings';\nimport { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { OMSettingsComponent } from '../components/om-settings.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { promptForApiKeyIfNeeded } from '../prompt-api-key.js';\nimport type { SlashCommandContext } from './types.js';\n\n// Re-exported for existing importers/tests; the implementations live in\n// onboarding/om-settings.ts so non-TUI surfaces (web routes) can share them.\nexport { applyOmRoleOverride, persistOmObserveAttachments };\n\nfunction persistOmRoleOverride(\n role: 'observer' | 'reflector',\n modelId: string,\n otherRoleCurrentModelId: string | null,\n): void {\n const settings = loadSettings();\n applyOmRoleOverride(settings, role, modelId, otherRoleCurrentModelId);\n saveSettings(settings);\n}\n\nfunction persistOmThresholds({\n observationThreshold,\n reflectionThreshold,\n}: {\n observationThreshold?: number;\n reflectionThreshold?: number;\n}): void {\n const settings = loadSettings();\n if (observationThreshold !== undefined) {\n settings.models.omObservationThreshold = observationThreshold;\n }\n if (reflectionThreshold !== undefined) {\n settings.models.omReflectionThreshold = reflectionThreshold;\n }\n saveSettings(settings);\n}\n\nfunction persistOmCavemanObservations(enabled: boolean): void {\n const settings = loadSettings();\n settings.models.omCavemanObservations = enabled;\n saveSettings(settings);\n}\n\nexport async function handleOMCommand(ctx: SlashCommandContext): Promise<void> {\n const availableModels = await ctx.state.controller.listAvailableModels();\n\n const agentControllerState = ctx.state.session.state.get() as Record<string, unknown> | undefined;\n const config = {\n observerModelId: ctx.state.session.om.observer.modelId() ?? '',\n reflectorModelId: ctx.state.session.om.reflector.modelId() ?? '',\n observationThreshold: ctx.state.session.om.observer.threshold() ?? 30_000,\n reflectionThreshold: ctx.state.session.om.reflector.threshold() ?? 40_000,\n cavemanObservations: (agentControllerState?.cavemanObservations as boolean | undefined) ?? false,\n observeAttachments: (agentControllerState?.observeAttachments as 'auto' | boolean | undefined) ?? 'auto',\n };\n\n return new Promise<void>(resolve => {\n const settings = new OMSettingsComponent(\n config,\n {\n onObserverModelChange: async model => {\n await promptForApiKeyIfNeeded(ctx.state.ui, model, ctx.authStorage);\n const currentReflector = ctx.state.session.om.reflector.modelId() ?? null;\n await ctx.state.session.om.observer.switchModel({ modelId: model.id });\n persistOmRoleOverride('observer', model.id, currentReflector);\n ctx.showInfo(`Observer model → ${model.id}`);\n },\n onReflectorModelChange: async model => {\n await promptForApiKeyIfNeeded(ctx.state.ui, model, ctx.authStorage);\n const currentObserver = ctx.state.session.om.observer.modelId() ?? null;\n await ctx.state.session.om.reflector.switchModel({ modelId: model.id });\n persistOmRoleOverride('reflector', model.id, currentObserver);\n ctx.showInfo(`Reflector model → ${model.id}`);\n },\n onObservationThresholdChange: async value => {\n await ctx.state.session.state.set({ observationThreshold: value } as any);\n await ctx.state.session.thread.setSetting({ key: 'observationThreshold', value });\n persistOmThresholds({ observationThreshold: value });\n },\n onReflectionThresholdChange: async value => {\n await ctx.state.session.state.set({ reflectionThreshold: value } as any);\n await ctx.state.session.thread.setSetting({ key: 'reflectionThreshold', value });\n persistOmThresholds({ reflectionThreshold: value });\n },\n onCavemanObservationsChange: async enabled => {\n await ctx.state.session.state.set({ cavemanObservations: enabled } as any);\n await ctx.state.session.thread.setSetting({ key: 'cavemanObservations', value: enabled });\n persistOmCavemanObservations(enabled);\n ctx.showInfo(`Caveman observations → ${enabled ? 'on' : 'off'}`);\n },\n onObserveAttachmentsChange: async value => {\n await ctx.state.session.state.set({ observeAttachments: value } as any);\n await ctx.state.session.thread.setSetting({ key: 'observeAttachments', value });\n persistOmObserveAttachments(value);\n const label = value === 'auto' ? 'auto' : value ? 'on' : 'off';\n ctx.showInfo(`Observe attachments → ${label}`);\n },\n onClose: () => {\n ctx.state.ui.hideOverlay();\n ctx.updateStatusLine();\n resolve();\n },\n },\n availableModels,\n ctx.state.ui,\n );\n\n showModalOverlay(ctx.state.ui, settings, { widthPercent: 0.8, maxHeight: '70%' });\n settings.focused = true;\n });\n}\n","/**\n * General settings component.\n * Uses pi-tui's SettingsList for a clean overlay with\n * notifications, YOLO mode, and thinking level configuration.\n *\n * Changes apply immediately — Esc closes the panel.\n */\n\nimport { Box, Container, SelectList, SettingsList, Spacer, Text, matchesKey } from '@earendil-works/pi-tui';\nimport type { Focusable, SelectItem, SettingItem } from '@earendil-works/pi-tui';\nimport type { StorageBackend } from '@mastra/code-sdk/onboarding/settings';\nimport type { NotificationMode } from '../notify.js';\nimport { theme, getSettingsListTheme, getSelectListTheme } from '../theme.js';\nimport { MaskedInput } from './masked-input.js';\nimport { getThinkingLevelsForModel } from './thinking-settings.js';\n\n// =============================================================================\n// Types\n// =============================================================================\nexport interface SettingsConfig {\n notifications: NotificationMode;\n yolo: boolean;\n thinkingLevel: string;\n currentModelId: string;\n escapeAsCancel: boolean;\n quietMode: boolean;\n quietModeMaxToolPreviewLines: number;\n storageBackend: StorageBackend;\n pgConnectionString: string;\n libsqlUrl: string;\n experimentalGithubSignals: boolean;\n}\n\nexport interface SettingsCallbacks {\n onNotificationsChange: (mode: NotificationMode) => void;\n onYoloChange: (enabled: boolean) => void;\n onThinkingLevelChange: (level: string) => void;\n onEscapeAsCancelChange: (enabled: boolean) => void;\n onQuietModeChange: (enabled: boolean) => void;\n onQuietModeMaxToolPreviewLinesChange: (lines: number) => void;\n onStorageBackendChange: (backend: StorageBackend, connectionUrl?: string) => void;\n onExperimentalGithubSignalsChange: (enabled: boolean) => boolean | void | Promise<boolean | void>;\n onApiKeys?: () => void;\n onClose: () => void;\n}\n\n// =============================================================================\n// Select Submenu (reusable for any enum-style setting)\n// =============================================================================\n\nclass SelectSubmenu extends SelectList {\n constructor(\n items: SelectItem[],\n currentValue: string,\n onSelect: (value: string) => void | Promise<void>,\n onBack: () => void,\n ) {\n super(items, Math.min(items.length, 8), getSelectListTheme());\n\n const currentIndex = items.findIndex(i => i.value === currentValue);\n if (currentIndex !== -1) {\n this.setSelectedIndex(currentIndex);\n }\n\n this.onSelect = async (item: SelectItem) => {\n await onSelect(item.value);\n };\n this.onCancel = onBack;\n }\n}\n\n// =============================================================================\n// Storage Backend Submenu (backend selector → optional PG connection input)\n// =============================================================================\n\nclass StorageBackendSubmenu extends Container {\n private phase: 'select' | 'connection' = 'select';\n private pendingBackend: StorageBackend = 'libsql';\n private selectList: SelectList;\n private input!: MaskedInput;\n private onDone: (backend: StorageBackend, connectionUrl?: string) => void;\n private onBack: () => void;\n private currentPgConnectionString: string;\n private currentLibsqlUrl: string;\n\n constructor(\n currentBackend: StorageBackend,\n currentPgConnectionString: string,\n currentLibsqlUrl: string,\n onDone: (backend: StorageBackend, connectionUrl?: string) => void,\n onBack: () => void,\n ) {\n super();\n this.onDone = onDone;\n this.onBack = onBack;\n this.currentPgConnectionString = currentPgConnectionString;\n this.currentLibsqlUrl = currentLibsqlUrl;\n\n // Phase 1: backend selection\n const items: SelectItem[] = [\n {\n value: 'libsql',\n label: ' LibSQL',\n description: 'Local file-based SQLite or remote Turso URL',\n },\n {\n value: 'pg',\n label: ' PostgreSQL',\n description: 'Remote PostgreSQL (requires connection string)',\n },\n ];\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n const currentIndex = items.findIndex(i => i.value === currentBackend);\n if (currentIndex !== -1) this.selectList.setSelectedIndex(currentIndex);\n\n this.selectList.onSelect = (item: SelectItem) => {\n this.pendingBackend = item.value as StorageBackend;\n this.showConnectionInput();\n };\n this.selectList.onCancel = onBack;\n\n this.addChild(this.selectList);\n }\n\n private showConnectionInput(): void {\n this.phase = 'connection';\n this.clear();\n\n if (this.pendingBackend === 'pg') {\n this.addChild(new Text(theme.bold(theme.fg('accent', 'PostgreSQL Connection')), 0, 0));\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', 'Enter a connection string:'), 0, 0));\n this.addChild(new Text(theme.fg('dim', 'e.g. postgresql://user:pass@localhost:5432/mydb'), 0, 0));\n } else {\n this.addChild(new Text(theme.bold(theme.fg('accent', 'LibSQL Connection')), 0, 0));\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', 'Enter a URL or leave empty for default local file:'), 0, 0));\n this.addChild(new Text(theme.fg('dim', 'e.g. libsql://your-db.turso.io'), 0, 0));\n }\n this.addChild(new Spacer(1));\n\n this.input = new MaskedInput();\n const currentValue = this.pendingBackend === 'pg' ? this.currentPgConnectionString : this.currentLibsqlUrl;\n if (currentValue) {\n this.input.setValue(currentValue);\n }\n this.addChild(this.input);\n\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('dim', 'Enter to save · Esc to go back'), 0, 0));\n }\n\n handleInput(data: string): void {\n if (this.phase === 'select') {\n this.selectList.handleInput(data);\n return;\n }\n\n // Connection string input phase\n if (matchesKey(data, 'enter') || data === '\\r' || data === '\\n') {\n const value = this.input.getValue().trim();\n if (this.pendingBackend === 'pg') {\n // PG requires a connection string\n if (value) {\n this.onDone('pg', value);\n }\n } else {\n // LibSQL: empty = default local file, non-empty = custom URL\n this.onDone('libsql', value || undefined);\n }\n return;\n }\n\n if (matchesKey(data, 'escape') || data === '\\x1b' || data === '\\x1b\\x1b') {\n this.onBack();\n return;\n }\n\n this.input.handleInput(data);\n }\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction quietPreviewLinesLabel(lines: number): string {\n return lines === 0 ? 'None' : `${lines} line${lines === 1 ? '' : 's'}`;\n}\n\nfunction storageLabel(config: SettingsConfig): string {\n if (config.storageBackend === 'pg') return 'PostgreSQL';\n if (config.libsqlUrl) return `LibSQL (${config.libsqlUrl})`;\n return 'LibSQL (local file)';\n}\n\n// =============================================================================\n// Settings Component\n// =============================================================================\n\nexport class SettingsComponent extends Box implements Focusable {\n private settingsList: SettingsList;\n private _focused = false;\n\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(config: SettingsConfig, callbacks: SettingsCallbacks) {\n super(4, 2, (text: string) => theme.bg('overlayBg', text));\n\n // Title\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Settings')), 0, 0));\n this.addChild(new Spacer(1));\n\n // Build settings items\n const notificationModes: {\n value: NotificationMode;\n label: string;\n desc: string;\n }[] = [\n { value: 'off', label: 'Off', desc: 'No notifications' },\n { value: 'bell', label: 'Bell', desc: 'Terminal bell (\\\\x07)' },\n { value: 'system', label: 'System', desc: 'Native OS notification' },\n { value: 'both', label: 'Both', desc: 'Bell + system notification' },\n ];\n\n const thinkingLevels = getThinkingLevelsForModel(config.currentModelId).map(level => ({\n value: level.id,\n label: level.label,\n desc: level.description,\n }));\n\n const getNotifLabel = (mode: NotificationMode) => notificationModes.find(m => m.value === mode)?.label ?? mode;\n\n const getThinkingLabel = (level: string) => thinkingLevels.find(l => l.value === level)?.label ?? level;\n\n const items: SettingItem[] = [\n {\n id: 'notifications',\n label: 'Notifications',\n description: 'How to alert when the agent needs attention',\n currentValue: getNotifLabel(config.notifications),\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n notificationModes.map(m => ({\n value: m.value,\n label: ` ${m.label}`,\n description: m.desc,\n })),\n config.notifications,\n value => {\n config.notifications = value as NotificationMode;\n callbacks.onNotificationsChange(config.notifications);\n done(getNotifLabel(config.notifications));\n },\n () => done(),\n ),\n },\n {\n id: 'yolo',\n label: 'YOLO mode',\n description: 'Auto-approve all tool calls without confirmation',\n currentValue: config.yolo ? 'On' : 'Off',\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n [\n {\n value: 'on',\n label: ' On',\n description: 'Auto-approve all tools',\n },\n {\n value: 'off',\n label: ' Off',\n description: 'Require approval for tools',\n },\n ],\n config.yolo ? 'on' : 'off',\n value => {\n config.yolo = value === 'on';\n callbacks.onYoloChange(config.yolo);\n done(config.yolo ? 'On' : 'Off');\n },\n () => done(),\n ),\n },\n {\n id: 'thinking',\n label: 'Thinking level',\n description: 'Reasoning depth level',\n currentValue: getThinkingLabel(config.thinkingLevel),\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n thinkingLevels.map(l => ({\n value: l.value,\n label: ` ${l.label}`,\n description: l.desc,\n })),\n config.thinkingLevel,\n value => {\n config.thinkingLevel = value;\n callbacks.onThinkingLevelChange(value);\n done(getThinkingLabel(value));\n },\n () => done(),\n ),\n },\n {\n id: 'escapeAsCancel',\n label: 'Escape cancels',\n description: 'Use Escape to cancel/clear (Ctrl+C always works).',\n currentValue: config.escapeAsCancel ? 'On' : 'Off',\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n [\n {\n value: 'on',\n label: ' On',\n description: 'Escape clears input / aborts',\n },\n {\n value: 'off',\n label: ' Off',\n description: 'Only Ctrl+C clears / aborts',\n },\n ],\n config.escapeAsCancel ? 'on' : 'off',\n value => {\n config.escapeAsCancel = value === 'on';\n callbacks.onEscapeAsCancelChange(config.escapeAsCancel);\n done(config.escapeAsCancel ? 'On' : 'Off');\n },\n () => done(),\n ),\n },\n {\n id: 'quietMode',\n label: 'Quiet mode',\n description: 'Render tool calls compactly and collapse subagent output after completion.',\n currentValue: config.quietMode ? 'On' : 'Off',\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n [\n {\n value: 'on',\n label: ' On',\n description: 'Compact older tool calls and completed subagents',\n },\n {\n value: 'off',\n label: ' Off',\n description: 'Keep normal tool and subagent rendering',\n },\n ],\n config.quietMode ? 'on' : 'off',\n value => {\n config.quietMode = value === 'on';\n callbacks.onQuietModeChange(config.quietMode);\n done(config.quietMode ? 'On' : 'Off');\n },\n () => done(),\n ),\n },\n ...(config.quietMode\n ? [\n {\n id: 'quietModeMaxToolPreviewLines',\n label: 'Quiet mode tool preview lines',\n description: 'Maximum compact tool detail preview lines. Set to None to hide previews.',\n currentValue: quietPreviewLinesLabel(config.quietModeMaxToolPreviewLines),\n submenu: (_currentValue: string, done: (value?: string) => void) =>\n new SelectSubmenu(\n [0, 1, 2, 4, 8].map(lines => ({\n value: String(lines),\n label: ` ${quietPreviewLinesLabel(lines)}`,\n description:\n lines === 0\n ? 'Hide compact tool detail previews'\n : `Show up to ${lines} preview line${lines === 1 ? '' : 's'}`,\n })),\n String(config.quietModeMaxToolPreviewLines),\n value => {\n config.quietModeMaxToolPreviewLines = Number(value);\n callbacks.onQuietModeMaxToolPreviewLinesChange(config.quietModeMaxToolPreviewLines);\n done(quietPreviewLinesLabel(config.quietModeMaxToolPreviewLines));\n },\n () => done(),\n ),\n },\n ]\n : []),\n {\n id: 'experimentalGithubSignals',\n label: 'Experimental GitHub signals',\n description: 'Enable local-first GitHub PR subscriptions with gitcrawl (restart required).',\n currentValue: config.experimentalGithubSignals ? 'On' : 'Off',\n submenu: (_currentValue, done) =>\n new SelectSubmenu(\n [\n {\n value: 'on',\n label: ' On',\n description: 'Enable GitHub signal processor and PR subscription tools',\n },\n {\n value: 'off',\n label: ' Off',\n description: 'Disable GitHub signal processor and tools',\n },\n ],\n config.experimentalGithubSignals ? 'on' : 'off',\n async value => {\n const nextValue = value === 'on';\n const accepted = await callbacks.onExperimentalGithubSignalsChange(nextValue);\n config.experimentalGithubSignals = accepted === false ? !nextValue : nextValue;\n done(config.experimentalGithubSignals ? 'On' : 'Off');\n },\n () => done(),\n ),\n },\n {\n id: 'storageBackend',\n label: 'Storage backend',\n description: 'Database backend for threads, memory, and agent data (restart required)',\n currentValue: storageLabel(config),\n submenu: (_currentValue, done) =>\n new StorageBackendSubmenu(\n config.storageBackend,\n config.pgConnectionString,\n config.libsqlUrl,\n (backend: StorageBackend, connectionUrl?: string) => {\n config.storageBackend = backend;\n if (backend === 'pg' && connectionUrl !== undefined) {\n config.pgConnectionString = connectionUrl;\n } else if (backend === 'libsql') {\n config.libsqlUrl = connectionUrl ?? '';\n }\n callbacks.onStorageBackendChange(backend, connectionUrl);\n done(storageLabel(config));\n },\n () => done(),\n ),\n },\n ];\n\n if (callbacks.onApiKeys) {\n items.push({\n id: 'apiKeys',\n label: 'API Keys',\n description: 'Add, update, or remove API keys for model providers',\n currentValue: 'Manage →',\n submenu: (_currentValue, done) => {\n done();\n callbacks.onApiKeys!();\n return new Text('', 0, 0);\n },\n });\n }\n\n this.settingsList = new SettingsList(\n items,\n 10,\n getSettingsListTheme(),\n (_id, _newValue) => {\n // All changes handled via submenu callbacks\n },\n callbacks.onClose,\n );\n\n this.addChild(this.settingsList);\n }\n\n handleInput(data: string): void {\n this.settingsList.handleInput(data);\n }\n}\n","/**\n * /api-keys command: manage API keys for model providers.\n * Lists known providers with their key status and allows adding, updating, or removing keys.\n */\n\nimport { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SelectItem } from '@earendil-works/pi-tui';\n\nimport { ApiKeyDialogComponent } from '../components/api-key-dialog.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { getSelectListTheme, theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\ninterface ProviderInfo {\n provider: string;\n envVar?: string;\n source: 'oauth' | 'env' | 'stored' | 'none';\n}\n\n/**\n * OAuth credentials are stored under the auth provider id, which differs from\n * the catalog provider id for OpenAI (stored as `openai-codex`).\n */\nfunction getAuthProviderId(provider: string): string {\n return provider === 'openai' ? 'openai-codex' : provider;\n}\n\n/**\n * Build a deduplicated list of providers from available models,\n * annotated with their current key source.\n */\nexport function getProviderList(\n ctx: SlashCommandContext,\n models: { provider: string; hasApiKey: boolean; apiKeyEnvVar?: string }[],\n): ProviderInfo[] {\n const seen = new Map<string, ProviderInfo>();\n\n for (const model of models) {\n if (seen.has(model.provider)) continue;\n\n let source: ProviderInfo['source'] = 'none';\n if (ctx.authStorage?.isLoggedIn(getAuthProviderId(model.provider))) {\n source = 'oauth';\n } else if (ctx.authStorage?.hasStoredApiKey(model.provider)) {\n source = 'stored';\n } else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {\n source = 'env';\n } else if (model.hasApiKey) {\n source = 'env';\n }\n\n seen.set(model.provider, {\n provider: model.provider,\n envVar: model.apiKeyEnvVar,\n source,\n });\n }\n\n return Array.from(seen.values()).sort((a, b) => a.provider.localeCompare(b.provider));\n}\n\nfunction statusLabel(info: ProviderInfo): string {\n switch (info.source) {\n case 'oauth':\n return theme.fg('success', '✓') + theme.fg('dim', ' (oauth)');\n case 'env':\n return theme.fg('success', '✓') + theme.fg('dim', ' (env)');\n case 'stored':\n return theme.fg('success', '✓') + theme.fg('dim', ' (stored)');\n case 'none':\n return theme.fg('error', '✗') + theme.fg('dim', ' (not set)');\n }\n}\n\nfunction buildItems(providers: ProviderInfo[]): SelectItem[] {\n return providers.map(info => ({\n value: info.provider,\n label: ` ${info.provider} ${statusLabel(info)}${info.envVar ? theme.fg('dim', ` ${info.envVar}`) : ''}`,\n }));\n}\n\nexport async function handleApiKeysCommand(ctx: SlashCommandContext): Promise<void> {\n let models = await ctx.state.controller.listAvailableModels();\n let providers = getProviderList(ctx, models);\n\n if (providers.length === 0) {\n ctx.showInfo('No model providers found.');\n return;\n }\n\n return new Promise<void>(resolve => {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', 'API Keys')), 0, 0));\n container.addChild(new Spacer(1));\n\n const detailText = new Text('', 0, 0);\n\n // Track which provider is currently highlighted\n let currentSelection = providers[0]!.provider;\n\n const updateDetail = (providerName: string) => {\n const info = providers.find(p => p.provider === providerName);\n if (!info) return;\n if (info.source === 'oauth') {\n detailText.setText(theme.fg('dim', ' Authenticated via OAuth. Press Enter to add an API key override.'));\n } else if (info.source === 'env') {\n detailText.setText(\n theme.fg('dim', ' Key set via environment variable. Press Enter to store a local override.'),\n );\n } else if (info.source === 'stored') {\n detailText.setText(theme.fg('dim', ' Key stored locally. Press Enter to update or Delete to remove.'));\n } else {\n detailText.setText(theme.fg('dim', ' No key configured. Press Enter to add one.'));\n }\n ctx.state.ui.requestRender();\n };\n\n // Build a SelectList with all event handlers wired up.\n // Called on initial render and again after save/remove to refresh status labels.\n let selectList: SelectList;\n const buildSelectList = (): SelectList => {\n const items = buildItems(providers);\n const list = new SelectList(items, Math.min(items.length, 15), getSelectListTheme());\n\n list.onSelect = (item: SelectItem) => {\n const info = providers.find(p => p.provider === item.value);\n if (!info) return;\n\n showKeyDialog(info);\n };\n\n list.onCancel = () => {\n ctx.state.ui.hideOverlay();\n resolve();\n };\n\n list.onSelectionChange = (item: SelectItem) => {\n currentSelection = item.value;\n updateDetail(item.value);\n };\n\n // Handle Delete key to remove stored keys\n const originalHandleInput = list.handleInput.bind(list);\n list.handleInput = async (data: string) => {\n // Delete or Backspace\n if (data === '\\x7f' || data === '\\x1b[3~') {\n const info = providers.find(p => p.provider === currentSelection);\n if (info?.source === 'stored' && ctx.authStorage) {\n const storedKey = ctx.authStorage.getStoredApiKey(info.provider);\n ctx.authStorage.remove(`apikey:${info.provider}`);\n if (info.envVar && process.env[info.envVar] === storedKey) {\n delete process.env[info.envVar];\n }\n ctx.state.controller.invalidateAvailableModelsCache();\n models = await ctx.state.controller.listAvailableModels();\n providers = getProviderList(ctx, models);\n ctx.showInfo(`API key removed for ${info.provider}`);\n rebuildList();\n } else if (info?.source === 'env') {\n ctx.showInfo(\n `${info.provider} key is set via environment variable${info.envVar ? ` (${info.envVar})` : ''}. Remove it from your shell environment to unset.`,\n );\n }\n return;\n }\n originalHandleInput(data);\n };\n\n return list;\n };\n\n const rebuildList = () => {\n const selectedIdx = Math.max(\n 0,\n providers.findIndex(p => p.provider === currentSelection),\n );\n container.clear();\n container.addChild(new Text(theme.bold(theme.fg('accent', 'API Keys')), 0, 0));\n container.addChild(new Spacer(1));\n selectList = buildSelectList();\n selectList.setSelectedIndex(selectedIdx);\n currentSelection = providers[selectedIdx]?.provider ?? providers[0]!.provider;\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(detailText);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter add/update · Delete remove · Esc close'), 0, 0));\n updateDetail(currentSelection);\n ctx.state.ui.requestRender();\n };\n\n const showKeyDialog = (info: ProviderInfo) => {\n const dialog = new ApiKeyDialogComponent({\n providerName: info.provider,\n apiKeyEnvVar: info.envVar,\n onSubmit: (key: string) => {\n ctx.state.ui.hideOverlay();\n if (ctx.authStorage) {\n ctx.authStorage.setStoredApiKey(info.provider, key, info.envVar);\n ctx.showInfo(`API key saved for ${info.provider}`);\n providers = getProviderList(ctx, models);\n rebuildList();\n } else {\n ctx.showError('Unable to save API key: storage unavailable');\n }\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n },\n });\n\n showModalOverlay(ctx.state.ui, dialog, { widthPercent: 0.7, maxHeight: '50%' });\n dialog.focused = true;\n };\n\n selectList = buildSelectList();\n container.addChild(selectList);\n container.addChild(new Spacer(1));\n container.addChild(detailText);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter add/update · Delete remove · Esc close'), 0, 0));\n\n updateDetail(providers[0]!.provider);\n\n const modal = container as Box & { handleInput: (data: string) => void };\n modal.handleInput = (data: string) => selectList.handleInput(data);\n showModalOverlay(ctx.state.ui, modal, { maxHeight: '75%' });\n });\n}\n","import { execFile, spawn } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { Box, Spacer, Text, matchesKey } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport type { StorageBackend, ThinkingLevelSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { SettingsComponent } from '../components/settings.js';\nimport type { IToolExecutionComponent } from '../components/tool-execution-interface.js';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { NotificationMode } from '../notify.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { handleApiKeysCommand } from './api-keys.js';\nimport type { SlashCommandContext } from './types.js';\n\nfunction getCurrentModeColor(ctx: SlashCommandContext): string | undefined {\n const color = ctx.state.session.mode.resolve().metadata?.color;\n return typeof color === 'string' ? color : undefined;\n}\n\nfunction commandExists(command: string): Promise<boolean> {\n return new Promise(resolve => {\n execFile('/bin/sh', ['-lc', `command -v ${command}`], error => resolve(!error));\n });\n}\n\nclass GitcrawlSetupProgress extends Box {\n private lines: string[] = [];\n private _focused = false;\n\n constructor(\n private title: string,\n private command: string,\n private onCancel: () => void,\n ) {\n super(2, 1);\n this.rebuild();\n }\n\n get focused(): boolean {\n return this._focused;\n }\n\n set focused(value: boolean) {\n this._focused = value;\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || data === '\\x1b' || data === '\\x1b\\x1b') {\n this.onCancel();\n }\n }\n\n addOutput(chunk: Buffer | string): void {\n const text = chunk.toString();\n const lines = text\n .split(/\\r?\\n/)\n .map(line => line.trimEnd())\n .filter(Boolean);\n this.lines = [...this.lines, ...lines].slice(-4);\n this.rebuild();\n }\n\n private rebuild(): void {\n this.clear();\n this.addChild(new Text(this.title, 0, 0));\n this.addChild(new Text(this.command, 0, 0));\n this.addChild(new Text('Press Esc to cancel.', 0, 0));\n this.addChild(new Spacer(1));\n const output = this.lines.length > 0 ? this.lines : ['Waiting for Homebrew output...'];\n for (const line of output) {\n this.addChild(new Text(line, 0, 0));\n }\n }\n}\n\nfunction runGitcrawlSetupCommand(\n tui: TUI,\n title: string,\n command: string,\n executable: string,\n args: string[],\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(executable, args, { stdio: ['ignore', 'pipe', 'pipe'] });\n let settled = false;\n const finish = (callback: () => void) => {\n if (settled) return;\n settled = true;\n overlay.hide();\n callback();\n };\n const progress = new GitcrawlSetupProgress(title, command, () => {\n child.kill('SIGTERM');\n finish(() => reject(new Error(`${title} cancelled`)));\n });\n const overlay = showModalOverlay(tui, progress, { maxHeight: '50%' });\n overlay.focus();\n\n child.stdout.on('data', chunk => {\n progress.addOutput(chunk);\n tui.requestRender();\n });\n child.stderr.on('data', chunk => {\n progress.addOutput(chunk);\n tui.requestRender();\n });\n child.on('error', error => finish(() => reject(error)));\n child.on('close', code => {\n finish(() => {\n if (code === 0) resolve();\n else reject(new Error(`${command} exited with code ${code}`));\n });\n });\n });\n}\n\nfunction installGitcrawl(tui: TUI): Promise<void> {\n return runGitcrawlSetupCommand(tui, 'Installing gitcrawl', 'brew install openclaw/tap/gitcrawl', 'brew', [\n 'install',\n 'openclaw/tap/gitcrawl',\n ]);\n}\n\nfunction gitcrawlConfigPath(): string {\n return join(homedir(), '.config', 'gitcrawl', 'config.toml');\n}\n\nasync function gitcrawlConfigExists(): Promise<boolean> {\n try {\n await access(gitcrawlConfigPath());\n return true;\n } catch {\n return false;\n }\n}\n\nfunction initGitcrawl(tui: TUI): Promise<void> {\n return runGitcrawlSetupCommand(tui, 'Configuring gitcrawl', 'gitcrawl init --json', 'gitcrawl', ['init', '--json']);\n}\n\nasync function ensureGitcrawlInstalled(ctx: SlashCommandContext): Promise<boolean> {\n if (await commandExists('gitcrawl')) return true;\n\n const answer = await askModalQuestion(ctx.state.ui, {\n question: 'gitcrawl is required for GitHub signals. Install it with Homebrew now?',\n options: [\n { label: 'Install', description: 'Run: brew install openclaw/tap/gitcrawl' },\n { label: 'Cancel', description: 'Leave GitHub signals disabled' },\n ],\n });\n if (answer !== 'Install') return false;\n\n await installGitcrawl(ctx.state.ui);\n return true;\n}\n\nasync function ensureGitcrawlConfigured(ctx: SlashCommandContext): Promise<boolean> {\n if (await gitcrawlConfigExists()) return true;\n\n await initGitcrawl(ctx.state.ui);\n return true;\n}\n\nasync function ensureGitcrawlReady(ctx: SlashCommandContext): Promise<boolean> {\n try {\n return (await ensureGitcrawlInstalled(ctx)) && (await ensureGitcrawlConfigured(ctx));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.endsWith(' cancelled')) ctx.showInfo(`${message}.`);\n else ctx.showError(`Failed to set up gitcrawl: ${message}`);\n return false;\n }\n}\n\nfunction applyQuietModeToRenderedTools(ctx: SlashCommandContext, enabled: boolean, previewLineLimit: number): void {\n const tools = ctx.state.allToolComponents.filter(\n (tool): tool is IToolExecutionComponent => typeof tool.setQuietModeDisplay === 'function',\n );\n\n tools.forEach(tool => {\n tool.setCompactToolModeColor?.(getCurrentModeColor(ctx));\n tool.setQuietModeDisplay?.(enabled ? 'quiet' : 'normal');\n tool.setQuietPreviewLineLimit?.(previewLineLimit);\n });\n\n ctx.state.ui.requestRender();\n}\n\nexport async function handleSettingsCommand(ctx: SlashCommandContext): Promise<void> {\n const state = ctx.state.session.state.get() as any;\n const globalSettings = loadSettings();\n const config = {\n notifications: (state?.notifications ?? 'off') as NotificationMode,\n yolo: state?.yolo === true,\n thinkingLevel: (state?.thinkingLevel ?? 'off') as string,\n currentModelId: ctx.state.session.model.get() ?? '',\n escapeAsCancel: ctx.state.editor.escapeEnabled,\n quietMode: globalSettings.preferences.quietMode,\n quietModeMaxToolPreviewLines: globalSettings.preferences.quietModeMaxToolPreviewLines,\n storageBackend: globalSettings.storage.backend,\n pgConnectionString: globalSettings.storage.pg?.connectionString ?? '',\n libsqlUrl: globalSettings.storage.libsql?.url ?? '',\n experimentalGithubSignals: globalSettings.signals.experimentalGithubSignals,\n };\n\n return new Promise<void>(resolve => {\n const settings = new SettingsComponent(config, {\n onNotificationsChange: async mode => {\n await ctx.state.session.state.set({ notifications: mode });\n ctx.showInfo(`Notifications: ${mode}`);\n },\n onYoloChange: async enabled => {\n await ctx.state.session.state.set({ yolo: enabled } as any);\n },\n onThinkingLevelChange: async level => {\n await ctx.state.session.state.set({ thinkingLevel: level } as any);\n const current = loadSettings();\n current.preferences.thinkingLevel = level as ThinkingLevelSetting;\n saveSettings(current);\n },\n onEscapeAsCancelChange: async enabled => {\n ctx.state.editor.escapeEnabled = enabled;\n await ctx.state.session.state.set({ escapeAsCancel: enabled });\n await ctx.state.session.thread.setSetting({ key: 'escapeAsCancel', value: enabled });\n },\n onQuietModeChange: enabled => {\n const current = loadSettings();\n current.preferences.quietMode = enabled;\n current.onboarding.quietModePreferenceSelected = true;\n saveSettings(current);\n ctx.state.quietMode = enabled;\n ctx.state.taskProgress?.setQuietMode(enabled);\n applyQuietModeToRenderedTools(ctx, enabled, ctx.state.quietModeMaxToolPreviewLines);\n },\n onQuietModeMaxToolPreviewLinesChange: lines => {\n const current = loadSettings();\n current.preferences.quietModeMaxToolPreviewLines = lines;\n saveSettings(current);\n ctx.state.quietModeMaxToolPreviewLines = lines;\n applyQuietModeToRenderedTools(ctx, ctx.state.quietMode, lines);\n },\n onStorageBackendChange: (backend: StorageBackend, connectionUrl?: string) => {\n const current = loadSettings();\n current.storage.backend = backend;\n if (backend === 'pg' && connectionUrl !== undefined) {\n current.storage.pg = { ...current.storage.pg, connectionString: connectionUrl };\n } else if (backend === 'libsql') {\n current.storage.libsql = { ...current.storage.libsql, url: connectionUrl || undefined };\n }\n saveSettings(current);\n ctx.state.ui.hideOverlay();\n ctx.stop();\n const label = backend === 'pg' ? 'PostgreSQL' : 'LibSQL';\n console.info(`\\nStorage backend changed to ${label}. Restarting is required.\\n`);\n process.exit(0);\n },\n onExperimentalGithubSignalsChange: async enabled => {\n if (enabled && !(await ensureGitcrawlReady(ctx))) return false;\n const current = loadSettings();\n current.signals.experimentalGithubSignals = enabled;\n saveSettings(current);\n ctx.showInfo(`Experimental GitHub signals: ${enabled ? 'on' : 'off'} (restart required)`);\n return true;\n },\n onApiKeys: () => {\n ctx.state.ui.hideOverlay();\n resolve();\n handleApiKeysCommand(ctx);\n },\n onClose: () => {\n ctx.state.ui.hideOverlay();\n resolve();\n },\n });\n\n showModalOverlay(ctx.state.ui, settings, { maxHeight: '75%' });\n settings.focused = true;\n });\n}\n","import type { BrowserProvider, BrowserSettings, StagehandEnv } from '@mastra/code-sdk/onboarding/settings';\nimport {\n checkProfileProviderMismatch,\n createBrowserFromSettings,\n loadSettings,\n saveSettings,\n setProfileProvider,\n} from '@mastra/code-sdk/onboarding/settings';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { SlashCommandContext } from './types.js';\n\n/**\n * Key used to store the active browser settings in controller state.\n * This tracks what browser config is actually running in this instance,\n * which may differ from the settings file if another instance changed it.\n */\nconst ACTIVE_BROWSER_KEY = 'activeBrowserSettings';\n\ntype BrowserAgent = { browser?: MastraBrowser; setBrowser?: (browser?: MastraBrowser) => void };\ntype StorageStateExportBrowser = MastraBrowser & { exportStorageState: (path: string) => Promise<void> };\n\n/**\n * /browser command - Configure browser automation for agents.\n *\n * Usage:\n * /browser - Interactive setup wizard\n * /browser status - Show current browser configuration\n * /browser on - Enable browser with current settings\n * /browser off - Disable browser\n * /browser set <k> <v> - Set a specific setting (profile, executablePath, storageState, cdpUrl)\n */\n\n/**\n * Helper to show an inline question and return the answer.\n */\nfunction askInline(\n ctx: SlashCommandContext,\n question: string,\n options: Array<{ label: string; description?: string }>,\n): Promise<string | null> {\n return askModalQuestion(ctx.state.ui, { question, options });\n}\n\n/**\n * Helper to show an inline text input and return the answer.\n */\nasync function askText(ctx: SlashCommandContext, question: string, defaultValue?: string): Promise<string | null> {\n const answer = await askModalQuestion(ctx.state.ui, { question, defaultValue, allowEmptyInput: true });\n const trimmed = answer?.trim() ?? '';\n return trimmed.length > 0 ? trimmed : null;\n}\n\n/**\n * Check for provider mismatch in profile and prompt for confirmation.\n * Returns true if we should proceed, false if user cancelled.\n */\nasync function checkAndConfirmProviderMismatch(\n ctx: SlashCommandContext,\n profile: string | undefined,\n targetProvider: BrowserProvider,\n): Promise<boolean> {\n if (!profile) return true;\n\n const existingProvider = checkProfileProviderMismatch(profile, targetProvider);\n if (!existingProvider) return true;\n\n const targetLabel = targetProvider === 'stagehand' ? 'Stagehand' : 'AgentBrowser';\n const existingLabel = existingProvider === 'stagehand' ? 'Stagehand' : 'AgentBrowser';\n\n ctx.showInfo(\n `⚠️ Warning: This profile was last used by ${existingLabel}, but you're now using ${targetLabel}.\\n` +\n 'Using the same profile across different providers can cause compatibility issues.',\n );\n\n const proceed = await askInline(ctx, 'Continue anyway?', [\n { label: 'No', description: 'Cancel and use a different profile' },\n { label: 'Yes', description: 'Proceed (may cause issues)' },\n ]);\n\n return proceed === 'Yes';\n}\n\n/**\n * Apply browser settings to all mode agents and track the active settings.\n */\nfunction resolveModeAgent(mode: unknown, agentControllerState: unknown): BrowserAgent | undefined {\n const modeAgent = (mode as { agent?: unknown }).agent;\n return typeof modeAgent === 'function'\n ? (modeAgent(agentControllerState) as BrowserAgent)\n : (modeAgent as BrowserAgent | undefined);\n}\n\nfunction applyBrowserToAgents(\n ctx: SlashCommandContext,\n browser: MastraBrowser | undefined,\n browserSettings?: BrowserSettings,\n): void {\n const modes = ctx.controller.listModes();\n let agentControllerState: unknown;\n for (const mode of modes) {\n const agent = resolveModeAgent(mode, (agentControllerState ??= ctx.state.session.state.get()));\n agent?.setBrowser?.(browser);\n }\n ctx.controller.setBrowser?.(browser);\n // Track the active browser settings in controller state\n void ctx.state.session.state.set({ [ACTIVE_BROWSER_KEY]: browserSettings } as any);\n}\n\n/**\n * Get a summary key for browser settings to detect config drift.\n */\nfunction getBrowserConfigKey(settings: BrowserSettings): string {\n if (!settings.enabled) return 'disabled';\n const parts: string[] = [settings.provider];\n if (settings.provider === 'stagehand' && settings.stagehand?.env) {\n parts.push(settings.stagehand.env);\n }\n parts.push(settings.headless ? 'headless' : 'headed');\n if (settings.profile) parts.push(`profile:${settings.profile}`);\n if (settings.executablePath) parts.push(`exec:${settings.executablePath}`);\n if (settings.cdpUrl) parts.push(`cdp:${settings.cdpUrl}`);\n if (settings.agentBrowser?.storageState) parts.push(`storage:${settings.agentBrowser.storageState}`);\n return parts.join(':');\n}\n\n/**\n * /browser — Configure browser automation settings.\n *\n * Interactive flow to set up browser provider (Stagehand or AgentBrowser),\n * headless mode, and provider-specific options.\n *\n * Changes are applied immediately to the current session.\n */\nexport async function handleBrowserCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n const settings = loadSettings();\n const browser = settings.browser;\n\n // Handle quick commands\n const arg = args[0]?.toLowerCase();\n\n // /browser set <key> <value> - set a specific setting\n if (arg === 'set') {\n const key = args[1]?.toLowerCase();\n const value = args.slice(2).join(' '); // Allow spaces in paths\n\n if (!key) {\n ctx.showInfo(\n 'Usage: /browser set <key> <value>\\n\\n' +\n 'Keys:\\n' +\n ' profile <path> - Browser profile directory\\n' +\n ' executablePath <path> - Browser executable path\\n' +\n ' storageState <path> - Playwright storage state file (agent-browser only)\\n' +\n ' cdpUrl <url> - CDP WebSocket URL\\n\\n' +\n 'To remove a setting, use: /browser clear <key>\\n\\n' +\n 'Examples:\\n' +\n ' /browser set profile ~/.mastracode/browser-profile-stagehand\\n' +\n ' /browser set executablePath /Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n );\n return;\n }\n\n const validKeys = ['profile', 'executablepath', 'storagestate', 'cdpurl'];\n if (!validKeys.includes(key)) {\n ctx.showError(`Unknown key: ${args[1]}. Valid keys: profile, executablePath, storageState, cdpUrl`);\n return;\n }\n\n if (!value) {\n ctx.showError(\n `Missing value. Use: /browser set ${args[1]} <value>\\nTo remove a setting, use: /browser clear ${args[1]}`,\n );\n return;\n }\n\n const expandedValue = value.trim().replace(/^~/, process.env.HOME || '~');\n\n switch (key) {\n case 'profile':\n settings.browser.profile = expandedValue;\n // Auto-set preserveUserDataDir for Stagehand when profile is configured\n settings.browser.stagehand = {\n ...settings.browser.stagehand,\n env: settings.browser.stagehand?.env ?? 'LOCAL',\n preserveUserDataDir: true,\n };\n // Profile is a launch option — incompatible with CDP connection\n if (settings.browser.cdpUrl) {\n delete settings.browser.cdpUrl;\n ctx.showInfo(`Note: Cleared cdpUrl (incompatible with profile).`);\n }\n break;\n case 'executablepath':\n settings.browser.executablePath = expandedValue;\n // ExecutablePath is a launch option — incompatible with CDP connection\n if (settings.browser.cdpUrl) {\n delete settings.browser.cdpUrl;\n ctx.showInfo(`Note: Cleared cdpUrl (incompatible with executablePath).`);\n }\n break;\n case 'storagestate':\n if (browser.provider !== 'agent-browser') {\n ctx.showError('storageState is only supported by agent-browser provider.');\n return;\n }\n settings.browser.agentBrowser = {\n ...settings.browser.agentBrowser,\n storageState: expandedValue,\n };\n break;\n case 'cdpurl':\n settings.browser.cdpUrl = expandedValue;\n // CDP connects to an existing browser — launch options are ignored\n if (settings.browser.profile || settings.browser.executablePath) {\n delete settings.browser.profile;\n delete settings.browser.executablePath;\n if (settings.browser.stagehand) {\n delete settings.browser.stagehand.preserveUserDataDir;\n }\n ctx.showInfo(`Note: Cleared profile and executablePath (ignored when using cdpUrl).`);\n }\n if (settings.browser.agentBrowser?.storageState) {\n delete settings.browser.agentBrowser.storageState;\n }\n break;\n }\n\n saveSettings(settings);\n ctx.showInfo(`Set ${args[1]} = ${expandedValue}\\nRun /browser on to apply.`);\n return;\n }\n\n if (arg === 'status') {\n // Get the active browser settings from controller state (what's actually running)\n const state = ctx.state.session.state.get() as any;\n const activeSettings = state?.[ACTIVE_BROWSER_KEY] as BrowserSettings | undefined;\n\n // Check for config drift between file and active instance\n const hasDrift = activeSettings && getBrowserConfigKey(browser) !== getBrowserConfigKey(activeSettings);\n\n if (hasDrift && activeSettings) {\n // Show both active and file settings when they differ\n const lines: string[] = [];\n\n // Active session settings\n const activeProvider =\n activeSettings.provider === 'stagehand' ? 'Stagehand (AI-powered)' : 'AgentBrowser (deterministic)';\n const activeIsBrowserbase =\n activeSettings.provider === 'stagehand' && activeSettings.stagehand?.env === 'BROWSERBASE';\n lines.push('Browser (active):');\n lines.push(` Provider: ${activeProvider}`);\n if (activeSettings.provider === 'stagehand' && activeSettings.stagehand) {\n lines.push(` Environment: ${activeSettings.stagehand.env}`);\n }\n if (!activeIsBrowserbase) {\n lines.push(` Headless: ${activeSettings.headless ? 'yes' : 'no'}`);\n }\n if (activeSettings.executablePath) lines.push(` Executable: ${activeSettings.executablePath}`);\n if (activeSettings.profile) lines.push(` Profile: ${activeSettings.profile}`);\n if (activeSettings.agentBrowser?.storageState)\n lines.push(` Storage State: ${activeSettings.agentBrowser.storageState}`);\n if (activeSettings.cdpUrl) lines.push(` CDP URL: ${activeSettings.cdpUrl}`);\n\n lines.push('');\n\n // Pending changes from file\n const fileProvider = browser.provider === 'stagehand' ? 'Stagehand (AI-powered)' : 'AgentBrowser (deterministic)';\n const fileIsBrowserbase = browser.provider === 'stagehand' && browser.stagehand?.env === 'BROWSERBASE';\n lines.push('Pending changes (not yet applied):');\n lines.push(` Provider: ${fileProvider}`);\n if (browser.provider === 'stagehand' && browser.stagehand) {\n lines.push(` Environment: ${browser.stagehand.env}`);\n }\n if (!fileIsBrowserbase) {\n lines.push(` Headless: ${browser.headless ? 'yes' : 'no'}`);\n }\n if (browser.executablePath) lines.push(` Executable: ${browser.executablePath}`);\n if (browser.profile) lines.push(` Profile: ${browser.profile}`);\n if (browser.agentBrowser?.storageState) lines.push(` Storage State: ${browser.agentBrowser.storageState}`);\n if (browser.cdpUrl) lines.push(` CDP URL: ${browser.cdpUrl}`);\n\n lines.push('');\n lines.push('⚠️ /browser on to apply, /browser to reconfigure, or restart.');\n\n ctx.showInfo(lines.join('\\n'));\n } else if (!browser.enabled) {\n ctx.showInfo('Browser: disabled');\n } else {\n // Normal status (no drift)\n const providerLabel =\n browser.provider === 'stagehand' ? 'Stagehand (AI-powered)' : 'AgentBrowser (deterministic)';\n const isBrowserbase = browser.provider === 'stagehand' && browser.stagehand?.env === 'BROWSERBASE';\n const lines = [`Browser: enabled`, ` Provider: ${providerLabel}`];\n if (browser.provider === 'stagehand' && browser.stagehand) {\n lines.push(` Environment: ${browser.stagehand.env}`);\n }\n if (!isBrowserbase) {\n lines.push(` Headless: ${browser.headless ? 'yes' : 'no'}`);\n }\n if (browser.executablePath) {\n lines.push(` Executable: ${browser.executablePath}`);\n }\n if (browser.profile) {\n lines.push(` Profile: ${browser.profile}`);\n }\n if (browser.agentBrowser?.storageState) {\n lines.push(` Storage State: ${browser.agentBrowser.storageState}`);\n }\n if (browser.cdpUrl) {\n lines.push(` CDP URL: ${browser.cdpUrl}`);\n }\n ctx.showInfo(lines.join('\\n'));\n }\n return;\n }\n\n if (arg === 'off' || arg === 'disable') {\n const disabledSettings = { ...settings.browser, enabled: false };\n settings.browser = disabledSettings;\n saveSettings(settings);\n applyBrowserToAgents(ctx, undefined, disabledSettings);\n ctx.showInfo('Browser disabled.');\n return;\n }\n\n if (arg === 'on' || arg === 'enable') {\n const nextBrowser = { ...settings.browser, enabled: true };\n\n // Check for provider mismatch in profile\n const shouldProceed = await checkAndConfirmProviderMismatch(ctx, nextBrowser.profile, nextBrowser.provider);\n if (!shouldProceed) {\n ctx.showInfo('Browser enable cancelled.');\n return;\n }\n\n try {\n const browserInstance = await createBrowserFromSettings(nextBrowser);\n applyBrowserToAgents(ctx, browserInstance, nextBrowser);\n if (nextBrowser.profile && nextBrowser.provider) {\n setProfileProvider(nextBrowser.profile, nextBrowser.provider);\n }\n settings.browser = nextBrowser;\n saveSettings(settings);\n const providerLabel = browser.provider === 'stagehand' ? 'Stagehand' : 'AgentBrowser';\n ctx.showInfo(`Browser enabled (${providerLabel}).`);\n } catch (err) {\n ctx.showError(`Failed to enable browser: ${err instanceof Error ? err.message : String(err)}`);\n }\n return;\n }\n\n // /browser clear [field] - reset all or specific setting (preserves enabled state)\n if (arg === 'clear') {\n const field = args[1]?.toLowerCase();\n\n if (!field) {\n // Clear all - reset to defaults but preserve enabled state\n const wasEnabled = settings.browser.enabled;\n settings.browser = {\n enabled: wasEnabled,\n provider: 'stagehand',\n headless: false,\n viewport: { width: 1280, height: 720 },\n };\n saveSettings(settings);\n // If it was enabled, we need to recreate the browser with new settings\n if (wasEnabled) {\n try {\n const browserInstance = await createBrowserFromSettings(settings.browser);\n applyBrowserToAgents(ctx, browserInstance, settings.browser);\n } catch (err) {\n // If recreation fails, disable and report\n settings.browser.enabled = false;\n saveSettings(settings);\n applyBrowserToAgents(ctx, undefined);\n ctx.showError(\n `Browser settings reset, but failed to restart: ${err instanceof Error ? err.message : String(err)}`,\n );\n return;\n }\n } else {\n applyBrowserToAgents(ctx, undefined);\n }\n ctx.showInfo('Browser settings reset to defaults.');\n return;\n }\n\n // Clear specific field\n switch (field) {\n case 'profile':\n delete settings.browser.profile;\n if (settings.browser.stagehand) {\n delete settings.browser.stagehand.preserveUserDataDir;\n }\n break;\n case 'executablepath':\n delete settings.browser.executablePath;\n break;\n case 'storagestate':\n if (settings.browser.agentBrowser) {\n delete settings.browser.agentBrowser.storageState;\n }\n break;\n case 'cdpurl':\n delete settings.browser.cdpUrl;\n break;\n default:\n ctx.showError(`Unknown field: ${field}. Valid fields: profile, executablePath, storageState, cdpUrl`);\n return;\n }\n\n saveSettings(settings);\n ctx.showInfo(`Cleared ${field}. Run /browser on to apply.`);\n return;\n }\n\n // /browser export storageState <path> - export current session's storage state\n if (arg === 'export') {\n const what = args[1]?.toLowerCase();\n const exportPath = args.slice(2).join(' ').trim();\n\n if (what !== 'storagestate' && what !== 'storage-state') {\n ctx.showError('Usage: /browser export storageState <path>');\n return;\n }\n\n if (!exportPath) {\n ctx.showError('Missing path. Usage: /browser export storageState <path>');\n return;\n }\n\n if (browser.provider !== 'agent-browser') {\n ctx.showError('export storageState is only supported by agent-browser provider.');\n return;\n }\n\n const currentMode = ctx.state.session.mode.resolve();\n const currentAgent = resolveModeAgent(currentMode, ctx.state.session.state.get());\n let browserInstance = currentAgent?.browser;\n\n if (!browserInstance && browser.enabled) {\n browserInstance = await createBrowserFromSettings(browser);\n applyBrowserToAgents(ctx, browserInstance, browser);\n }\n\n if (!browserInstance) {\n ctx.showError('Browser not enabled. Run /browser on first.');\n return;\n }\n\n const { AgentBrowser } = await import('@mastra/agent-browser');\n if (!(browserInstance instanceof AgentBrowser)) {\n ctx.showError('Current browser instance does not support exporting storage state.');\n return;\n }\n const exportableBrowser = browserInstance as StorageStateExportBrowser;\n\n const expandedPath = exportPath.replace(/^~/, process.env.HOME || '~');\n\n try {\n await exportableBrowser.exportStorageState(expandedPath);\n ctx.showInfo(`Storage state exported to: ${expandedPath}`);\n } catch (error) {\n ctx.showError(`Failed to export storage state: ${error instanceof Error ? error.message : String(error)}`);\n }\n return;\n }\n\n // /browser help, --help, -h, or unrecognized command\n if (arg && !['set', 'status', 'on', 'off', 'enable', 'disable', 'export'].includes(arg)) {\n const help = [\n 'usage: /browser <command> [options]',\n '',\n ' (no command) Interactive setup wizard',\n ' on, enable Enable browser with current settings',\n ' off, disable Disable browser',\n ' status Show current configuration',\n ' clear Reset all settings to defaults',\n ' clear <key> Clear: profile, executablePath, storageState, cdpUrl',\n ' set <key> <v> Set: profile, executablePath, storageState, cdpUrl',\n ' export storageState <path> Export session cookies/localStorage (agent-browser)',\n ];\n ctx.showInfo(help.join('\\n'));\n return;\n }\n\n // Step 1: Enable/disable browser (interactive)\n const enableChoice = await askInline(ctx, 'Enable browser automation?', [\n { label: 'Yes', description: 'Give the agent browser tools for web automation' },\n { label: 'No', description: 'Disable browser automation' },\n ]);\n\n // Cancel preserves current state\n if (!enableChoice) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n if (enableChoice === 'No') {\n if (browser.enabled) {\n settings.browser.enabled = false;\n saveSettings(settings);\n applyBrowserToAgents(ctx, undefined);\n ctx.showInfo('Browser automation disabled.');\n } else {\n ctx.showInfo('Browser automation remains disabled.');\n }\n return;\n }\n\n // Step 2: Select provider\n const providerChoice = await askInline(ctx, 'Select browser provider:', [\n { label: 'Stagehand', description: 'AI-powered (natural language instructions, recommended)' },\n { label: 'AgentBrowser', description: 'Deterministic (explicit selectors, requires Playwright)' },\n ]);\n\n if (!providerChoice) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n const provider: BrowserProvider = providerChoice === 'AgentBrowser' ? 'agent-browser' : 'stagehand';\n\n // Step 3: Stagehand-specific settings (ask environment first)\n let stagehandSettings: BrowserSettings['stagehand'];\n let isBrowserbase = false;\n if (provider === 'stagehand') {\n const envChoice = await askInline(ctx, 'Stagehand environment:', [\n { label: 'LOCAL', description: 'Run browser locally' },\n { label: 'BROWSERBASE', description: 'Use Browserbase cloud (requires API key)' },\n ]);\n\n if (!envChoice) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n const env = envChoice as StagehandEnv;\n isBrowserbase = env === 'BROWSERBASE';\n\n if (isBrowserbase) {\n ctx.showInfo(\n 'Browserbase requires BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID.\\n' +\n 'Set these in your shell profile (~/.zshrc) or pass them when starting MastraCode.',\n );\n }\n\n stagehandSettings = { env };\n }\n\n // Step 4: Headless mode (skip for Browserbase - runs in cloud)\n let headless = false;\n if (!isBrowserbase) {\n const headlessChoice = await askInline(ctx, 'Run in headless mode?', [\n { label: 'No', description: 'Show browser window (easier to debug)' },\n { label: 'Yes', description: 'Hide browser window (faster, less resource usage)' },\n ]);\n\n if (!headlessChoice) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n headless = headlessChoice === 'Yes';\n }\n\n // Step 5: Launch mode (bundled, custom executable, or CDP)\n let profile = browser.profile;\n let executablePath = browser.executablePath;\n let storageState = browser.agentBrowser?.storageState;\n let cdpUrl = browser.cdpUrl;\n\n if (isBrowserbase) {\n cdpUrl = undefined;\n profile = undefined;\n executablePath = undefined;\n storageState = undefined;\n }\n\n // Only show launch mode options for local browsers (not Browserbase)\n if (!isBrowserbase) {\n const launchMode = await askInline(ctx, 'How do you want to launch the browser?', [\n { label: 'Bundled browser', description: 'Use built-in Chromium (recommended)' },\n { label: 'Custom executable', description: 'Use Chrome, Brave, Edge, etc.' },\n { label: 'Connect via CDP', description: 'Connect to an already-running browser' },\n ]);\n\n if (!launchMode) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n if (launchMode === 'Custom executable') {\n // Clear cdpUrl when using custom browser (mutually exclusive)\n cdpUrl = undefined;\n\n const execPath = await askText(ctx, 'Browser executable path:', executablePath);\n if (execPath === null) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n executablePath = execPath.replace(/^~/, process.env.HOME || '~');\n } else if (launchMode === 'Connect via CDP') {\n const cdpUrlInput = await askText(ctx, 'CDP WebSocket URL (e.g., ws://localhost:9222):', cdpUrl);\n if (cdpUrlInput === null) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n cdpUrl = cdpUrlInput;\n // Clear launch options when using CDP (they don't apply)\n profile = undefined;\n executablePath = undefined;\n storageState = undefined;\n } else {\n // Bundled browser - clear custom paths\n cdpUrl = undefined;\n executablePath = undefined;\n }\n\n // Step 6: Profile option (only for bundled or custom executable, not CDP)\n if (launchMode !== 'Connect via CDP') {\n const useProfile = await askInline(ctx, 'Use a browser profile?', [\n { label: 'No', description: 'Fresh session each time' },\n { label: 'Yes', description: 'Persist logins, cookies, extensions' },\n ]);\n\n if (!useProfile) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n if (useProfile === 'Yes') {\n const defaultProfile = `~/.mastracode/browser-profile-${provider}`;\n const profilePath = await askText(ctx, 'Profile directory path:', profile || defaultProfile);\n if (profilePath === null) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n profile = profilePath.replace(/^~/, process.env.HOME || '~');\n } else {\n profile = undefined;\n }\n }\n }\n\n // Build new browser settings\n // Auto-set preserveUserDataDir when profile is configured for Stagehand\n if (provider === 'stagehand' && profile && stagehandSettings) {\n stagehandSettings.preserveUserDataDir = true;\n }\n\n const nextBrowser: BrowserSettings = {\n enabled: true,\n provider,\n headless,\n viewport: browser.viewport ?? { width: 1280, height: 720 },\n cdpUrl,\n profile,\n executablePath,\n stagehand: stagehandSettings,\n agentBrowser: storageState ? { storageState } : undefined,\n };\n\n // Check for provider mismatch in profile\n const shouldProceed = await checkAndConfirmProviderMismatch(ctx, profile, provider);\n if (!shouldProceed) {\n ctx.showInfo('Browser setup cancelled.');\n return;\n }\n\n // Apply browser to agents first, then persist on success\n try {\n const browserInstance = await createBrowserFromSettings(nextBrowser);\n applyBrowserToAgents(ctx, browserInstance, nextBrowser);\n if (nextBrowser.profile && nextBrowser.provider) {\n setProfileProvider(nextBrowser.profile, nextBrowser.provider);\n }\n settings.browser = nextBrowser;\n saveSettings(settings);\n } catch (err) {\n ctx.showError(`Failed to create browser: ${err instanceof Error ? err.message : String(err)}`);\n return;\n }\n\n // Summary\n const summary = [\n 'Browser automation enabled:',\n ` Provider: ${provider === 'stagehand' ? 'Stagehand (AI-powered)' : 'AgentBrowser (deterministic)'}`,\n ];\n\n if (provider === 'stagehand' && stagehandSettings) {\n summary.push(` Environment: ${stagehandSettings.env}`);\n }\n\n // Only show headless for local browsers\n if (!isBrowserbase) {\n summary.push(` Headless: ${headless ? 'yes' : 'no'}`);\n }\n\n // Show advanced options if configured\n if (cdpUrl) {\n summary.push(` CDP URL: ${cdpUrl}`);\n }\n if (executablePath) {\n summary.push(` Executable: ${executablePath}`);\n }\n if (profile) {\n summary.push(` Profile: ${profile}`);\n }\n if (storageState) {\n summary.push(` Storage State: ${storageState}`);\n }\n\n ctx.showInfo(summary.join('\\n'));\n}\n","/**\n * Login dialog component - handles OAuth login flow UI\n */\n\nimport { Box, Container, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, TUI } from '@earendil-works/pi-tui';\nimport { getOAuthProviders } from '@mastra/code-sdk/auth/index';\nimport { openUrlInBrowser } from '../open-url.js';\nimport { theme } from '../theme.js';\nimport { MaskedInput } from './masked-input.js';\n\nexport class LoginDialogComponent extends Box implements Focusable {\n private contentContainer: Container;\n private input: MaskedInput;\n private tui: TUI;\n private abortController = new AbortController();\n private inputResolver?: (value: string) => void;\n private inputRejecter?: (error: Error) => void;\n\n // Focusable implementation\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n this.input.focused = value;\n }\n\n constructor(\n tui: TUI,\n providerId: string,\n private onComplete: (success: boolean, message?: string) => void,\n ) {\n // Box with padding and background\n super(2, 1, text => theme.bg('overlayBg', text));\n this.tui = tui;\n\n const providerInfo = getOAuthProviders().find(p => p.id === providerId);\n const providerName = providerInfo?.name || providerId;\n\n // Title\n this.addChild(new Text(theme.fg('warning', `Login to ${providerName}`)));\n this.addChild(new Spacer(1));\n\n // Dynamic content area\n this.contentContainer = new Container();\n this.addChild(this.contentContainer);\n\n // Input (always present, used when needed)\n this.input = new MaskedInput();\n this.input.onSubmit = () => {\n if (this.inputResolver) {\n this.inputResolver(this.input.getValue());\n this.inputResolver = undefined;\n this.inputRejecter = undefined;\n }\n };\n this.input.onEscape = () => {\n this.cancel();\n };\n }\n\n get signal(): AbortSignal {\n return this.abortController.signal;\n }\n\n private cancel(): void {\n try {\n this.abortController.abort();\n } catch {}\n if (this.inputRejecter) {\n this.inputRejecter(new Error('Login cancelled'));\n this.inputResolver = undefined;\n this.inputRejecter = undefined;\n }\n this.onComplete(false, 'Login cancelled');\n }\n\n /**\n * Called by onAuth callback - show URL and optional instructions\n */\n showAuth(url: string, instructions?: string): void {\n this.contentContainer.clear();\n\n this.contentContainer.addChild(new Text(theme.fg('accent', url)));\n\n const clickHint = process.platform === 'darwin' ? 'Cmd+click to open' : 'Ctrl+click to open';\n const hyperlink = `\\x1b]8;;${url}\\x07${clickHint}\\x1b]8;;\\x07`;\n this.contentContainer.addChild(new Text(theme.fg('muted', hyperlink)));\n\n if (instructions) {\n this.contentContainer.addChild(new Spacer(1));\n this.contentContainer.addChild(new Text(theme.fg('warning', instructions)));\n }\n\n // Try to open browser. The URL comes from the auth provider, so treat it\n // as untrusted: only open well-formed http(s) URLs, and spawn without a\n // shell so it can't be used for command injection (CodeQL\n // js/shell-command-constructed-from-input).\n openUrlInBrowser(url);\n\n this.tui.requestRender();\n }\n\n /**\n * Called by onPrompt callback - show prompt and wait for input\n */\n showPrompt(message: string, placeholder?: string): Promise<string> {\n this.contentContainer.addChild(new Spacer(1));\n this.contentContainer.addChild(new Text(theme.fg('text', message)));\n if (placeholder) {\n this.contentContainer.addChild(new Text(theme.fg('muted', `e.g., ${placeholder}`)));\n }\n this.contentContainer.addChild(this.input);\n this.contentContainer.addChild(new Text(theme.fg('muted', '(Escape to cancel, Enter to submit)')));\n\n this.input.setValue('');\n this.tui.requestRender();\n\n return new Promise((resolve, reject) => {\n this.inputResolver = resolve;\n this.inputRejecter = reject;\n });\n }\n\n /**\n * Show progress message\n */\n showProgress(message: string): void {\n this.contentContainer.addChild(new Text(theme.fg('muted', message)));\n this.tui.requestRender();\n }\n\n handleInput(data: string): void {\n const kb = getKeybindings();\n\n if (kb.matches(data, 'tui.select.cancel')) {\n this.cancel();\n return;\n }\n\n // Pass to input\n this.input.handleInput(data);\n }\n}\n","/**\n * Auth-mode selector component used between the provider selector and the login dialog\n * when an OAuth provider advertises more than one `authModes` entry. Lets the user pick\n * (for example) \"Browser (local callback)\" vs \"Device code (headless)\" without setting\n * an env var.\n */\n\nimport { Box, Container, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { TUI } from '@earendil-works/pi-tui';\nimport type { AuthMode } from '@mastra/code-sdk/auth/types';\nimport { showModalOverlay } from '../overlay.js';\nimport { theme } from '../theme.js';\n\nexport class LoginModeSelectorComponent extends Box {\n private listContainer: Container;\n private modes: ReadonlyArray<AuthMode>;\n private selectedIndex = 0;\n private onSelectCallback: (modeId: string) => void;\n private onCancelCallback: () => void;\n\n constructor(\n providerName: string,\n modes: ReadonlyArray<AuthMode>,\n onSelect: (modeId: string) => void,\n onCancel: () => void,\n ) {\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.modes = modes;\n this.onSelectCallback = onSelect;\n this.onCancelCallback = onCancel;\n\n this.addChild(new Text(theme.fg('text', `How do you want to sign in to ${providerName}?`)));\n this.addChild(new Spacer(1));\n\n this.listContainer = new Container();\n this.addChild(this.listContainer);\n\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', 'Press Enter to select, Escape to cancel')));\n\n this.updateList();\n }\n\n private updateList(): void {\n this.listContainer.clear();\n\n for (let i = 0; i < this.modes.length; i++) {\n const mode = this.modes[i];\n if (!mode) continue;\n\n const isSelected = i === this.selectedIndex;\n const prefix = isSelected ? theme.fg('accent', '→ ') : ' ';\n const label = isSelected ? theme.fg('accent', mode.name) : mode.name;\n this.listContainer.addChild(new Text(`${prefix}${label}`));\n\n if (mode.description) {\n this.listContainer.addChild(new Text(theme.fg('muted', ` ${mode.description}`)));\n }\n }\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n if (kb.matches(keyData, 'tui.select.up')) {\n this.selectedIndex = Math.max(0, this.selectedIndex - 1);\n this.updateList();\n } else if (kb.matches(keyData, 'tui.select.down')) {\n this.selectedIndex = Math.min(this.modes.length - 1, this.selectedIndex + 1);\n this.updateList();\n } else if (kb.matches(keyData, 'tui.select.confirm')) {\n const selected = this.modes[this.selectedIndex];\n if (selected) {\n this.onSelectCallback(selected.id);\n }\n } else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancelCallback();\n }\n }\n}\n\n/**\n * Prompt the user to pick an auth mode if the provider advertises more than one.\n * Returns the chosen mode id, `undefined` when the provider has 0/1 modes (no prompt),\n * or `null` when the user cancelled.\n */\nexport async function promptAuthMode(\n tui: TUI,\n providerName: string,\n modes: ReadonlyArray<AuthMode> | undefined,\n): Promise<string | undefined | null> {\n if (!modes || modes.length < 2) {\n return modes && modes.length === 1 ? modes[0]!.id : undefined;\n }\n\n return new Promise(resolve => {\n const selector = new LoginModeSelectorComponent(\n providerName,\n modes,\n modeId => {\n tui.hideOverlay();\n resolve(modeId);\n },\n () => {\n tui.hideOverlay();\n resolve(null);\n },\n );\n\n showModalOverlay(tui, selector, { widthPercent: 0.8, maxHeight: '60%' });\n });\n}\n","/**\n * OAuth provider selector component for /login and /logout commands\n */\n\nimport { Box, Container, getKeybindings, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { OAuthProviderInterface } from '@mastra/code-sdk/auth/types';\nimport { theme } from '../theme.js';\n\n/**\n * Interface for auth provider that the selector needs.\n * Can be satisfied by AgentController or AuthStorage.\n */\nexport interface AuthProviderSource {\n getOAuthProviders(): OAuthProviderInterface[];\n isLoggedIn(providerId: string): boolean;\n}\n\nexport class LoginSelectorComponent extends Box {\n private listContainer: Container;\n private allProviders: { id: string; name: string }[] = [];\n private selectedIndex: number = 0;\n private mode: 'login' | 'logout';\n private authSource: AuthProviderSource;\n private onSelectCallback: (providerId: string) => void;\n private onCancelCallback: () => void;\n\n constructor(\n mode: 'login' | 'logout',\n authSource: AuthProviderSource,\n onSelect: (providerId: string) => void,\n onCancel: () => void,\n ) {\n // Box with padding and background\n super(2, 1, text => theme.bg('overlayBg', text));\n\n this.mode = mode;\n this.authSource = authSource;\n this.onSelectCallback = onSelect;\n this.onCancelCallback = onCancel;\n\n // Load all OAuth providers\n this.loadProviders();\n\n // Add title\n const title = mode === 'login' ? 'Select provider to login:' : 'Select provider to logout:';\n this.addChild(new Text(theme.fg('text', title)));\n this.addChild(new Spacer(1));\n\n // Create list container\n this.listContainer = new Container();\n this.addChild(this.listContainer);\n\n this.addChild(new Spacer(1));\n this.addChild(new Text(theme.fg('muted', 'Press Enter to select, Escape to cancel')));\n\n // Initial render\n this.updateList();\n }\n\n private loadProviders(): void {\n this.allProviders = this.authSource.getOAuthProviders().map(p => ({ id: p.id, name: p.name }));\n }\n\n private updateList(): void {\n this.listContainer.clear();\n\n for (let i = 0; i < this.allProviders.length; i++) {\n const provider = this.allProviders[i];\n if (!provider) continue;\n\n const isSelected = i === this.selectedIndex;\n\n // Check if user is logged in for this provider\n const isLoggedIn = this.authSource.isLoggedIn(provider.id);\n const statusIndicator = isLoggedIn ? theme.fg('success', ' ✓ logged in') : '';\n\n let line = '';\n if (isSelected) {\n line = theme.fg('accent', '→ ' + provider.name) + statusIndicator;\n } else {\n line = ' ' + provider.name + statusIndicator;\n }\n\n this.listContainer.addChild(new Text(line));\n }\n\n // Show \"no providers\" if empty\n if (this.allProviders.length === 0) {\n const message =\n this.mode === 'login' ? 'No OAuth providers available' : 'No OAuth providers logged in. Use /login first.';\n this.listContainer.addChild(new Text(theme.fg('muted', message)));\n }\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n // Up arrow\n if (kb.matches(keyData, 'tui.select.up')) {\n this.selectedIndex = Math.max(0, this.selectedIndex - 1);\n this.updateList();\n }\n // Down arrow\n else if (kb.matches(keyData, 'tui.select.down')) {\n this.selectedIndex = Math.min(this.allProviders.length - 1, this.selectedIndex + 1);\n this.updateList();\n }\n // Enter\n else if (kb.matches(keyData, 'tui.select.confirm')) {\n const selectedProvider = this.allProviders[this.selectedIndex];\n if (selectedProvider) {\n this.onSelectCallback(selectedProvider.id);\n }\n }\n // Escape or Ctrl+C\n else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancelCallback();\n }\n }\n}\n","import { applyOMDefaultIfUnconfigured } from '@mastra/code-sdk/onboarding/om-settings';\nimport type { OMPack } from '@mastra/code-sdk/onboarding/packs';\nimport { resolveProviderOMDefault } from '@mastra/code-sdk/onboarding/packs';\nimport { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport type { TUIState } from './state.js';\n\n/** Point both live OM roles at one model, without pinning it to the current thread. */\nexport async function applyOMModelToSession(state: TUIState, modelId: string): Promise<void> {\n await state.session.state.set({ observerModelId: modelId, reflectorModelId: modelId });\n}\n\n/** Seed OM from a provider login, preserving explicit settings; undefined when nothing was seeded. */\nexport async function applyProviderOMDefaultIfUnconfigured(\n state: TUIState,\n providerId: string,\n): Promise<OMPack | undefined> {\n const pack = resolveProviderOMDefault(providerId);\n // No cheap OM pack for this provider — leave OM open for a later login rather\n // than pinning observation and reflection to a full-size coding model.\n if (pack.id === 'custom') return undefined;\n\n const settings = loadSettings();\n if (!applyOMDefaultIfUnconfigured(settings, pack)) return undefined;\n\n saveSettings(settings);\n await applyOMModelToSession(state, pack.modelId);\n return pack;\n}\n\n// Never rejects: runs after the login success message, and the login .catch would\n// report a settings failure as an authentication failure.\nexport async function seedOMDefaultAfterLogin(\n state: TUIState,\n providerId: string,\n showInfo: (message: string) => void,\n): Promise<void> {\n try {\n const pack = await applyProviderOMDefaultIfUnconfigured(state, providerId);\n if (pack) showInfo(`Observational memory - switched to ${pack.modelId}`);\n } catch (error) {\n showInfo(`Observational memory default unchanged: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","import { getOAuthProviders, PROVIDER_DEFAULT_MODELS } from '@mastra/code-sdk/auth/storage';\nimport { LoginDialogComponent } from '../components/login-dialog.js';\nimport { promptAuthMode } from '../components/login-mode-selector.js';\nimport { LoginSelectorComponent } from '../components/login-selector.js';\nimport { seedOMDefaultAfterLogin } from '../om-defaults.js';\nimport { showModalOverlay } from '../overlay.js';\nimport type { SlashCommandContext } from './types.js';\n\nasync function performLogin(ctx: SlashCommandContext, providerId: string): Promise<void> {\n const provider = getOAuthProviders().find(p => p.id === providerId);\n const providerName = provider?.name || providerId;\n\n if (!ctx.authStorage) {\n ctx.showError('Auth storage not configured');\n return;\n }\n\n const authMode = await promptAuthMode(ctx.state.ui, providerName, provider?.authModes);\n if (authMode === null) {\n // User cancelled at the mode-selection step.\n return;\n }\n\n return new Promise(resolve => {\n const dialog = new LoginDialogComponent(ctx.state.ui, providerId, (success, message) => {\n ctx.state.ui.hideOverlay();\n if (success) {\n ctx.showInfo(`Successfully logged in to ${providerName}`);\n } else if (message) {\n ctx.showInfo(message);\n }\n resolve();\n });\n\n showModalOverlay(ctx.state.ui, dialog, { widthPercent: 0.8, maxHeight: '60%' });\n dialog.focused = true;\n\n ctx\n .authStorage!.login(providerId, {\n onAuth: (info: { url: string; instructions?: string }) => {\n dialog.showAuth(info.url, info.instructions);\n },\n onPrompt: async (prompt: { message: string; placeholder?: string }) => {\n return dialog.showPrompt(prompt.message, prompt.placeholder);\n },\n onProgress: (message: string) => {\n dialog.showProgress(message);\n },\n signal: dialog.signal,\n authMode,\n })\n .then(async () => {\n ctx.state.ui.hideOverlay();\n\n // The `/login` command must not change the user's active model or model\n // pack — that only belongs to the onboarding flow. Only auto-select the\n // provider default when no model is selected yet (e.g. onboarding was\n // skipped), so the user isn't left without a usable model.\n const hasSelectedModel = ctx.state.session.model.get() !== '';\n const defaultModel = PROVIDER_DEFAULT_MODELS[providerId as keyof typeof PROVIDER_DEFAULT_MODELS];\n if (defaultModel && !hasSelectedModel) {\n await ctx.state.session.model.switch({ modelId: defaultModel });\n ctx.showInfo(`Logged in to ${providerName} - switched to ${defaultModel}`);\n } else {\n ctx.showInfo(`Successfully logged in to ${providerName}`);\n }\n await seedOMDefaultAfterLogin(ctx.state, providerId, message => ctx.showInfo(message));\n\n resolve();\n })\n .catch((error: Error) => {\n ctx.state.ui.hideOverlay();\n if (error.message !== 'Login cancelled') {\n ctx.showError(`Failed to login: ${error.message}`);\n }\n resolve();\n });\n });\n}\n\nexport async function handleLoginCommand(ctx: SlashCommandContext, mode: 'login' | 'logout'): Promise<void> {\n const allProviders = getOAuthProviders();\n const loggedInIds = allProviders.filter(p => ctx.authStorage?.isLoggedIn(p.id)).map(p => p.id);\n\n if (mode === 'logout') {\n if (loggedInIds.length === 0) {\n ctx.showInfo('No OAuth providers logged in. Use /login first.');\n return;\n }\n }\n\n const providers = mode === 'logout' ? allProviders.filter(p => loggedInIds.includes(p.id)) : allProviders;\n\n if (providers.length === 0) {\n ctx.showInfo('No OAuth providers available.');\n return;\n }\n\n if (mode === 'login') {\n ctx.analytics?.trackInteractivePrompt('login_provider_selector', {\n threadId: ctx.state.session.thread.getId(),\n resourceId: ctx.state.session.identity.getResourceId(),\n mode: ctx.state.session.mode.get(),\n });\n }\n\n return new Promise<void>(resolve => {\n const selector = new LoginSelectorComponent(\n mode,\n {\n getOAuthProviders: () => providers,\n isLoggedIn: providerId => loggedInIds.includes(providerId),\n },\n async providerId => {\n ctx.state.ui.hideOverlay();\n const provider = providers.find(p => p.id === providerId);\n if (provider) {\n if (mode === 'login') {\n await performLogin(ctx, provider.id);\n } else {\n if (ctx.authStorage) {\n ctx.authStorage.logout(provider.id);\n ctx.showInfo(`Logged out from ${provider.name}`);\n } else {\n ctx.showError('Auth storage not configured');\n }\n }\n }\n resolve();\n },\n () => {\n ctx.state.ui.hideOverlay();\n resolve();\n },\n );\n\n showModalOverlay(ctx.state.ui, selector, { widthPercent: 0.8, maxHeight: '60%' });\n });\n}\n","import { sendSlashCommandMessage } from './send-slash-command-message.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handleReviewCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n if (!ctx.state.session.model.hasSelection()) {\n ctx.showInfo('No model selected. Use /models to select a model, or /login to authenticate.');\n return;\n }\n\n // Ensure thread exists\n if (ctx.state.pendingNewThread) {\n await ctx.state.session.thread.create();\n ctx.state.pendingNewThread = false;\n }\n\n const prNumber = args[0];\n const focusArea = args.slice(1).join(' ');\n\n let prompt: string;\n\n if (!prNumber) {\n prompt =\n `List the open pull requests for this repository using \\`gh pr list --limit 20\\`. ` +\n `Present them in a clear table with PR number, title, and author. ` +\n `Then ask me which PR I'd like you to review.`;\n } else {\n prompt =\n `Do a thorough code review of PR #${prNumber}. Follow these steps:\\n\\n` +\n `1. Run \\`gh pr view ${prNumber}\\` to get the PR description and metadata.\\n` +\n `2. Run \\`gh pr diff ${prNumber}\\` to get the full diff.\\n` +\n `3. Run \\`gh pr checks ${prNumber}\\` to check CI status.\\n` +\n `4. Read any relevant source files for full context on the changes.\\n` +\n `5. Provide a detailed code review covering:\\n` +\n ` - Overview of what the PR does\\n` +\n ` - Root cause analysis (if it's a fix)\\n` +\n ` - Code quality assessment\\n` +\n ` - Potential concerns or edge cases\\n` +\n ` - CI status\\n` +\n ` - Suggestions for improvement\\n` +\n ` - Final verdict (approve/request changes/comment)\\n`;\n\n if (focusArea) {\n prompt += `\\nPay special attention to: ${focusArea}\\n`;\n }\n }\n\n const displayText = prNumber ? `/review ${args.join(' ')}` : '/review';\n sendSlashCommandMessage(ctx, displayText, prompt).catch(error => {\n ctx.showError(error instanceof Error ? error.message : 'Review failed');\n });\n}\n","import { sendSlashCommandMessage } from './send-slash-command-message.js';\nimport type { SlashCommandContext } from './types.js';\n\nconst MASTRA_REPO = 'mastra-ai/mastra';\nconst MASTRA_LABEL = 'mastracode';\n\nexport async function handleReportIssueCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n if (!ctx.state.session.model.hasSelection()) {\n ctx.showInfo('No model selected. Use /models to select a model, or /login to authenticate.');\n return;\n }\n\n // Ensure thread exists\n if (ctx.state.pendingNewThread) {\n await ctx.state.session.thread.create();\n ctx.state.pendingNewThread = false;\n }\n\n const extraContext = args.join(' ').trim();\n\n const prompt =\n `The user wants to report a GitHub issue on ${MASTRA_REPO}. Help them through this process.\\n\\n` +\n (extraContext ? `The user provided this initial context: \"${extraContext}\"\\n\\n` : '') +\n `## Step 1: Understand the problem\\n\\n` +\n `Ask the user to describe the issue in their own words. Ask follow-up questions to gather:\\n` +\n `- What happened / what's wrong\\n` +\n `- What they expected to happen\\n` +\n `- Steps to reproduce (if applicable)\\n\\n` +\n `Also gather environment info by running:\\n` +\n '```\\n' +\n `mastracode --version 2>/dev/null || echo \"unknown\"\\n` +\n `node --version\\n` +\n `uname -s\\n` +\n '```\\n\\n' +\n `Use the conversation history for additional context about what the user was working on when they hit this issue.\\n\\n` +\n `## Step 2: Check for duplicates\\n\\n` +\n `Once you understand the problem, search for similar existing issues:\\n` +\n '```\\n' +\n `gh issue list --repo ${MASTRA_REPO} --label ${MASTRA_LABEL} --state open --limit 50 --json number,title,body\\n` +\n '```\\n\\n' +\n `Also search more broadly:\\n` +\n '```\\n' +\n `gh search issues --repo ${MASTRA_REPO} --state open \"<relevant keywords>\" --limit 20 --json number,title,body,labels\\n` +\n '```\\n\\n' +\n `If you find similar issue(s):\\n` +\n `- Present them with their number, title, and a brief summary\\n` +\n `- Ask the user whether they'd like to add a comment on an existing issue instead of opening a new one\\n` +\n `- If they choose to comment, draft the comment, show it to the user for approval, then run:\\n` +\n '```\\n' +\n `gh issue comment <number> --repo ${MASTRA_REPO} --body \"<comment>\"\\n` +\n '```\\n' +\n `Then stop here.\\n\\n` +\n `## Step 3: Draft the issue\\n\\n` +\n `Based on what you've gathered, write a clear, well-structured issue with:\\n` +\n `- A concise, descriptive title\\n` +\n `- A body covering: description, expected behavior, steps to reproduce, and environment info\\n\\n` +\n `**Show the full title and body to the user and ask for their approval before creating it.** Let them suggest edits.\\n\\n` +\n `## Step 4: Create the issue\\n\\n` +\n `Only after the user approves, create the issue:\\n` +\n '```\\n' +\n `gh issue create --repo ${MASTRA_REPO} --label ${MASTRA_LABEL} --title \"<title>\" --body \"<body>\"\\n` +\n '```\\n\\n' +\n `Report the created issue URL back to the user.`;\n\n const displayText = extraContext ? `/report-issue ${extraContext}` : '/report-issue';\n sendSlashCommandMessage(ctx, displayText, prompt).catch(error => {\n ctx.showError(error instanceof Error ? error.message : 'Report issue command failed');\n });\n}\n","import type { SlashCommandContext } from './types.js';\n\nexport async function handleSetupCommand(ctx: SlashCommandContext): Promise<void> {\n await ctx.showOnboarding();\n}\n","import { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { detectTerminalTheme } from '../detect-theme.js';\nimport { applyThemeMode, getThemeMode } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\n/**\n * /theme [auto|dark|light] — show or change the color theme.\n */\nexport async function handleThemeCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const arg = args[0]?.toLowerCase();\n\n if (!arg) {\n const mode = getThemeMode();\n const settings = loadSettings();\n const pref = settings.preferences.theme ?? 'auto';\n ctx.showInfo(`Theme: ${mode} (preference: ${pref})`);\n return;\n }\n\n if (arg !== 'auto' && arg !== 'dark' && arg !== 'light') {\n ctx.showError('Usage: /theme [auto|dark|light]');\n return;\n }\n\n // Persist the preference\n const settings = loadSettings();\n settings.preferences.theme = arg;\n saveSettings(settings);\n\n // Apply immediately\n if (arg === 'auto') {\n const detection = await detectTerminalTheme();\n applyThemeMode(detection.mode, detection.detectedBgHex);\n ctx.showInfo(`Theme set to auto (detected: ${detection.mode})`);\n } else {\n applyThemeMode(arg);\n ctx.showInfo(`Theme set to ${arg}`);\n }\n ctx.state.ui.requestRender();\n}\n","import { loadSettings, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport {\n detectPackageManager,\n fetchChangelog,\n fetchLatestVersion,\n isNewerVersion,\n performUpdate,\n} from '@mastra/code-sdk/utils/update-check';\nimport { AskQuestionInlineComponent } from '../components/ask-question-inline.js';\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handleUpdateCommand(ctx: SlashCommandContext): Promise<void> {\n const currentVersion = ctx.state.options.version;\n if (!currentVersion) {\n ctx.showError('Could not determine the current version.');\n return;\n }\n\n ctx.showInfo('Checking for updates…');\n\n const latestVersion = await fetchLatestVersion();\n if (!latestVersion) {\n ctx.showError('Could not reach the npm registry. Check your network connection.');\n return;\n }\n\n if (!isNewerVersion(currentVersion, latestVersion)) {\n ctx.showInfo(`You are already on the latest version (v${currentVersion}).`);\n return;\n }\n\n const [pm, changelog] = await Promise.all([detectPackageManager(), fetchChangelog(latestVersion)]);\n\n // Clear any previously dismissed version so the prompt always shows\n const settings = loadSettings();\n if (settings.updateDismissedVersion) {\n settings.updateDismissedVersion = null;\n saveSettings(settings);\n }\n\n // Build question text with optional changelog\n let question = `A new version is available: v${latestVersion} (current: v${currentVersion}).`;\n if (changelog) {\n question += `\\n\\nWhat's new:\\n${changelog}`;\n }\n question += `\\n\\nWould you like to update now?`;\n\n const answer = await new Promise<string | null>(resolve => {\n const component = new AskQuestionInlineComponent(\n {\n question,\n options: [\n { label: 'Yes', description: 'Update and restart' },\n { label: 'No', description: 'Skip this version' },\n ],\n allowCustomResponse: false,\n onSubmit: answer => {\n ctx.state.activeInlineQuestion = undefined;\n resolve(answer);\n },\n onCancel: () => {\n ctx.state.activeInlineQuestion = undefined;\n resolve(null);\n },\n },\n ctx.state.ui,\n );\n\n ctx.state.chatContainer.addChild(component);\n ctx.state.activeInlineQuestion = component;\n component.focused = true;\n ctx.state.ui.requestRender();\n });\n\n if (answer === 'Yes') {\n ctx.showInfo(`Updating to v${latestVersion}…`);\n const outcome = await performUpdate(pm, latestVersion);\n if (outcome.status === 'updated') {\n // Printed after TUI teardown — a message rendered inside it is lost in the exit race.\n ctx.stop();\n console.info(outcome.message);\n process.exit(0);\n } else {\n ctx.showError(outcome.message);\n }\n } else if (answer === 'No') {\n const s = loadSettings();\n s.updateDismissedVersion = latestVersion;\n saveSettings(s);\n ctx.showInfo('Update skipped.');\n }\n}\n","import {\n loadSettings,\n saveSettings,\n MASTRA_GATEWAY_PROVIDER,\n MASTRA_GATEWAY_DEFAULT_URL,\n} from '@mastra/code-sdk/onboarding/settings';\nimport { GatewayRegistry } from '@mastra/core/llm';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { SlashCommandContext } from './types.js';\n\nasync function askText(ctx: SlashCommandContext, question: string, defaultValue?: string): Promise<string | null> {\n const answer = await askModalQuestion(ctx.state.ui, { question, defaultValue });\n const trimmed = answer?.trim() ?? '';\n return trimmed.length > 0 ? trimmed : null;\n}\n\nasync function askSelect(\n ctx: SlashCommandContext,\n question: string,\n options: Array<{ label: string; value: string; description?: string }>,\n): Promise<string | null> {\n const answer = await askModalQuestion(ctx.state.ui, {\n question,\n options: options.map(option => ({ label: option.label, description: option.description })),\n });\n const selected = options.find(option => option.label === answer);\n const trimmed = answer?.trim() ?? '';\n return selected?.value ?? (trimmed.length > 0 ? trimmed : null);\n}\n\nasync function refreshGatewayModels(ctx: SlashCommandContext): Promise<void> {\n try {\n await GatewayRegistry.getInstance({ useDynamicLoading: true }).syncGateways(true);\n } catch (error) {\n ctx.showError(`Failed to refresh gateway models: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nexport async function handleMastraGatewayCommand(ctx: SlashCommandContext): Promise<void> {\n const authStorage = ctx.authStorage;\n if (!authStorage) {\n ctx.showError('Auth storage not available');\n return;\n }\n\n // Resolve effective state from storage + env\n const currentKey = authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER) ?? process.env['MASTRA_GATEWAY_API_KEY'];\n const settings = loadSettings();\n const effectiveUrl =\n settings.memoryGateway?.baseUrl ?? process.env['MASTRA_GATEWAY_URL'] ?? MASTRA_GATEWAY_DEFAULT_URL;\n\n if (currentKey) {\n const masked = currentKey.length > 6 ? `****${currentKey.slice(-4)}` : '****';\n ctx.showInfo(`Current API key: ${masked} | URL: ${effectiveUrl}`);\n } else {\n ctx.showInfo(`No API key set | URL: ${effectiveUrl}`);\n }\n\n // Ask for API key\n const keyAnswer = await askText(\n ctx,\n currentKey\n ? `API key (ENTER to keep current, 'clear' to remove, ESC to skip):`\n : `API key (or 'clear' to remove, ESC to cancel):`,\n currentKey,\n );\n if (keyAnswer === null) {\n // ESC with no key — abort; ESC with existing key — proceed to URL prompt\n if (!currentKey) return;\n } else if (keyAnswer.toLowerCase() === 'clear') {\n authStorage.remove(`apikey:${MASTRA_GATEWAY_PROVIDER}`);\n delete process.env['MASTRA_GATEWAY_API_KEY'];\n delete process.env['MASTRA_GATEWAY_URL'];\n settings.memoryGateway = {};\n saveSettings(settings);\n await refreshGatewayModels(ctx);\n ctx.showInfo('Gateway cleared. Memory mode changes take effect on next restart.');\n return;\n } else if (keyAnswer.length > 0) {\n authStorage.setStoredApiKey(MASTRA_GATEWAY_PROVIDER, keyAnswer, 'MASTRA_GATEWAY_API_KEY');\n }\n\n const urlChoice = await askSelect(ctx, 'Gateway URL', [\n {\n label: MASTRA_GATEWAY_DEFAULT_URL,\n value: MASTRA_GATEWAY_DEFAULT_URL,\n description: effectiveUrl === MASTRA_GATEWAY_DEFAULT_URL ? 'current' : 'hosted default',\n },\n {\n label: 'http://localhost:4111',\n value: 'http://localhost:4111',\n description: effectiveUrl === 'http://localhost:4111' ? 'current' : 'local development',\n },\n ]);\n\n if (urlChoice === null) {\n return;\n }\n\n const urlAnswer = urlChoice;\n\n if (urlAnswer && urlAnswer !== MASTRA_GATEWAY_DEFAULT_URL) {\n settings.memoryGateway = { baseUrl: urlAnswer };\n process.env['MASTRA_GATEWAY_URL'] = urlAnswer;\n } else {\n settings.memoryGateway = {};\n delete process.env['MASTRA_GATEWAY_URL'];\n }\n saveSettings(settings);\n await refreshGatewayModels(ctx);\n\n ctx.showInfo('Gateway configured. Memory mode changes take effect on next restart.');\n}\n","import { Box, SelectList, Spacer, Text, matchesKey } from '@earendil-works/pi-tui';\nimport type { SelectItem } from '@earendil-works/pi-tui';\n\nimport type { LoadedPlugin, PluginScope } from '@mastra/code-sdk/plugins/types';\nimport type { MastraCodePluginConfigOption, MastraCodePluginConfigValue } from '../../plugin.js';\nimport { ModelSelectorComponent } from '../components/model-selector.js';\nimport type { ModelItem } from '../components/model-selector.js';\nimport { askModalQuestion } from '../modal-question.js';\nimport { showModalOverlay } from '../overlay.js';\nimport { promptForApiKeyIfNeeded } from '../prompt-api-key.js';\nimport { getSelectListTheme, theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\nconst INSTALL_VALUE = '__install__';\nconst BACK_VALUE = '__back__';\n\nclass PluginInstallProgress extends Box {\n private lines: string[] = [];\n private _focused = false;\n\n constructor(\n private specifier: string,\n private onCancel: () => void,\n ) {\n super(4, 2, text => theme.bg('overlayBg', text));\n this.rebuild();\n }\n\n get focused(): boolean {\n return this._focused;\n }\n\n set focused(value: boolean) {\n this._focused = value;\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c') || data === '\\x1b' || data === '\\x1b\\x1b') {\n this.onCancel();\n }\n }\n\n addOutput(chunk: Buffer | string): void {\n const lines = chunk\n .toString()\n .split(/\\r?\\n/)\n .map(line => line.trimEnd())\n .filter(Boolean);\n this.lines = [...this.lines, ...lines].slice(-8);\n this.rebuild();\n }\n\n private rebuild(): void {\n this.clear();\n this.addChild(new Text(theme.bold(theme.fg('accent', 'Installing GitHub plugin')), 0, 0));\n this.addChild(new Text(this.specifier, 0, 0));\n this.addChild(new Text(theme.fg('dim', 'Press Esc or Ctrl-C to cancel.'), 0, 0));\n this.addChild(new Spacer(1));\n const output = this.lines.length > 0 ? this.lines : ['Waiting for clone output...'];\n for (const line of output) {\n this.addChild(new Text(line, 0, 0));\n }\n }\n}\n\nexport async function handlePluginsCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n if (!ctx.pluginManager) {\n ctx.showInfo('Plugin system not initialized.');\n return;\n }\n\n await ctx.pluginManager.reload();\n const pluginId = args[0];\n if (pluginId) {\n const plugins = ctx.pluginManager.getLoadedPlugins();\n const plugin = plugins.find(\n candidate => candidate.id === pluginId || `${candidate.scope}:${candidate.id}` === pluginId,\n );\n if (!plugin) {\n ctx.showError(`Plugin not found: ${pluginId}`);\n return;\n }\n showPluginDetail(ctx, plugin);\n return;\n }\n\n showPluginsList(ctx);\n}\n\nfunction pluginStatus(plugin: LoadedPlugin): string {\n if (plugin.status === 'active') return theme.fg('success', 'active');\n if (plugin.status === 'inactive') return theme.fg('dim', 'inactive');\n if (plugin.status === 'blocked') return theme.fg('warning', 'blocked');\n if (plugin.status === 'conflicted') return theme.fg('warning', 'conflicted');\n return theme.fg('error', 'load failed');\n}\n\nfunction pluginLabel(plugin: LoadedPlugin): string {\n const name = plugin.name ? `${plugin.name} ` : '';\n return ` ${name}${theme.fg('dim', `(${plugin.id})`)} ${theme.fg('dim', plugin.scope)} ${pluginStatus(plugin)}`;\n}\n\nfunction buildPluginItems(plugins: LoadedPlugin[]): SelectItem[] {\n const project = plugins.filter(plugin => plugin.scope === 'project');\n const global = plugins.filter(plugin => plugin.scope === 'global');\n return [\n { value: INSTALL_VALUE, label: ' Install new plugin' },\n ...project.map(plugin => ({ value: `project:${plugin.id}`, label: pluginLabel(plugin) })),\n ...global.map(plugin => ({ value: `global:${plugin.id}`, label: pluginLabel(plugin) })),\n ];\n}\n\nfunction showPluginsList(ctx: SlashCommandContext): void {\n const plugins = ctx.pluginManager?.getLoadedPlugins() ?? [];\n const items = buildPluginItems(plugins);\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', 'Plugins')), 0, 0));\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', 'Scaffold with: mastracode plugin scaffold <dir>'), 0, 0));\n container.addChild(new Spacer(1));\n\n const list = new SelectList(items, Math.min(items.length, 15), getSelectListTheme());\n list.onSelect = item => {\n if (item.value === INSTALL_VALUE) {\n ctx.state.ui.hideOverlay();\n void installPluginFlow(ctx);\n return;\n }\n const [scope, id] = item.value.split(':', 2) as [PluginScope, string];\n const plugin = plugins.find(candidate => candidate.scope === scope && candidate.id === id);\n if (plugin) {\n ctx.state.ui.hideOverlay();\n showPluginDetail(ctx, plugin);\n }\n };\n list.onCancel = () => ctx.state.ui.hideOverlay();\n\n container.addChild(list);\n container.addChild(new Spacer(1));\n container.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc close'), 0, 0));\n const modal = container as Box & { handleInput: (data: string) => void };\n modal.handleInput = (data: string) => list.handleInput(data);\n showModalOverlay(ctx.state.ui, modal, { maxHeight: '80%' });\n}\n\nfunction reportPluginMutationError(ctx: SlashCommandContext, action: string, error: unknown): void {\n const message = error instanceof Error ? error.message : String(error);\n ctx.showError(`${action} failed: ${message}`);\n}\n\nasync function withGithubPluginInstallProgress<T>(\n ctx: SlashCommandContext,\n specifier: string,\n install: (options: { onOutput: (chunk: Buffer | string) => void; signal: AbortSignal }) => Promise<T>,\n): Promise<T> {\n const controller = new AbortController();\n let rejectCancelled: (error: Error) => void = () => {};\n const cancelled = new Promise<never>((_, reject) => {\n rejectCancelled = reject;\n });\n const progress = new PluginInstallProgress(specifier, () => {\n controller.abort();\n rejectCancelled(new Error('GitHub plugin install cancelled'));\n });\n const overlay = showModalOverlay(ctx.state.ui, progress, { maxHeight: '70%' });\n overlay?.focus?.();\n ctx.state.ui.requestRender?.();\n try {\n const installPromise = install({\n onOutput: chunk => {\n progress.addOutput(chunk);\n ctx.state.ui.requestRender?.();\n },\n signal: controller.signal,\n });\n installPromise.catch(() => undefined);\n return await Promise.race([installPromise, cancelled]);\n } finally {\n overlay?.hide?.();\n ctx.state.ui.requestRender?.();\n }\n}\n\nfunction showPluginDetail(ctx: SlashCommandContext, plugin: LoadedPlugin): void {\n const container = new Box(4, 2, text => theme.bg('overlayBg', text));\n container.addChild(new Text(theme.bold(theme.fg('accent', plugin.name ?? plugin.id)), 0, 0));\n container.addChild(new Spacer(1));\n container.addChild(new Text(`id: ${plugin.id}`, 0, 0));\n container.addChild(new Text(`scope: ${plugin.scope}`, 0, 0));\n container.addChild(new Text(`source: ${plugin.source} ${plugin.specifier}`, 0, 0));\n container.addChild(new Text(`status: ${plugin.status}`, 0, 0));\n if (plugin.version) container.addChild(new Text(`version: ${plugin.version}`, 0, 0));\n if (plugin.description) container.addChild(new Text(`description: ${plugin.description}`, 0, 0));\n container.addChild(new Text(`tools: ${plugin.toolNames.length ? plugin.toolNames.join(', ') : '(none)'}`, 0, 0));\n const configEntries = Object.entries(plugin.configSchema ?? {});\n if (configEntries.length) {\n container.addChild(new Text(`config: ${configEntries.map(([key]) => key).join(', ')}`, 0, 0));\n }\n if (plugin.error) container.addChild(new Text(theme.fg('error', `error: ${plugin.error}`), 0, 0));\n if (plugin.status === 'blocked')\n container.addChild(new Text(theme.fg('warning', 'blocked by plugins.json disabledPlugins'), 0, 0));\n if (plugin.conflicts?.length)\n container.addChild(new Text(theme.fg('warning', `conflicts: ${plugin.conflicts.join(', ')}`), 0, 0));\n container.addChild(new Spacer(1));\n\n const actionLabel = plugin.enabled ? 'Deactivate' : 'Activate';\n const actionItems: SelectItem[] = [\n ...(configEntries.length && plugin.status !== 'blocked' ? [{ value: 'configure', label: ' Configure' }] : []),\n ...(plugin.status === 'blocked' ? [] : [{ value: 'toggle', label: ` ${actionLabel}` }]),\n { value: 'uninstall', label: ' Uninstall' },\n { value: BACK_VALUE, label: ' Back' },\n ];\n const actions = new SelectList(actionItems, actionItems.length, getSelectListTheme());\n actions.onSelect = item => {\n if (!ctx.pluginManager) return;\n if (item.value === BACK_VALUE) {\n ctx.state.ui.hideOverlay();\n showPluginsList(ctx);\n return;\n }\n if (item.value === 'configure') {\n ctx.state.ui.hideOverlay();\n void configurePluginFlow(ctx, plugin);\n return;\n }\n if (item.value === 'toggle') {\n void ctx.pluginManager\n .setEnabled(plugin.id, plugin.scope, !plugin.enabled)\n .then(() => {\n ctx.state.ui.hideOverlay();\n showPluginsList(ctx);\n })\n .catch(error => reportPluginMutationError(ctx, actionLabel, error));\n return;\n }\n if (item.value === 'uninstall') {\n void ctx.pluginManager\n .uninstall(plugin.id, plugin.scope)\n .then(() => {\n ctx.state.ui.hideOverlay();\n showPluginsList(ctx);\n })\n .catch(error => reportPluginMutationError(ctx, 'Uninstall', error));\n }\n };\n actions.onCancel = () => {\n ctx.state.ui.hideOverlay();\n showPluginsList(ctx);\n };\n container.addChild(actions);\n const modal = container as Box & { handleInput: (data: string) => void };\n modal.handleInput = (data: string) => actions.handleInput(data);\n showModalOverlay(ctx.state.ui, modal, { maxHeight: '80%' });\n}\n\nasync function configurePluginFlow(ctx: SlashCommandContext, plugin: LoadedPlugin): Promise<void> {\n if (!ctx.pluginManager || !plugin.configSchema) return;\n const entries = Object.entries(plugin.configSchema);\n const selected = await askModalQuestion(ctx.state.ui, {\n question: `Configure ${plugin.name ?? plugin.id}:`,\n options: entries.map(([key, option]) => ({\n label: option.label ?? key,\n description: formatConfigDescription(key, option, plugin.configValues?.[key]),\n })),\n allowCustomResponse: false,\n });\n if (!selected) {\n showPluginDetail(ctx, plugin);\n return;\n }\n\n const entry = entries.find(([key, option]) => selected === (option.label ?? key));\n if (!entry) {\n showPluginDetail(ctx, plugin);\n return;\n }\n const [key, option] = entry;\n const value = await askPluginConfigValue(ctx, plugin, key, option);\n if (value === undefined) {\n await configurePluginFlow(ctx, plugin);\n return;\n }\n try {\n await ctx.pluginManager.setConfigValue(plugin.id, plugin.scope, key, value);\n ctx.showInfo(`Updated plugin setting ${key}.`);\n } catch (error) {\n reportPluginMutationError(ctx, `Update setting ${key}`, error);\n }\n}\n\nfunction formatConfigDescription(\n key: string,\n option: MastraCodePluginConfigOption,\n value: MastraCodePluginConfigValue,\n): string {\n const current = value === undefined ? '(unset)' : String(value);\n return `${option.type} · ${option.description ?? key} · current: ${current}`;\n}\n\nfunction formatConfigValueQuestion(key: string, option: MastraCodePluginConfigOption): string {\n const label = option.label ?? key;\n return option.description ? `${label}\\n${theme.fg('dim', option.description)}` : label;\n}\n\nasync function askPluginConfigValue(\n ctx: SlashCommandContext,\n plugin: LoadedPlugin,\n key: string,\n option: MastraCodePluginConfigOption,\n): Promise<MastraCodePluginConfigValue> {\n const current = plugin.configValues?.[key];\n if (option.type === 'boolean') {\n const answer = await askModalQuestion(ctx.state.ui, {\n question: formatConfigValueQuestion(key, option),\n options: [\n { label: 'Use default', description: 'Clear this setting and use the plugin default' },\n { label: 'On', description: 'true' },\n { label: 'Off', description: 'false' },\n ],\n allowCustomResponse: false,\n });\n if (!answer) return undefined;\n if (answer === 'Use default') return '';\n return answer === 'On';\n }\n\n if (option.type === 'model') {\n return askPluginModelValue(\n ctx,\n formatConfigValueQuestion(key, option),\n typeof current === 'string' ? current : undefined,\n );\n }\n\n const answer = await askModalQuestion(ctx.state.ui, {\n question: formatConfigValueQuestion(key, option),\n defaultValue: typeof current === 'string' ? current : undefined,\n allowCustomResponse: true,\n allowEmptyInput: true,\n });\n return answer ?? undefined;\n}\n\nasync function askPluginModelValue(\n ctx: SlashCommandContext,\n title: string,\n currentModelId?: string,\n): Promise<string | undefined> {\n const action = await askModalQuestion(ctx.state.ui, {\n question: title,\n options: [\n { label: 'Select model', description: currentModelId ? `current: ${currentModelId}` : 'Choose a specific model' },\n { label: 'Inherit parent model', description: 'Clear this setting and use the active session model' },\n ],\n allowCustomResponse: false,\n });\n if (!action) return undefined;\n if (action === 'Inherit parent model') return '';\n\n const availableModels = await ctx.state.controller.listAvailableModels();\n if (availableModels.length === 0) return undefined;\n\n return new Promise<string | undefined>(resolve => {\n const selector = new ModelSelectorComponent({\n tui: ctx.state.ui,\n models: availableModels,\n currentModelId,\n title,\n onSelect: async (model: ModelItem) => {\n ctx.state.ui.hideOverlay();\n await promptForApiKeyIfNeeded(ctx.state.ui, model, ctx.authStorage);\n resolve(model.id);\n },\n onCancel: () => {\n ctx.state.ui.hideOverlay();\n resolve(undefined);\n },\n });\n\n showModalOverlay(ctx.state.ui, selector, { maxHeight: '75%' });\n selector.focused = true;\n });\n}\n\nasync function installPluginFlow(ctx: SlashCommandContext): Promise<void> {\n if (!ctx.pluginManager) return;\n const source = await askModalQuestion(ctx.state.ui, {\n question: 'Install plugin from:',\n options: [{ label: 'GitHub URL' }, { label: 'Local path' }],\n });\n if (!source) return;\n\n const specifier =\n source === 'Local path'\n ? await askLocalPluginPath(ctx)\n : await askModalQuestion(ctx.state.ui, {\n question: 'GitHub URL:',\n allowCustomResponse: true,\n });\n if (!specifier) return;\n\n const scopeAnswer = await askModalQuestion(ctx.state.ui, {\n question: 'Install scope:',\n options: [{ label: 'global' }, { label: 'project' }],\n });\n if (scopeAnswer !== 'project' && scopeAnswer !== 'global') return;\n\n const installWarning =\n source === 'GitHub URL'\n ? 'Plugins run code inside Mastra Code and can access your workspace. GitHub plugins also auto-update from their repository, so only install plugins from sources you trust. Continue?'\n : 'Plugins run code inside Mastra Code and can access your workspace. Continue?';\n const confirmed = await askModalQuestion(ctx.state.ui, {\n question: installWarning,\n options: [{ label: 'Install' }, { label: 'Cancel' }],\n });\n if (confirmed !== 'Install') return;\n\n try {\n const id = await installPluginWithOptionalEntryPrompt(ctx, source, specifier, scopeAnswer);\n if (!id) return;\n ctx.showInfo(`Installed plugin ${id}.`);\n showPluginsList(ctx);\n } catch (error) {\n ctx.showError(error instanceof Error ? error.message : String(error));\n }\n}\n\nasync function askLocalPluginPath(ctx: SlashCommandContext): Promise<string | null> {\n const discovered = ctx.pluginManager?.discoverLocal('.') ?? [];\n return askModalQuestion(ctx.state.ui, {\n question: discovered.length ? 'Local plugin path or discovered plugin:' : 'Local plugin path:',\n ...(discovered.length\n ? {\n options: discovered.map(plugin => ({ label: plugin.path, description: plugin.name })),\n allowCustomResponse: true,\n }\n : { allowCustomResponse: true }),\n });\n}\n\nasync function installPluginWithOptionalEntryPrompt(\n ctx: SlashCommandContext,\n source: string,\n specifier: string,\n scope: PluginScope,\n): Promise<string | undefined> {\n if (!ctx.pluginManager) return undefined;\n const install = (entry?: string) => {\n if (source === 'Local path') {\n return entry\n ? ctx.pluginManager!.installLocal(specifier, scope, { entry })\n : ctx.pluginManager!.installLocal(specifier, scope);\n }\n return withGithubPluginInstallProgress(ctx, specifier, options =>\n entry\n ? ctx.pluginManager!.installGithub(specifier, scope, { entry, ...options })\n : ctx.pluginManager!.installGithub(specifier, scope, options),\n );\n };\n\n try {\n return await install();\n } catch (error) {\n if (!isEntryDetectionError(error)) throw error;\n if (source === 'Local path') {\n const discovered = ctx.pluginManager.discoverLocal(specifier);\n if (discovered.length > 0) {\n const selected = await askModalQuestion(ctx.state.ui, {\n question: 'That path is not a plugin. Install discovered plugin:',\n options: discovered.map(plugin => ({ label: plugin.path, description: plugin.name })),\n });\n if (!selected) return undefined;\n return ctx.pluginManager.installLocal(selected, scope);\n }\n }\n\n const entry = await askModalQuestion(ctx.state.ui, {\n question: 'Could not auto-detect plugin entry. Entry file or directory path:',\n allowCustomResponse: true,\n });\n if (!entry) return undefined;\n return install(entry);\n }\n}\n\nfunction isEntryDetectionError(error: unknown): boolean {\n return error instanceof Error && error.message.startsWith('Could not find a plugin entry file.');\n}\n","import { getUserName } from '@mastra/code-sdk/utils/project';\nimport type { SlashCommandContext } from './types.js';\n\n/**\n * /feedback command — annotate the most recent trace with user feedback.\n *\n * Feedback is emitted through the observability event bus so it reaches all\n * configured exporters (DuckDB, cloud, Langfuse, etc.) without requiring\n * direct storage access. A minimal correlationContext is supplied so the\n * observability layer does not need to re-hydrate the trace from storage —\n * this keeps the command working even when the local DuckDB is locked by\n * another process.\n *\n * Usage:\n * /feedback up — thumbs up\n * /feedback down — thumbs down\n * /feedback down Bad tool selection — thumbs down with comment\n * /feedback 4 — numeric rating (0–10)\n * /feedback comment Great response — text comment only\n */\nexport async function handleFeedbackCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n if (args.length === 0) {\n ctx.showInfo(`Usage:\n /feedback up — thumbs up\n /feedback down — thumbs down\n /feedback down <comment> — thumbs down with comment\n /feedback <0-10> — numeric rating\n /feedback comment <text> — text comment only`);\n return;\n }\n\n // Resolve trace context.\n // session.run.getTraceId() returns the actual observability traceId (OTel 32-hex-char ID)\n // captured from the stream response. session.getCurrentRunId() returns the agent's runId (UUID).\n // We pass both so the cloud endpoint can correlate feedback to the correct trace.\n const traceId = ctx.state.session.run.getTraceId() ?? undefined;\n const runId = ctx.state.session.getCurrentRunId() ?? undefined;\n const threadId = ctx.state.session.thread.getId() ?? undefined;\n\n // Feedback correlates to an actual run/trace. A bound thread alone is not\n // enough — every session has a thread, but there may be no run to rate yet.\n if (!traceId && !runId) {\n ctx.showError('No active session to attach feedback to.');\n return;\n }\n\n // Get observability from the Mastra instance so feedback flows through the\n // event bus to all exporters (cloud, DuckDB, etc.).\n const mastra = ctx.controller.getMastra();\n const observability = mastra?.observability;\n if (!observability?.addFeedback) {\n ctx.showError('Observability not configured — cannot save feedback.');\n return;\n }\n\n // Parse the feedback input\n const subcommand = args[0]!.toLowerCase();\n const rest = args.slice(1).join(' ').trim();\n\n let feedbackType: string;\n let value: number | string;\n let comment: string | undefined;\n\n if (subcommand === 'up') {\n feedbackType = 'thumbs';\n value = 1;\n comment = rest || undefined;\n } else if (subcommand === 'down') {\n feedbackType = 'thumbs';\n value = 0;\n comment = rest || undefined;\n } else if (subcommand === 'comment') {\n if (!rest) {\n ctx.showError('Please provide a comment: /feedback comment <text>');\n return;\n }\n feedbackType = 'comment';\n value = rest;\n comment = rest;\n } else {\n // Try numeric rating\n const num = Number(subcommand);\n if (!Number.isNaN(num) && num >= 0 && num <= 10) {\n feedbackType = 'rating';\n value = num;\n comment = rest || undefined;\n } else {\n ctx.showError(`Unknown feedback type: \"${subcommand}\". Use up, down, comment, or a number 0-10.`);\n return;\n }\n }\n\n try {\n await observability.addFeedback({\n // Pass the actual traceId so the feedback is correlated to the trace.\n traceId,\n // Supply a correlationContext so the observability layer emits the event\n // directly without looking up the trace from storage (which may be locked).\n correlationContext: {\n traceId,\n runId,\n },\n feedback: {\n feedbackType,\n feedbackSource: 'mastracode',\n feedbackUserId: getUserName(),\n value,\n comment,\n metadata: {\n ...(threadId ? { threadId } : {}),\n ...(runId ? { runId } : {}),\n },\n },\n });\n\n // Build confirmation message\n let msg: string;\n if (feedbackType === 'thumbs') {\n msg = value === 1 ? 'Feedback recorded: 👍' : 'Feedback recorded: 👎';\n } else if (feedbackType === 'rating') {\n msg = `Feedback recorded: ${value}/10`;\n } else {\n msg = 'Comment recorded.';\n }\n if (comment && feedbackType !== 'comment') {\n msg += ` — \"${comment}\"`;\n }\n\n ctx.showInfo(msg);\n } catch (err) {\n ctx.showError(`Failed to save feedback: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n","import { loadSettings, OBSERVABILITY_AUTH_PREFIX, saveSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { askModalQuestion } from '../modal-question.js';\nimport { theme } from '../theme.js';\nimport type { SlashCommandContext } from './types.js';\n\nconst VALID_PROJECT_ID = /^[a-zA-Z0-9_-]+$/;\n\nfunction showStatus(ctx: SlashCommandContext): void {\n const resourceId = ctx.state.session.identity.getResourceId();\n const settings = loadSettings();\n const resourceConfig = settings.observability.resources[resourceId];\n const hasToken = ctx.authStorage?.hasStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`) ?? false;\n\n const lines: string[] = [theme.bold(theme.fg('accent', 'Observability')), ''];\n\n // Cloud status\n lines.push(theme.bold('Cloud'));\n if (resourceConfig && hasToken) {\n lines.push(` ${theme.fg('success', '●')} Connected`);\n lines.push(` Project: ${resourceConfig.projectId}`);\n lines.push(` Resource: ${resourceId}`);\n lines.push(` Since: ${new Date(resourceConfig.configuredAt).toLocaleDateString()}`);\n } else if (resourceConfig && !hasToken) {\n lines.push(` ${theme.fg('warning', '●')} Partially configured (missing token)`);\n lines.push(` Project: ${resourceConfig.projectId}`);\n lines.push('');\n lines.push(theme.fg('dim', ' Run /observability connect to re-enter credentials.'));\n } else {\n const envToken = process.env.MASTRA_CLOUD_ACCESS_TOKEN;\n const envProject = process.env.MASTRA_PROJECT_ID;\n if (envToken) {\n lines.push(` ${theme.fg('success', '●')} Connected ${theme.fg('dim', '(via environment variables)')}`);\n if (envProject) {\n lines.push(` Project: ${envProject}`);\n }\n lines.push(` Resource: ${resourceId}`);\n } else {\n lines.push(` ${theme.fg('dim', '●')} Not configured`);\n lines.push(` Resource: ${resourceId}`);\n }\n }\n\n // Local tracing status\n lines.push('');\n lines.push(theme.bold('Local tracing (DuckDB)'));\n if (settings.observability.localTracing) {\n lines.push(` ${theme.fg('success', '●')} Enabled`);\n } else {\n lines.push(` ${theme.fg('dim', '●')} Disabled`);\n }\n\n lines.push('');\n lines.push(theme.fg('dim', 'Commands:'));\n lines.push(theme.fg('dim', ' /observability connect — configure cloud project'));\n lines.push(theme.fg('dim', ' /observability disconnect — remove cloud configuration'));\n lines.push(theme.fg('dim', ' /observability local on — enable local DuckDB tracing'));\n lines.push(theme.fg('dim', ' /observability local off — disable local DuckDB tracing'));\n\n ctx.showInfo(lines.join('\\n'));\n}\n\nasync function handleConnect(ctx: SlashCommandContext): Promise<void> {\n if (!ctx.authStorage) {\n ctx.showError('Auth storage not available. Cannot store credentials.');\n return;\n }\n\n const resourceId = ctx.state.session.identity.getResourceId();\n const projectId = await askModalQuestion(ctx.state.ui, { question: 'Enter your cloud project ID:' });\n if (!projectId) return;\n\n if (!VALID_PROJECT_ID.test(projectId)) {\n ctx.showError('Invalid project ID. Only letters, numbers, hyphens, and underscores are allowed.');\n return;\n }\n\n const token = await askModalQuestion(ctx.state.ui, { question: 'Enter your cloud access token:' });\n if (!token) return;\n\n const settings = loadSettings();\n settings.observability.resources[resourceId] = {\n projectId,\n configuredAt: new Date().toISOString(),\n };\n saveSettings(settings);\n\n ctx.authStorage.setStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`, token);\n\n ctx.showInfo(\n `${theme.fg('success', '✓')} Cloud observability configured.\\n` +\n ` Project: ${projectId}\\n` +\n ` Resource: ${resourceId}\\n\\n` +\n theme.fg('dim', 'Restart MastraCode for the new configuration to take effect.'),\n );\n}\n\nfunction handleLocal(ctx: SlashCommandContext, args: string[]): void {\n const toggle = args[1]?.trim().toLowerCase();\n if (toggle !== 'on' && toggle !== 'off') {\n const settings = loadSettings();\n const current = settings.observability.localTracing ? 'on' : 'off';\n ctx.showInfo(\n `Local DuckDB tracing is currently ${theme.bold(current)}.\\n\\n` +\n theme.fg('dim', 'Usage:\\n /observability local on — enable\\n /observability local off — disable'),\n );\n return;\n }\n\n const enable = toggle === 'on';\n const settings = loadSettings();\n if (settings.observability.localTracing === enable) {\n ctx.showInfo(`Local tracing is already ${theme.bold(toggle)}.`);\n return;\n }\n\n settings.observability.localTracing = enable;\n saveSettings(settings);\n\n if (enable) {\n ctx.showInfo(\n `${theme.fg('success', '✓')} Local DuckDB tracing enabled.\\n` +\n theme.fg('dim', 'Restart MastraCode for changes to take effect.'),\n );\n } else {\n ctx.showInfo(\n `${theme.fg('success', '✓')} Local DuckDB tracing disabled.\\n` +\n theme.fg(\n 'dim',\n 'Restart MastraCode for changes to take effect.\\nExisting data remains at the DuckDB path — delete manually if needed.',\n ),\n );\n }\n}\n\nfunction handleDisconnect(ctx: SlashCommandContext): void {\n const resourceId = ctx.state.session.identity.getResourceId();\n const settings = loadSettings();\n\n const hadConfig = resourceId in settings.observability.resources;\n const hadToken = ctx.authStorage?.hasStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`) ?? false;\n\n if (!hadConfig && !hadToken) {\n ctx.showInfo(`No cloud observability configured for resource \"${resourceId}\".`);\n return;\n }\n\n delete settings.observability.resources[resourceId];\n saveSettings(settings);\n\n if (ctx.authStorage) {\n ctx.authStorage.remove(`apikey:${OBSERVABILITY_AUTH_PREFIX}${resourceId}`);\n }\n\n ctx.showInfo(\n `${theme.fg('success', '✓')} Cloud observability disconnected for resource \"${resourceId}\".\\n` +\n theme.fg('dim', 'Restart MastraCode for changes to take effect.'),\n );\n}\n\nexport async function handleObservabilityCommand(ctx: SlashCommandContext, args: string[]): Promise<void> {\n const sub = args[0]?.trim().toLowerCase();\n\n switch (sub) {\n case 'connect':\n await handleConnect(ctx);\n break;\n case 'disconnect':\n handleDisconnect(ctx);\n break;\n case 'local':\n handleLocal(ctx, args);\n break;\n case 'status':\n case undefined:\n showStatus(ctx);\n break;\n default:\n ctx.showInfo(\n 'Usage:\\n' +\n ' /observability — show current status\\n' +\n ' /observability connect — configure cloud observability\\n' +\n ' /observability disconnect — remove cloud configuration\\n' +\n ' /observability local on — enable local DuckDB tracing\\n' +\n ' /observability local off — disable local DuckDB tracing',\n );\n }\n}\n","import { loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { GITHUB_SIGNALS_METADATA_KEY } from '@mastra/github-signals';\nimport type { GithubPRSignalInput } from '@mastra/github-signals';\nimport { askModalQuestion } from '../modal-question.js';\nimport type { SlashCommandContext } from './types.js';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction formatLocalTimestamp(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: 'medium',\n timeStyle: 'medium',\n hour12: true,\n }).format(date);\n}\n\nfunction formatPollInterval(value: number): string {\n if (value % 60_000 === 0) return `${value / 60_000}m`;\n return `${Math.round(value / 1000)}s`;\n}\n\nfunction parseGithubPRReference(input: string): GithubPRSignalInput | undefined {\n const trimmed = input.trim();\n if (!trimmed) return undefined;\n\n const numberOnly = /^#?(\\d+)$/.exec(trimmed);\n if (numberOnly?.[1]) return Number(numberOnly[1]);\n\n const repoReference = /^(?:https:\\/\\/github\\.com\\/)?([^\\s/#]+)\\/([^\\s/#]+)(?:\\/pull\\/|#)(\\d+)$/.exec(trimmed);\n if (repoReference?.[1] && repoReference[2] && repoReference[3]) {\n return { owner: repoReference[1], repo: repoReference[2], number: Number(repoReference[3]) };\n }\n\n return undefined;\n}\n\nasync function getCurrentGithubThread(ctx: SlashCommandContext): Promise<{\n threadId?: string;\n resourceId?: string;\n metadata?: Record<string, unknown>;\n}> {\n const session = ctx.state.session as unknown as {\n identity?: {\n getResourceId?: () => string | undefined;\n };\n thread?: {\n getId?: () => string | undefined;\n list?: (input?: {\n allResources?: boolean;\n }) => Promise<Array<{ id: string; resourceId?: string; metadata?: Record<string, unknown> }>>;\n };\n };\n const threadId = session?.thread?.getId?.();\n if (!threadId) return {};\n\n const thread = (await session?.thread?.list?.({ allResources: true }))?.find(item => item.id === threadId);\n return {\n threadId,\n resourceId: thread?.resourceId ?? session?.identity?.getResourceId?.(),\n metadata: thread?.metadata,\n };\n}\n\nfunction getGithubSubscriptionsFromThreadMetadata(metadata: Record<string, unknown> | undefined): Array<{\n owner?: string;\n repo?: string;\n number: number;\n}> {\n const mastra = isPlainObject(metadata?.mastra) ? metadata.mastra : {};\n const githubSignals = isPlainObject(mastra[GITHUB_SIGNALS_METADATA_KEY]) ? mastra[GITHUB_SIGNALS_METADATA_KEY] : {};\n const subscriptions = Array.isArray(githubSignals.subscriptions) ? githubSignals.subscriptions : [];\n return subscriptions.flatMap(subscription => {\n if (!isPlainObject(subscription) || typeof subscription.number !== 'number') return [];\n return [\n {\n ...(typeof subscription.owner === 'string' ? { owner: subscription.owner } : {}),\n ...(typeof subscription.repo === 'string' ? { repo: subscription.repo } : {}),\n number: subscription.number,\n },\n ];\n });\n}\n\nasync function describeGithubSubscriptions(ctx: SlashCommandContext): Promise<string> {\n const { threadId, resourceId, metadata } = await getCurrentGithubThread(ctx);\n if (!threadId) return 'GitHub Signals debug: no current thread.';\n\n const thread = { resourceId, metadata };\n const mastra = isPlainObject(thread?.metadata?.mastra) ? thread.metadata.mastra : {};\n const githubSignals = isPlainObject(mastra[GITHUB_SIGNALS_METADATA_KEY]) ? mastra[GITHUB_SIGNALS_METADATA_KEY] : {};\n const subscriptions = Array.isArray(githubSignals.subscriptions) ? githubSignals.subscriptions : [];\n if (subscriptions.length === 0) return `GitHub Signals debug for ${threadId}: no subscribed PRs.`;\n\n const githubSignalsProcessor = ctx.state.options?.githubSignals;\n const pollingActive = thread?.resourceId\n ? (githubSignalsProcessor?.isPollingThread({ threadId, resourceId: thread.resourceId }) ?? false)\n : false;\n const pollIntervalMs = githubSignalsProcessor?.getPollIntervalMs?.();\n const header = `GitHub Signals debug for ${threadId}: ${subscriptions.length} subscription${subscriptions.length === 1 ? '' : 's'}, polling=${pollingActive ? 'active' : 'inactive'}${pollIntervalMs ? `, interval=${formatPollInterval(pollIntervalMs)}` : ''}`;\n\n const lines = subscriptions.map(subscription => {\n if (!isPlainObject(subscription)) return '- invalid subscription metadata';\n const pr = `${subscription.owner}/${subscription.repo}#${subscription.number}`;\n const sync = subscription.lastSyncStatus ? `sync=${subscription.lastSyncStatus}` : 'sync=unknown';\n const poll = subscription.lastSyncAt\n ? `lastPoll=${formatLocalTimestamp(subscription.lastSyncAt)}`\n : 'lastPoll=never';\n const observed = [\n subscription.lastObservedGithubUpdatedAt\n ? `githubUpdated=${formatLocalTimestamp(subscription.lastObservedGithubUpdatedAt)}`\n : undefined,\n subscription.lastObservedState ? `state=${subscription.lastObservedState}` : undefined,\n subscription.lastObservedCiState ? `ci=${subscription.lastObservedCiState}` : undefined,\n subscription.lastObservedMergeableState ? `merge=${subscription.lastObservedMergeableState}` : undefined,\n subscription.lastObservedReviewStateHash ? `reviews=${subscription.lastObservedReviewStateHash}` : undefined,\n ].filter(Boolean);\n const notificationTime = formatLocalTimestamp(subscription.lastNotificationAt) ?? 'unknown time';\n const notification = subscription.lastNotificationKind\n ? `lastNotification=${subscription.lastNotificationKind}/${subscription.lastNotificationPriority ?? 'unknown'} at ${notificationTime}: ${subscription.lastNotificationSummary ?? ''}`\n : 'lastNotification=none';\n return `- ${pr} ${sync} ${poll}${subscription.lastSyncError ? ` error=${subscription.lastSyncError}` : ''}${observed.length ? ` (${observed.join(', ')})` : ''}\\n ${notification}`;\n });\n return [header, ...lines].join('\\n');\n}\n\nasync function syncGithubSubscriptions(ctx: SlashCommandContext): Promise<void> {\n const githubSignalsProcessor = ctx.state.options?.githubSignals;\n if (!githubSignalsProcessor?.syncThreadNow) {\n ctx.showError('GitHub signals are not available. Enable them in /settings and restart MastraCode.');\n return;\n }\n\n const { threadId, resourceId } = await getCurrentGithubThread(ctx);\n if (!threadId || !resourceId) {\n ctx.showError('GitHub sync requires a current thread.');\n return;\n }\n\n try {\n const count = await githubSignalsProcessor.syncThreadNow({ threadId, resourceId });\n if (count === 0) {\n ctx.showInfo('No GitHub PR subscriptions to sync.');\n }\n } catch (error) {\n ctx.showError(`Failed to sync GitHub PR subscriptions: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nasync function detectCurrentPullRequest(ctx: SlashCommandContext): Promise<string> {\n const { execFile } = await import('node:child_process');\n return new Promise(resolve => {\n execFile(\n 'gh',\n ['pr', 'view', '--json', 'url', '--jq', '.url'],\n { cwd: ctx.state.projectInfo.rootPath },\n (error, stdout) => {\n resolve(error ? '' : stdout.trim());\n },\n );\n });\n}\n\nexport async function handleGithubCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n if (!loadSettings().signals.experimentalGithubSignals) {\n ctx.showError('Experimental GitHub signals are disabled. Enable them in /settings and restart MastraCode.');\n return;\n }\n\n const [maybeAction, ...restArgs] = args;\n if (maybeAction === 'debug') {\n ctx.showInfo(await describeGithubSubscriptions(ctx));\n return;\n }\n if (maybeAction === 'sync') {\n await syncGithubSubscriptions(ctx);\n return;\n }\n const explicitSubscribe = maybeAction === 'subscribe' || maybeAction === 'sub';\n const action = maybeAction === 'unsubscribe' || maybeAction === 'unsub' ? 'unsubscribe' : 'subscribe';\n const referenceArgs = action === 'unsubscribe' || explicitSubscribe ? restArgs : args;\n const inlineReference = referenceArgs.join(' ').trim();\n const currentThread = await getCurrentGithubThread(ctx);\n const existingSubscriptions = getGithubSubscriptionsFromThreadMetadata(currentThread.metadata);\n const reference = inlineReference\n ? inlineReference\n : action === 'unsubscribe' && existingSubscriptions.length === 1\n ? existingSubscriptions[0]!\n : await askModalQuestion(ctx.state.ui, {\n question: `GitHub PR to ${action} ${action === 'subscribe' ? 'to' : 'from'}`,\n defaultValue: await detectCurrentPullRequest(ctx),\n });\n if (reference === null) return;\n\n const parsed = typeof reference === 'string' ? parseGithubPRReference(reference) : reference;\n if (!parsed) {\n ctx.showError(\n 'Usage: /github 123, /github owner/repo#123, /github unsubscribe 123, /github sync, /github debug, or /github https://github.com/owner/repo/pull/123',\n );\n return;\n }\n if (!currentThread.threadId || !currentThread.resourceId) {\n ctx.showError(`GitHub ${action} requires a current thread.`);\n return;\n }\n\n const githubSignalsProcessor = ctx.state.options?.githubSignals;\n const runOperation =\n action === 'unsubscribe'\n ? githubSignalsProcessor?.unsubscribeThreadFromPR\n : githubSignalsProcessor?.subscribeThreadToPR;\n if (!runOperation) {\n ctx.showError('GitHub signals are not available. Enable them in /settings and restart MastraCode.');\n return;\n }\n\n try {\n const result = await runOperation.call(githubSignalsProcessor, {\n threadId: currentThread.threadId,\n resourceId: currentThread.resourceId,\n pr: parsed,\n });\n const prefix =\n action === 'unsubscribe' ? (result.removed ? 'Unsubscribed from' : 'No subscription found for') : 'Subscribed to';\n ctx.showInfo(`${prefix} ${result.owner}/${result.repo}#${result.number}.`);\n } catch (error) {\n ctx.showError(`Failed to ${action} GitHub PR: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","/**\n * /prune — hand the terminal over to storage maintenance.\n *\n * Retention deletes and VACUUM need the database to themselves: running them\n * over the live connection contends with agent writes (SQLITE_BUSY) and\n * starves the TUI event loop, freezing the UI. So this command stops the TUI,\n * quiesces background writers, runs maintenance with plain-text progress\n * output on the released terminal, then exits the process.\n *\n * Usage:\n * /prune delete rows older than the retention policies, then exit\n * /prune vacuum prune, then checkpoint WAL + VACUUM to return disk to the OS, then exit\n * /prune keep-memory prune, but keep chat history (messages/threads)\n * /prune vacuum keep-memory flags combine in any order\n */\nimport { runStorageMaintenance } from '@mastra/code-sdk/utils/storage-maintenance';\n\nimport type { SlashCommandContext } from './types.js';\n\nexport async function handlePruneCommand(ctx: SlashCommandContext, args: string[] = []): Promise<void> {\n const maintenance = ctx.state.options.storageMaintenance;\n if (!maintenance) {\n ctx.showError('Storage maintenance is not available in this session.');\n return;\n }\n\n const flags = new Set(args.map(a => a.toLowerCase()));\n const unknown = [...flags].filter(f => f !== 'vacuum' && f !== 'keep-memory');\n if (unknown.length > 0) {\n ctx.showError(`Unknown /prune option: ${unknown.join(', ')}\\nUsage: /prune [vacuum] [keep-memory]`);\n return;\n }\n const vacuum = flags.has('vacuum');\n const keepMemory = flags.has('keep-memory');\n\n // Hand the terminal back so progress prints as plain text and the deletes\n // can't freeze the UI or race the agent's own writes. The TUI's alternate\n // screen is discarded on stop, so all messaging goes to console.log after.\n ctx.stop();\n\n // console.info goes to the released terminal (and is captured by the e2e\n // terminal backend).\n const log = (line: string) => console.info(line);\n log('Closing the TUI to run storage maintenance…');\n let exitCode = 0;\n try {\n // Quiesce background writers so maintenance has the db to itself. Surface\n // any failures — a writer that didn't stop is exactly the SQLITE_BUSY\n // contention this handoff exists to prevent.\n const quiesceSteps = ['MCP disconnect', 'stop workers', 'stop intervals'] as const;\n const quiesceResults = await Promise.allSettled([\n ctx.mcpManager?.disconnect(),\n ctx.controller.getMastra()?.stopWorkers(),\n ctx.controller.stopIntervals(),\n ]);\n for (const [i, result] of quiesceResults.entries()) {\n if (result.status === 'rejected') {\n log(\n `Warning: failed to quiesce a background writer (${quiesceSteps[i]}): ${\n result.reason instanceof Error ? result.reason.message : String(result.reason)\n }`,\n );\n }\n }\n\n await runStorageMaintenance({ maintenance, vacuum, keepMemory, log });\n log('Storage maintenance complete. Run mastracode to start a new session.');\n } catch (err) {\n log(`Storage maintenance failed: ${err instanceof Error ? err.message : String(err)}`);\n exitCode = 1;\n }\n // The storage connection is closed — a fresh process is required either way.\n process.exit(exitCode);\n}\n","import { showInfo } from './display.js';\nimport type { TUIState } from './state.js';\n\nexport const GOAL_JUDGE_INPUT_LOCK_MESSAGE = 'Goal judge is evaluating; wait a moment or press Esc to pause the goal.';\n\nexport function isGoalJudgeInputLocked(state: TUIState): boolean {\n return Boolean(state.activeGoalJudge);\n}\n\nexport function showGoalJudgeInputLockInfo(state: TUIState): void {\n showInfo(state, GOAL_JUDGE_INPUT_LOCK_MESSAGE);\n}\n\nexport function canRunSlashCommandDuringGoalJudge(command: string, args: string[]): boolean {\n if (command === 'exit') return true;\n if (command !== 'goal') return false;\n return args[0] === 'pause' || args[0] === 'clear';\n}\n","/**\n * Slash command dispatcher: routes command strings to extracted handlers.\n */\nimport { processSlashCommand } from '@mastra/code-sdk/utils/slash-command-processor';\nimport { insertChatComponentWithBoundarySpacing } from './chat-boundary-reconciliation.js';\nimport { startGoalWithDefaults } from './commands/goal.js';\nimport {\n handleHelpCommand,\n handleCostCommand,\n handleYoloCommand,\n handleVoiceCommand,\n handleThinkCommand,\n handlePermissionsCommand,\n handleNameCommand,\n handleExitCommand,\n handleHooksCommand,\n handleMcpCommand,\n handleModeCommand,\n handleSkillCommand,\n handleSkillsCommand,\n handleNewCommand,\n handleCloneCommand,\n handleResourceCommand,\n handleDiffCommand,\n handleThreadsCommand,\n handleThreadCommand,\n handleThreadTagDirCommand,\n handleSandboxCommand as handleSandboxCmd,\n handleModelsPackCommand,\n handleCustomProvidersCommand,\n handleSubagentsCommand,\n handleOMCommand,\n handleSettingsCommand,\n handleLoginCommand,\n handleReviewCommand as handleReviewCmd,\n handleReportIssueCommand as handleReportIssueCmd,\n handleSetupCommand,\n handleBrowserCommand,\n handleThemeCommand,\n handleUpdateCommand,\n handleMastraGatewayCommand,\n handleApiKeysCommand,\n handlePluginsCommand,\n handleFeedbackCommand,\n handleObservabilityCommand,\n handleGithubCommand,\n handleGoalCommand,\n handlePruneCommand,\n} from './commands/index.js';\nimport { isCurrentThreadActive, sendSlashCommandMessage } from './commands/send-slash-command-message.js';\nimport type { SlashCommandContext } from './commands/types.js';\nimport { SlashCommandComponent } from './components/slash-command.js';\nimport { showError, showInfo } from './display.js';\nimport {\n canRunSlashCommandDuringGoalJudge,\n isGoalJudgeInputLocked,\n showGoalJudgeInputLockInfo,\n} from './goal-input-lock.js';\nimport type { TUIState } from './state.js';\n\nconst TRACKED_COMMANDS = new Set([\n 'login',\n 'models',\n 'mode',\n 'gateway',\n 'memory-gateway',\n 'custom-providers',\n 'threads',\n 'new',\n]);\n\n/**\n * Dispatch a slash command input to the appropriate handler.\n * Returns true if the command was handled (or was unknown), false if not a command.\n */\nexport async function dispatchSlashCommand(\n input: string,\n state: TUIState,\n buildCtx: () => SlashCommandContext,\n): Promise<boolean> {\n const trackCommand = (ctx: SlashCommandContext, command: string) => {\n if (!TRACKED_COMMANDS.has(command)) return;\n ctx.analytics?.trackCommand(command, {\n action: 'attempted',\n threadId: state.session.thread.getId(),\n resourceId: state.session.identity.getResourceId(),\n mode: state.session.mode.get(),\n });\n };\n const trimmedInput = input.trim();\n\n const slashMatch = trimmedInput.match(/^(\\/\\/?)([\\s\\S]*)$/);\n const slashPrefix = slashMatch?.[1] ?? '';\n const withoutSlashes = slashMatch?.[2] ?? trimmedInput;\n const firstWhitespaceIndex = withoutSlashes.search(/\\s/);\n const commandText = firstWhitespaceIndex === -1 ? withoutSlashes : withoutSlashes.slice(0, firstWhitespaceIndex);\n const rawArgsText = firstWhitespaceIndex === -1 ? '' : withoutSlashes.slice(firstWhitespaceIndex).trim();\n const parsedArgs = rawArgsText ? rawArgsText.split(/\\s+/) : [];\n\n if (slashPrefix === '//') {\n if (isGoalJudgeInputLocked(state)) {\n showGoalJudgeInputLockInfo(state);\n return true;\n }\n\n const cmdName = commandText;\n const cmdArgs = parsedArgs;\n const customCommand = state.customSlashCommands.find(cmd => cmd.name === cmdName);\n if (customCommand) {\n await handleCustomSlashCommand(\n state,\n customCommand,\n cmdArgs,\n buildCtx(),\n `//${cmdName}${rawArgsText ? ` ${rawArgsText}` : ''}`,\n );\n return true;\n }\n\n showError(state, `Unknown custom command: ${cmdName}`);\n return true;\n }\n\n const command = commandText;\n const goalSubcommands = new Set(['status', 'pause', 'resume', 'clear']);\n const firstGoalArg = parsedArgs[0]?.toLowerCase();\n const args =\n command === 'goal' && rawArgsText && !goalSubcommands.has(firstGoalArg ?? '') ? [rawArgsText] : parsedArgs;\n\n if (!command) {\n return true;\n }\n\n if (isGoalJudgeInputLocked(state) && !canRunSlashCommandDuringGoalJudge(command, args)) {\n showGoalJudgeInputLockInfo(state);\n return true;\n }\n\n const ctx = buildCtx();\n trackCommand(ctx, command);\n\n if (command.startsWith('goal/')) {\n await handleGoalSourceCommand(state, command.slice('goal/'.length), args, ctx);\n return true;\n }\n\n if (command.startsWith('skill/')) {\n await handleSkillCommand(buildCtx(), command.slice('skill/'.length), args);\n return true;\n }\n\n switch (command) {\n case 'new':\n await handleNewCommand(ctx);\n return true;\n case 'clone':\n await handleCloneCommand(ctx);\n return true;\n case 'threads':\n await handleThreadsCommand(ctx);\n return true;\n case 'thread':\n await handleThreadCommand(ctx);\n return true;\n case 'skills':\n await handleSkillsCommand(ctx);\n return true;\n case 'thread:tag-dir':\n await handleThreadTagDirCommand(ctx);\n return true;\n case 'sandbox':\n await handleSandboxCmd(ctx, args);\n return true;\n case 'mode':\n await handleModeCommand(ctx, args);\n return true;\n case 'models':\n await handleModelsPackCommand(ctx);\n return true;\n case 'custom-providers':\n await handleCustomProvidersCommand(ctx);\n return true;\n case 'subagents':\n await handleSubagentsCommand(ctx);\n return true;\n case 'memory':\n case 'om':\n await handleOMCommand(ctx);\n return true;\n case 'think':\n await handleThinkCommand(ctx, args);\n return true;\n case 'permissions':\n await handlePermissionsCommand(ctx, args);\n return true;\n case 'yolo':\n handleYoloCommand(ctx);\n return true;\n case 'voice':\n await handleVoiceCommand(ctx, args);\n return true;\n case 'settings':\n await handleSettingsCommand(ctx);\n return true;\n case 'login':\n await handleLoginCommand(ctx, 'login');\n return true;\n case 'logout':\n await handleLoginCommand(ctx, 'logout');\n return true;\n case 'cost':\n handleCostCommand(ctx);\n return true;\n case 'prune':\n await handlePruneCommand(ctx, args);\n return true;\n case 'diff':\n await handleDiffCommand(ctx, args[0]);\n return true;\n case 'name':\n await handleNameCommand(ctx, args);\n return true;\n case 'resource':\n await handleResourceCommand(ctx, args);\n return true;\n case 'exit':\n handleExitCommand(ctx);\n return true;\n case 'help':\n handleHelpCommand(ctx);\n return true;\n case 'hooks':\n handleHooksCommand(ctx, args);\n return true;\n case 'mcp':\n await handleMcpCommand(ctx, args);\n return true;\n case 'review':\n await handleReviewCmd(ctx, args);\n return true;\n case 'report-issue':\n await handleReportIssueCmd(ctx, args);\n return true;\n case 'setup':\n await handleSetupCommand(ctx);\n return true;\n case 'browser':\n await handleBrowserCommand(ctx, args);\n return true;\n case 'theme':\n await handleThemeCommand(ctx, args);\n return true;\n case 'update':\n await handleUpdateCommand(ctx);\n return true;\n case 'gateway':\n case 'memory-gateway':\n await handleMastraGatewayCommand(ctx);\n return true;\n case 'api-keys':\n await handleApiKeysCommand(buildCtx());\n return true;\n case 'plugins':\n await handlePluginsCommand(buildCtx(), args);\n return true;\n case 'feedback':\n await handleFeedbackCommand(buildCtx(), args);\n return true;\n case 'observability':\n await handleObservabilityCommand(buildCtx(), args);\n return true;\n case 'github':\n await handleGithubCommand(buildCtx(), args);\n return true;\n case 'goal':\n await handleGoalCommand(buildCtx(), args);\n return true;\n default: {\n const customCommand = state.customSlashCommands.find(cmd => cmd.name === command);\n if (customCommand) {\n await handleCustomSlashCommand(\n state,\n customCommand,\n args,\n ctx,\n `/${command}${rawArgsText ? ` ${rawArgsText}` : ''}`,\n );\n return true;\n }\n showError(state, `Unknown command: ${command}`);\n return true;\n }\n }\n}\n\n/**\n * Handle a custom slash command by processing its template and adding to context.\n */\nasync function handleGoalSourceCommand(\n state: TUIState,\n sourceName: string,\n args: string[],\n ctx: SlashCommandContext,\n): Promise<void> {\n const customCommand = state.customSlashCommands.find(cmd => cmd.name === sourceName && cmd.goal === true);\n if (customCommand) {\n try {\n const processedContent = await processSlashCommand(customCommand, args, process.cwd());\n const objective = processedContent.trim();\n if (!objective) {\n showInfo(state, `Goal command /goal/${customCommand.name} produced no output.`);\n return;\n }\n await startGoalWithDefaults(ctx, objective);\n } catch (error) {\n showError(\n state,\n `Error executing /goal/${sourceName}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n return;\n }\n\n const goalSkill = state.goalSkillCommands.find(skill => skill.name === sourceName);\n if (goalSkill) {\n try {\n let workspace = ctx.getResolvedWorkspace();\n if (!workspace && ctx.controller?.hasWorkspace?.()) {\n workspace = await ctx.controller.resolveWorkspace({ session: ctx.state.session });\n }\n const skill = await workspace?.skills?.get(goalSkill.path || goalSkill.name);\n if (!skill || skill.metadata?.goal !== true) {\n showError(state, `Unknown goal command: ${sourceName}`);\n return;\n }\n const trimmedArgs = args.join(' ').trim();\n const objective = `# Skill goal: ${skill.name}\\n\\n${skill.instructions}${\n trimmedArgs ? `\\n\\nARGUMENTS: ${trimmedArgs}` : ''\n }`;\n await startGoalWithDefaults(ctx, objective);\n } catch (error) {\n showError(\n state,\n `Error executing /goal/${sourceName}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n return;\n }\n\n showError(state, `Unknown goal command: ${sourceName}`);\n}\n\nasync function handleCustomSlashCommand(\n state: TUIState,\n command: { name: string; template: string; description?: string },\n args: string[],\n ctx: SlashCommandContext,\n displayText: string,\n): Promise<void> {\n try {\n // Process the command template\n const processedContent = await processSlashCommand(command as any, args, process.cwd());\n // Add the processed content as a system message / context\n if (processedContent.trim()) {\n const commandCtx = { ...ctx, state, controller: ctx.controller ?? state.controller } as SlashCommandContext;\n if (!isCurrentThreadActive(commandCtx)) {\n const slashComp = new SlashCommandComponent(command.name, processedContent.trim());\n state.allSlashCommandComponents.push(slashComp);\n insertChatComponentWithBoundarySpacing(state.chatContainer, slashComp);\n state.ui.requestRender();\n }\n\n // Wrap in <slash-command> tags so the assistant sees the full\n // content but addUserMessage won't double-render it.\n const wrapped = `<slash-command name=\"${command.name}\">\\n${processedContent.trim()}\\n</slash-command>`;\n await sendSlashCommandMessage(commandCtx, displayText, wrapped, { renderIdleUserMessage: false });\n } else {\n showInfo(state, `Executed //${command.name} (no output)`);\n }\n } catch (error) {\n showError(state, `Error executing //${command.name}: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","import type { Component } from '@earendil-works/pi-tui';\n\nimport type { TUIState } from './state.js';\n\nconst MAX_CHILDREN = 5000;\nconst KEEP_CHILDREN = 3000;\n\nexport function pruneChatContainer(state: TUIState): void {\n const children = state.chatContainer.children as Component[];\n if (children.length <= MAX_CHILDREN) {\n return;\n }\n\n const removeCount = children.length - KEEP_CHILDREN;\n const removed = new Set(children.slice(0, removeCount));\n\n children.splice(0, removeCount);\n state.chatContainer.invalidate();\n\n state.allToolComponents = state.allToolComponents.filter(\n component => !removed.has(component as unknown as Component),\n );\n state.allSlashCommandComponents = state.allSlashCommandComponents.filter(component => !removed.has(component));\n state.allSystemReminderComponents = state.allSystemReminderComponents.filter(component => !removed.has(component));\n state.allShellComponents = state.allShellComponents.filter(\n component => !removed.has(component as unknown as Component),\n );\n for (const [id, pending] of state.pendingSignalMessageComponentsById) {\n if (removed.has(pending.component as unknown as Component)) {\n state.pendingSignalMessageComponentsById.delete(id);\n }\n }\n}\n","/**\n * Event handlers for agent lifecycle events:\n * agent_start, agent_end (normal / aborted / error).\n */\nimport { getCurrentGitBranchAsync } from '@mastra/code-sdk/utils/project';\nimport type { GoalEvaluationPayload } from '@mastra/core/stream';\n\nimport { insertChatComponentWithBoundarySpacing } from '../chat-boundary-reconciliation.js';\nimport { JudgeDisplayComponent } from '../components/judge-display.js';\nimport { GradientAnimator } from '../components/obi-loader.js';\nimport { pruneChatContainer } from '../prune-chat.js';\nimport { clearPendingUserMessages, removePendingUserMessage } from '../render-messages.js';\nimport { flushRender, requestRender } from '../render-scheduler.js';\n\nimport type { EventHandlerContext } from './types.js';\n\nexport function handleAgentStart(ctx: EventHandlerContext): void {\n const { state } = ctx;\n\n // Refresh git branch async to avoid blocking the event loop\n getCurrentGitBranchAsync(state.projectInfo.rootPath).then(freshBranch => {\n if (freshBranch) {\n state.projectInfo.gitBranch = freshBranch;\n ctx.updateStatusLine();\n }\n });\n\n if (!state.gradientAnimator) {\n state.gradientAnimator = new GradientAnimator(() => {\n ctx.updateStatusLine();\n requestRender(state);\n });\n }\n state.gradientAnimator.start();\n}\n\nexport function handleAgentEnd(ctx: EventHandlerContext): void {\n const { state } = ctx;\n if (state.gradientAnimator) {\n state.gradientAnimator.fadeOut();\n }\n\n // Refresh git branch async — tool calls during this turn may have switched branches\n getCurrentGitBranchAsync(state.projectInfo.rootPath).then(freshBranch => {\n if (freshBranch) {\n state.projectInfo.gitBranch = freshBranch;\n ctx.updateStatusLine();\n }\n });\n\n if (state.streamingComponent) {\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n }\n // Drop the live judge reference so that a continuation turn creates a fresh\n // JudgeDisplayComponent *after* the new streaming text. Without this the\n // reused component stays at the position of the previous turn's evaluation,\n // causing the new turn's text to visually overwrite the old text + judge.\n state.activeGoalJudge = undefined;\n state.followUpComponents = [];\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n pruneChatContainer(state);\n ctx.updateStatusLine();\n flushRender(state);\n\n ctx.notify('agent_done');\n\n drainQueuedAction(ctx);\n}\n\nfunction drainQueuedAction(ctx: EventHandlerContext): boolean {\n const { state } = ctx;\n\n // Drain queued follow-up actions once all controller-level follow-ups are done.\n // Each queued action that starts a new agent operation will eventually trigger\n // handleAgentEnd again, which drains the next FIFO item.\n if (state.session.followUps.count() > 0) {\n return true;\n }\n\n // User-queued actions preempt the goal loop — if the user typed something\n // while the agent was running, process that first.\n const nextAction = state.pendingQueuedActions.shift();\n ctx.updateStatusLine();\n if (!nextAction) {\n return false;\n }\n\n if (nextAction === 'message') {\n const nextMessage = state.pendingFollowUpMessages.shift();\n if (!nextMessage) {\n return true;\n }\n\n ctx.addUserMessage({\n id: `user-${Date.now()}`,\n role: 'user',\n content: {\n format: 2,\n parts: [\n { type: 'text', text: nextMessage.content },\n ...(nextMessage.images?.map(img => ({\n type: 'file' as const,\n data: img.data,\n mimeType: img.mimeType,\n })) ?? []),\n ],\n },\n createdAt: new Date(),\n });\n // Track the text so the subscription echo is suppressed in addUserMessage.\n const key = nextMessage.content.trim();\n const counts = (state.firedQueuedMessageTexts ??= new Map<string, number>());\n counts.set(key, (counts.get(key) ?? 0) + 1);\n flushRender(state);\n ctx.fireMessage(nextMessage.content, nextMessage.images);\n return true;\n }\n\n const nextCommand = state.pendingSlashCommands.shift();\n const pendingMessageId = state.pendingSlashCommandMessageIds.shift();\n if (!nextCommand) {\n if (pendingMessageId) {\n removePendingUserMessage(state, pendingMessageId);\n }\n return true;\n }\n\n if (pendingMessageId) {\n removePendingUserMessage(state, pendingMessageId);\n }\n ctx.handleSlashCommand(nextCommand).catch(error => {\n ctx.showError(error instanceof Error ? error.message : 'Queued slash command failed');\n });\n return true;\n}\n\nexport function handleAgentAborted(ctx: EventHandlerContext): void {\n const { state } = ctx;\n if (state.gradientAnimator) {\n state.gradientAnimator.fadeOut();\n }\n\n // User-initiated aborts and plan \"Request Changes\" aborts are intentional.\n // The timing line already says \"canceled after x\", so don't also render a\n // redundant \"Error: Interrupted\" message in the transcript.\n if (state.planRejectionAbort || state.userInitiatedAbort) {\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n } else if (state.streamingComponent && state.streamingMessage) {\n // Update streaming message to show it was interrupted. Terminal status\n // lives in content.metadata under the DB-native contract.\n state.streamingMessage.content.metadata = {\n ...state.streamingMessage.content.metadata,\n stopReason: 'aborted',\n errorMessage: 'Interrupted',\n };\n state.streamingComponent.updateContent(state.streamingMessage);\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n }\n state.userInitiatedAbort = false;\n state.planRejectionAbort = false;\n if (state.activeGoalJudge) {\n removeJudgeComponent(state, state.activeGoalJudge.component);\n state.activeGoalJudge = undefined;\n }\n\n state.followUpComponents = [];\n state.pendingFollowUpMessages = [];\n state.pendingQueuedActions = [];\n state.pendingSlashCommands = [];\n state.pendingSlashCommandMessageIds = [];\n clearPendingUserMessages(state);\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n pruneChatContainer(state);\n ctx.updateStatusLine();\n flushRender(state);\n}\n\nexport function handleAgentError(ctx: EventHandlerContext): void {\n const { state } = ctx;\n if (state.gradientAnimator) {\n state.gradientAnimator.fadeOut();\n }\n\n if (state.streamingComponent) {\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n }\n if (state.activeGoalJudge) {\n removeJudgeComponent(state, state.activeGoalJudge.component);\n state.activeGoalJudge = undefined;\n }\n\n state.followUpComponents = [];\n state.pendingFollowUpMessages = [];\n state.pendingQueuedActions = [];\n state.pendingSlashCommands = [];\n state.pendingSlashCommandMessageIds = [];\n clearPendingUserMessages(state);\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n pruneChatContainer(state);\n ctx.updateStatusLine();\n flushRender(state);\n}\n\n// =============================================================================\n// Goal Evaluation\n// =============================================================================\n\n/** Remove the judge display component from the chat container if present. */\nfunction removeJudgeComponent(state: EventHandlerContext['state'], component: JudgeDisplayComponent): void {\n // Use the container's removal API so parent/layout bookkeeping stays\n // consistent, rather than splicing `children` directly.\n if (state.chatContainer.children.includes(component)) {\n state.chatContainer.removeChild(component);\n }\n}\n\n/**\n * Render an in-loop goal evaluation surfaced by the core goal step as a `goal`\n * stream chunk (bridged to a `goal_evaluation` controller event). The core loop\n * owns continuation — this handler only mirrors the judge's decision into the\n * UI, syncs the adapter's progress, and runs the plan-mode auto-switch when a\n * plan-started goal completes.\n */\nexport function handleGoalEvaluation(ctx: EventHandlerContext, payload: GoalEvaluationPayload): void {\n const { state } = ctx;\n\n // Esc/Ctrl+C pauses the goal and aborts the run. If a judge stream races in a\n // late goal chunk after that, don't let it recreate UI or overwrite the\n // user-paused objective with the stale active/continue result.\n if (state.userInitiatedAbort && state.goalManager.getGoal()?.status === 'paused') {\n return;\n }\n\n // Reuse the existing judge component for this turn, or create one inline so\n // the judge's progress appears alongside the agent's response.\n let activeGoalJudge = state.activeGoalJudge;\n if (!activeGoalJudge) {\n const goal = state.goalManager.getGoal();\n const component = new JudgeDisplayComponent(null, payload.iteration, payload.maxRuns);\n activeGoalJudge = {\n modelId: goal?.judgeModelId ?? '',\n abortController: new AbortController(),\n component,\n };\n state.activeGoalJudge = activeGoalJudge;\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n }\n\n if (payload.activity?.length) {\n for (const activity of payload.activity) {\n if (activity.type === 'reason') {\n activeGoalJudge.component.setStreamingReason(activity.message);\n } else {\n activeGoalJudge.component.addActivity(activity.message);\n }\n }\n }\n\n // A pending chunk signals that scoring has started but isn't finished yet.\n // Show the loading indicator (the component already renders \"evaluating…\"\n // when result is null) and wait for the follow-up chunk with the result.\n if (payload.pending) {\n ctx.updateStatusLine();\n flushRender(state);\n return;\n }\n\n activeGoalJudge.component.setEvaluation(payload);\n\n // Mirror the loop's progress into the synchronous adapter view so the status\n // line and modal reflect the latest run count and lifecycle status.\n state.goalManager.applyEvaluation({ runsUsed: payload.iteration, status: payload.status });\n\n ctx.updateStatusLine();\n flushRender(state);\n\n // A final (non-pending) goal chunk completes this judge display. Keep the\n // rendered component in history, but drop the live reference so an in-loop\n // continuation creates a fresh display after the next assistant output instead\n // of updating the previous turn's component in place.\n state.activeGoalJudge = undefined;\n\n if (payload.status === 'done') {\n const goal = state.goalManager.getGoal();\n if (goal && goal.id === state.planStartedGoalId) {\n const goalId = state.planStartedGoalId;\n state.planStartedGoalId = undefined;\n state.session.mode.switch({ modeId: 'plan' }).catch(error => {\n ctx.showError(`Failed to switch to Plan mode: ${error instanceof Error ? error.message : String(error)}`);\n state.planStartedGoalId = goalId;\n });\n }\n }\n}\n","/**\n * Event handlers for message streaming events:\n * message_start, message_update, message_end.\n *\n * The harness streams the canonical `MastraDBMessage` shape: assistant text /\n * reasoning / tool calls live as nested `content.parts`, and signals arrive as\n * their own `role: 'signal'` messages (their own `message_start`/`message_end`\n * pair) rather than inline parts of an assistant message. Signal rendering is\n * therefore delegated to `addUserMessage` / `renderSignalMessage`; this file\n * only drives the streaming assistant component and its tool boundaries.\n */\nimport type { MastraDBMessage } from '@mastra/core/agent-controller';\n\nimport { reconcileChatBoundarySpacers } from '../chat-boundary-reconciliation.js';\nimport { AssistantMessageComponent } from '../components/assistant-message.js';\nimport { ToolExecutionComponentEnhanced } from '../components/tool-execution-enhanced.js';\nimport { getAssistantRenderParts, isGoalJudgeEvaluationSignal } from '../db-message-parts.js';\nimport type { ToolRenderPart } from '../db-message-parts.js';\nimport { flushRender, requestRender } from '../render-scheduler.js';\nimport { getMarkdownTheme } from '../theme.js';\n\nimport { createStaticSubagentComponent } from './tool.js';\nimport type { EventHandlerContext } from './types.js';\n\ntype MessageContent = Exclude<MastraDBMessage['content'], string>;\ntype MessagePart = MessageContent['parts'][number];\n\nfunction getCurrentModeColor(ctx: EventHandlerContext): string | undefined {\n const color = ctx.state.session?.mode?.resolve?.()?.metadata?.color;\n return typeof color === 'string' ? color : undefined;\n}\n\nfunction getContent(message: MastraDBMessage): MessageContent | undefined {\n const content = message.content;\n if (typeof content === 'string') return undefined;\n return content;\n}\n\nfunction getRawParts(message: MastraDBMessage): MessagePart[] {\n return getContent(message)?.parts ?? [];\n}\n\nfunction isToolPart(part: MessagePart): boolean {\n return part.type === 'tool-invocation';\n}\n\n/**\n * Build a `MastraDBMessage` view that carries only a subset of `content.parts`,\n * preserving the rest of the message (id/role/metadata) so the assistant\n * component can read stop-reason metadata while rendering the sliced text.\n */\nfunction withParts(message: MastraDBMessage, parts: MessagePart[]): MastraDBMessage {\n const content = getContent(message);\n return {\n ...message,\n content: { ...(content ?? { format: 2, parts: [] }), parts } as MessageContent,\n };\n}\n\n/**\n * Parts after the last tool-invocation part. These are the text/reasoning parts\n * that belong to the currently-streaming assistant component (below the last\n * tool). If there are no tool parts, all parts are returned.\n */\nfunction getTrailingParts(message: MastraDBMessage): MessagePart[] {\n const parts = getRawParts(message);\n let lastToolIndex = -1;\n for (let i = parts.length - 1; i >= 0; i--) {\n if (isToolPart(parts[i]!)) {\n lastToolIndex = i;\n break;\n }\n }\n return lastToolIndex === -1 ? parts : parts.slice(lastToolIndex + 1);\n}\n\n/**\n * Text/reasoning parts between the last already-seen tool part and the tool part\n * with `toolCallId`. Used to freeze the pre-subagent assistant slice.\n */\nfunction getPartsBeforeTool(message: MastraDBMessage, toolCallId: string, seenToolCallIds: Set<string>): MessagePart[] {\n const parts = getRawParts(message);\n const targetIndex = parts.findIndex(part => isToolPart(part) && toolInvocationId(part) === toolCallId);\n if (targetIndex === -1) return parts;\n\n let startIndex = 0;\n for (let i = targetIndex - 1; i >= 0; i--) {\n const part = parts[i]!;\n if (isToolPart(part)) {\n const id = toolInvocationId(part);\n if (id && seenToolCallIds.has(id)) {\n startIndex = i + 1;\n break;\n }\n }\n }\n\n return parts.slice(startIndex, targetIndex).filter(part => part.type === 'text' || part.type === 'reasoning');\n}\n\nfunction toolInvocationId(part: MessagePart): string | undefined {\n const inv = (part as { toolInvocation?: { toolCallId?: unknown } }).toolInvocation;\n return typeof inv?.toolCallId === 'string' ? inv.toolCallId : undefined;\n}\n\nfunction getTerminalStatus(message: MastraDBMessage): { stopReason?: string; errorMessage?: string } {\n const metadata = getContent(message)?.metadata as { stopReason?: string; errorMessage?: string } | undefined;\n return { stopReason: metadata?.stopReason, errorMessage: metadata?.errorMessage };\n}\n\nexport function handleMessageStart(ctx: EventHandlerContext, message: MastraDBMessage): void {\n const { state } = ctx;\n\n if (message.role === 'signal' || message.role === 'user') {\n // Signals arrive as distinct message_start/message_end pairs. Guard against\n // the same signal being re-emitted within a run (reminders in particular do\n // not self-register for id-based dedup in the shared renderer).\n if (message.role === 'signal') {\n if (state.currentRunSystemReminderKeys.has(message.id)) return;\n state.currentRunSystemReminderKeys.add(message.id);\n if (isGoalJudgeEvaluationSignal(message)) return;\n }\n ctx.addUserMessage(message);\n return;\n }\n\n if (message.role === 'assistant') {\n // Clear tool component references when starting a new assistant message\n state.lastAskUserComponent = undefined;\n state.lastSubmitPlanComponent = undefined;\n if (!state.streamingComponent) {\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n state.streamingMessage = message;\n state.streamingComponent.updateContent(withParts(message, getTrailingParts(message)));\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n flushRender(state);\n }\n}\n\nexport function handleMessageUpdate(ctx: EventHandlerContext, message: MastraDBMessage): void {\n const { state } = ctx;\n\n // Signals arrive as their own message_start/message_end pair; if an update is\n // delivered for one, route it through the shared signal renderer (deduped by id).\n if (message.role === 'signal') {\n if (isGoalJudgeEvaluationSignal(message)) return;\n ctx.addUserMessage(message);\n return;\n }\n\n if (message.role !== 'assistant') return;\n\n const renderParts = getAssistantRenderParts(message);\n const toolParts = renderParts.filter((part): part is ToolRenderPart => part.kind === 'tool');\n const trailingParts = getTrailingParts(message);\n const hasToolCalls = toolParts.length > 0;\n\n let createdStreamingComponent = false;\n if (!state.streamingComponent) {\n if (trailingParts.length === 0 && !hasToolCalls) {\n return;\n }\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n createdStreamingComponent = true;\n }\n\n state.streamingMessage = message;\n\n // Check for new tool calls\n for (const tool of toolParts) {\n if (!state.seenToolCallIds.has(tool.toolCallId)) {\n state.seenToolCallIds.add(tool.toolCallId);\n\n const preParts = getPartsBeforeTool(message, tool.toolCallId, state.seenToolCallIds);\n state.streamingComponent.updateContent(withParts(message, preParts));\n\n const staticSubagent = createStaticSubagentComponent(ctx, tool.toolCallId, tool.toolName, tool.args);\n if (staticSubagent) {\n state.subagentToolCallIds.add(tool.toolCallId);\n createdStreamingComponent = true;\n continue;\n }\n\n // For built-in subagent calls without a plugin renderer, freeze the current\n // assistant slice before the tool and continue text in a fresh component.\n if (tool.toolName === 'subagent' && !state.subagentToolCallIds.has(tool.toolCallId)) {\n state.subagentToolCallIds.add(tool.toolCallId);\n state.streamingComponent = new AssistantMessageComponent(\n undefined,\n state.hideThinkingBlock,\n getMarkdownTheme(),\n );\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n createdStreamingComponent = true;\n continue;\n }\n\n const component = new ToolExecutionComponentEnhanced(\n tool.toolName,\n tool.args as Record<string, unknown>,\n { showImages: false, collapsedByDefault: !state.toolOutputExpanded },\n state.ui,\n );\n component.setExpanded(state.toolOutputExpanded);\n if (state.quietMode) {\n component.setCompactToolModeColor(getCurrentModeColor(ctx));\n component.setQuietModeDisplay('quiet');\n component.setQuietPreviewLineLimit(state.quietModeMaxToolPreviewLines);\n }\n ctx.addChildBeforeFollowUps(component);\n state.pendingTools.set(tool.toolCallId, component);\n state.allToolComponents.push(component);\n reconcileChatBoundarySpacers(state.chatContainer);\n\n state.streamingComponent = new AssistantMessageComponent(undefined, state.hideThinkingBlock, getMarkdownTheme());\n ctx.addChildBeforeFollowUps(state.streamingComponent);\n createdStreamingComponent = true;\n } else {\n const component = state.pendingTools.get(tool.toolCallId);\n if (component) {\n component.updateArgs(tool.args as Record<string, unknown>);\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n }\n }\n\n // Avoid replacing visible assistant text with an empty trailing segment\n // (commonly happens immediately after tool-result-only updates).\n if (trailingParts.length > 0) {\n const wasSpacingParticipant = state.streamingComponent.getChatSpacingKind() !== undefined;\n state.streamingComponent.updateContent(withParts(message, trailingParts));\n if (\n createdStreamingComponent ||\n (!wasSpacingParticipant && state.streamingComponent.getChatSpacingKind() !== undefined)\n ) {\n reconcileChatBoundarySpacers(state.chatContainer);\n }\n }\n\n requestRender(state);\n}\n\nexport function handleMessageEnd(ctx: EventHandlerContext, message: MastraDBMessage): void {\n const { state } = ctx;\n if (message.role === 'signal' || message.role === 'user') return;\n\n if (state.streamingComponent && message.role === 'assistant') {\n state.streamingMessage = message;\n const trailingParts = getTrailingParts(message);\n const { stopReason, errorMessage } = getTerminalStatus(message);\n\n // If the final assistant chunk has no trailing text/thinking after tools,\n // keep the last rendered content instead of blanking the component.\n if (trailingParts.length > 0 || stopReason === 'aborted' || stopReason === 'error') {\n state.streamingComponent.updateContent(withParts(message, trailingParts));\n }\n\n if (stopReason === 'aborted' || stopReason === 'error') {\n const abortMessage = errorMessage || 'Operation aborted';\n for (const [, component] of state.pendingTools) {\n component.updateResult(\n {\n content: [{ type: 'text', text: abortMessage }],\n isError: true,\n },\n false,\n );\n }\n reconcileChatBoundarySpacers(state.chatContainer);\n state.pendingTools.clear();\n state.pendingTaskToolIds?.clear();\n }\n\n state.streamingComponent = undefined;\n state.streamingMessage = undefined;\n state.seenToolCallIds.clear();\n state.subagentToolCallIds.clear();\n state.currentRunSystemReminderKeys.clear();\n }\n flushRender(state);\n}\n","/**\n * Event handlers for Observational Memory (OM) events:\n * om_status, om_observation_start/end, om_reflection_start/end,\n * om_buffering_start/end/failed, om_activation, and om_*_failed.\n *\n * All omProgress state updates are handled by the AgentController display state.\n * These handlers focus on UI component creation/removal.\n */\nimport type { Component } from '@earendil-works/pi-tui';\n\nimport {\n insertChatComponentWithBoundarySpacing,\n reconcileChatBoundarySpacers,\n} from '../chat-boundary-reconciliation.js';\nimport { isChatBoundarySpacer } from '../components/chat-boundary-spacer.js';\nimport { OMMarkerComponent } from '../components/om-marker.js';\nimport type { OMMarkerData } from '../components/om-marker.js';\nimport { OMOutputComponent } from '../components/om-output.js';\n\nimport type { EventHandlerContext } from './types.js';\n\n/**\n * Insert a child component *before* the current streaming component so it\n * doesn't get pushed down as text streams in. Falls back to a normal\n * append when nothing is streaming.\n */\nfunction getInsertIndexBeforeStreaming(ctx: EventHandlerContext): number {\n const { state } = ctx;\n if (state.streamingComponent) {\n const idx = state.chatContainer.children.indexOf(state.streamingComponent);\n if (idx >= 0) return idx;\n }\n return state.chatContainer.children.length;\n}\n\nfunction addChildBeforeStreaming(ctx: EventHandlerContext, child: Component): void {\n const insertIndex = getInsertIndexBeforeStreaming(ctx);\n insertChatComponentWithBoundarySpacing(ctx.state.chatContainer, child, insertIndex);\n}\n\nfunction isImmediatelyBeforeStreamingInsert(ctx: EventHandlerContext, child: Component): boolean {\n const insertIndex = getInsertIndexBeforeStreaming(ctx);\n // Walk backward from the insert point, skipping boundary spacers,\n // to find the actual preceding component.\n for (let i = insertIndex - 1; i >= 0; i--) {\n if (!isChatBoundarySpacer(ctx.state.chatContainer.children[i]!)) {\n return ctx.state.chatContainer.children[i] === child;\n }\n }\n return false;\n}\n\nfunction removeChatChild(ctx: EventHandlerContext, child: Component | undefined): void {\n if (!child) return;\n const idx = ctx.state.chatContainer.children.indexOf(child);\n if (idx >= 0) {\n ctx.state.chatContainer.children.splice(idx, 1);\n reconcileChatBoundarySpacers(ctx.state.chatContainer);\n }\n}\n\nexport function handleOMObservationStart(ctx: EventHandlerContext, cycleId: string, tokensToObserve: number): void {\n const { state } = ctx;\n // Show in-progress marker in chat\n state.activeOMMarker = new OMMarkerComponent({\n type: 'om_observation_start',\n tokensToObserve,\n operationType: 'observation',\n });\n addChildBeforeStreaming(ctx, state.activeOMMarker);\n state.ui.requestRender();\n}\n\nexport function handleOMObservationEnd(\n ctx: EventHandlerContext,\n _cycleId: string,\n durationMs: number,\n tokensObserved: number,\n observationTokens: number,\n observations?: string,\n currentTask?: string,\n suggestedResponse?: string,\n): void {\n const { state } = ctx;\n // Remove in-progress marker — the output box replaces it\n if (state.activeOMMarker) {\n const idx = state.chatContainer.children.indexOf(state.activeOMMarker);\n if (idx >= 0) {\n state.chatContainer.children.splice(idx, 1);\n state.chatContainer.invalidate();\n }\n state.activeOMMarker = undefined;\n }\n // Show observation output in a bordered box (includes marker info in footer)\n const outputComponent = new OMOutputComponent({\n type: 'observation',\n observations: observations ?? '',\n currentTask,\n suggestedResponse,\n durationMs,\n tokensObserved,\n observationTokens,\n });\n addChildBeforeStreaming(ctx, outputComponent);\n state.ui.requestRender();\n}\n\nexport function handleOMReflectionStart(ctx: EventHandlerContext, cycleId: string, tokensToReflect: number): void {\n const { state } = ctx;\n // Show in-progress marker in chat\n state.activeOMMarker = new OMMarkerComponent({\n type: 'om_observation_start',\n tokensToObserve: tokensToReflect,\n operationType: 'reflection',\n });\n addChildBeforeStreaming(ctx, state.activeOMMarker);\n state.ui.requestRender();\n}\n\nexport function handleOMReflectionEnd(\n ctx: EventHandlerContext,\n _cycleId: string,\n durationMs: number,\n compressedTokens: number,\n observations?: string,\n): void {\n const { state } = ctx;\n // Read pre-compression tokens from display state (set during om_reflection_start)\n // Note: AgentController has already updated observationTokens to compressedTokens,\n // so we use tokensToReflect from the start event via the cycleId context.\n // For display purposes, we read the event parameter directly.\n const ds = state.session.displayState.get();\n // Remove in-progress marker — the output box replaces it\n if (state.activeOMMarker) {\n const idx = state.chatContainer.children.indexOf(state.activeOMMarker);\n if (idx >= 0) {\n state.chatContainer.children.splice(idx, 1);\n state.chatContainer.invalidate();\n }\n state.activeOMMarker = undefined;\n }\n // Show reflection output in a bordered box (includes marker info in footer)\n const outputComponent = new OMOutputComponent({\n type: 'reflection',\n observations: observations ?? '',\n durationMs,\n compressedTokens,\n // preReflectionTokens captures observationTokens before compression started\n tokensObserved: ds.omProgress.preReflectionTokens,\n });\n addChildBeforeStreaming(ctx, outputComponent);\n state.ui.requestRender();\n}\n\nexport function handleOMFailed(\n ctx: EventHandlerContext,\n _cycleId: string,\n error: string,\n operation: 'observation' | 'reflection',\n): void {\n const { state } = ctx;\n // Update existing marker in-place, or create new one\n const failData: OMMarkerData = {\n type: 'om_observation_failed',\n error,\n operationType: operation,\n };\n if (state.activeOMMarker) {\n state.activeOMMarker.update(failData);\n state.activeOMMarker = undefined;\n } else {\n addChildBeforeStreaming(ctx, new OMMarkerComponent(failData));\n }\n state.ui.requestRender();\n}\n\nexport function handleOMBufferingStart(\n ctx: EventHandlerContext,\n operationType: 'observation' | 'reflection',\n tokensToBuffer: number,\n): void {\n const { state } = ctx;\n state.activeActivationMarker = undefined;\n state.activeActivationData = undefined;\n state.activeActivationProviderChangeMarker = undefined;\n if (state.quietMode) {\n removeChatChild(ctx, state.activeBufferingMarker);\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n return;\n }\n state.activeBufferingMarker = new OMMarkerComponent({\n type: 'om_buffering_start',\n operationType,\n tokensToBuffer,\n });\n addChildBeforeStreaming(ctx, state.activeBufferingMarker);\n state.ui.requestRender();\n}\n\nexport function handleOMBufferingEnd(\n ctx: EventHandlerContext,\n operationType: 'observation' | 'reflection',\n tokensBuffered: number,\n bufferedTokens: number,\n observations?: string,\n): void {\n const { state } = ctx;\n if (state.quietMode) {\n removeChatChild(ctx, state.activeBufferingMarker);\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n return;\n }\n if (state.activeBufferingMarker) {\n state.activeBufferingMarker.update({\n type: 'om_buffering_end',\n operationType,\n tokensBuffered,\n bufferedTokens,\n observations,\n });\n }\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n}\n\nexport function handleOMBufferingFailed(\n ctx: EventHandlerContext,\n operationType: 'observation' | 'reflection',\n error: string,\n): void {\n const { state } = ctx;\n if (state.quietMode) {\n removeChatChild(ctx, state.activeBufferingMarker);\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n return;\n }\n if (state.activeBufferingMarker) {\n state.activeBufferingMarker.update({\n type: 'om_buffering_failed',\n operationType,\n error,\n });\n }\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n}\n\nexport function handleOMActivation(\n ctx: EventHandlerContext,\n operationType: 'observation' | 'reflection',\n tokensActivated: number,\n observationTokens: number,\n triggeredBy?: 'threshold' | 'ttl' | 'provider_change',\n activateAfterIdle?: number,\n ttlExpiredMs?: number,\n previousModel?: string,\n currentModel?: string,\n): void {\n const { state } = ctx;\n\n if (triggeredBy === 'provider_change' && previousModel && currentModel) {\n const providerChangeData: OMMarkerData = {\n type: 'om_activation_provider_change',\n previousModel,\n currentModel,\n };\n\n if (state.activeActivationProviderChangeMarker) {\n state.activeActivationProviderChangeMarker.update(providerChangeData);\n } else {\n state.activeActivationProviderChangeMarker = new OMMarkerComponent(providerChangeData);\n addChildBeforeStreaming(ctx, state.activeActivationProviderChangeMarker);\n }\n }\n\n const previousActivationData = state.activeActivationData;\n const canCombineActivation =\n previousActivationData?.type === 'om_activation' &&\n previousActivationData.operationType === operationType &&\n state.activeActivationMarker !== undefined &&\n isImmediatelyBeforeStreamingInsert(ctx, state.activeActivationMarker);\n\n const activationData: OMMarkerData = canCombineActivation\n ? {\n type: 'om_activation',\n operationType,\n tokensActivated: previousActivationData.tokensActivated + tokensActivated,\n observationTokens: previousActivationData.observationTokens + observationTokens,\n activationCount: (previousActivationData.activationCount ?? 1) + 1,\n activateAfterIdle: previousActivationData.activateAfterIdle ?? activateAfterIdle,\n }\n : {\n type: 'om_activation',\n operationType,\n tokensActivated,\n observationTokens,\n ...(triggeredBy === 'ttl' && activateAfterIdle !== undefined ? { activateAfterIdle } : {}),\n };\n\n if (canCombineActivation && state.activeActivationMarker) {\n state.activeActivationMarker.update(activationData);\n } else {\n state.activeActivationMarker = new OMMarkerComponent(activationData);\n addChildBeforeStreaming(ctx, state.activeActivationMarker);\n }\n\n state.activeActivationData = activationData;\n state.activeBufferingMarker = undefined;\n state.ui.requestRender();\n}\n\nexport function handleOMThreadTitleUpdated(ctx: EventHandlerContext, newTitle: string, oldTitle?: string): void {\n if (ctx.state.quietMode) return;\n const marker = new OMMarkerComponent({\n type: 'om_thread_title_updated',\n newTitle,\n oldTitle,\n });\n addChildBeforeStreaming(ctx, marker);\n ctx.state.ui.requestRender();\n}\n","/**\n * Event handlers for interactive prompt events:\n * tool_suspended (ask_user / request_access / submit_plan).\n */\nimport { shouldShowDiff } from '@mastra/code-sdk/utils/plan-diff';\nimport { approvePlanFile, readPlanFile, resolvePlanPath } from '@mastra/code-sdk/utils/plans';\nimport type { AskUserSelectionMode } from '@mastra/core/tools';\nimport { AskQuestionDialogComponent } from '../components/ask-question-dialog.js';\nimport { AskQuestionInlineComponent } from '../components/ask-question-inline.js';\nimport { PlanApprovalInlineComponent } from '../components/plan-approval-inline.js';\nimport { showModalOverlay } from '../overlay.js';\nimport type { TUIState } from '../state.js';\nimport { theme } from '../theme.js';\n\nimport type { EventHandlerContext } from './types.js';\n\n/**\n * Process the next pending inline question from the queue.\n * Called when the current active question is resolved (submitted or cancelled).\n */\nfunction processNextInlineQuestion(state: TUIState): void {\n const next = state.pendingInlineQuestions.shift();\n if (next) {\n next();\n }\n}\n\n/**\n * Handle an ask_question event from the ask_user tool.\n * Shows a dialog overlay and resolves the tool's pending promise.\n *\n * If another inline question is already active, the new question is queued\n * and will be shown once the current one is answered.\n */\nexport async function handleAskQuestion(\n ctx: EventHandlerContext,\n toolCallId: string,\n question: string,\n options?: Array<{ label: string; description?: string }>,\n selectionMode?: AskUserSelectionMode,\n): Promise<void> {\n const { state } = ctx;\n\n return new Promise(resolve => {\n // The suspended run can die after the question is rendered (e.g. persisting\n // the suspended snapshot failed), in which case the session cancels the\n // suspension because the answer could never be resumed. That cancellation\n // must bypass the TUI's serialized event queue — the queue is parked on\n // this very promise — so listen on the session directly and retract the\n // prompt out-of-band.\n let cancelled = false;\n let retract: () => void = () => {};\n const unsubscribeCancel =\n state.session.subscribe?.(event => {\n if (event.type !== 'tool_suspension_cancelled' || event.toolCallId !== toolCallId) return;\n if (cancelled) return;\n cancelled = true;\n unsubscribeCancel();\n retract();\n resolve();\n }) ?? (() => {});\n const finish = () => {\n unsubscribeCancel();\n resolve();\n };\n\n if (state.options.inlineQuestions) {\n // Look up the streaming component created for THIS tool call. Using the\n // per-toolCallId map (instead of the single lastAskUserComponent field)\n // keeps parallel ask_user suspensions bound to their own components so\n // each question renders distinctly (#13642).\n const askUserComponent = state.pendingAskUserComponents?.get(toolCallId) ?? state.lastAskUserComponent;\n state.pendingAskUserComponents?.delete(toolCallId);\n\n let shownComponent: AskQuestionInlineComponent | undefined = askUserComponent;\n retract = () => {\n shownComponent?.dismiss();\n if (state.activeInlineQuestion === shownComponent) {\n state.activeInlineQuestion = undefined;\n processNextInlineQuestion(state);\n }\n state.ui.requestRender();\n };\n\n const activate = () => {\n // Retracted while waiting in the queue — skip activation and let the\n // next queued question take the slot.\n if (cancelled) {\n processNextInlineQuestion(state);\n return;\n }\n try {\n let questionComponent: AskQuestionInlineComponent;\n\n if (askUserComponent) {\n // Activate the existing streaming component with interactive elements.\n // ask_user is the agent's free-text channel — opt into multiline so users\n // can paste logs / write paragraph-length replies.\n askUserComponent.activate({\n question,\n options,\n selectionMode,\n multiline: true,\n tui: state.ui,\n onSubmit: answer => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: answer });\n finish();\n processNextInlineQuestion(state);\n },\n onSubmitMulti: answers => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: answers });\n finish();\n processNextInlineQuestion(state);\n },\n onCancel: () => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: '(skipped)' });\n finish();\n processNextInlineQuestion(state);\n },\n });\n questionComponent = askUserComponent;\n } else {\n // Fallback: create a new component if no streaming one exists.\n // Multiline opt-in matches the streaming branch above.\n questionComponent = new AskQuestionInlineComponent(\n {\n question,\n options,\n selectionMode,\n multiline: true,\n onSubmit: answer => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: answer });\n finish();\n processNextInlineQuestion(state);\n },\n onSubmitMulti: answers => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: answers });\n finish();\n processNextInlineQuestion(state);\n },\n onCancel: () => {\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: '(skipped)' });\n finish();\n processNextInlineQuestion(state);\n },\n },\n state.ui,\n );\n state.chatContainer.addChild(questionComponent);\n }\n\n // Store as active question\n shownComponent = questionComponent;\n state.activeInlineQuestion = questionComponent;\n\n state.ui.requestRender();\n\n // Ensure the chat scrolls to show the question\n state.chatContainer.invalidate();\n\n // Focus the question component\n questionComponent.focused = true;\n } catch {\n // Don't let ask_user errors crash the process — skip the question\n state.activeInlineQuestion = undefined;\n state.session.respondToToolSuspension({ toolCallId, resumeData: '(skipped)' });\n finish();\n processNextInlineQuestion(state);\n }\n };\n\n // If another inline question is already active, queue this one\n if (state.activeInlineQuestion) {\n state.pendingInlineQuestions.push(activate);\n } else {\n activate();\n }\n } else {\n retract = () => {\n state.ui.hideOverlay();\n state.ui.requestRender();\n };\n // Dialog mode: Show overlay. Multiline opt-in matches the inline branch.\n const dialog = new AskQuestionDialogComponent({\n question,\n options,\n selectionMode,\n multiline: true,\n tui: state.ui,\n onSubmit: answer => {\n state.ui.hideOverlay();\n state.session.respondToToolSuspension({ toolCallId, resumeData: answer });\n finish();\n },\n onSubmitMulti: answers => {\n state.ui.hideOverlay();\n state.session.respondToToolSuspension({ toolCallId, resumeData: answers });\n finish();\n },\n onCancel: () => {\n state.ui.hideOverlay();\n state.session.respondToToolSuspension({ toolCallId, resumeData: '(skipped)' });\n finish();\n },\n });\n showModalOverlay(state.ui, dialog, { widthPercent: 0.7 });\n dialog.focused = true;\n }\n\n ctx.notify('ask_question', question);\n });\n}\n\n/**\n * Handle a sandbox_access_request event from the request_access tool.\n * Shows an inline prompt for the user to approve or deny directory access.\n *\n * If another inline question is already active, the new prompt is queued\n * and will be shown once the current one is answered.\n */\nexport async function handleSandboxAccessRequest(\n ctx: EventHandlerContext,\n toolCallId: string,\n requestedPath: string,\n reason: string,\n): Promise<void> {\n const { state } = ctx;\n return new Promise(resolve => {\n const firePermissionResult = (decision: 'approved' | 'declined' | 'dismissed') => {\n state.hookManager\n ?.runPermissionResult('sandbox_access', toolCallId, 'request_access', decision, { path: requestedPath, reason })\n .catch(() => {});\n };\n const activate = () => {\n const questionComponent = new AskQuestionInlineComponent(\n {\n question: `Grant sandbox access to \"${requestedPath}\"?\\n${theme.fg('dim', `Reason: ${reason}`)}`,\n options: [\n { label: 'Yes', description: 'Allow access to this directory' },\n { label: 'No', description: 'Deny access' },\n ],\n onSubmit: answer => {\n state.activeInlineQuestion = undefined;\n firePermissionResult(answer.toLowerCase().startsWith('y') ? 'approved' : 'declined');\n state.session.respondToToolSuspension({ toolCallId, resumeData: answer });\n resolve();\n processNextInlineQuestion(state);\n },\n onCancel: () => {\n state.activeInlineQuestion = undefined;\n firePermissionResult('dismissed');\n state.session.respondToToolSuspension({ toolCallId, resumeData: 'No' });\n resolve();\n processNextInlineQuestion(state);\n },\n formatResult: answer => {\n const approved = answer.toLowerCase().startsWith('y');\n return approved ? `Granted access to ${requestedPath}` : `Denied access to ${requestedPath}`;\n },\n isNegativeAnswer: answer => !answer.toLowerCase().startsWith('y'),\n },\n state.ui,\n );\n\n // Store as active question so input routing works\n state.activeInlineQuestion = questionComponent;\n\n // Add to chat\n state.chatContainer.addChild(questionComponent);\n questionComponent.focused = true;\n state.ui.requestRender();\n state.chatContainer.invalidate();\n };\n\n // If another inline question is already active, queue this one\n if (state.activeInlineQuestion) {\n state.pendingInlineQuestions.push(activate);\n } else {\n activate();\n }\n\n ctx.notify('sandbox_access', `Sandbox access requested: ${requestedPath}`);\n });\n}\n\n/**\n * Handle a suspended submit_plan tool call.\n * Shows the plan inline with Approve/Use as Goal/Request Changes options.\n *\n * On each submission the plan is saved to a `.md` file and the previous plan\n * content is snapshotted so that resubmissions can show a diff.\n *\n * \"Request changes\" rejects the tool call and aborts the agent so the user can\n * provide revision feedback via a normal chat message.\n */\nasync function approvePlan(\n ctx: EventHandlerContext,\n toolCallId: string,\n title: string,\n plan: string,\n planPath: string | undefined,\n submittedPath: string,\n): Promise<void> {\n const { state } = ctx;\n await state.session.state.set({\n activePlan: {\n title,\n plan,\n approvedAt: new Date().toISOString(),\n },\n });\n\n // Archive the approved plan to the global plans dir so it's findable later. The\n // local plan file is left in place so the user can review every plan made.\n if (planPath) {\n await approvePlanFile({\n planPath,\n title,\n resourceId: state.session.identity.getResourceId(),\n }).catch(() => {});\n }\n\n // Reset in-memory diff state so the next plan doesn't diff against this one.\n state.previousPlanSnapshot = undefined;\n state.lastSubmitPlanComponent = undefined;\n\n await state.session.respondToToolSuspension({\n toolCallId,\n resumeData: { action: 'approved', path: submittedPath, title, plan },\n });\n}\n\nfunction formatPlanGoalObjective(title: string, plan: string): string {\n return `# ${title}\\n\\n${plan}`;\n}\n\nexport async function handlePlanApproval(\n ctx: EventHandlerContext,\n toolCallId: string,\n submittedPath: string,\n): Promise<void> {\n const { state } = ctx;\n\n // submit_plan carries the plan file path. The agent can write the plan anywhere it\n // has access, so read whatever path it submitted (resolved relative to the project)\n // and parse the `# heading` as the title.\n const projectPath = (state.session.state.get() as any)?.projectPath as string | undefined;\n const planPath = submittedPath ? resolvePlanPath(projectPath ?? process.cwd(), submittedPath) : undefined;\n const current = planPath ? await readPlanFile(planPath) : undefined;\n if (!current) {\n state.previousPlanSnapshot = undefined;\n }\n\n // Surface a clear error in the approval card when the plan file can't be read,\n // instead of rendering an empty plan.\n const plan =\n current?.plan ??\n `⚠️ Could not read the plan file at \\`${submittedPath}\\`. Make sure it exists before submitting it.`;\n const resolvedTitle = current?.title || 'Implementation Plan';\n // Snapshot history is keyed by the submitted path so a revision of the same file\n // diffs against the prior submission, but a brand-new file renders in full.\n const snapshotKey = submittedPath;\n\n // A previous snapshot is only a valid diff base for a revision of the SAME\n // plan file. A different path means a brand-new plan, so render it in full\n // rather than diffing against an unrelated plan.\n const snapshot = state.previousPlanSnapshot;\n const snapshotPlan = snapshot && snapshot.path === snapshotKey ? snapshot.plan : undefined;\n const previousPlan = snapshotPlan && shouldShowDiff(snapshotPlan, plan) ? snapshotPlan : undefined;\n\n // Snapshot this submission (keyed by submitted path) so the next resubmission of\n // the same file can diff against it. Skip seeding history when the file\n // couldn't be read.\n if (current) {\n state.previousPlanSnapshot = { path: snapshotKey, plan };\n }\n\n return new Promise(resolve => {\n const planFilename = snapshotKey;\n const firePermissionResult = (decision: 'approved' | 'declined') => {\n state.hookManager\n ?.runPermissionResult('plan_approval', toolCallId, 'submit_plan', decision, { path: snapshotKey })\n .catch(() => {});\n };\n const approvalOptions = {\n toolCallId,\n title: resolvedTitle,\n plan,\n planFilename,\n previousPlan,\n onApprove: async () => {\n state.activeInlinePlanApproval = undefined;\n state.ui.setFocus(state.editor);\n firePermissionResult('approved');\n await approvePlan(ctx, toolCallId, resolvedTitle, plan, planPath, snapshotKey);\n resolve();\n },\n onGoal: async () => {\n state.activeInlinePlanApproval = undefined;\n state.ui.setFocus(state.editor);\n firePermissionResult('approved');\n await approvePlan(ctx, toolCallId, resolvedTitle, plan, planPath, snapshotKey);\n\n // `approvePlan` waits for plan mode to idle before `startGoal` sends\n // the canonical goal reminder, so this starts a fresh build-mode run.\n const objective = formatPlanGoalObjective(resolvedTitle, plan);\n await ctx.startGoal(objective, 'Goal cancelled.');\n\n const goal = state.goalManager.getGoal();\n if (goal?.id) {\n state.planStartedGoalId = goal.id;\n }\n\n resolve();\n },\n onReject: () => {\n state.activeInlinePlanApproval = undefined;\n state.ui.setFocus(state.editor);\n firePermissionResult('declined');\n // Resume the tool with a rejection so the rejection result is persisted\n // in thread history (the next run sees it for context). For submit_plan,\n // respondToToolSuspension resolves at the resumed tool's `tool_end`\n // boundary — i.e. once the rejection result has been emitted and the\n // suspension dropped — but BEFORE the follow-up LLM step runs. We await\n // that boundary, then abort the run host-side so the model never gets to\n // generate trailing text. This is deterministic and does not race the\n // in-loop PlanRejectionAbortProcessor (which remains as a backstop). The\n // planRejectionAbort flag suppresses the \"Interrupted\" abort UI so the\n // transcript stays clean for the user's revision feedback.\n void (async () => {\n try {\n await state.session.respondToToolSuspension({\n toolCallId,\n resumeData: { action: 'rejected', path: snapshotKey, title: resolvedTitle, plan },\n });\n } finally {\n state.planRejectionAbort = true;\n state.session.abort();\n }\n })();\n resolve();\n },\n };\n\n const approvalComponent =\n state.lastSubmitPlanComponent instanceof PlanApprovalInlineComponent\n ? state.lastSubmitPlanComponent\n : new PlanApprovalInlineComponent(approvalOptions, state.ui);\n approvalComponent.activate(approvalOptions);\n\n // Store as active plan approval\n state.activeInlinePlanApproval = approvalComponent;\n\n // Insert after the submit_plan placeholder; if streaming already created the\n // plan box, activate that component in place instead of rendering a duplicate.\n if (state.lastSubmitPlanComponent) {\n const children = [...state.chatContainer.children];\n const submitPlanIndex = children.indexOf(state.lastSubmitPlanComponent as any);\n if (submitPlanIndex >= 0) {\n state.chatContainer.clear();\n for (let i = 0; i <= submitPlanIndex; i++) {\n state.chatContainer.addChild(children[i]!);\n }\n if (state.lastSubmitPlanComponent !== approvalComponent) {\n state.chatContainer.addChild(approvalComponent);\n }\n for (let i = submitPlanIndex + 1; i < children.length; i++) {\n state.chatContainer.addChild(children[i]!);\n }\n } else {\n state.chatContainer.addChild(approvalComponent);\n }\n } else {\n state.chatContainer.addChild(approvalComponent);\n }\n state.ui.requestRender();\n state.chatContainer.invalidate();\n state.ui.setFocus(approvalComponent);\n\n ctx.notify('plan_approval', `Plan \"${resolvedTitle}\" requires approval`);\n });\n}\n","/**\n * Event handlers for subagent delegation events:\n * subagent_start, subagent_tool_start, subagent_tool_end, subagent_end.\n */\nimport { insertChatComponentWithBoundarySpacing } from '../chat-boundary-reconciliation.js';\nimport { SubagentExecutionComponent } from '../components/subagent-execution.js';\nimport { flushRender, requestRender } from '../render-scheduler.js';\n\nimport type { EventHandlerContext } from './types.js';\n\nexport function handleSubagentStart(\n ctx: EventHandlerContext,\n toolCallId: string,\n agentType: string,\n task: string,\n modelId?: string,\n forked?: boolean,\n): void {\n const { state } = ctx;\n const component = new SubagentExecutionComponent(agentType, task, state.ui, modelId, {\n collapseOnComplete: false,\n expandOnComplete: state.quietMode,\n forked,\n });\n state.pendingSubagents.set(toolCallId, component);\n state.allToolComponents.push(component as any);\n\n // Insert before the current streamingComponent so subagent box\n // appears between pre-subagent text and post-subagent text\n if (state.streamingComponent) {\n const idx = state.chatContainer.children.indexOf(state.streamingComponent as any);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(state.chatContainer, component, idx);\n } else {\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n }\n } else {\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n }\n\n flushRender(state);\n}\n\nexport function handleSubagentToolStart(\n ctx: EventHandlerContext,\n toolCallId: string,\n subToolName: string,\n subToolArgs: unknown,\n): void {\n const component = ctx.state.pendingSubagents.get(toolCallId);\n if (component) {\n component.addToolStart(subToolName, subToolArgs);\n requestRender(ctx.state);\n }\n}\n\nexport function handleSubagentToolEnd(\n ctx: EventHandlerContext,\n toolCallId: string,\n subToolName: string,\n subToolResult: unknown,\n isError: boolean,\n): void {\n const component = ctx.state.pendingSubagents.get(toolCallId);\n if (component) {\n component.addToolEnd(subToolName, subToolResult, isError);\n requestRender(ctx.state);\n }\n}\n\nexport function handleSubagentEnd(\n ctx: EventHandlerContext,\n toolCallId: string,\n isError: boolean,\n durationMs: number,\n result?: string,\n): void {\n const component = ctx.state.pendingSubagents.get(toolCallId);\n if (component) {\n component.finish(isError, durationMs, result);\n ctx.state.pendingSubagents.delete(toolCallId);\n flushRender(ctx.state);\n }\n}\n","/**\n * Drop-in replacement for pi-tui's `SelectList` used by the editor's\n * slash-command / autocomplete dropdown. Behaves like `SelectList` (same\n * prefix, primary column, and description styling) but word-wraps long\n * descriptions across multiple terminal rows instead of truncating them on a\n * single line. Continuation rows are indented under the description column so\n * the full command/skill description stays readable without widening the\n * terminal.\n *\n * Arrow keys move item-to-item (not row-to-row), so navigation stays\n * predictable regardless of how many rows a description wraps onto.\n */\n\nimport { getKeybindings, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\nimport type { Component, SelectItem, SelectListTheme } from '@earendil-works/pi-tui';\n\nconst DEFAULT_PRIMARY_COLUMN_WIDTH = 32;\nconst PRIMARY_COLUMN_GAP = 2;\nconst MIN_DESCRIPTION_WIDTH = 10;\nconst DESCRIPTION_WIDTH_THRESHOLD = 40;\n\nexport interface WrappingAutocompleteListLayout {\n minPrimaryColumnWidth?: number;\n maxPrimaryColumnWidth?: number;\n}\n\nconst normalizeToSingleLine = (text: string): string => text.replace(/[\\r\\n]+/g, ' ').trim();\nconst clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(value, max));\n\nexport class WrappingAutocompleteList implements Component {\n private items: SelectItem[];\n private filteredItems: SelectItem[];\n private selectedIndex = 0;\n private maxVisible: number;\n private theme: SelectListTheme;\n private layout: WrappingAutocompleteListLayout;\n\n onSelect?: (item: SelectItem) => void;\n onCancel?: () => void;\n onSelectionChange?: (item: SelectItem) => void;\n\n constructor(\n items: SelectItem[],\n maxVisible: number,\n theme: SelectListTheme,\n layout: WrappingAutocompleteListLayout = {},\n ) {\n this.items = items;\n this.filteredItems = items;\n this.maxVisible = maxVisible;\n this.theme = theme;\n this.layout = layout;\n }\n\n setFilter(filter: string): void {\n this.filteredItems = this.items.filter(item => item.value.toLowerCase().startsWith(filter.toLowerCase()));\n this.selectedIndex = 0;\n }\n\n setSelectedIndex(index: number): void {\n this.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));\n }\n\n invalidate(): void {}\n\n getSelectedItem(): SelectItem | null {\n return this.filteredItems[this.selectedIndex] ?? null;\n }\n\n render(width: number): string[] {\n const lines: string[] = [];\n\n if (this.filteredItems.length === 0) {\n lines.push(this.theme.noMatch(' No matching commands'));\n return lines;\n }\n\n const primaryColumnWidth = this.getPrimaryColumnWidth();\n const startIndex = Math.max(\n 0,\n Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n );\n const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n for (let i = startIndex; i < endIndex; i++) {\n const item = this.filteredItems[i];\n if (!item) continue;\n const isSelected = i === this.selectedIndex;\n const description = item.description ? normalizeToSingleLine(item.description) : undefined;\n for (const row of this.renderItem(item, isSelected, width, description, primaryColumnWidth)) {\n lines.push(row);\n }\n }\n\n if (startIndex > 0 || endIndex < this.filteredItems.length) {\n const scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;\n lines.push(this.theme.scrollInfo(truncateToWidth(scrollText, width - 2, '')));\n }\n\n return lines;\n }\n\n handleInput(keyData: string): void {\n const kb = getKeybindings();\n\n if (kb.matches(keyData, 'tui.select.up')) {\n this.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1;\n this.notifySelectionChange();\n } else if (kb.matches(keyData, 'tui.select.down')) {\n this.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1;\n this.notifySelectionChange();\n } else if (kb.matches(keyData, 'tui.select.confirm')) {\n const selected = this.filteredItems[this.selectedIndex];\n if (selected && this.onSelect) this.onSelect(selected);\n } else if (kb.matches(keyData, 'tui.select.cancel')) {\n this.onCancel?.();\n }\n }\n\n private renderItem(\n item: SelectItem,\n isSelected: boolean,\n width: number,\n description: string | undefined,\n primaryColumnWidth: number,\n ): string[] {\n const prefix = isSelected ? '→ ' : ' ';\n const prefixWidth = visibleWidth(prefix);\n\n if (description && width > DESCRIPTION_WIDTH_THRESHOLD) {\n const effectivePrimaryColumnWidth = Math.max(1, Math.min(primaryColumnWidth, width - prefixWidth - 4));\n const maxPrimaryWidth = Math.max(1, effectivePrimaryColumnWidth - PRIMARY_COLUMN_GAP);\n const truncatedValue = this.truncatePrimary(item, maxPrimaryWidth);\n const truncatedValueWidth = visibleWidth(truncatedValue);\n const spacing = ' '.repeat(Math.max(1, effectivePrimaryColumnWidth - truncatedValueWidth));\n const descriptionStart = prefixWidth + truncatedValueWidth + spacing.length;\n const remainingWidth = width - descriptionStart - 2; // -2 for safety, mirrors SelectList\n\n if (remainingWidth > MIN_DESCRIPTION_WIDTH) {\n // Wrap the description across rows instead of truncating it. The first\n // row keeps the primary column; continuation rows indent under the\n // description column so the wrapped text aligns.\n const wrapped = wrapTextWithAnsi(description, remainingWidth);\n const continuationIndent = ' '.repeat(descriptionStart);\n\n return wrapped.map((chunk, index) => {\n if (index === 0) {\n if (isSelected) {\n return this.theme.selectedText(`${prefix}${truncatedValue}${spacing}${chunk}`);\n }\n return prefix + truncatedValue + this.theme.description(spacing + chunk);\n }\n if (isSelected) {\n return this.theme.selectedText(`${continuationIndent}${chunk}`);\n }\n return this.theme.description(continuationIndent + chunk);\n });\n }\n }\n\n const maxWidth = width - prefixWidth - 2;\n const truncatedValue = this.truncatePrimary(item, maxWidth);\n if (isSelected) {\n return [this.theme.selectedText(`${prefix}${truncatedValue}`)];\n }\n return [prefix + truncatedValue];\n }\n\n private getPrimaryColumnWidth(): number {\n const { min, max } = this.getPrimaryColumnBounds();\n const widestPrimary = this.filteredItems.reduce(\n (widest, item) => Math.max(widest, visibleWidth(this.getDisplayValue(item)) + PRIMARY_COLUMN_GAP),\n 0,\n );\n return clamp(widestPrimary, min, max);\n }\n\n private getPrimaryColumnBounds(): { min: number; max: number } {\n const rawMin =\n this.layout.minPrimaryColumnWidth ?? this.layout.maxPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n const rawMax =\n this.layout.maxPrimaryColumnWidth ?? this.layout.minPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n return {\n min: Math.max(1, Math.min(rawMin, rawMax)),\n max: Math.max(1, Math.max(rawMin, rawMax)),\n };\n }\n\n private truncatePrimary(item: SelectItem, maxWidth: number): string {\n return truncateToWidth(this.getDisplayValue(item), maxWidth, '');\n }\n\n private getDisplayValue(item: SelectItem): string {\n return item.label || item.value;\n }\n\n private notifySelectionChange(): void {\n const selected = this.filteredItems[this.selectedIndex];\n if (selected && this.onSelectionChange) this.onSelectionChange(selected);\n }\n}\n","/**\n * Custom editor that handles app-level keybindings for Mastra Code.\n */\n\nimport { readFileSync, statSync } from 'node:fs';\nimport { extname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Editor, matchesKey } from '@earendil-works/pi-tui';\nimport type { EditorTheme, SelectItem, TUI } from '@earendil-works/pi-tui';\nimport { getClipboardImage, getClipboardText } from '@mastra/code-sdk/clipboard/index';\nimport type { ClipboardImage } from '@mastra/code-sdk/clipboard/index';\nimport chalk from 'chalk';\nimport { mastra, theme } from '../theme.js';\nimport type { GradientAnimator } from './obi-loader.js';\nimport { WrappingAutocompleteList } from './wrapping-autocomplete-list.js';\n\n// Mirrors pi-tui's SLASH_COMMAND_SELECT_LIST_LAYOUT so slash-command rows keep\n// the same primary-column sizing as the upstream SelectList.\nconst SLASH_COMMAND_LIST_LAYOUT = {\n minPrimaryColumnWidth: 12,\n maxPrimaryColumnWidth: 32,\n};\n\nconst PASTE_START = '\\x1b[200~';\nconst PASTE_END = '\\x1b[201~';\nconst IMAGE_MIME_TYPES_BY_EXTENSION: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.bmp': 'image/bmp',\n '.tif': 'image/tiff',\n '.tiff': 'image/tiff',\n '.heic': 'image/heic',\n '.heif': 'image/heif',\n};\n\n/**\n * Push-to-talk voice input interface the editor drives. Implemented by\n * VoiceController. Terminals do not emit key-up events, so a held space is\n * inferred from auto-repeat: a burst of rapid repeated spaces means the key is\n * held (start recording); recording stops once those repeats stop arriving.\n */\nexport interface VoiceInputHook {\n isEnabled(): boolean;\n isRecording(): boolean;\n startRecording(): void;\n stopRecording(): void | Promise<void>;\n}\n\n// A held key repeats only after the OS key-repeat delay (~500ms on macOS),\n// then steadily (~80ms cadence). A space tap counts toward \"held\" only when it\n// follows the previous space within this window.\nconst SPACE_REPEAT_MAX_GAP_MS = 180;\n// Number of rapid consecutive spaces that confirm the key is held rather than\n// being tapped. The literal spaces typed before this point are removed.\nconst SPACE_HOLD_REPEAT_THRESHOLD = 3;\n// While recording, the space is considered released once no repeat arrives for\n// this long (comfortably above the ~80ms repeat cadence).\nconst SPACE_RELEASE_IDLE_MS = 250;\n\nexport type AppAction =\n | 'clear'\n | 'exit'\n | 'suspend'\n | 'undo'\n | 'toggleThinking'\n | 'expandTools'\n | 'followUp'\n | 'queueFollowUp'\n | 'cycleMode'\n | 'toggleYolo';\n\n// Pre-compiled constant (avoid re-creation per render)\nconst ANSI_STRIP_RE = /\\x1b\\[[0-9;]*m/g;\nfunction parseHex(hex: string): [number, number, number] {\n const h = hex.replace('#', '');\n return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];\n}\n\n// Vertical bar glyphs ordered low→high; cycled to animate a soundwave cell.\nconst VOICE_WAVE_BARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'] as const;\n\nconst DEFAULT_PROMPT_ICON = '•';\nconst PROMPT_ICON_CHOICES = [\n '☯',\n '✺',\n '☻',\n '✿',\n '◒',\n '◓',\n '♞',\n '☘',\n '☸',\n '❂',\n '❁',\n '✽',\n '❉',\n '✹',\n '❨',\n '❩',\n '✚',\n '⚉',\n '❣',\n '❥',\n '♫',\n '❤',\n] as const;\n\nfunction getRandomPromptIcon(currentIcon: string): string {\n if (Math.random() < 0.99) {\n return DEFAULT_PROMPT_ICON;\n }\n\n const nextChoices = PROMPT_ICON_CHOICES.filter(icon => icon !== currentIcon);\n const choices = nextChoices.length > 0 ? nextChoices : PROMPT_ICON_CHOICES;\n return choices[Math.floor(Math.random() * choices.length)]!;\n}\n\nexport class CustomEditor extends Editor {\n private actionHandlers: Map<AppAction, () => unknown> = new Map();\n\n public onCtrlD?: () => void;\n public escapeEnabled = true;\n public onImagePaste?: (image: ClipboardImage) => void;\n public getModeColor?: () => string | undefined;\n public getPromptAnimator?: () => GradientAnimator | undefined;\n public requestRender?: () => void;\n private pendingBracketedPaste: string | null = null;\n\n /**\n * Push-to-talk voice hook. When set and enabled, holding the space bar starts\n * recording; releasing it (auto-repeat stops) transcribes and inserts at the\n * cursor.\n */\n public voiceInput?: VoiceInputHook;\n // Timestamp of the previous space key event, used to measure repeat cadence.\n private lastSpaceAt = 0;\n // Count of consecutive rapid spaces seen so far (the current repeat burst).\n private spaceRepeatCount = 0;\n // Whether a held-space recording session is currently active.\n private voiceRecordingActive = false;\n // Fires when space auto-repeat stops, signalling the key was released.\n private spaceReleaseTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Whether the \"listening\" prompt animation is active (recording in progress).\n private voiceListening = false;\n // Drives the listening pulse so the prompt indicator animates while recording.\n private voiceListenTimer: ReturnType<typeof setInterval> | null = null;\n private voiceListenPhase = 0;\n // The dictated run currently rendered greyed-out. Cleared once the user edits,\n // so dictated text reads as \"not written by us\" until accepted.\n private voiceTranscriptText = '';\n // Text surrounding the dictated run, captured at the cursor position where\n // dictation began. Lets live replacements rebuild the input in place instead\n // of always appending to the end.\n private voicePrefix = '';\n private voiceSuffix = '';\n // True while a dictation session owns the trailing run. Set when listening\n // starts, cleared on a real user keystroke so late async transcripts that\n // arrive after the user resumed typing are ignored rather than re-appended.\n private voiceDictationActive = false;\n\n private _cachedModeColorHex?: string;\n private _cachedColorFn?: (s: string) => string;\n private promptIcon = DEFAULT_PROMPT_ICON;\n private lastPromptWasInvisible = false;\n\n private requestEditorRender(): void {\n if (this.requestRender) {\n this.requestRender();\n return;\n }\n this.tui.requestRender();\n }\n\n constructor(tui: TUI, theme: EditorTheme) {\n super(tui, theme);\n (this as any).getBestAutocompleteMatchIndex = (items: Array<{ value: string }>, prefix: string): number => {\n if (!prefix) {\n return -1;\n }\n\n const normalizeSlashCommandValue = (value: string) => value.replace(/^\\/+/, '');\n const shouldNormalizeSlashCommand = prefix.startsWith('/');\n const normalizedPrefix = shouldNormalizeSlashCommand ? normalizeSlashCommandValue(prefix) : prefix;\n\n let firstPrefixIndex = -1;\n for (let i = 0; i < items.length; i++) {\n const value = items[i]?.value ?? '';\n const comparableValue = shouldNormalizeSlashCommand ? normalizeSlashCommandValue(value) : value;\n\n if (comparableValue === normalizedPrefix) {\n return i;\n }\n\n if (firstPrefixIndex === -1 && comparableValue.startsWith(normalizedPrefix)) {\n firstPrefixIndex = i;\n }\n }\n\n return firstPrefixIndex;\n };\n\n // Override pi-tui's private `createAutocompleteList` so the slash-command /\n // autocomplete dropdown uses WrappingAutocompleteList. This wraps long\n // command/skill descriptions across multiple rows instead of truncating\n // them on a single line. Wired here (rather than as a class method) because\n // the base declares it `private`, so a normal override would be a type clash.\n (this as any).createAutocompleteList = (prefix: string, items: SelectItem[]) => {\n const layout = prefix.startsWith('/') ? SLASH_COMMAND_LIST_LAYOUT : undefined;\n const internals = this as unknown as { autocompleteMaxVisible: number; theme: EditorTheme };\n return new WrappingAutocompleteList(items, internals.autocompleteMaxVisible, internals.theme.selectList, layout);\n };\n }\n\n onAction(action: AppAction, handler: () => unknown): void {\n this.actionHandlers.set(action, handler);\n }\n\n render(width: number): string[] {\n const text = this.getText().trimStart();\n const isSlash = text.startsWith('/');\n const isAt = text.startsWith('@');\n const isBang = text.startsWith('!');\n const color = this.getModeColor?.() || mastra.green;\n const promptAnimator = this.getPromptAnimator?.();\n const shouldAnimatePrompt = !isSlash && !isAt && !isBang;\n const isPromptAnimated = shouldAnimatePrompt && Boolean(promptAnimator?.isRunning());\n const fadeProgress = isPromptAnimated ? promptAnimator!.getFadeProgress() : 1;\n const isTransitioningIn = isPromptAnimated && promptAnimator!.isFadingIn();\n const isTransitioningOut = isPromptAnimated && promptAnimator!.isFadingOut();\n const promptOffset = isPromptAnimated ? promptAnimator!.getOffset() : 0;\n const pulseWave = isPromptAnimated ? (Math.sin(promptOffset * Math.PI * 2) + 1) / 2 : 0;\n const transitionPhase = isTransitioningIn || isTransitioningOut ? 1 - fadeProgress : 1;\n const chevronBrightness = isPromptAnimated\n ? isTransitioningIn\n ? transitionPhase < 0.5\n ? Math.max(0, 1 - transitionPhase * 2)\n : 0\n : isTransitioningOut\n ? transitionPhase <= 0.5\n ? Math.max(0, 1 - transitionPhase * 2)\n : 0\n : 0\n : 1;\n const dotBrightness = isPromptAnimated\n ? isTransitioningIn\n ? transitionPhase <= 0.5\n ? 0\n : Math.max(0, (transitionPhase - 0.5) * 2)\n : isTransitioningOut\n ? transitionPhase < 0.5\n ? 0\n : Math.max(0, (transitionPhase - 0.5) * 2)\n : pulseWave\n : 0;\n\n const isSteadyPulse = isPromptAnimated && !isTransitioningIn && !isTransitioningOut;\n if (!isPromptAnimated) {\n this.promptIcon = DEFAULT_PROMPT_ICON;\n this.lastPromptWasInvisible = false;\n } else if (!isSteadyPulse) {\n this.lastPromptWasInvisible = false;\n }\n\n const promptIsInvisible = isSteadyPulse && dotBrightness <= 0.05;\n if (promptIsInvisible && !this.lastPromptWasInvisible) {\n this.promptIcon = getRandomPromptIcon(this.promptIcon);\n }\n this.lastPromptWasInvisible = promptIsInvisible;\n\n const promptChar = isSlash\n ? '/'\n : isAt\n ? '@'\n : isBang\n ? '!'\n : chevronBrightness > 0.05\n ? '›'\n : dotBrightness > 0.05\n ? this.promptIcon\n : ' ';\n const promptBrightness = isPromptAnimated ? Math.max(chevronBrightness, dotBrightness) : 1;\n\n // Cache colorFn and prompt — only recreate when color changes\n if (this._cachedModeColorHex !== color) {\n this._cachedModeColorHex = color;\n this._cachedColorFn = chalk.hex(color);\n }\n const colorFn = this._cachedColorFn!;\n const b = colorFn;\n const [r, g, bValue] = parseHex(color);\n let prompt: string;\n if (this.voiceListening) {\n // Animated single-cell soundwave: a vertical bar that rises and falls like\n // an equalizer, so the prompt reads as a live waveform while recording.\n const wave = (Math.sin(this.voiceListenPhase * 0.6) + 1) / 2; // 0..1\n const bar = VOICE_WAVE_BARS[Math.round(wave * (VOICE_WAVE_BARS.length - 1))]!;\n // Pulse the wave using the current mode color so it matches the prompt.\n const brightness = 0.5 + wave * 0.5;\n prompt = chalk.bold.rgb(\n Math.round(r * brightness),\n Math.round(g * brightness),\n Math.round(bValue * brightness),\n )(bar);\n } else {\n prompt = chalk.bold.rgb(\n Math.round(r * promptBrightness),\n Math.round(g * promptBrightness),\n Math.round(bValue * promptBrightness),\n )(promptChar);\n }\n\n // Box structure: \"│ > content │\" or \"│ content │\"\n // Left: \"│ > \" (4) or \"│ \" (4), Right: \" │\" (2) = 6 chars total\n const promptWidth = 4; // \"│ > \" or \"│ \"\n const contentWidth = width - 6;\n // Slash, mention and shell markers are rendered in the prompt chrome, so remove them\n // from the editor's layout state before wrapping and restore the state after.\n const editorState = (\n this as unknown as {\n state: { lines: string[]; cursorLine: number; cursorCol: number };\n }\n ).state;\n const decorativePrompt = isSlash ? '/' : isAt ? '@' : isBang ? '!' : undefined;\n const firstLine = editorState.lines[0];\n const markerIndex = firstLine?.search(/\\S/) ?? -1;\n const shouldHideDecorativePrompt =\n decorativePrompt !== undefined && firstLine !== undefined && firstLine[markerIndex] === decorativePrompt;\n const cursorLine = editorState.cursorLine;\n const cursorCol = editorState.cursorCol;\n const cursorOnDecorativePrompt = shouldHideDecorativePrompt && cursorLine === 0 && cursorCol === markerIndex;\n if (cursorOnDecorativePrompt && !this.voiceListening) {\n prompt = `\\x1b[7m${prompt}\\x1b[0m`;\n }\n let editorLines: string[];\n if (shouldHideDecorativePrompt) {\n editorState.lines[0] = firstLine.slice(0, markerIndex) + firstLine.slice(markerIndex + 1);\n if (cursorOnDecorativePrompt) {\n editorState.cursorLine = -1;\n } else if (editorState.cursorLine === 0 && cursorCol > markerIndex) {\n editorState.cursorCol = cursorCol - 1;\n }\n try {\n editorLines = super.render(contentWidth);\n } finally {\n editorState.lines[0] = firstLine;\n editorState.cursorLine = cursorLine;\n editorState.cursorCol = cursorCol;\n }\n } else {\n editorLines = super.render(contentWidth);\n }\n\n // Extract content lines (skip editor's invisible borders)\n const contentLines: string[] = [];\n const scrollIndicators: string[] = [];\n let isTop = true;\n for (const line of editorLines) {\n const stripped = line.replace(ANSI_STRIP_RE, '');\n if (stripped.length > 0 && stripped[0] === '─') {\n if (isTop) {\n isTop = false;\n continue;\n }\n if (stripped.includes('↑') || stripped.includes('↓')) {\n scrollIndicators.push(b(stripped));\n continue;\n }\n continue;\n }\n contentLines.push(line);\n }\n\n // Build rounded box\n const result: string[] = [];\n const hBarLen = width - 2;\n\n // Solid mode-color border\n const top = b('╭') + b('─').repeat(hBarLen) + b('╮');\n const leftBorder = b('│');\n const rightBorder = b('│');\n const bottom = b('╰') + b('─').repeat(hBarLen) + b('╯');\n\n // Assemble box\n const textColorOpen = `\\x1b[38;2;${parseHex(theme.getTheme().text).join(';')}m`;\n const textColorClose = '\\x1b[39m';\n result.push(top);\n\n // How many trailing characters are dictated and should render greyed-out.\n const fullText = this.getText();\n let greyRemaining =\n this.voiceTranscriptText.length > 0 && fullText.endsWith(this.voiceTranscriptText)\n ? this.voiceTranscriptText.length\n : 0;\n const greyOpen = `\\x1b[38;2;${parseHex(theme.getTheme().muted).join(';')}m`;\n\n for (let i = contentLines.length - 1; i >= 0; i--) {\n if (greyRemaining > 0) {\n const { line, consumed } = this.greyifyTrailing(contentLines[i]!, greyRemaining, greyOpen, textColorOpen);\n contentLines[i] = line;\n greyRemaining -= consumed;\n }\n }\n\n for (let i = 0; i < contentLines.length; i++) {\n const line = `${textColorOpen}${contentLines[i]!}${textColorClose}`;\n if (i === 0) {\n result.push(`${leftBorder} ${prompt} ${line} ${rightBorder}`);\n } else {\n result.push(`${leftBorder}${' '.repeat(promptWidth - 1)}${line} ${rightBorder}`);\n }\n }\n\n result.push(bottom);\n\n // Scroll indicators below the box\n for (const ind of scrollIndicators) {\n result.push(ind);\n }\n\n return result;\n }\n\n private maybeHandleBracketedPaste(data: string): boolean {\n const pasteStartIndex = this.pendingBracketedPaste ? -1 : data.indexOf(PASTE_START);\n if (!this.pendingBracketedPaste && pasteStartIndex === -1) {\n return false;\n }\n\n const beforePaste = this.pendingBracketedPaste ? '' : data.slice(0, pasteStartIndex);\n const pasteChunk = this.pendingBracketedPaste\n ? `${this.pendingBracketedPaste}${data}`\n : data.slice(pasteStartIndex);\n\n if (beforePaste) {\n super.handleInput(beforePaste);\n }\n\n const pasteEndIndex = pasteChunk.indexOf(PASTE_END);\n if (pasteEndIndex === -1) {\n this.pendingBracketedPaste = pasteChunk;\n return true;\n }\n\n this.pendingBracketedPaste = null;\n\n const pasteContent = pasteChunk.slice(PASTE_START.length, pasteEndIndex);\n const afterPaste = pasteChunk.slice(pasteEndIndex + PASTE_END.length);\n\n if (this.shouldPasteClipboardImage(pasteContent)) {\n const clipboardImage = getClipboardImage();\n if (clipboardImage) {\n this.onImagePaste?.(clipboardImage);\n if (afterPaste.length > 0) {\n this.handleInput(afterPaste);\n }\n return true;\n }\n }\n\n const clipboardImageForRemoteUrl = this.getClipboardImageForPastedRemoteImageUrl(pasteContent);\n if (clipboardImageForRemoteUrl) {\n this.onImagePaste?.(clipboardImageForRemoteUrl);\n if (afterPaste.length > 0) {\n this.handleInput(afterPaste);\n }\n return true;\n }\n\n const pastedImageSource = this.readPastedImageSource(pasteContent);\n if (pastedImageSource) {\n this.onImagePaste?.(pastedImageSource);\n if (afterPaste.length > 0) {\n this.handleInput(afterPaste);\n }\n return true;\n }\n\n super.handleInput(`${PASTE_START}${pasteContent}${PASTE_END}`);\n if (afterPaste.length > 0) {\n this.handleInput(afterPaste);\n }\n return true;\n }\n\n private shouldPasteClipboardImage(pasteContent: string): boolean {\n return Boolean(this.onImagePaste) && pasteContent.trim().length === 0;\n }\n\n private getClipboardImageForPastedRemoteImageUrl(pasteContent: string): ClipboardImage | null {\n if (!this.onImagePaste) {\n return null;\n }\n\n if (!this.normalizePastedImageUrl(this.normalizePastedPathLike(pasteContent) ?? '')) {\n return null;\n }\n\n return getClipboardImage();\n }\n\n private readPastedImageSource(pasteContent: string): ClipboardImage | null {\n if (!this.onImagePaste) {\n return null;\n }\n\n const normalizedPaste = this.normalizePastedPathLike(pasteContent);\n if (!normalizedPaste) {\n return null;\n }\n\n const imageUrl = this.normalizePastedImageUrl(normalizedPaste);\n if (imageUrl) {\n const mimeType = this.getImageMimeType(imageUrl);\n return mimeType\n ? {\n data: imageUrl,\n mimeType,\n }\n : null;\n }\n\n const filePath = this.normalizePastedFilePath(normalizedPaste);\n if (!filePath) {\n return null;\n }\n\n const mimeType = this.getImageMimeType(filePath);\n if (!mimeType) {\n return null;\n }\n\n try {\n if (!statSync(filePath).isFile()) {\n return null;\n }\n\n return {\n data: readFileSync(filePath).toString('base64'),\n mimeType,\n };\n } catch {\n return null;\n }\n }\n\n private normalizePastedPathLike(pasteContent: string): string | null {\n const trimmed = pasteContent.trim();\n if (!trimmed || trimmed.includes('\\n')) {\n return null;\n }\n\n const unquoted =\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) || (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ? trimmed.slice(1, -1)\n : trimmed;\n\n return unquoted.replace(/\\\\([ !$&'()\\[\\]{}])/g, '$1');\n }\n\n private normalizePastedImageUrl(pasteContent: string): string | null {\n if (!/^https?:\\/\\//i.test(pasteContent)) {\n return null;\n }\n\n try {\n const url = new URL(pasteContent);\n return this.getImageMimeType(url.toString()) ? url.toString() : null;\n } catch {\n return null;\n }\n }\n\n private normalizePastedFilePath(pasteContent: string): string | null {\n if (/^https?:\\/\\//i.test(pasteContent)) {\n return null;\n }\n\n if (/^file:\\/\\//i.test(pasteContent)) {\n try {\n return fileURLToPath(pasteContent);\n } catch {\n return null;\n }\n }\n\n return pasteContent;\n }\n\n private getImageMimeType(pathOrUrl: string): string | null {\n const extensionSource = /^https?:\\/\\//i.test(pathOrUrl) ? new URL(pathOrUrl).pathname : pathOrUrl;\n return IMAGE_MIME_TYPES_BY_EXTENSION[extname(extensionSource).toLowerCase()] ?? null;\n }\n\n private handleExplicitPaste(): boolean {\n if (this.onImagePaste) {\n const clipboardImage = getClipboardImage();\n if (clipboardImage) {\n this.onImagePaste(clipboardImage);\n return true;\n }\n }\n\n const clipboardText = getClipboardText();\n if (clipboardText) {\n const syntheticPaste = `${PASTE_START}${clipboardText}${PASTE_END}`;\n super.handleInput(syntheticPaste);\n return true;\n }\n\n return true;\n }\n\n private completeAutocompleteSelection(): boolean {\n if (!this.isShowingAutocomplete()) {\n return false;\n }\n\n const wasSlashCommand = this.getText().trimStart().startsWith('/');\n super.handleInput('\\t');\n const completedText = this.getText();\n if (wasSlashCommand && !completedText.trimStart().startsWith('/')) {\n this.setText(`/${completedText.trimStart()}`);\n }\n return wasSlashCommand;\n }\n\n /**\n * Capture the cursor position where dictation begins so the dictated run can be\n * inserted (and later replaced) in place, even when the cursor sits in the\n * middle of existing input.\n */\n private beginDictation(): void {\n const offset = this.getCursorOffset();\n const full = this.getText();\n this.voicePrefix = full.slice(0, offset);\n this.voiceSuffix = full.slice(offset);\n this.voiceTranscriptText = '';\n this.voiceDictationActive = true;\n }\n\n /**\n * Flatten the editor's {line, col} cursor into a single string offset over the\n * newline-joined text.\n */\n private getCursorOffset(): number {\n const lines = this.getText().split('\\n');\n const { line, col } = (this as any).getCursor?.() ?? {\n line: lines.length - 1,\n col: lines[lines.length - 1]?.length ?? 0,\n };\n const clampedLine = Math.min(Math.max(line, 0), lines.length - 1);\n let offset = 0;\n for (let i = 0; i < clampedLine; i++) offset += (lines[i]?.length ?? 0) + 1; // +1 for the '\\n'\n return offset + Math.min(Math.max(col, 0), lines[clampedLine]?.length ?? 0);\n }\n\n /**\n * Restore the cursor to a flat string offset over the newline-joined text.\n * Uses the editor's internal state directly since pi-tui exposes no public\n * cursor setter.\n */\n private setCursorOffset(offset: number): void {\n const lines = this.getText().split('\\n');\n let remaining = Math.max(offset, 0);\n let lineIdx = 0;\n while (lineIdx < lines.length - 1 && remaining > (lines[lineIdx]?.length ?? 0)) {\n remaining -= (lines[lineIdx]?.length ?? 0) + 1;\n lineIdx += 1;\n }\n const col = Math.min(remaining, lines[lineIdx]?.length ?? 0);\n const state = (this as any).state;\n const setCursorCol = (this as any).setCursorCol;\n if (state && typeof setCursorCol === 'function') {\n state.cursorLine = lineIdx;\n setCursorCol.call(this, col);\n }\n }\n\n /**\n * Insert dictated text at the captured dictation anchor. Used for the final\n * (non-live) transcript path.\n */\n public insertVoiceTranscript(text: string): void {\n const trimmed = text.trim();\n if (!trimmed) return;\n this.applyDictation(trimmed);\n }\n\n /**\n * Replace the current dictated run with a new transcript. Used for live\n * transcription, where each partial result supersedes the previous one as the\n * user keeps speaking.\n */\n public replaceVoiceTranscript(text: string): void {\n // The user resumed typing before this async result arrived; honor their edit\n // rather than clobbering it with a stale partial.\n if (!this.voiceDictationActive) return;\n this.applyDictation(text.trim());\n }\n\n /**\n * Rebuild the input as prefix + dictated payload + suffix, keeping the dictated\n * run anchored at the cursor position where dictation began and leaving the\n * cursor just after the dictated text.\n */\n private applyDictation(trimmed: string): void {\n const needsLeadingSpace = this.voicePrefix.length > 0 && !/\\s$/.test(this.voicePrefix);\n const payload = trimmed ? (needsLeadingSpace ? ` ${trimmed}` : trimmed) : '';\n this.voiceTranscriptText = payload;\n this.setText(this.voicePrefix + payload + this.voiceSuffix);\n this.setCursorOffset(this.voicePrefix.length + payload.length);\n // Programmatic insertion mutates editor state but does not repaint on its\n // own, so force a render to show the transcript immediately.\n this.requestEditorRender();\n }\n\n /**\n * Wrap up to `count` trailing dictated characters of a rendered content line in\n * the grey (muted) color. The underlying pi-tui editor produces plain text plus\n * a few artifacts that must be skipped: an APC hardware-cursor marker\n * (`\\x1b_pi:c\\x07`), a reverse-video cursor highlight (`\\x1b[7m…\\x1b[0m`), and\n * trailing padding spaces. We isolate the real content region (everything\n * before the cursor highlight / padding) and grey only its trailing characters,\n * leaving the cursor and padding untouched.\n *\n * Returns the recolored line and how many content characters were greyed.\n */\n private greyifyTrailing(\n line: string,\n count: number,\n greyOpen: string,\n textColorOpen: string,\n ): { line: string; consumed: number } {\n // Split the content region (real text) from the trailing artifacts: the\n // hardware-cursor marker, the cursor highlight, and any padding after it.\n const CURSOR_MARKER = '\\x1b_pi:c\\x07';\n const cursorHighlight = /\\x1b\\[7m[\\s\\S]*?\\x1b\\[0m/;\n let head = line;\n let tail = '';\n\n const markerIdx = line.indexOf(CURSOR_MARKER);\n if (markerIdx !== -1) {\n head = line.slice(0, markerIdx);\n tail = line.slice(markerIdx);\n } else {\n const hl = cursorHighlight.exec(line);\n if (hl) {\n head = line.slice(0, hl.index);\n tail = line.slice(hl.index);\n } else {\n // No cursor on this line: trailing run is padding spaces. Strip them so\n // we grey real characters, not the box padding.\n const trimmed = line.replace(/ +$/, '');\n head = trimmed;\n tail = line.slice(trimmed.length);\n }\n }\n\n // Within `head`, tokenize into SGR escapes and visible characters and grey\n // the trailing `count` visible characters.\n const tokens: Array<{ ansi: boolean; text: string }> = [];\n const re = /\\x1b\\[[0-9;]*m/g;\n let last = 0;\n let mt: RegExpExecArray | null;\n while ((mt = re.exec(head)) !== null) {\n if (mt.index > last) {\n for (const ch of head.slice(last, mt.index)) tokens.push({ ansi: false, text: ch });\n }\n tokens.push({ ansi: true, text: mt[0] });\n last = re.lastIndex;\n }\n for (const ch of head.slice(last)) tokens.push({ ansi: false, text: ch });\n\n let consumed = 0;\n let firstGreyIdx = -1;\n for (let i = tokens.length - 1; i >= 0 && consumed < count; i--) {\n if (!tokens[i]!.ansi) {\n firstGreyIdx = i;\n consumed += 1;\n }\n }\n if (firstGreyIdx === -1) return { line, consumed: 0 };\n\n const before = tokens\n .slice(0, firstGreyIdx)\n .map(t => t.text)\n .join('');\n const grey = tokens\n .slice(firstGreyIdx)\n .map(t => t.text)\n .join('');\n // Re-open the normal text color before the cursor/padding tail so only the\n // dictated run is grey.\n return { line: `${before}${greyOpen}${grey}${textColorOpen}${tail}`, consumed };\n }\n\n /**\n * Start or stop the \"listening\" prompt animation. While listening, the prompt\n * indicator pulses on its own timer so the user gets clear visual feedback\n * that the mic is recording.\n */\n public setVoiceListening(listening: boolean): void {\n if (listening === this.voiceListening) return;\n this.voiceListening = listening;\n if (listening) {\n this.beginDictation();\n this.voiceListenPhase = 0;\n this.voiceListenTimer ??= setInterval(() => {\n this.voiceListenPhase += 1;\n this.requestEditorRender();\n }, 120);\n } else if (this.voiceListenTimer) {\n clearInterval(this.voiceListenTimer);\n this.voiceListenTimer = null;\n }\n this.requestEditorRender();\n }\n\n /**\n * Push-to-talk space handling. Returns true when the space was consumed by\n * voice handling and must not be processed further.\n *\n * Normal spaces are typed instantly (no deferral, no lag). A held space is\n * detected from terminal auto-repeat: once SPACE_HOLD_REPEAT_THRESHOLD rapid\n * spaces arrive, the literal spaces already typed are deleted and recording\n * begins. While recording, repeats are swallowed and reset a release timer;\n * when repeats stop (key released) recording stops and transcribes.\n */\n private maybeHandleVoiceSpace(data: string): boolean {\n if (data !== ' ' || !this.voiceInput?.isEnabled()) {\n if (data !== ' ') {\n // Any non-space key ends a potential repeat burst.\n this.spaceRepeatCount = 0;\n }\n return false;\n }\n\n const now = Date.now();\n const gap = this.lastSpaceAt ? now - this.lastSpaceAt : Infinity;\n this.lastSpaceAt = now;\n\n // Already recording: swallow the repeat and keep the release timer alive.\n if (this.voiceRecordingActive) {\n this.armSpaceReleaseTimer();\n return true;\n }\n\n if (gap <= SPACE_REPEAT_MAX_GAP_MS) {\n this.spaceRepeatCount += 1;\n } else {\n this.spaceRepeatCount = 1;\n }\n\n // Threshold reached: this is a held key. Remove the literal spaces already\n // typed during the burst and start recording.\n if (this.spaceRepeatCount >= SPACE_HOLD_REPEAT_THRESHOLD) {\n const typedSpaces = SPACE_HOLD_REPEAT_THRESHOLD - 1;\n for (let i = 0; i < typedSpaces; i++) {\n // Backspace removes one previously inserted literal space.\n super.handleInput('\\x7f');\n }\n this.spaceRepeatCount = 0;\n this.voiceRecordingActive = true;\n this.voiceInput.startRecording();\n this.armSpaceReleaseTimer();\n return true;\n }\n\n // Not yet confirmed as a hold: type the space normally (instant, no lag).\n return false;\n }\n\n private armSpaceReleaseTimer(): void {\n if (this.spaceReleaseTimer) {\n clearTimeout(this.spaceReleaseTimer);\n }\n this.spaceReleaseTimer = setTimeout(() => {\n this.spaceReleaseTimer = null;\n this.voiceRecordingActive = false;\n this.lastSpaceAt = 0;\n this.spaceRepeatCount = 0;\n void this.voiceInput?.stopRecording();\n }, SPACE_RELEASE_IDLE_MS);\n }\n\n handleInput(data: string): void {\n if (this.maybeHandleBracketedPaste(data)) {\n return;\n }\n\n if (this.maybeHandleVoiceSpace(data)) {\n return;\n }\n\n // Any genuine keystroke means the user is editing — stop greying the\n // dictated text so it now reads as their own input, and end the dictation\n // session so any late async transcript that arrives after this edit is\n // ignored instead of clobbering the user's input.\n this.voiceTranscriptText = '';\n this.voiceDictationActive = false;\n\n if (matchesKey(data, 'ctrl+v') || matchesKey(data, 'alt+v')) {\n this.handleExplicitPaste();\n return;\n }\n\n if (matchesKey(data, 'ctrl+c')) {\n const handler = this.actionHandlers.get('clear');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'escape') && this.escapeEnabled) {\n const handler = this.actionHandlers.get('clear');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'ctrl+d')) {\n if (this.getText().length === 0) {\n const handler = this.onCtrlD ?? this.actionHandlers.get('exit');\n if (handler) handler();\n }\n return;\n }\n\n if (matchesKey(data, 'ctrl+z')) {\n const handler = this.actionHandlers.get('suspend');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'alt+z')) {\n const handler = this.actionHandlers.get('undo');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'ctrl+t')) {\n const handler = this.actionHandlers.get('toggleThinking');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'ctrl+e')) {\n const handler = this.actionHandlers.get('expandTools');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'ctrl+f')) {\n const handler = this.actionHandlers.get('queueFollowUp');\n if (handler) {\n this.completeAutocompleteSelection();\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'enter')) {\n // Let pi-tui handle \\+Enter newline workaround\n const lines = (this as any).state?.lines;\n const cursorCol = (this as any).state?.cursorCol;\n const currentLine = lines?.[(this as any).state?.cursorLine] || '';\n if (cursorCol > 0 && currentLine[cursorCol - 1] === '\\\\') {\n super.handleInput(data);\n return;\n }\n const handler = this.actionHandlers.get('followUp');\n if (handler) {\n if (this.isShowingAutocomplete()) {\n if (this.completeAutocompleteSelection() && handler() !== false) {\n return;\n }\n return;\n }\n if (handler() !== false) {\n return;\n }\n }\n }\n\n if (matchesKey(data, 'shift+tab')) {\n const handler = this.actionHandlers.get('cycleMode');\n if (handler) {\n handler();\n return;\n }\n }\n\n if (matchesKey(data, 'ctrl+y')) {\n const handler = this.actionHandlers.get('toggleYolo');\n if (handler) {\n handler();\n return;\n }\n }\n\n super.handleInput(data);\n }\n}\n","/**\n * Local microphone capture for push-to-talk voice input.\n *\n * Spawns an external recorder binary (sox/rec or ffmpeg) to capture audio\n * from the system microphone into a temporary WAV file. Audio is recorded as\n * 16kHz mono PCM, which is what speech-to-text models expect.\n *\n * The capture lifecycle is: detect a recorder once, start() spawns the process,\n * stop() signals the process to finish and resolves with the recorded buffer.\n */\n\nimport type { ChildProcess } from 'node:child_process';\nimport { execFileSync, spawn } from 'node:child_process';\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\n\nexport type RecorderKind = 'sox' | 'ffmpeg' | 'pipewire' | 'pulse' | 'alsa';\n\nexport interface RecorderInfo {\n kind: RecorderKind;\n /** Resolved binary name used to spawn the recorder. */\n bin: string;\n}\n\nconst SAMPLE_RATE = 16000;\nconst CHANNELS = 1;\n\n/**\n * Detect an available recorder binary on the host (Linux/macOS).\n *\n * On Linux, prefer native recorders that ship with common desktop audio stacks\n * (PipeWire's `pw-record`, PulseAudio's `parecord`, ALSA's `arecord`) so most\n * users need no extra install. macOS has no reliable built-in CLI recorder, so\n * it falls back to sox/ffmpeg. Both also fall back to sox/ffmpeg if present.\n *\n * Returns null if nothing usable is installed.\n */\nexport function detectRecorder(): RecorderInfo | null {\n // Only macOS and Linux are supported; other platforms (e.g. Windows) have no\n // input backend wired up, so don't advertise a recorder we can't drive.\n if (process.platform !== 'darwin' && process.platform !== 'linux') {\n return null;\n }\n if (process.platform === 'linux') {\n if (commandExists('pw-record')) return { kind: 'pipewire', bin: 'pw-record' };\n if (commandExists('parecord')) return { kind: 'pulse', bin: 'parecord' };\n if (commandExists('arecord')) return { kind: 'alsa', bin: 'arecord' };\n }\n for (const bin of ['rec', 'sox']) {\n if (commandExists(bin)) {\n return { kind: 'sox', bin };\n }\n }\n // ffmpegInputArgs() only knows the macOS avfoundation backend, so only offer\n // ffmpeg there. Linux falls back to the dedicated recorders above.\n if (process.platform === 'darwin' && commandExists('ffmpeg')) {\n return { kind: 'ffmpeg', bin: 'ffmpeg' };\n }\n return null;\n}\n\nfunction commandExists(bin: string): boolean {\n try {\n const probe = process.platform === 'win32' ? 'where' : 'which';\n execFileSync(probe, [bin], { stdio: ['ignore', 'ignore', 'ignore'], timeout: 3000 });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * A single in-progress microphone recording.\n */\nexport class MicRecording {\n private proc: ChildProcess;\n private outputPath: string;\n private recorder: RecorderInfo;\n private stderr = '';\n private exited: Promise<void>;\n private resolveExited!: () => void;\n private stopped = false;\n\n constructor(recorder: RecorderInfo) {\n this.recorder = recorder;\n this.outputPath = join(tmpdir(), `mastra-voice-${Date.now()}-${Math.random().toString(36).slice(2)}.wav`);\n\n const { command, args } = buildRecorderCommand(recorder, this.outputPath);\n this.proc = spawn(command, args, { stdio: ['ignore', 'ignore', 'pipe'] });\n\n this.exited = new Promise<void>(resolve => {\n this.resolveExited = resolve;\n });\n\n this.proc.stderr?.on('data', (chunk: Buffer) => {\n this.stderr += chunk.toString();\n });\n this.proc.on('error', () => {\n this.resolveExited();\n });\n this.proc.on('close', () => {\n this.resolveExited();\n });\n }\n\n /**\n * Stop recording and return the captured audio as a WAV buffer.\n * Returns null if recording failed or produced no audio.\n */\n async stop(): Promise<Buffer | null> {\n if (this.stopped) return null;\n this.stopped = true;\n\n // ffmpeg listens for `q` on stdin to finish cleanly and flush the file.\n // sox/rec respond to SIGINT/SIGTERM by finalizing the WAV header.\n if (this.recorder.kind === 'ffmpeg' && this.proc.stdin && !this.proc.stdin.destroyed) {\n try {\n this.proc.stdin.write('q');\n this.proc.stdin.end();\n } catch {\n this.proc.kill('SIGINT');\n }\n } else {\n this.proc.kill('SIGINT');\n }\n\n await this.exited;\n\n try {\n if (!existsSync(this.outputPath)) return null;\n const buffer = readFileSync(this.outputPath);\n // A bare WAV header is 44 bytes; anything at or below that is empty audio.\n if (buffer.length <= 44) return null;\n return buffer;\n } catch {\n return null;\n } finally {\n this.cleanup();\n }\n }\n\n /**\n * Read the audio captured so far, mid-recording, as a playable WAV buffer.\n *\n * The recorder is still appending to the file and has not finalized the WAV\n * header's size fields, so we read the current bytes and patch the RIFF/data\n * chunk sizes to match what's actually on disk. Returns null if there isn't\n * enough audio yet to transcribe.\n */\n snapshot(): Buffer | null {\n if (this.stopped) return null;\n try {\n if (!existsSync(this.outputPath)) return null;\n const buffer = readFileSync(this.outputPath);\n // Need a header plus a little audio to be worth transcribing.\n if (buffer.length <= 1024) return null;\n return fixWavHeader(buffer);\n } catch {\n return null;\n }\n }\n\n /**\n * Abort recording without returning audio (e.g. on cancel).\n */\n cancel(): void {\n if (this.stopped) return;\n this.stopped = true;\n try {\n this.proc.kill('SIGKILL');\n } catch {\n // ignore\n }\n this.cleanup();\n }\n\n private cleanup(): void {\n try {\n if (existsSync(this.outputPath)) unlinkSync(this.outputPath);\n } catch {\n // ignore cleanup errors\n }\n }\n}\n\n/**\n * Patch a WAV buffer's RIFF/data chunk sizes to match its actual byte length.\n *\n * Recorders write a placeholder (often zero or streaming) size while capture is\n * ongoing, so a mid-recording snapshot has wrong sizes. We rewrite the RIFF\n * chunk size (total file size minus 8) and the `data` chunk size (bytes after\n * the data header) so decoders read the audio we actually have.\n */\nfunction fixWavHeader(buffer: Buffer): Buffer {\n if (buffer.length < 44 || buffer.toString('ascii', 0, 4) !== 'RIFF') {\n return buffer;\n }\n const out = Buffer.from(buffer);\n // RIFF chunk size = total length - 8 (the \"RIFF\" tag and this size field).\n out.writeUInt32LE(out.length - 8, 4);\n\n // Locate the \"data\" sub-chunk; its size field is the 4 bytes that follow.\n const dataIdx = out.indexOf('data', 12, 'ascii');\n if (dataIdx !== -1 && dataIdx + 8 <= out.length) {\n const dataSize = out.length - (dataIdx + 8);\n out.writeUInt32LE(dataSize, dataIdx + 4);\n }\n return out;\n}\n\nfunction buildRecorderCommand(recorder: RecorderInfo, outputPath: string): { command: string; args: string[] } {\n switch (recorder.kind) {\n case 'pipewire':\n // PipeWire: record from the default source as 16kHz mono signed 16-bit WAV.\n return {\n command: recorder.bin,\n args: ['--rate', String(SAMPLE_RATE), '--channels', String(CHANNELS), '--format', 's16', outputPath],\n };\n case 'pulse':\n // PulseAudio's parecord writes a WAV when the path ends in .wav.\n return {\n command: recorder.bin,\n args: ['--rate', String(SAMPLE_RATE), '--channels', String(CHANNELS), '--format', 's16le', outputPath],\n };\n case 'alsa':\n // ALSA's arecord from the default device.\n return {\n command: recorder.bin,\n args: ['-q', '-f', 'S16_LE', '-c', String(CHANNELS), '-r', String(SAMPLE_RATE), '-t', 'wav', outputPath],\n };\n case 'sox': {\n // `rec` is sox's record front-end; when only `sox` exists, use `-d` for the\n // default input device. Output is 16kHz mono signed 16-bit WAV.\n const baseArgs = ['-q', '-c', String(CHANNELS), '-r', String(SAMPLE_RATE), '-b', '16', '-e', 'signed-integer'];\n if (recorder.bin === 'rec') {\n return { command: 'rec', args: [...baseArgs, outputPath] };\n }\n return { command: 'sox', args: ['-d', ...baseArgs, outputPath] };\n }\n case 'ffmpeg':\n default: {\n const input = ffmpegInputArgs();\n return {\n command: 'ffmpeg',\n args: [\n '-hide_banner',\n '-loglevel',\n 'error',\n ...input,\n '-ac',\n String(CHANNELS),\n '-ar',\n String(SAMPLE_RATE),\n '-y',\n outputPath,\n ],\n };\n }\n }\n}\n\nfunction ffmpegInputArgs(): string[] {\n switch (process.platform) {\n case 'darwin':\n // Capture from the default audio input device, no video.\n return ['-f', 'avfoundation', '-i', ':default'];\n case 'linux':\n default:\n // Prefer PulseAudio's default source; ALSA's `default` is the fallback.\n return ['-f', 'pulse', '-i', 'default'];\n }\n}\n","/**\n * Cloud STT engine.\n *\n * Records microphone audio to a WAV via `MicRecording`, then transcribes it\n * through a cloud provider (`transcribe.ts`, provider-agnostic). While\n * recording, it periodically re-transcribes the audio-so-far and emits that as\n * a partial, which keeps the live text stable and self-correcting (the provider\n * re-derives the whole utterance each tick). On stop it emits the final, most\n * accurate transcript.\n *\n * This preserves the original chunked-live behavior for non-macOS / cloud users\n * while keeping the controller engine-agnostic.\n */\n\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { detectRecorder, MicRecording } from '../mic-capture.js';\nimport type { RecorderInfo } from '../mic-capture.js';\nimport { createTranscriber, hasProviderCredential } from '../transcribe.js';\nimport type { ReusableTranscriber } from '../transcribe.js';\nimport type { STTEngine, STTSession, STTSessionCallbacks } from './types.js';\n\n/** How often to re-transcribe the audio-so-far while recording (ms). */\nconst LIVE_TRANSCRIBE_INTERVAL_MS = 1200;\n/**\n * Delay before the *first* live tick. Kept short so the opening words appear\n * quickly: the recorder needs a moment to spawn and write a usable WAV, and\n * until then `snapshot()` returns null and the tick is a cheap no-op that\n * re-arms at this same short cadence — so the first partial fires as soon as\n * there's audio rather than waiting a full interval.\n */\nconst LIVE_TRANSCRIBE_FIRST_MS = 250;\n\nexport interface CloudEngineOptions {\n provider: string;\n model?: string;\n authStorage?: AuthStorage;\n}\n\nfunction missingRecorderMessage(): string {\n if (process.platform === 'darwin') {\n return 'Voice input needs a recorder. Install sox (`brew install sox`) or ffmpeg, then run /voice again.';\n }\n return 'Voice input needs a recorder. Install one of pipewire-utils (pw-record), pulseaudio-utils (parecord), alsa-utils (arecord), or sox, then run /voice again.';\n}\n\nclass CloudSession implements STTSession {\n private recording: MicRecording | null;\n private liveTimer: ReturnType<typeof setTimeout> | null = null;\n private liveInFlight = false;\n private stopped = false;\n private lastPartial = '';\n private sawAudio = false;\n private readonly transcriber: ReusableTranscriber;\n\n constructor(\n recorder: RecorderInfo,\n private readonly options: CloudEngineOptions,\n private readonly callbacks: STTSessionCallbacks,\n ) {\n // Build the provider client once and reuse it across ticks so its HTTP\n // connection stays warm (keep-alive). This removes the DNS + TLS handshake\n // cost from every request — the main reason the first dictation streamed in\n // slowly while later ones felt instant.\n this.transcriber = createTranscriber({\n provider: this.options.provider,\n model: this.options.model,\n authStorage: this.options.authStorage,\n });\n try {\n this.recording = new MicRecording(recorder);\n } catch {\n this.recording = null;\n // Surface asynchronously so `start()` can return a session handle first.\n queueMicrotask(() => this.callbacks.onError(new Error('Could not start the microphone recorder.')));\n return;\n }\n this.startLiveTranscription();\n }\n\n async stop(): Promise<void> {\n if (this.stopped) return;\n this.stopped = true;\n this.stopLiveTranscription();\n const recording = this.recording;\n this.recording = null;\n if (!recording) return;\n\n let audio: Buffer | null = null;\n try {\n audio = await recording.stop();\n } catch (err) {\n this.callbacks.onError(err instanceof Error ? err : new Error('Could not stop the microphone recorder.'));\n return;\n }\n if (!audio) {\n this.callbacks.onFinal('');\n return;\n }\n\n try {\n const text = await this.transcriber.transcribe(audio);\n this.callbacks.onFinal(text);\n } catch (err) {\n this.callbacks.onError(err instanceof Error ? err : new Error('Transcription failed.'));\n }\n }\n\n cancel(): void {\n if (this.stopped) return;\n this.stopped = true;\n this.stopLiveTranscription();\n if (this.recording) {\n this.recording.cancel();\n this.recording = null;\n }\n }\n\n /**\n * Schedule live ticks as a self-rescheduling timeout chain rather than a\n * setInterval. This keeps `liveTimer` a single timeout handle (so cancellation\n * is unambiguous) and guarantees ticks never overlap: the next tick is only\n * armed after the current one settles, even when a transcription request runs\n * longer than the interval.\n */\n private startLiveTranscription(): void {\n const schedule = (delay: number) => {\n if (this.stopped) return;\n this.liveTimer = setTimeout(async () => {\n await this.runLiveTick();\n // Until the recorder has produced enough audio to transcribe, keep\n // polling at the short first-tick cadence so the opening partial fires\n // the instant audio is available. Once we've seen audio, fall back to\n // the normal interval to avoid hammering the provider.\n schedule(this.sawAudio ? LIVE_TRANSCRIBE_INTERVAL_MS : LIVE_TRANSCRIBE_FIRST_MS);\n }, delay);\n };\n schedule(LIVE_TRANSCRIBE_FIRST_MS);\n }\n\n private stopLiveTranscription(): void {\n if (this.liveTimer) {\n clearTimeout(this.liveTimer);\n this.liveTimer = null;\n }\n }\n\n private async runLiveTick(): Promise<void> {\n if (this.liveInFlight || this.stopped || !this.recording) return;\n const snapshot = this.recording.snapshot();\n if (!snapshot) return;\n this.sawAudio = true;\n\n this.liveInFlight = true;\n try {\n const text = await this.transcriber.transcribe(snapshot);\n if (!this.stopped && text && text !== this.lastPartial) {\n this.lastPartial = text;\n this.callbacks.onPartial(text);\n }\n } catch (err) {\n // Transient mid-recording failures are expected (e.g. a snapshot taken\n // before the recorder flushed a full frame). Log for diagnosability;\n // stop() still surfaces a persistent failure to the user.\n if (process.env.MASTRACODE_VOICE_DEBUG) {\n console.error('[voice] live transcription tick failed:', err);\n }\n } finally {\n this.liveInFlight = false;\n }\n }\n}\n\nexport class CloudSTTEngine implements STTEngine {\n readonly kind = 'cloud' as const;\n\n constructor(private readonly options: CloudEngineOptions) {}\n\n checkReady(): string | null {\n if (!detectRecorder()) return missingRecorderMessage();\n if (!hasProviderCredential(this.options.provider, this.options.authStorage)) {\n const env =\n this.options.provider === 'openai' ? 'OPENAI_API_KEY' : `${this.options.provider.toUpperCase()}_API_KEY`;\n return `Voice input needs a ${this.options.provider} API key. Set ${env} or add one with /api-keys.`;\n }\n return null;\n }\n\n start(callbacks: STTSessionCallbacks): STTSession {\n const recorder = detectRecorder();\n if (!recorder) {\n queueMicrotask(() => callbacks.onError(new Error(missingRecorderMessage())));\n return inertSession();\n }\n try {\n return new CloudSession(recorder, this.options, callbacks);\n } catch (err) {\n // createTranscriber throws VoiceCredentialError when no key is available;\n // checkReady() normally catches this first, but surface it cleanly here too.\n queueMicrotask(() => callbacks.onError(err instanceof Error ? err : new Error('Transcription unavailable.')));\n return inertSession();\n }\n }\n}\n\nfunction inertSession(): STTSession {\n return {\n async stop() {},\n cancel() {},\n };\n}\n","/**\n * Lazily build the bundled macOS STT Swift recognizer into a cached `.app` bundle.\n *\n * On first use we `swiftc`-compile `macos-stt.swift` into `Contents/MacOS/` of a\n * `.app` bundle written to the cache dir, alongside a generated `Contents/Info.plist`\n * (derived from `macos-stt.plist`). The bundle is keyed by a hash of the script\n * source + the Info.plist source so a change to either rebuilds. If a cached\n * bundle already exists it is reused (fast path).\n *\n * Why a `.app` bundle and not a loose binary: macOS only shows the Speech\n * Recognition / Microphone TCC permission prompts for a process launched as a\n * bundled app through LaunchServices (`open`). A bare CLI executable — even one\n * with the Info.plist embedded in its `__info_plist` Mach-O section and ad-hoc\n * signed — never triggers the `SFSpeechRecognizer.requestAuthorization` callback;\n * macOS silently denies and the recognizer aborts. A real `.app` with an\n * `Info.plist` carrying the usage strings, ad-hoc signed and launched via `open`,\n * is the only reliable way to get the prompt to appear and access to be granted.\n *\n * The bundle's binary is also usable directly (not via `open`) for `--probe`,\n * which only reads authorization status and does not touch protected APIs.\n *\n * Compilation is async and never blocks the event loop; callers await it before\n * launching the recognizer.\n */\n\nimport { spawn } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, writeFile, rm, stat } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Resolve a native asset (the Swift recognizer or its plist) at runtime.\n *\n * In dev (tsx) the assets sit next to this source file. In a built CLI the JS is\n * bundled into a chunk under `dist/`, so the assets are copied to `dist/native/`\n * by tsdown. We probe both layouts plus a couple of nearby fallbacks so the\n * recognizer resolves regardless of how mastracode was launched.\n */\nfunction resolveAsset(name: string): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, name), // dev: src/tui/voice/native/<name>\n join(here, 'native', name), // bundled chunk sitting beside dist/native/\n join(here, '..', 'native', name),\n join(here, '..', '..', 'native', name),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n // Fall back to the dev-layout path so the eventual readFile error is clear.\n return join(here, name);\n}\n\nconst SCRIPT_PATH = resolveAsset('macos-stt.swift');\nconst PLIST_PATH = resolveAsset('macos-stt.plist');\n\n/** The bundle name and the executable inside it. */\nconst APP_NAME = 'MastraCodeVoice';\nconst BUNDLE_ID = 'ai.mastra.mastracode.voice';\n\n/** How to launch the recognizer. */\nexport interface RecognizerInvocation {\n /** Path to the `.app` bundle, launched via `open` for recording (TCC prompt). */\n appPath: string;\n /** Path to the executable inside the bundle, run directly for `--probe`. */\n binaryPath: string;\n}\n\nfunction cacheDir(): string {\n const base = process.env.XDG_CACHE_HOME?.trim() || join(homedir(), 'Library', 'Caches');\n return join(base, 'mastracode', 'voice');\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function hasSwiftc(): Promise<boolean> {\n return runOk('swiftc', ['--version']);\n}\n\nfunction runOk(command: string, args: string[]): Promise<boolean> {\n return new Promise(resolve => {\n let child;\n try {\n child = spawn(command, args, { stdio: 'ignore' });\n } catch {\n resolve(false);\n return;\n }\n child.on('error', () => resolve(false));\n child.on('exit', code => resolve(code === 0));\n });\n}\n\nfunction compile(scriptPath: string, outPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('swiftc', ['-O', scriptPath, '-o', outPath], { stdio: 'ignore' });\n child.on('error', reject);\n child.on('exit', code => {\n if (code === 0) resolve();\n else reject(new Error(`swiftc exited with code ${code}`));\n });\n });\n}\n\n/**\n * Ad-hoc sign the `.app` bundle. The bundle's `Info.plist` (with the TCC usage\n * strings) is sealed into the signature, which is what lets macOS read the\n * strings and present the permission prompt when the app is launched via `open`.\n */\nfunction adhocSign(appPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('codesign', ['-f', '-s', '-', '-i', BUNDLE_ID, appPath], { stdio: 'ignore' });\n child.on('error', reject);\n child.on('exit', code => {\n if (code === 0) resolve();\n else reject(new Error(`codesign exited with code ${code}`));\n });\n });\n}\n\n/**\n * Build the bundle's `Info.plist` from the checked-in plist source, adding the\n * `.app` bundle keys (`CFBundleExecutable`, `CFBundlePackageType`) that a real\n * bundle requires on top of the usage-description strings.\n */\nfunction buildInfoPlist(source: string): string {\n // The source plist already carries CFBundleIdentifier/Name + usage strings.\n // Inject the executable + package-type keys right after the opening <dict>.\n const extras = [\n ' <key>CFBundleExecutable</key>',\n ` <string>${APP_NAME}</string>`,\n ' <key>CFBundlePackageType</key>',\n ' <string>APPL</string>',\n ' <key>LSUIElement</key>',\n ' <true/>',\n ].join('\\n');\n if (source.includes('<key>CFBundleExecutable</key>')) return source;\n return source.replace('<dict>', `<dict>\\n${extras}`);\n}\n\n/**\n * Write the `.app` bundle layout: `Contents/Info.plist` + `Contents/MacOS/<exe>`.\n * The Swift binary is compiled straight into `Contents/MacOS/`.\n */\nasync function buildBundle(scriptPath: string, plistSource: string, appPath: string): Promise<void> {\n // Rebuild from scratch so a stale partial bundle never lingers.\n await rm(appPath, { recursive: true, force: true });\n const macosDir = join(appPath, 'Contents', 'MacOS');\n await mkdir(macosDir, { recursive: true });\n await writeFile(join(appPath, 'Contents', 'Info.plist'), buildInfoPlist(plistSource), 'utf8');\n await compile(scriptPath, join(macosDir, APP_NAME));\n await adhocSign(appPath);\n}\n\n/**\n * Resolve how to launch the recognizer, building+caching the `.app` bundle on\n * first use.\n *\n * Returns `null` when `swiftc` is unavailable or the build fails — the caller\n * surfaces a clear \"install Xcode command line tools\" message.\n */\nexport async function resolveRecognizer(\n scriptPath: string = SCRIPT_PATH,\n plistPath: string = PLIST_PATH,\n): Promise<RecognizerInvocation | null> {\n let source: string;\n let plist: string;\n try {\n [source, plist] = await Promise.all([readFile(scriptPath, 'utf8'), readFile(plistPath, 'utf8')]);\n } catch {\n // Native assets aren't shipped/readable — treat as \"native unavailable\".\n return null;\n }\n // `v3` busts caches built before the .app-bundle + LaunchServices approach\n // (loose binaries never triggered the TCC prompt).\n const hash = createHash('sha256').update('v3').update(source).update('\\0').update(plist).digest('hex').slice(0, 16);\n const dir = cacheDir();\n const appPath = join(dir, `macos-stt-${hash}.app`);\n const binaryPath = join(appPath, 'Contents', 'MacOS', APP_NAME);\n\n if (await exists(binaryPath)) {\n return { appPath, binaryPath };\n }\n\n if (!(await hasSwiftc())) {\n return null;\n }\n\n await mkdir(dir, { recursive: true });\n try {\n await buildBundle(scriptPath, plist, appPath);\n } catch {\n return null;\n }\n return { appPath, binaryPath };\n}\n\n/** Directory used to cache compiled recognizer bundles (exported for tests). */\nexport function recognizerCacheDir(): string {\n return cacheDir();\n}\n\nexport { SCRIPT_PATH, PLIST_PATH };\n","/**\n * macOS native STT engine.\n *\n * Launches the bundled on-device `SFSpeechRecognizer` `.app` (built and cached by\n * `native/compile.ts`) through LaunchServices (`open`) — the only launch path\n * that makes macOS show the Speech Recognition / Microphone permission prompts.\n * Because a LaunchServices-launched app has no usable stdin/stdout pipe back to\n * the parent, IPC is file-based: the recognizer appends newline-delimited JSON\n * events to an `events.jsonl` file we tail, and we ask it to stop by creating a\n * `stop` sentinel file it polls for. Partial hypotheses arrive in true realtime\n * with no network and no per-utterance cost; the final result is emitted on stop.\n *\n * `stop()` writes the stop sentinel so the recognizer flushes a final result,\n * then resolves once that final event arrives. `cancel()` tears it down.\n */\n\nimport { spawn } from 'node:child_process';\nimport { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { resolveRecognizer } from '../native/compile.js';\nimport type { PermissionGuidance, STTEngine, STTSession, STTSessionCallbacks } from './types.js';\n\n/** Deep links to the exact macOS Privacy & Security panes. */\nconst MIC_SETTINGS_URL = 'x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone';\nconst SPEECH_SETTINGS_URL = 'x-apple.systempreferences:com.apple.preference.security?Privacy_SpeechRecognition';\n\n/**\n * How long to wait after closing stdin for the recognizer to flush its final\n * result before falling back to SIGTERM. The Swift side gives itself up to ~1.5s\n * to emit a final, so this is set a little above that.\n */\nconst FINAL_FLUSH_GRACE_MS = 2000;\n\ninterface RecognizerEvent {\n type: 'ready' | 'partial' | 'final' | 'error';\n text?: string;\n message?: string;\n}\n\ntype TccStatus = 'authorized' | 'denied' | 'restricted' | 'notDetermined' | 'unknown';\n\ninterface ProbeResult {\n speech: TccStatus;\n mic: TccStatus;\n available: boolean;\n}\n\n/**\n * Run the recognizer in `--probe` mode to read Speech Recognition + Microphone\n * authorization status without recording. Returns null if the probe can't run\n * (e.g. swiftc missing) — the caller handles that separately.\n *\n * The probe is launched through the same `.app` bundle via LaunchServices that\n * the recording path uses. macOS attributes TCC grants to the bundle identity\n * (`ai.mastra.mastracode.voice`), so running the loose binary directly would\n * query a *different* TCC identity (the terminal's) and wrongly report\n * `notDetermined`/`denied` even after the user granted access to the bundle.\n * Because LaunchServices apps have no usable stdout pipe, the probe writes its\n * result to an events file (shared file-IPC) that we read back.\n */\nasync function probePermissions(): Promise<ProbeResult | null> {\n const invocation = await resolveRecognizer();\n if (!invocation) return null;\n\n let workDir: string;\n try {\n workDir = await mkdtemp(join(tmpdir(), 'mastracode-voice-probe-'));\n } catch {\n return null;\n }\n const eventPath = join(workDir, 'probe.jsonl');\n try {\n await writeFile(eventPath, '', 'utf8');\n } catch {\n // Non-fatal: the probe creates it on first emit.\n }\n\n const cleanup = () => {\n void rm(workDir, { recursive: true, force: true }).catch(() => {});\n };\n\n return new Promise<ProbeResult | null>(resolve => {\n let settled = false;\n const done = (result: ProbeResult | null) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(result);\n };\n\n let child: ReturnType<typeof spawn>;\n try {\n // Launch via LaunchServices so the probe runs under the granted bundle\n // identity. `-g` keeps it from stealing focus; `-W` waits for exit.\n child = spawn('open', ['-n', '-W', '-g', invocation.appPath, '--args', '--probe', '--events', eventPath], {\n stdio: ['ignore', 'ignore', 'ignore'],\n });\n } catch {\n done(null);\n return;\n }\n\n const readProbe = async (): Promise<ProbeResult | null> => {\n let out = '';\n try {\n out = await readFile(eventPath, 'utf8');\n } catch {\n return null;\n }\n const line = out.split('\\n').find(l => l.includes('\"type\":\"probe\"') || l.includes('\"type\": \"probe\"'));\n if (!line) return null;\n try {\n const parsed = JSON.parse(line) as { speech?: TccStatus; mic?: TccStatus; available?: boolean };\n return {\n speech: parsed.speech ?? 'unknown',\n mic: parsed.mic ?? 'unknown',\n available: parsed.available ?? false,\n };\n } catch {\n return null;\n }\n };\n\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n void readProbe().then(done);\n }, 5000);\n\n child.on('error', () => {\n clearTimeout(timer);\n done(null);\n });\n child.on('exit', () => {\n clearTimeout(timer);\n void readProbe().then(done);\n });\n });\n}\n\n/** Turn a probe result into a user-facing problem message, or null if ready. */\nfunction describeProbe(probe: ProbeResult): string | null {\n const settingsHint = 'System Settings › Privacy & Security';\n if (probe.mic === 'denied' || probe.mic === 'restricted') {\n return `Microphone access is blocked. Enable MastraCode Voice under ${settingsHint} › Microphone, then restart your terminal.`;\n }\n if (probe.speech === 'denied' || probe.speech === 'restricted') {\n return `Speech Recognition access is blocked. Enable MastraCode Voice under ${settingsHint} › Speech Recognition, then restart your terminal.`;\n }\n if (probe.mic === 'notDetermined' || probe.speech === 'notDetermined') {\n return 'Microphone / Speech Recognition access not granted yet — the first time you hold space to dictate, macOS will prompt; click Allow on both.';\n }\n if (!probe.available) {\n return 'On-device speech recognition is not available for your locale.';\n }\n return null;\n}\n\n/** Turn a probe result into structured, actionable permission guidance. */\nfunction guidanceFromProbe(probe: ProbeResult): PermissionGuidance {\n const blockedMic = probe.mic === 'denied' || probe.mic === 'restricted';\n const blockedSpeech = probe.speech === 'denied' || probe.speech === 'restricted';\n\n if (blockedMic || blockedSpeech) {\n const which = blockedMic ? 'Microphone' : 'Speech Recognition';\n return {\n state: 'blocked',\n summary: `${which} access is turned off for MastraCode Voice, so on-device dictation can't run.`,\n steps: [\n `Open System Settings › Privacy & Security › ${which}.`,\n 'Turn on the switch next to MastraCode Voice.',\n 'Fully quit and reopen the terminal so the change takes effect.',\n ],\n settingsUrl: blockedMic ? MIC_SETTINGS_URL : SPEECH_SETTINGS_URL,\n actionLabel: `Open ${which} settings`,\n };\n }\n\n if (probe.mic === 'notDetermined' || probe.speech === 'notDetermined') {\n return {\n state: 'will-prompt',\n summary: \"macOS hasn't asked for access yet — it will prompt the first time you dictate.\",\n steps: [\n 'Hold the space bar and start speaking.',\n 'When macOS asks, click Allow for both Microphone and Speech Recognition.',\n ],\n };\n }\n\n if (!probe.available) {\n return {\n state: 'unsupported',\n summary: 'On-device speech recognition is not available for your locale. Switch to a cloud provider with /voice.',\n };\n }\n\n return { state: 'ok', summary: 'Microphone and Speech Recognition access are granted.' };\n}\n\n/** How often to poll the event file for newly appended JSON lines. */\nconst EVENT_POLL_INTERVAL_MS = 80;\n\nclass MacosNativeSession implements STTSession {\n private openChild: ReturnType<typeof spawn> | null = null;\n private workDir: string | null = null;\n private eventPath = '';\n private stopPath = '';\n private readOffset = 0;\n private pendingLine = '';\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private polling = false;\n private sawEvent = false;\n private cancelled = false;\n private finalResolve: (() => void) | null = null;\n private finalPromise: Promise<void>;\n private settled = false;\n\n constructor(private readonly callbacks: STTSessionCallbacks) {\n this.finalPromise = new Promise(resolve => {\n this.finalResolve = resolve;\n });\n void this.launch();\n }\n\n private async launch(): Promise<void> {\n const invocation = await resolveRecognizer();\n if (!invocation) {\n this.fail(new Error('Swift toolchain not found. Install Xcode command line tools (`xcode-select --install`).'));\n return;\n }\n\n try {\n this.workDir = await mkdtemp(join(tmpdir(), 'mastracode-voice-'));\n } catch (err) {\n this.fail(err instanceof Error ? err : new Error('Could not create a temp dir for the macOS recognizer.'));\n return;\n }\n this.eventPath = join(this.workDir, 'events.jsonl');\n this.stopPath = join(this.workDir, 'stop');\n // Pre-create the event file so the first poll has something to read.\n try {\n await writeFile(this.eventPath, '', 'utf8');\n } catch {\n // Non-fatal: the recognizer creates it on first emit.\n }\n\n // Launch the .app via LaunchServices. `open` is the only path that makes\n // macOS present the Speech Recognition / Microphone permission prompts.\n // -n always start a new instance\n // -W wait until the app exits (so the child exit tells us it's done)\n // -g do not bring the app to the foreground / steal focus\n // Args after `--args` are forwarded to the app's executable.\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(\n 'open',\n ['-n', '-W', '-g', invocation.appPath, '--args', '--events', this.eventPath, '--stop', this.stopPath],\n { stdio: ['ignore', 'ignore', 'pipe'] },\n );\n } catch (err) {\n this.fail(err instanceof Error ? err : new Error('Could not launch the macOS recognizer.'));\n return;\n }\n this.openChild = child;\n let stderr = '';\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', err => this.fail(err instanceof Error ? err : new Error(String(err))));\n child.on('exit', (code, signal) => this.onOpenExit(code, signal, stderr));\n\n this.startPolling();\n }\n\n private startPolling(): void {\n this.pollTimer = setInterval(() => {\n void this.poll();\n }, EVENT_POLL_INTERVAL_MS);\n }\n\n private async poll(flush = false): Promise<void> {\n if (this.settled || this.polling) return;\n this.polling = true;\n try {\n const contents = await readFile(this.eventPath, 'utf8');\n if (contents.length > this.readOffset) {\n const fresh = contents.slice(this.readOffset);\n this.readOffset = contents.length;\n // The recognizer may be mid-write, leaving a trailing partial line.\n // Buffer it and only dispatch complete (newline-terminated) lines.\n const lines = (this.pendingLine + fresh).split('\\n');\n this.pendingLine = lines.pop() ?? '';\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed) this.handleLine(trimmed);\n }\n }\n // On a final drain the recognizer has exited, so any buffered remainder\n // is a complete line that simply lacked a trailing newline — flush it.\n if (flush && this.pendingLine.trim()) {\n const trimmed = this.pendingLine.trim();\n this.pendingLine = '';\n this.handleLine(trimmed);\n }\n } catch {\n // File may not exist yet between launch and first emit; ignore.\n } finally {\n this.polling = false;\n }\n }\n\n /**\n * If `open` exits before the recognizer ever emitted a JSON event, the app\n * crashed before recording could start — almost always a denied/suppressed\n * macOS permission prompt or a TCC kill. Surface a clear, actionable error\n * instead of settling silently.\n */\n private onOpenExit(code: number | null, signal: NodeJS.Signals | null, stderr: string): void {\n // Drain any events the recognizer wrote just before exiting, flushing a\n // final line that may lack a trailing newline.\n void this.poll(true).then(() => {\n if (this.settled) return;\n if (!this.sawEvent) {\n const detail = stderr.trim();\n const reason = detail\n ? detail.split('\\n').slice(-1)[0]\n : signal\n ? `terminated (${signal})`\n : `exited with code ${code ?? 'unknown'}`;\n this.fail(\n new Error(\n `macOS speech recognition stopped before it could start (${reason}). ` +\n `If macOS didn't prompt you, enable MastraCode Voice under System Settings › Privacy & Security › ` +\n `Microphone and Speech Recognition, then fully quit and reopen the terminal.`,\n ),\n );\n return;\n }\n this.settle();\n });\n }\n\n private handleLine(line: string): void {\n let event: RecognizerEvent;\n try {\n event = JSON.parse(line) as RecognizerEvent;\n } catch {\n return;\n }\n this.sawEvent = true;\n // Once cancelled we only let the recognizer wind down; no transcripts surface.\n if (this.cancelled) {\n if (event.type === 'final' || event.type === 'error') this.settle();\n return;\n }\n switch (event.type) {\n case 'partial':\n if (event.text) this.callbacks.onPartial(event.text);\n break;\n case 'final':\n this.callbacks.onFinal(event.text ?? '');\n this.settle();\n break;\n case 'error':\n this.fail(new Error(event.message ?? 'macOS speech recognition failed.'));\n break;\n case 'ready':\n default:\n break;\n }\n }\n\n private fail(error: Error): void {\n if (this.settled) return;\n this.callbacks.onError(error);\n this.teardown();\n this.settle();\n }\n\n private settle(): void {\n if (this.settled) return;\n this.settled = true;\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.finalResolve?.();\n void this.cleanupWorkDir();\n }\n\n private teardown(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.openChild) {\n this.openChild.kill('SIGKILL');\n this.openChild = null;\n }\n }\n\n /**\n * Stop recording without emitting a transcript, but let the recognizer wind\n * down gracefully so it releases the microphone. We write the stop sentinel\n * and wait for the LaunchServices app to observe it and exit on its own (its\n * `exit` handler settles us and removes the temp dir). A SIGKILL + forced\n * cleanup is only a safety net if the app never acknowledges the sentinel —\n * tearing the temp dir down immediately would delete the stop file before the\n * detached app could poll it, leaving the mic live with no control channel.\n */\n private async gracefulCancel(): Promise<void> {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.signalStop();\n if (this.settled || !this.openChild) {\n this.settle();\n return;\n }\n const safetyNet = setTimeout(() => {\n this.teardown();\n this.settle();\n }, FINAL_FLUSH_GRACE_MS);\n void this.finalPromise.finally(() => clearTimeout(safetyNet));\n }\n\n private async cleanupWorkDir(): Promise<void> {\n const dir = this.workDir;\n this.workDir = null;\n if (!dir) return;\n try {\n await rm(dir, { recursive: true, force: true });\n } catch {\n // Best effort.\n }\n }\n\n /** Signal the recognizer to flush a final result, then wait for it. */\n private async signalStop(): Promise<void> {\n if (this.stopPath) {\n try {\n await writeFile(this.stopPath, '', 'utf8');\n } catch {\n // If we can't write the sentinel, fall back to killing the app.\n this.openChild?.kill('SIGTERM');\n }\n }\n }\n\n async stop(): Promise<void> {\n if (!this.settled) {\n await this.signalStop();\n // The recognizer needs a moment after seeing the stop file to run its\n // final recognition pass and append the `final` event. The poll loop will\n // pick it up and settle. A delayed kill is only a safety net.\n const safetyNet = setTimeout(() => {\n if (!this.settled) {\n this.openChild?.kill('SIGTERM');\n }\n }, FINAL_FLUSH_GRACE_MS);\n void this.finalPromise.finally(() => clearTimeout(safetyNet));\n }\n await this.finalPromise;\n }\n\n cancel(): void {\n if (this.settled || this.cancelled) return;\n this.cancelled = true;\n void this.gracefulCancel();\n }\n}\n\nexport class MacosNativeSTTEngine implements STTEngine {\n readonly kind = 'macos-native' as const;\n\n checkReady(): string | null {\n if (process.platform !== 'darwin') {\n return 'macOS native speech recognition is only available on macOS. Choose a cloud provider with /voice.';\n }\n return null;\n }\n\n /**\n * Deeper preflight: confirm the Swift toolchain compiles the recognizer, then\n * probe the actual Speech Recognition + Microphone TCC authorization status so\n * /voice status can tell the user exactly which permission to enable instead of\n * letting it fail silently mid-dictation.\n */\n async verify(): Promise<string | null> {\n const platform = this.checkReady();\n if (platform) return platform;\n const invocation = await resolveRecognizer();\n if (!invocation) {\n return 'macOS native STT needs the Swift toolchain. Install Xcode command line tools (`xcode-select --install`), then run /voice again.';\n }\n const probe = await probePermissions();\n if (probe) {\n const problem = describeProbe(probe);\n if (problem) return problem;\n }\n return null;\n }\n\n /**\n * Structured permission guidance for the TUI. Confirms the toolchain compiles,\n * then probes the real TCC state and returns actionable steps (and a Settings\n * deep link) so the UI can walk the user through granting access.\n */\n async permissions(): Promise<PermissionGuidance> {\n if (process.platform !== 'darwin') {\n return {\n state: 'unsupported',\n summary: 'macOS native speech recognition is only available on macOS. Choose a cloud provider with /voice.',\n };\n }\n const invocation = await resolveRecognizer();\n if (!invocation) {\n return {\n state: 'unsupported',\n summary: 'On-device dictation needs the Swift toolchain.',\n steps: ['Run `xcode-select --install` to install the Xcode command line tools.', 'Then run /voice again.'],\n };\n }\n const probe = await probePermissions();\n if (!probe) {\n // Probe couldn't run; assume macOS will prompt on first dictation.\n return {\n state: 'will-prompt',\n summary: \"Couldn't read permission state — macOS will prompt the first time you dictate.\",\n steps: ['Hold the space bar and start speaking.', 'Click Allow when macOS asks for access.'],\n };\n }\n return guidanceFromProbe(probe);\n }\n\n start(callbacks: STTSessionCallbacks): STTSession {\n return new MacosNativeSession(callbacks);\n }\n}\n","/**\n * Engine factory: builds the active `STTEngine` from voice settings.\n */\n\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { CloudSTTEngine } from './cloud-engine.js';\nimport { MacosNativeSTTEngine } from './macos-native-engine.js';\nimport type { STTEngine, STTEngineKind } from './types.js';\n\nexport interface EngineSettings {\n engine: STTEngineKind;\n provider: string;\n model?: string;\n}\n\nexport function createSTTEngine(settings: EngineSettings, authStorage?: AuthStorage): STTEngine {\n if (settings.engine === 'macos-native') {\n return new MacosNativeSTTEngine();\n }\n return new CloudSTTEngine({ provider: settings.provider, model: settings.model, authStorage });\n}\n\nexport * from './types.js';\nexport { CloudSTTEngine } from './cloud-engine.js';\nexport { MacosNativeSTTEngine } from './macos-native-engine.js';\n","/**\n * Push-to-talk voice input controller for the TUI.\n *\n * Owns the enabled/recording state and ties microphone capture to\n * transcription. The editor drives this controller from its key dispatch:\n * it calls startRecording() when a held space begins push-to-talk, and\n * stopRecording() when the space key is released (detected as an idle gap\n * after the last repeated space).\n *\n * Transcribed text is delivered through the onTranscript callback so the\n * editor can insert it at the cursor.\n */\n\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport type { VoiceSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { createSTTEngine } from './engines/index.js';\nimport type { PermissionGuidance, STTEngine, STTSession } from './engines/types.js';\n\nexport interface VoiceControllerOptions {\n authStorage?: AuthStorage;\n /** Voice configuration (engine/provider/model). */\n settings: VoiceSettings;\n /** Called with transcribed text to insert at the cursor. */\n onTranscript: (text: string) => void;\n /**\n * Called repeatedly during recording with the best transcript of the audio\n * captured so far. Each call supersedes the previous one (replace, not\n * append), so the input shows live dictation as the user keeps speaking.\n */\n onPartialTranscript?: (text: string) => void;\n /** Show a transient informational message. */\n showInfo: (message: string) => void;\n /** Show a transient error message. */\n showError: (message: string) => void;\n /**\n * Called when push-to-talk recording starts (true) and ends (false) so the\n * editor can drive a \"listening\" cursor animation.\n */\n onListeningChange?: (listening: boolean) => void;\n}\n\nexport type VoiceState = 'idle' | 'recording' | 'transcribing';\n\nexport class VoiceController {\n private enabled = false;\n private state: VoiceState = 'idle';\n private session: STTSession | null = null;\n private engine: STTEngine;\n private settings: VoiceSettings;\n // Whether at least one live partial transcript actually streamed during the\n // current recording. Lets stop() distinguish \"nothing was heard\" from \"live\n // text already surfaced\", so the capture warning only fires when truly empty.\n private liveTranscriptEmitted = false;\n private readonly options: VoiceControllerOptions;\n\n constructor(options: VoiceControllerOptions) {\n this.options = options;\n this.settings = options.settings;\n this.engine = createSTTEngine(this.settings, options.authStorage);\n }\n\n /**\n * Swap the active engine/provider/model from updated settings. If voice is\n * currently enabled it is re-validated against the new engine.\n */\n reconfigure(settings: VoiceSettings): void {\n this.cancelRecording();\n this.settings = settings;\n this.engine = createSTTEngine(settings, this.options.authStorage);\n if (this.enabled) {\n const problem = this.engine.checkReady();\n if (problem) {\n this.enabled = false;\n this.options.showError(problem);\n }\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Deeper readiness check that may do async work (e.g. compiling the native\n * recognizer). Returns `null` when ready or a user-facing problem message.\n * Falls back to the synchronous check when the engine has no async verify.\n */\n async verifyReady(): Promise<string | null> {\n if (this.engine.verify) return this.engine.verify();\n return this.engine.checkReady();\n }\n\n /**\n * Structured, actionable permission guidance for the active engine (e.g. how\n * to grant macOS Microphone/Speech access). Returns `null` for engines that\n * don't expose it (cloud), so callers can skip the guided flow.\n */\n async permissionGuidance(): Promise<PermissionGuidance | null> {\n if (this.engine.permissions) return this.engine.permissions();\n return null;\n }\n\n getState(): VoiceState {\n return this.state;\n }\n\n isRecording(): boolean {\n return this.state === 'recording';\n }\n\n /**\n * Toggle voice input on/off. Returns the new enabled state.\n * Reports problems (missing recorder/credentials) via showError and stays\n * disabled when prerequisites are missing.\n */\n toggle(): boolean {\n if (this.enabled) {\n this.disable();\n return false;\n }\n return this.enable();\n }\n\n enable(): boolean {\n const problem = this.engine.checkReady();\n if (problem) {\n this.options.showError(problem);\n return false;\n }\n this.enabled = true;\n this.options.showInfo('Voice input on. Hold space to talk; release to transcribe. /voice to turn off.');\n return true;\n }\n\n /**\n * Restore the persisted enabled state at startup without emitting the\n * interactive \"voice input on\" message or surfacing errors. Silently stays\n * disabled if the active engine is not ready.\n */\n restoreEnabled(): void {\n if (this.enabled) return;\n if (this.engine.checkReady()) return;\n this.enabled = true;\n }\n\n disable(): void {\n this.cancelRecording();\n this.enabled = false;\n this.options.showInfo('Voice input off.');\n }\n\n /**\n * Begin a streaming recognition session. No-op if disabled or already active.\n * Partial results stream into the input via onPartialTranscript; the final\n * result replaces the live text (live mode) or streams in word-by-word.\n */\n startRecording(): void {\n if (!this.enabled || this.state !== 'idle') return;\n const live = !!this.options.onPartialTranscript;\n this.liveTranscriptEmitted = false;\n this.state = 'recording';\n this.options.onListeningChange?.(true);\n\n this.session = this.engine.start({\n onPartial: text => {\n if (this.state !== 'recording' || !text) return;\n this.liveTranscriptEmitted = true;\n this.options.onPartialTranscript?.(text);\n },\n onFinal: text => {\n if (live) {\n // Replace the live partial with the final, most accurate transcript.\n if (text) this.options.onPartialTranscript!(text);\n else if (!this.liveTranscriptEmitted) this.options.showInfo('No speech detected.');\n } else if (text) {\n void this.streamTranscript(text);\n } else {\n this.options.showInfo('No speech detected.');\n }\n },\n onError: err => {\n void this.reportSessionError(err);\n },\n });\n }\n\n /**\n * Stop the session and let the engine emit its final transcript.\n */\n async stopRecording(): Promise<void> {\n if (this.state !== 'recording') return;\n const session = this.session;\n this.session = null;\n this.state = 'transcribing';\n this.options.onListeningChange?.(false);\n try {\n await session?.stop();\n } finally {\n this.state = 'idle';\n }\n }\n\n /**\n * Abort any in-progress session without transcribing.\n */\n cancelRecording(): void {\n if (this.session) {\n this.session.cancel();\n this.session = null;\n }\n if (this.state !== 'idle') {\n this.state = 'idle';\n this.options.onListeningChange?.(false);\n }\n }\n\n /**\n * Surface a session error. If the active engine can explain a permission\n * problem (e.g. macOS access is blocked), append the concrete fix steps so the\n * user knows exactly what to do instead of seeing a bare failure.\n */\n private async reportSessionError(err: Error): Promise<void> {\n const base = err.message || 'Transcription failed.';\n try {\n const guidance = await this.engine.permissions?.();\n // Only dress the error with fix steps when access is actually blocked or\n // unavailable. A `will-prompt` (not-yet-determined) state is NOT the reason\n // a session failed — surfacing \"macOS will prompt next time\" in red after a\n // crash is confusing, so we let the real error message through instead.\n if (guidance && (guidance.state === 'blocked' || guidance.state === 'unsupported') && guidance.steps?.length) {\n const steps = guidance.steps.map((step, i) => ` ${i + 1}. ${step}`).join('\\n');\n this.options.showError(`${guidance.summary}\\n${steps}`);\n return;\n }\n } catch {\n // Fall through to the plain error if guidance can't be produced.\n }\n this.options.showError(base);\n }\n\n /**\n * Feed the transcript into the editor incrementally so it visibly streams in\n * word-by-word rather than appearing all at once. Each chunk keeps its\n * trailing whitespace so word spacing is preserved.\n */\n private async streamTranscript(text: string): Promise<void> {\n const chunks = text.match(/\\S+\\s*/g);\n if (!chunks) {\n this.options.onTranscript(text);\n return;\n }\n for (const chunk of chunks) {\n this.options.onTranscript(chunk);\n await new Promise(resolve => setTimeout(resolve, 30));\n }\n }\n}\n","/**\n * Shared TUI state — the single source of truth for all mutable state\n * in the Mastra TUI. Extracted so that slash commands, event handlers,\n * and other modules can operate on the state without coupling to the\n * MastraTUI class.\n */\nimport { Container, TUI, ProcessTerminal } from '@earendil-works/pi-tui';\nimport type { CombinedAutocompleteProvider, Component, Terminal, Text } from '@earendil-works/pi-tui';\nimport type { MastraCodeAnalytics } from '@mastra/code-sdk/analytics';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport type { HookManager } from '@mastra/code-sdk/hooks/index';\nimport type { McpManager } from '@mastra/code-sdk/mcp/manager';\nimport { loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport type { PluginManager } from '@mastra/code-sdk/plugins/manager';\nimport { detectProject } from '@mastra/code-sdk/utils/project';\nimport type { ProjectInfo } from '@mastra/code-sdk/utils/project';\nimport type { SlashCommandMetadata } from '@mastra/code-sdk/utils/slash-command-loader';\nimport type { StorageMaintenance } from '@mastra/code-sdk/utils/storage-maintenance';\nimport type { AgentController, MastraDBMessage, Session } from '@mastra/core/agent-controller';\nimport type { SkillMetadata, Workspace } from '@mastra/core/workspace';\nimport type { GithubSignals } from '@mastra/github-signals';\nimport type { AskQuestionInlineComponent } from './components/ask-question-inline.js';\nimport type { AssistantMessageComponent } from './components/assistant-message.js';\nimport { CustomEditor } from './components/custom-editor.js';\nimport type { IdleCounterComponent } from './components/idle-counter.js';\nimport type { JudgeDisplayComponent } from './components/judge-display.js';\nimport type { GradientAnimator } from './components/obi-loader.js';\nimport type { OMMarkerComponent, OMMarkerData } from './components/om-marker.js';\nimport type { OMProgressComponent } from './components/om-progress.js';\nimport type { PlanApprovalInlineComponent } from './components/plan-approval-inline.js';\nimport type { ShellStreamComponent } from './components/shell-output.js';\nimport type { SlashCommandComponent } from './components/slash-command.js';\nimport type { SubagentExecutionComponent } from './components/subagent-execution.js';\nimport type { SystemReminderComponent } from './components/system-reminder.js';\nimport type { TaskProgressComponent } from './components/task-progress.js';\nimport type { TemporalGapComponent } from './components/temporal-gap.js';\nimport type { IToolExecutionComponent } from './components/tool-execution-interface.js';\nimport type { UserMessageComponent } from './components/user-message.js';\nimport { showError, showInfo } from './display.js';\n\nimport { GoalManager } from './goal-manager.js';\nimport type { OnboardingInlineComponent } from './onboarding-inline.js';\nimport { RenderScheduler } from './render-scheduler.js';\nimport { getEditorTheme, mastra, TERM_WIDTH_BUFFER } from './theme.js';\nimport { VoiceController } from './voice/voice-controller.js';\n\nexport interface PendingSignalMessage {\n component: Component;\n text: string;\n images?: Array<{ data: string; mimeType: string }>;\n isInterjection?: boolean;\n}\n\nexport interface GithubPrSubscriptionBadge {\n owner?: string;\n repo?: string;\n prNumber: number;\n lastSyncStatus?: string;\n lastNotificationKind?: string;\n lastNotificationPriority?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function getGithubPrSubscriptionsFromMetadata(\n metadata: Record<string, unknown> | undefined,\n): GithubPrSubscriptionBadge[] {\n const mastraMetadata = isRecord(metadata?.mastra) ? metadata.mastra : undefined;\n const githubSignals = isRecord(mastraMetadata?.githubSignals) ? mastraMetadata.githubSignals : undefined;\n const subscriptions = Array.isArray(githubSignals?.subscriptions) ? githubSignals.subscriptions : [];\n const result: GithubPrSubscriptionBadge[] = [];\n for (const subscription of subscriptions) {\n if (!isRecord(subscription)) continue;\n const prNumber = typeof subscription.number === 'number' ? subscription.number : undefined;\n if (!prNumber) continue;\n result.push({\n prNumber,\n ...(typeof subscription.owner === 'string' ? { owner: subscription.owner } : {}),\n ...(typeof subscription.repo === 'string' ? { repo: subscription.repo } : {}),\n ...(typeof subscription.lastSyncStatus === 'string' ? { lastSyncStatus: subscription.lastSyncStatus } : {}),\n ...(typeof subscription.lastNotificationKind === 'string'\n ? { lastNotificationKind: subscription.lastNotificationKind }\n : {}),\n ...(typeof subscription.lastNotificationPriority === 'string'\n ? { lastNotificationPriority: subscription.lastNotificationPriority }\n : {}),\n });\n }\n return result.sort((a, b) => a.prNumber - b.prNumber);\n}\n// =============================================================================\n// MastraTUIOptions\n// =============================================================================\n\nexport interface MastraTUIOptions {\n /** The controller instance */\n controller: AgentController<any>;\n\n /** The session created from the controller that all work runs through */\n session: Session<any>;\n\n /** Hook manager for session lifecycle hooks */\n hookManager?: HookManager;\n\n /** Analytics client for product telemetry */\n analytics?: MastraCodeAnalytics;\n\n /** Auth storage for OAuth login/logout */\n authStorage?: AuthStorage;\n\n /** MCP manager for server status and reload */\n mcpManager?: McpManager;\n\n /** Plugin manager for /plugins. */\n pluginManager?: PluginManager;\n\n /**\n * @deprecated Workspace is now obtained from the AgentController.\n * Configure workspace via AgentControllerConfig.workspace instead.\n * Kept as fallback for backward compatibility.\n */\n workspace?: Workspace;\n\n /** Initial message to send on startup */\n initialMessage?: string;\n\n /** Whether to show verbose startup info */\n verbose?: boolean;\n\n /** App name for header */\n appName?: string;\n\n /** App version for header */\n version?: string;\n\n /** Use inline questions instead of dialog overlays */\n inlineQuestions?: boolean;\n\n /** GitHub PR signal processor used for status-line polling state. */\n githubSignals?: GithubSignals;\n\n /** Storage maintenance handle for /prune (retention pruning + disk reclamation). */\n storageMaintenance?: StorageMaintenance;\n\n /** Optional terminal injection for in-process tests. Defaults to ProcessTerminal. */\n terminal?: Terminal;\n}\n\n// =============================================================================\n// TUIState\n// =============================================================================\n\nexport interface TUIState {\n // ── Core dependencies (set once) ──────────────────────────────────────\n controller: AgentController<any>;\n session: Session<any>;\n options: MastraTUIOptions;\n hookManager?: HookManager;\n analytics?: MastraCodeAnalytics;\n authStorage?: AuthStorage;\n mcpManager?: McpManager;\n pluginManager?: PluginManager;\n workspace?: Workspace;\n\n // ── TUI framework (set once) ──────────────────────────────────────────\n ui: TUI;\n renderScheduler?: RenderScheduler;\n chatContainer: Container;\n editorContainer: Container;\n idleCounter?: IdleCounterComponent;\n lastRenderedMessageAt?: number;\n editor: CustomEditor;\n footer: Container;\n terminal: Terminal;\n voiceController?: VoiceController;\n\n // ── Agent / streaming ─────────────────────────────────────────────────\n isInitialized: boolean;\n gradientAnimator?: GradientAnimator;\n streamingComponent?: AssistantMessageComponent;\n streamingMessage?: MastraDBMessage;\n pendingTools: Map<string, IToolExecutionComponent>;\n /** Task tools are hidden on success but promoted to normal tool boxes on errors */\n pendingTaskToolIds: Set<string>;\n /** Position hint for inline task-tool rendering when streaming */\n taskToolInsertIndex: number;\n /** Track all tool IDs seen during current stream (prevents duplicates) */\n seenToolCallIds: Set<string>;\n /** Track subagent tool call IDs to skip in trailing content logic */\n subagentToolCallIds: Set<string>;\n /** Track streamed system reminders for the active assistant run */\n currentRunSystemReminderKeys: Set<string>;\n /** Track all tools for expand/collapse */\n allToolComponents: IToolExecutionComponent[];\n /** Track slash command boxes for expand/collapse */\n allSlashCommandComponents: SlashCommandComponent[];\n /** Track inline system reminders for expand/collapse */\n allSystemReminderComponents: Array<SystemReminderComponent | TemporalGapComponent>;\n /** Track rendered message components by message id for anchored inserts */\n messageComponentsById: Map<string, Component>;\n /** Track shell passthrough components for expand/collapse */\n allShellComponents: ShellStreamComponent[];\n /** Track active subagent tasks */\n pendingSubagents: Map<string, SubagentExecutionComponent>;\n toolOutputExpanded: boolean;\n hideThinkingBlock: boolean;\n quietMode: boolean;\n quietModeMaxToolPreviewLines: number;\n /** Active goal judge status-line override while evaluating the last turn. */\n activeGoalJudge?: { modelId: string; abortController: AbortController; component: JudgeDisplayComponent };\n\n // ── Thread / conversation ─────────────────────────────────────────────\n /** True when we want a new thread but haven't created it yet */\n pendingNewThread: boolean;\n /** Current thread title (for display in status line) */\n currentThreadTitle?: string;\n /** GitHub PR subscriptions for the current thread. */\n activeGithubPrSubscriptions: GithubPrSubscriptionBadge[];\n /** Cached thread previews for the current TUI session */\n threadPreviewCache: Map<string, { preview: string; updatedAt: number }>;\n /** Threads whose preview lookup already returned empty during this session */\n attemptedThreadPreviewIds: Set<string>;\n\n // ── Inline interaction ────────────────────────────────────────────────\n /** Track the most recent ask_user component for inline question activation */\n lastAskUserComponent?: AskQuestionInlineComponent;\n /** Map toolCallId → AskQuestionInlineComponent for streaming arg updates */\n pendingAskUserComponents: Map<string, AskQuestionInlineComponent>;\n /** Saved editor text for Alt+Z undo */\n lastClearedText: string;\n activeInlineQuestion?: AskQuestionInlineComponent;\n /** Queue of pending inline questions waiting to be shown (when one is already active) */\n pendingInlineQuestions: Array<() => void>;\n activeInlinePlanApproval?: PlanApprovalInlineComponent;\n activeOnboarding?: OnboardingInlineComponent;\n lastSubmitPlanComponent?: Component;\n pendingSubmitPlanComponents: Map<string, PlanApprovalInlineComponent>;\n /** Previous plan snapshot (keyed by plan file path) for diff display on resubmission */\n previousPlanSnapshot?: { path: string; plan: string };\n /** User-message follow-ups queued while the agent is running */\n pendingFollowUpMessages: Array<{ content: string; images?: Array<{ data: string; mimeType: string }> }>;\n /** FIFO ordering across queued follow-up messages and slash commands */\n pendingQueuedActions: Array<'message' | 'slash'>;\n /** Follow-up messages rendered while streaming so tool output stays above them */\n followUpComponents: UserMessageComponent[];\n /** Pending signal messages waiting for the stream echo */\n pendingSignalMessageComponentsById: Map<string, PendingSignalMessage>;\n /** Slash commands queued while the agent is running */\n pendingSlashCommands: string[];\n /** Pending user-message component ids for queued slash commands */\n pendingSlashCommandMessageIds: string[];\n /** Active approval dialog dismiss callback — called on Ctrl+C or user interruption to unblock the dialog */\n pendingApprovalDismiss: ((context?: { reason?: string; message?: string }) => void) | null;\n\n // ── Status line ───────────────────────────────────────────────────────\n projectInfo: ProjectInfo;\n statusLine?: Text;\n memoryStatusLine?: Text;\n modelAuthStatus: { hasAuth: boolean; apiKeyEnvVar?: string };\n githubPrGradientAnimator?: GradientAnimator;\n githubPrPollingActive: boolean;\n /** Timestamp (ms) when the current agent run started. */\n agentRunStartedAt?: number;\n /** Timestamp (ms) when the current agent run last received streamed content. */\n agentRunLastStreamPartAt?: number;\n /** Duration (ms) of the most recently completed agent run. */\n lastAgentRunDurationMs?: number;\n /** Timestamp (ms) when the most recent agent run ended. */\n lastAgentRunEndedAt?: number;\n /** End state of the most recent agent run. */\n lastAgentRunEndReason?: 'done' | 'aborted' | 'error';\n\n // ── Tokens/sec tracking ────────────────────────────────────────────────\n /**\n * Timestamp (ms) of the first streamed content delta of the current step —\n * i.e. when decoding began. tokens/sec is measured over decode time only\n * (excludes TTFT and inter-step tool gaps). 0 means decode not yet started.\n */\n decodeStartedAt: number;\n /** Current computed tokens/sec rate (0 when idle) */\n tokensPerSec: number;\n\n // ── Observational Memory ──────────────────────────────────────────────\n omProgressComponent?: OMProgressComponent;\n activeOMMarker?: OMMarkerComponent;\n activeBufferingMarker?: OMMarkerComponent;\n activeActivationMarker?: OMMarkerComponent;\n activeActivationData?: OMMarkerData;\n activeActivationProviderChangeMarker?: OMMarkerComponent;\n\n // ── Tasks ─────────────────────────────────────────────────────────────\n taskProgress?: TaskProgressComponent;\n\n // ── Goal loop ─────────────────────────────────────────────────────────\n goalManager: GoalManager;\n /** Track a goal started from plan approval — return to plan mode when it completes */\n planStartedGoalId?: string;\n\n // ── Input ─────────────────────────────────────────────────────────────\n autocompleteProvider?: CombinedAutocompleteProvider;\n customSlashCommands: SlashCommandMetadata[];\n skillCommands: SkillMetadata[];\n goalSkillCommands: SkillMetadata[];\n /** Pending images from clipboard paste */\n pendingImages: Array<{ data: string; mimeType: string }>;\n\n // ── Dedup ────────────────────────────────────────────────────────────\n /** Texts of queued messages that were locally rendered and fired — used to\n * suppress the subscription echo that would otherwise create a duplicate. */\n firedQueuedMessageTexts?: Map<string, number>;\n\n // ── Abort tracking ────────────────────────────────────────────────────\n lastCtrlCTime: number;\n /** Track user-initiated aborts (Ctrl+C/Esc) vs system aborts */\n userInitiatedAbort: boolean;\n /**\n * Set when the run is aborted because the user clicked \"Request Changes\" on a\n * plan approval. Suppresses the \"Interrupted\" abort UI so the rejection ends\n * cleanly and the user can type revision feedback.\n */\n planRejectionAbort: boolean;\n\n // ── Cleanup ───────────────────────────────────────────────────────────\n unsubscribe?: () => void;\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\n/**\n * Create the initial TUIState from options.\n * Instantiates TUI framework objects (terminal, containers, editor)\n * and sets all mutable fields to their defaults.\n */\nexport function createTUIState(options: MastraTUIOptions): TUIState {\n const terminal = options.terminal ?? new ProcessTerminal();\n // Override columns getter to prevent line wrapping in nested terminal emulators\n if (!options.terminal) {\n Object.defineProperty(terminal, 'columns', {\n get: () => (process.stdout.columns || 80) - TERM_WIDTH_BUFFER,\n });\n }\n const ui = new TUI(terminal);\n const renderScheduler = new RenderScheduler(() => ui.requestRender());\n\n // Perf profiling removed\n\n const chatContainer = new Container();\n const editorContainer = new Container();\n const footer = new Container();\n const editor = new CustomEditor(ui, getEditorTheme());\n editor.requestRender = () => renderScheduler.request();\n const result: TUIState = {\n // Core dependencies\n controller: options.controller,\n session: options.session,\n options,\n hookManager: options.hookManager,\n analytics: options.analytics,\n authStorage: options.authStorage,\n mcpManager: options.mcpManager,\n pluginManager: options.pluginManager,\n workspace: options.workspace,\n\n // TUI framework\n ui,\n renderScheduler,\n chatContainer,\n editorContainer,\n editor,\n footer,\n terminal,\n\n // Agent / streaming\n isInitialized: false,\n pendingTools: new Map(),\n pendingTaskToolIds: new Set(),\n taskToolInsertIndex: -1,\n seenToolCallIds: new Set(),\n subagentToolCallIds: new Set(),\n currentRunSystemReminderKeys: new Set(),\n allToolComponents: [],\n allSlashCommandComponents: [],\n allSystemReminderComponents: [],\n messageComponentsById: new Map(),\n allShellComponents: [],\n pendingSubagents: new Map(),\n toolOutputExpanded: false,\n hideThinkingBlock: true,\n quietMode: false,\n quietModeMaxToolPreviewLines: 2,\n\n // Thread / conversation\n pendingNewThread: false,\n currentThreadTitle: undefined,\n activeGithubPrSubscriptions: [],\n threadPreviewCache: new Map(),\n attemptedThreadPreviewIds: new Set(),\n\n // Inline interaction\n lastClearedText: '',\n pendingAskUserComponents: new Map(),\n pendingSubmitPlanComponents: new Map(),\n pendingInlineQuestions: [],\n pendingFollowUpMessages: [],\n pendingQueuedActions: [],\n followUpComponents: [],\n pendingSignalMessageComponentsById: new Map(),\n pendingSlashCommands: [],\n pendingSlashCommandMessageIds: [],\n pendingApprovalDismiss: null,\n\n // Status line\n projectInfo: detectProject(process.cwd()),\n modelAuthStatus: { hasAuth: true },\n githubPrPollingActive: false,\n\n // Tokens/sec tracking\n decodeStartedAt: 0,\n tokensPerSec: 0,\n\n // Goal loop\n goalManager: new GoalManager(),\n planStartedGoalId: undefined,\n\n // Input\n customSlashCommands: [],\n skillCommands: [],\n goalSkillCommands: [],\n pendingImages: [],\n\n // Abort tracking\n lastCtrlCTime: 0,\n userInitiatedAbort: false,\n planRejectionAbort: false,\n };\n editor.getModeColor = () => {\n if (result.activeGoalJudge) {\n return mastra.blue;\n }\n const color = result.session.mode.resolve()?.metadata?.color;\n return typeof color === 'string' ? color : undefined;\n };\n\n const voiceSettings = loadSettings().voice;\n result.voiceController = new VoiceController({\n authStorage: result.authStorage,\n settings: voiceSettings,\n onTranscript: text => editor.insertVoiceTranscript(text),\n onPartialTranscript: text => editor.replaceVoiceTranscript(text),\n showInfo: message => showInfo(result, message),\n showError: message => showError(result, message),\n onListeningChange: listening => editor.setVoiceListening(listening),\n });\n editor.voiceInput = result.voiceController;\n if (voiceSettings.enabled) {\n result.voiceController.restoreEnabled();\n }\n\n return result;\n}\n","/**\n * Event dispatcher: maps AgentControllerEvent types to extracted handler functions.\n */\nimport { getCurrentGitBranchAsync } from '@mastra/code-sdk/utils/project';\nimport type { AgentControllerEvent, AgentControllerThread } from '@mastra/core/agent-controller';\nimport type { TaskItemSnapshot } from '@mastra/core/signals';\nimport type { AskUserSelectionMode } from '@mastra/core/tools';\n\nimport { getMessageText } from './db-message-parts.js';\nimport {\n handleAgentStart,\n handleAgentEnd,\n handleAgentAborted,\n handleAgentError,\n handleGoalEvaluation,\n handleMessageStart,\n handleMessageUpdate,\n handleMessageEnd,\n handleOMObservationStart,\n handleOMObservationEnd,\n handleOMReflectionStart,\n handleOMReflectionEnd,\n handleOMFailed,\n handleOMBufferingStart,\n handleOMBufferingEnd,\n handleOMBufferingFailed,\n handleOMActivation,\n handleOMThreadTitleUpdated,\n handleAskQuestion,\n handleSandboxAccessRequest,\n handlePlanApproval,\n handleSubagentStart,\n handleSubagentToolStart,\n handleSubagentToolEnd,\n handleSubagentEnd,\n handleToolApprovalRequired,\n handleToolStart,\n handleToolUpdate,\n handleShellOutput,\n handleToolInputStart,\n handleToolInputDelta,\n handleToolInputEnd,\n handleToolEnd,\n clearPendingShellOutputs,\n clearToolInputParsers,\n} from './handlers/index.js';\nimport type { EventHandlerContext } from './handlers/types.js';\nimport { flushRender } from './render-scheduler.js';\nimport type { TUIState } from './state.js';\nimport { getGithubPrSubscriptionsFromMetadata } from './state.js';\n\n/**\n * Dispatch a AgentControllerEvent to the appropriate handler.\n */\nfunction trackInteractivePrompt(\n ectx: EventHandlerContext,\n promptType: string,\n properties?: Record<string, unknown>,\n): void {\n ectx.analytics?.trackInteractivePrompt(promptType, properties);\n}\n\nexport async function dispatchEvent(\n event: AgentControllerEvent,\n ectx: EventHandlerContext,\n state: TUIState,\n): Promise<void> {\n switch (event.type) {\n case 'agent_start':\n clearToolInputParsers();\n clearPendingShellOutputs();\n // Reset tokens/sec at the start of a new turn (not at the end) so the\n // last turn's reading stays visible while idle — short single-step turns\n // would otherwise zero it before it could be read.\n state.tokensPerSec = 0;\n state.decodeStartedAt = 0;\n state.agentRunStartedAt = Date.now();\n state.agentRunLastStreamPartAt = state.agentRunStartedAt;\n state.lastAgentRunDurationMs = undefined;\n state.lastAgentRunEndedAt = undefined;\n state.lastAgentRunEndReason = undefined;\n ectx.updateStatusLine();\n handleAgentStart(ectx);\n break;\n\n case 'agent_end':\n // Keep tokensPerSec as the last turn's reading; only clear the in-flight\n // decode window so a stale start can't bleed into the next turn.\n if (state.agentRunStartedAt !== undefined) {\n const now = Date.now();\n state.lastAgentRunDurationMs = Math.max(0, now - state.agentRunStartedAt);\n state.lastAgentRunEndedAt = now;\n state.lastAgentRunEndReason = event.reason === 'aborted' || event.reason === 'error' ? event.reason : 'done';\n state.agentRunStartedAt = undefined;\n state.agentRunLastStreamPartAt = undefined;\n }\n state.decodeStartedAt = 0;\n ectx.updateStatusLine();\n if (event.reason === 'aborted') {\n clearPendingShellOutputs();\n handleAgentAborted(ectx);\n } else if (event.reason === 'error') {\n clearPendingShellOutputs();\n handleAgentError(ectx);\n } else {\n handleAgentEnd(ectx);\n }\n break;\n\n case 'message_start':\n handleMessageStart(ectx, event.message);\n break;\n\n case 'message_update': {\n // Only open the decode window when an assistant message carries actual\n // streamed text — tool-result-only updates (e.g. plan approval resume) and\n // user/system message updates must not count toward tokens/sec.\n const hasAssistantText = event.message.role === 'assistant' && getMessageText(event.message).trim().length > 0;\n if (hasAssistantText) {\n state.agentRunLastStreamPartAt = Date.now();\n if (state.decodeStartedAt === 0) {\n state.decodeStartedAt = state.agentRunLastStreamPartAt;\n }\n }\n ectx.updateStatusLine();\n handleMessageUpdate(ectx, event.message);\n break;\n }\n\n case 'message_end':\n handleMessageEnd(ectx, event.message);\n break;\n\n case 'tool_start':\n state.agentRunLastStreamPartAt = Date.now();\n handleToolStart(ectx, event.toolCallId, event.toolName, event.args);\n break;\n\n case 'tool_approval_required':\n trackInteractivePrompt(ectx, 'tool_approval_required', {\n toolName: event.toolName,\n threadId: state.session.thread.getId(),\n resourceId: state.session.identity.getResourceId(),\n });\n handleToolApprovalRequired(ectx, event.toolCallId, event.toolName, event.args);\n break;\n\n case 'tool_update':\n state.agentRunLastStreamPartAt = Date.now();\n handleToolUpdate(ectx, event.toolCallId, event.partialResult);\n break;\n\n case 'shell_output':\n state.agentRunLastStreamPartAt = Date.now();\n handleShellOutput(ectx, event.toolCallId, event.output, event.stream);\n break;\n\n case 'tool_input_start':\n if (event.toolName === 'ask_user' || event.toolName === 'request_access' || event.toolName === 'submit_plan') {\n trackInteractivePrompt(ectx, event.toolName, {\n toolName: event.toolName,\n threadId: state.session.thread.getId(),\n resourceId: state.session.identity.getResourceId(),\n });\n }\n handleToolInputStart(ectx, event.toolCallId, event.toolName);\n break;\n\n case 'tool_input_delta':\n // Display processors may transform argsTextDelta to a non-string payload.\n if (typeof event.argsTextDelta === 'string') {\n handleToolInputDelta(ectx, event.toolCallId, event.argsTextDelta);\n }\n break;\n\n case 'tool_input_end':\n handleToolInputEnd(ectx, event.toolCallId);\n break;\n\n case 'tool_end':\n state.agentRunLastStreamPartAt = Date.now();\n handleToolEnd(ectx, event.toolCallId, event.result, event.isError);\n break;\n\n case 'info':\n ectx.showInfo(event.message);\n break;\n\n case 'error':\n ectx.showFormattedError(event);\n break;\n\n case 'mode_changed':\n await ectx.refreshModelAuthStatus();\n break;\n\n case 'model_changed':\n await ectx.refreshModelAuthStatus();\n break;\n\n case 'thread_changed': {\n ectx.showInfo(`Switched to thread: ${event.threadId}`);\n // Clear per-thread ephemeral state first so renderExistingMessages\n // and other downstream observers see clean state.\n await state.session.state.set({ tasks: [], activePlan: null, sandboxAllowedPaths: [] });\n state.previousPlanSnapshot = undefined;\n if (state.taskProgress) {\n state.taskProgress.updateTasks([]);\n flushRender(state);\n }\n state.taskToolInsertIndex = -1;\n await ectx.renderExistingMessages();\n await state.controller.loadOMProgress(state.session);\n // Refresh git branch async so TUI status line reflects the current branch\n getCurrentGitBranchAsync(state.projectInfo.rootPath).then(freshBranch => {\n if (freshBranch) {\n state.projectInfo.gitBranch = freshBranch;\n ectx.updateStatusLine();\n }\n });\n // Update current thread title for status line display\n const threads = await state.session.thread.list();\n const currentThread = threads.find((t: AgentControllerThread) => t.id === event.threadId);\n if (currentThread) {\n state.currentThreadTitle = currentThread.title;\n const metadata = currentThread.metadata as Record<string, unknown> | undefined;\n state.activeGithubPrSubscriptions = getGithubPrSubscriptionsFromMetadata(metadata);\n state.githubPrPollingActive = false;\n state.githubPrGradientAnimator?.stop();\n // Load the objective from the durable ThreadState slot, falling back to\n // the legacy thread-metadata goal for pre-migration threads.\n await state.goalManager.loadFromThread(state);\n if (!state.goalManager.getGoal()) {\n state.goalManager.loadFromThreadMetadata(metadata);\n }\n }\n break;\n }\n\n case 'thread_created': {\n ectx.showInfo(`Created thread: ${event.thread.id}`);\n // Update current thread title for status line display\n state.currentThreadTitle = event.thread.title;\n state.activeGithubPrSubscriptions = getGithubPrSubscriptionsFromMetadata(\n event.thread.metadata as Record<string, unknown> | undefined,\n );\n state.githubPrPollingActive = false;\n state.githubPrGradientAnimator?.stop();\n // If /goal started without an existing thread, save that pending goal to the\n // newly-created thread. Otherwise load the thread's own goal metadata so goals\n // do not bleed into unrelated new threads.\n const shouldPersistPendingGoal = state.goalManager?.consumePersistOnNextThreadCreate() ?? false;\n if (shouldPersistPendingGoal) {\n state.goalManager?.saveToThread(state).catch(() => {});\n } else {\n state.goalManager?.loadFromThreadMetadata(event.thread.metadata as Record<string, unknown> | undefined);\n }\n // Sync inherited resource-level settings\n const tState = state.session.state.get() as any;\n if (typeof tState?.escapeAsCancel === 'boolean') {\n state.editor.escapeEnabled = tState.escapeAsCancel;\n }\n // Clear per-thread ephemeral state so new threads start clean.\n await state.session.state.set({ tasks: [], activePlan: null, sandboxAllowedPaths: [] });\n state.previousPlanSnapshot = undefined;\n if (state.taskProgress) {\n state.taskProgress.updateTasks([]);\n }\n state.taskToolInsertIndex = -1;\n break;\n }\n\n case 'usage_update': {\n // Token accumulation handled by AgentController display state.\n // usage_update fires at step-finish and carries the completion (and any\n // reasoning) tokens generated during this step. Measure tokens/sec over the\n // decode window only — from this step's first content delta\n // (state.decodeStartedAt) to now — which excludes TTFT and inter-step\n // tool/scheduling time. Smooth with an exponential moving average (α=0.3).\n const now = Date.now();\n const stepTokens = (event.usage.completionTokens ?? 0) + (event.usage.reasoningTokens ?? 0);\n if (state.decodeStartedAt > 0 && stepTokens > 0) {\n const decodeSec = (now - state.decodeStartedAt) / 1000;\n if (decodeSec > 0) {\n const instantaneous = stepTokens / decodeSec;\n const alpha = 0.3;\n const ema = state.tokensPerSec > 0 ? alpha * instantaneous + (1 - alpha) * state.tokensPerSec : instantaneous;\n state.tokensPerSec = Math.round(ema);\n }\n }\n // Re-arm: the next step's decode window opens on its first content delta.\n state.decodeStartedAt = 0;\n ectx.updateStatusLine();\n state.ui.requestRender();\n break;\n }\n\n // Observational Memory events\n case 'om_status':\n // All state updates handled by AgentController applyDisplayStateUpdate\n break;\n\n case 'om_observation_start':\n handleOMObservationStart(ectx, event.cycleId, event.tokensToObserve);\n break;\n\n case 'om_observation_end':\n handleOMObservationEnd(\n ectx,\n event.cycleId,\n event.durationMs,\n event.tokensObserved,\n event.observationTokens,\n event.observations,\n event.currentTask,\n event.suggestedResponse,\n );\n break;\n\n case 'om_observation_failed':\n handleOMFailed(ectx, event.cycleId, event.error, 'observation');\n break;\n\n case 'om_reflection_start':\n handleOMReflectionStart(ectx, event.cycleId, event.tokensToReflect);\n break;\n\n case 'om_reflection_end':\n handleOMReflectionEnd(ectx, event.cycleId, event.durationMs, event.compressedTokens, event.observations);\n break;\n\n case 'om_reflection_failed':\n handleOMFailed(ectx, event.cycleId, event.error, 'reflection');\n break;\n\n case 'om_buffering_start':\n handleOMBufferingStart(ectx, event.operationType, event.tokensToBuffer);\n break;\n\n case 'om_buffering_end':\n handleOMBufferingEnd(ectx, event.operationType, event.tokensBuffered, event.bufferedTokens, event.observations);\n break;\n\n case 'om_buffering_failed':\n handleOMBufferingFailed(ectx, event.operationType, event.error);\n break;\n\n case 'om_activation': {\n const activationEvent = event as Extract<AgentControllerEvent, { type: 'om_activation' }> & {\n triggeredBy?: 'threshold' | 'ttl' | 'provider_change';\n lastActivityAt?: number;\n ttlExpiredMs?: number;\n activateAfterIdle?: number;\n previousModel?: string;\n currentModel?: string;\n };\n handleOMActivation(\n ectx,\n activationEvent.operationType,\n activationEvent.tokensActivated,\n activationEvent.observationTokens,\n activationEvent.triggeredBy,\n activationEvent.activateAfterIdle,\n activationEvent.ttlExpiredMs,\n activationEvent.previousModel,\n activationEvent.currentModel,\n );\n break;\n }\n\n case 'om_thread_title_updated':\n state.currentThreadTitle = event.newTitle;\n handleOMThreadTitleUpdated(ectx, event.newTitle, event.oldTitle);\n ectx.updateStatusLine();\n break;\n\n case 'follow_up_queued': {\n ectx.updateStatusLine();\n break;\n }\n\n case 'workspace_ready':\n // Workspace initialized successfully - silent unless verbose\n break;\n\n case 'workspace_error':\n ectx.showError(`Workspace: ${event.error.message}`);\n break;\n\n case 'workspace_status_changed':\n if (event.status === 'error' && event.error) {\n ectx.showError(`Workspace: ${event.error.message}`);\n }\n break;\n\n // Subagent / Task delegation events\n case 'subagent_start':\n handleSubagentStart(ectx, event.toolCallId, event.agentType, event.task, event.modelId, event.forked);\n break;\n\n case 'subagent_tool_start':\n handleSubagentToolStart(ectx, event.toolCallId, event.subToolName, event.subToolArgs);\n break;\n\n case 'subagent_tool_end':\n handleSubagentToolEnd(ectx, event.toolCallId, event.subToolName, event.subToolResult, event.isError);\n break;\n\n case 'subagent_text_delta':\n // Text deltas are streamed but we don't render them incrementally\n // (the final result is shown via tool_end for the parent tool call)\n break;\n\n case 'subagent_end':\n handleSubagentEnd(ectx, event.toolCallId, event.isError, event.durationMs, event.result);\n break;\n\n case 'task_updated': {\n const tasks = event.tasks as TaskItemSnapshot[];\n if (state.taskProgress) {\n state.taskProgress.updateTasks(tasks ?? []);\n\n // Defensive cleanup for older or non-streaming task_write components.\n // Current task tools update the pinned component directly through task_updated.\n let insertIndex = -1;\n for (let i = state.allToolComponents.length - 1; i >= 0; i--) {\n const comp = state.allToolComponents[i];\n if ((comp as any).toolName === 'task_write') {\n insertIndex = state.chatContainer.children.indexOf(comp as any);\n state.chatContainer.removeChild(comp as any);\n state.allToolComponents.splice(i, 1);\n break;\n }\n }\n // Fall back to the position recorded during streaming (when no inline component was created)\n if (insertIndex === -1 && state.taskToolInsertIndex >= 0) {\n insertIndex = state.taskToolInsertIndex;\n state.taskToolInsertIndex = -1;\n }\n\n const previousTasks = state.session.displayState.get().previousTasks;\n if (tasks?.length > 0 && tasks.every(task => task.status === 'completed')) {\n ectx.renderCompletedTasksInline(tasks, insertIndex);\n } else if (previousTasks.length > 0 && (!tasks || tasks.length === 0)) {\n ectx.renderClearedTasksInline(previousTasks, insertIndex);\n } else if (tasks?.length > 0) {\n ectx.renderTaskDeltaInline(previousTasks, tasks, insertIndex);\n }\n\n state.ui.requestRender();\n }\n break;\n }\n\n case 'goal_evaluation': {\n handleGoalEvaluation(ectx, event.payload);\n break;\n }\n\n case 'tool_suspended': {\n // Interactive built-in tools pause via the native tool-suspension primitive.\n // Route the suspension to the matching prompt UI using the suspend payload;\n // the UI resumes the tool by calling controller.session.respondToToolSuspension({ toolCallId }).\n const payload = (event.suspendPayload ?? {}) as Record<string, unknown>;\n if (event.toolName === 'request_access' || payload.kind === 'sandbox_access_request') {\n await handleSandboxAccessRequest(\n ectx,\n event.toolCallId,\n String(payload.path ?? ''),\n String(payload.reason ?? ''),\n );\n } else if (event.toolName === 'ask_user') {\n await handleAskQuestion(\n ectx,\n event.toolCallId,\n String(payload.question ?? ''),\n payload.options as Array<{ label: string; description?: string }> | undefined,\n payload.selectionMode as AskUserSelectionMode | undefined,\n );\n } else if (event.toolName === 'submit_plan') {\n await handlePlanApproval(ectx, event.toolCallId, String(payload.path ?? ''));\n }\n break;\n }\n\n case 'display_state_changed':\n // The AgentController emits this after every event with the updated display state.\n // Use it as the single trigger for status-line re-renders since all the\n // fields it reads (isRunning, omProgress, buffering flags) are now\n // maintained by the AgentController.\n ectx.updateStatusLine();\n break;\n }\n}\n","/**\n * Setup onboarding component.\n *\n * Walks the user through a multi-step wizard:\n * 1. Welcome\n * 2. Auth / Login prompt\n * 3. Mode pack selection (build / plan / fast model preset)\n * 4. OM pack selection (observational memory model)\n * 5. YOLO mode toggle\n *\n * The component renders as a settings overlay. On completion it fires\n * `onComplete` with the collected choices.\n */\n\nimport { Box, SelectList, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { Focusable, SelectItem, TUI } from '@earendil-works/pi-tui';\nimport type { ModePack, OMPack } from '@mastra/code-sdk/onboarding/packs';\nimport chalk from 'chalk';\nimport { AskQuestionInlineComponent } from './components/ask-question-inline.js';\nimport { BOX_INDENT, theme, getSelectListTheme, mastra } from './theme.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface OnboardingResult {\n modePack: ModePack;\n omPack: OMPack;\n yolo: boolean;\n /** True if the user chose to log in (auth flow handled externally). */\n loginRequested: boolean;\n loginProvider?: string;\n}\n\n/** Previously saved selections to pre-populate when re-running /setup. */\nexport interface PreviousSetupChoices {\n modePackId: string | null;\n omPackId: string | null;\n yolo: boolean | null;\n}\n\nexport interface OnboardingOptions {\n tui: TUI;\n /** OAuth providers available for login. label=display name, value=provider id */\n authProviders: Array<{ label: string; value: string; loggedIn: boolean }>;\n /** Available mode packs (pre-filtered by provider access). */\n modePacks: ModePack[];\n /** Available OM packs (pre-filtered by provider access). */\n omPacks: OMPack[];\n /** Preferred OM pack for first-run setup, usually derived from the connected provider. */\n preferredOmPackId?: string;\n /** Whether the user has any provider access (API key or OAuth) — even for providers without a built-in pack. */\n hasProviderAccess: boolean;\n /** Previously saved choices — used to highlight current selections when re-running. */\n previous?: PreviousSetupChoices;\n /** Called when the wizard completes. */\n onComplete: (result: OnboardingResult) => void;\n /** Called if the user cancels the wizard (Esc on welcome). */\n onCancel: () => void;\n /** Called when the user requests login during onboarding. */\n onLogin: (providerId: string, done: () => void) => void;\n /** Show the model selector overlay and return the chosen model ID (or undefined on cancel). */\n onSelectModel: (title: string, modeColor?: string) => Promise<string | undefined>;\n}\n\n// ---------------------------------------------------------------------------\n// Steps\n// ---------------------------------------------------------------------------\n\ntype StepId = 'welcome' | 'auth' | 'modePack' | 'omPack' | 'yolo' | 'done';\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport class OnboardingInlineComponent extends Box implements Focusable {\n private tui: TUI;\n private options: OnboardingOptions;\n\n // Track which step we're on (written by renderStep for debugging / future use)\n private currentStep: StepId = 'welcome';\n private stepBox!: Box;\n private selectList?: SelectList;\n private activeInlineQuestion?: AskQuestionInlineComponent;\n private _finished = false;\n\n // Collected choices\n private loginRequested = false;\n private loginProvider?: string;\n private selectedModePack!: ModePack;\n private selectedOmPack!: OMPack;\n private selectedYolo = true;\n\n // Focusable\n private _focused = false;\n get focused(): boolean {\n return this._focused;\n }\n set focused(value: boolean) {\n this._focused = value;\n }\n\n constructor(options: OnboardingOptions) {\n super(4, 2, (text: string) => theme.bg('overlayBg', text));\n this.tui = options.tui;\n this.options = options;\n\n // Initialize defaults — prefer previous selection if it still exists in the available packs\n const prevModePack = options.previous?.modePackId\n ? options.modePacks.find(p => p.id === options.previous!.modePackId)\n : undefined;\n this.selectedModePack = prevModePack ?? options.modePacks[0]!;\n\n const prevOmPack = options.previous?.omPackId\n ? options.omPacks.find(p => p.id === options.previous!.omPackId)\n : undefined;\n const preferredOmPack = options.preferredOmPackId\n ? options.omPacks.find(p => p.id === options.preferredOmPackId)\n : undefined;\n this.selectedOmPack = prevOmPack ??\n preferredOmPack ??\n options.omPacks[0] ?? { id: 'none', name: 'None available', description: '', modelId: '' };\n\n if (options.previous?.yolo != null) {\n this.selectedYolo = options.previous.yolo;\n }\n\n this.renderStep('welcome');\n }\n\n get finished(): boolean {\n return this._finished;\n }\n\n /** Programmatically cancel the wizard (e.g. on Ctrl+C). */\n cancel(): void {\n if (this._finished) return;\n this._finished = true;\n this.collapseStep('Setup skipped — run /setup anytime to configure');\n this.options.onCancel();\n }\n\n /** Refresh the available mode packs (e.g. after a login grants new provider access). */\n updateModePacks(packs: ModePack[]): void {\n this.options.modePacks = packs;\n if (!this.selectedModePack || !packs.find(p => p.id === this.selectedModePack.id)) {\n this.selectedModePack = packs[0]!;\n }\n }\n\n /** Refresh the available OM packs (e.g. after a login grants new provider access). */\n updateOmPacks(packs: OMPack[], preferredOmPackId?: string): void {\n this.options.omPacks = packs;\n if (!this.options.previous?.omPackId && preferredOmPackId) {\n const preferred = packs.find(p => p.id === preferredOmPackId);\n if (preferred) {\n this.selectedOmPack = preferred;\n this.options.preferredOmPackId = preferred.id;\n return;\n }\n }\n if (!this.selectedOmPack || !packs.find(p => p.id === this.selectedOmPack.id)) {\n this.selectedOmPack = packs[0]!;\n }\n }\n\n /** Update whether the user has any provider access (e.g. after a login). */\n updateHasProviderAccess(hasAccess: boolean): void {\n this.options.hasProviderAccess = hasAccess;\n }\n\n // ---------------------------------------------------------------------------\n // Rendering helpers\n // ---------------------------------------------------------------------------\n\n private clearStep(): void {\n if (this.stepBox) {\n this.removeChild(this.stepBox);\n }\n this.selectList = undefined;\n }\n\n private renderStep(step: StepId): void {\n this.currentStep = step;\n\n switch (step) {\n case 'welcome':\n return this.renderWelcome();\n case 'auth':\n return this.renderAuth();\n case 'modePack':\n return this.renderModePack();\n case 'omPack':\n return this.renderOmPack();\n case 'yolo':\n return this.renderYolo();\n case 'done':\n return this.renderDone();\n }\n }\n\n private stepCount = 0;\n\n private makeBox(): Box {\n this.clearStep();\n this.stepBox = new Box(BOX_INDENT, 1, (text: string) => theme.bg('overlayBg', text));\n // Add a spacer between steps, but not before the very first one\n if (this.stepCount > 0) {\n this.addChild(new Spacer(1));\n }\n this.stepCount++;\n this.addChild(this.stepBox);\n return this.stepBox;\n }\n\n // ---------------------------------------------------------------------------\n // Step: Welcome\n // ---------------------------------------------------------------------------\n\n private renderWelcome(): void {\n const box = this.makeBox();\n box.addChild(new Text(theme.bold(theme.fg('accent', '👋 Welcome to Mastra Code')), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('text', \"Let's configure your models and preferences.\"), 0, 0));\n box.addChild(new Text(chalk.white('You can re-run this anytime with /setup.'), 0, 0));\n box.addChild(new Spacer(1));\n\n const items: SelectItem[] = [\n { value: 'continue', label: ` ${theme.fg('success', 'Continue')}` },\n { value: 'skip', label: ` ${theme.fg('dim', 'Skip')}` },\n ];\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n this.selectList.onSelect = (item: SelectItem) => {\n if (item.value === 'continue') {\n this.collapseStep('Welcome');\n this.renderStep('auth');\n } else {\n this._finished = true;\n this.collapseStep('Setup skipped — run /setup anytime to configure');\n this.options.onCancel();\n }\n };\n this.selectList.onCancel = () => {\n this._finished = true;\n this.collapseStep('Setup skipped — run /setup anytime to configure');\n this.options.onCancel();\n };\n box.addChild(this.selectList);\n }\n\n // ---------------------------------------------------------------------------\n // Step: Auth\n // ---------------------------------------------------------------------------\n\n private renderAuth(): void {\n const box = this.makeBox();\n box.addChild(new Text(theme.bold(theme.fg('accent', '🔑 Authentication')), 0, 0));\n box.addChild(new Spacer(1));\n\n const providers = this.options.authProviders;\n if (providers.length === 0) {\n box.addChild(new Text(theme.fg('dim', 'No OAuth providers available. Skipping.'), 0, 0));\n // auto-advance after brief moment\n setTimeout(() => this.renderStep('modePack'), 100);\n return;\n }\n\n box.addChild(new Text(theme.fg('text', 'Log in with an AI provider to use your subscription,'), 0, 0));\n box.addChild(new Text(theme.fg('text', 'or skip if you have API keys configured as environment variables.'), 0, 0));\n box.addChild(new Spacer(1));\n\n const items: SelectItem[] = providers.map(p => ({\n value: p.value,\n label: p.loggedIn ? ` ${p.label} ${theme.fg('success', '✓ logged in')}` : ` ${p.label}`,\n }));\n items.push({\n value: '__skip',\n label: ` ${theme.fg('dim', 'Skip (use API keys or configure later with /login)')}`,\n });\n\n this.selectList = new SelectList(items, Math.min(items.length, 8), getSelectListTheme());\n this.selectList.onSelect = (item: SelectItem) => {\n if (item.value === '__skip') {\n this.renderStep('modePack');\n } else {\n this.loginRequested = true;\n this.loginProvider = item.value;\n // Hand off to the external login flow; it calls `done()` when finished\n this.options.onLogin(item.value, () => {\n this.renderStep('modePack');\n });\n }\n };\n this.selectList.onCancel = () => {\n this.renderStep('modePack');\n };\n\n box.addChild(this.selectList);\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc skip'), 0, 0));\n }\n\n // ---------------------------------------------------------------------------\n // Step: Mode pack\n // ---------------------------------------------------------------------------\n\n /** Text component showing details for the currently highlighted mode pack. */\n private modePackDetail?: Text;\n\n private renderModePack(): void {\n const packs = this.options.modePacks;\n const box = this.makeBox();\n\n // No API keys and no OAuth logins — show warning but allow the user to continue\n if (!this.options.hasProviderAccess) {\n box.addChild(new Text(theme.bold(theme.fg('warning', 'No model providers configured')), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('text', 'To use Mastra Code you need at least one API key or OAuth login'), 0, 0));\n box.addChild(new Text(theme.fg('text', 'for Anthropic, OpenAI, or another supported provider.'), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(\n new Text(theme.fg('dim', 'See https://mastra.ai/models for supported providers and API key env vars.'), 0, 0),\n );\n box.addChild(new Spacer(1));\n box.addChild(\n new Text(theme.fg('dim', 'Set an API key and restart, or run /login to authenticate via OAuth.'), 0, 0),\n );\n box.addChild(new Spacer(1));\n }\n\n box.addChild(new Text(theme.bold(theme.fg('accent', 'Model Packs')), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('text', 'Choose default models for each mode (build / plan / fast):'), 0, 0));\n box.addChild(new Spacer(1));\n\n const prevId = this.options.previous?.modePackId ?? null;\n const items: SelectItem[] = packs.map(p => ({\n value: p.id,\n label: ` ${p.name} ${theme.fg('dim', p.description)}${p.id === prevId ? theme.fg('dim', ' (current)') : ''}`,\n }));\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n\n // Pre-select the previously chosen pack\n const prevIdx = prevId ? packs.findIndex(p => p.id === prevId) : -1;\n if (prevIdx > 0) this.selectList.setSelectedIndex(prevIdx);\n\n this.selectList.onSelect = (item: SelectItem) => {\n const pack = packs.find(p => p.id === item.value) ?? packs[0]!;\n if (pack.id === 'custom') {\n this.runCustomPackFlow();\n } else {\n this.selectedModePack = pack;\n this.preferMatchingOmPack(pack.id);\n this.collapseStep(`Model pack → ${theme.bold(this.selectedModePack.name)}`);\n this.renderStep('omPack');\n }\n };\n this.selectList.onCancel = () => {\n this.collapseStep(`Model pack → ${theme.bold(this.selectedModePack.name)} (default)`);\n this.renderStep('omPack');\n };\n this.selectList.onSelectionChange = (item: SelectItem) => {\n this.updateModePackDetail(packs, item.value);\n };\n\n box.addChild(this.selectList);\n box.addChild(new Spacer(1));\n\n // Detail line — shows models for the currently highlighted pack\n this.modePackDetail = new Text('', 0, 0);\n box.addChild(this.modePackDetail);\n\n // Initialize detail for the highlighted item\n const initialId = prevIdx > 0 ? packs[prevIdx]!.id : packs[0]!.id;\n this.updateModePackDetail(packs, initialId);\n\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc use default'), 0, 0));\n }\n\n private updateModePackDetail(packs: ModePack[], highlightedId: string): void {\n const pack = packs.find(p => p.id === highlightedId);\n if (!pack || !this.modePackDetail) return;\n\n if (pack.id === 'custom') {\n this.modePackDetail.setText(theme.fg('dim', \" You'll pick a model for each mode in the next steps.\"));\n } else {\n const detail = [\n ` ${chalk.hex(mastra.blue)('plan')} → ${theme.fg('text', pack.models.plan)}`,\n ` ${chalk.hex(mastra.purple)('build')} → ${theme.fg('text', pack.models.build)}`,\n ` ${chalk.hex(mastra.green)('fast')} → ${theme.fg('text', pack.models.fast)}`,\n ].join('\\n');\n this.modePackDetail.setText(detail);\n }\n this.tui.requestRender();\n }\n\n // ---------------------------------------------------------------------------\n // Custom pack flow — sequential model selection for each mode\n // ---------------------------------------------------------------------------\n\n private async promptCustomPackName(): Promise<string | null> {\n return new Promise(resolve => {\n const question = new AskQuestionInlineComponent(\n {\n question: 'Name this custom pack',\n formatResult: answer => `Custom pack: ${answer}`,\n onSubmit: answer => {\n this.activeInlineQuestion = undefined;\n const trimmed = answer.trim();\n resolve(trimmed.length > 0 ? trimmed : null);\n },\n onCancel: () => {\n this.activeInlineQuestion = undefined;\n resolve(null);\n },\n },\n this.tui,\n );\n\n this.activeInlineQuestion = question;\n this.stepBox.addChild(new Spacer(1));\n this.stepBox.addChild(question);\n this.tui.requestRender();\n });\n }\n\n private async runCustomPackFlow(): Promise<void> {\n // Clear the pack selector so it doesn't capture input while overlays are shown\n this.selectList = undefined;\n\n const packName = await this.promptCustomPackName();\n if (!packName) {\n const fallback = this.options.modePacks.find(p => p.id !== 'custom') ?? this.options.modePacks[0]!;\n this.selectedModePack = fallback;\n this.collapseStep(`Model pack → ${theme.bold(this.selectedModePack.name)} (cancelled custom)`);\n this.renderStep('omPack');\n this.tui.requestRender();\n return;\n }\n\n this.collapseStep(`Model pack → Custom (${packName})`);\n\n const modes: Array<{ id: 'plan' | 'build' | 'fast'; label: string; color: string }> = [\n { id: 'plan', label: 'plan', color: mastra.purple },\n { id: 'build', label: 'build', color: mastra.green },\n { id: 'fast', label: 'fast', color: mastra.orange },\n ];\n\n const models: Record<string, string> = { build: '', plan: '', fast: '' };\n\n for (const mode of modes) {\n const title = `Select model for ${mode.label} mode`;\n const modelId = await this.options.onSelectModel(title, mode.color);\n\n if (!modelId) {\n // User cancelled — fall back to first non-custom pack (or keep current)\n const fallback = this.options.modePacks.find(p => p.id !== 'custom') ?? this.options.modePacks[0]!;\n this.selectedModePack = fallback;\n this.collapseStep(`Model pack → ${theme.bold(this.selectedModePack.name)} (cancelled custom)`);\n this.renderStep('omPack');\n this.tui.requestRender();\n return;\n }\n\n models[mode.id] = modelId;\n }\n\n this.selectedModePack = {\n id: `custom:${packName}`,\n name: packName,\n description: 'Saved custom pack',\n models: { build: models.build!, plan: models.plan!, fast: models.fast! },\n };\n\n this.collapseStep(\n `Model pack → ${theme.bold(packName)} ` +\n `${chalk.hex(mastra.blue)('plan')} ${models.plan} ` +\n `${chalk.hex(mastra.purple)('build')} ${models.build} ` +\n `${chalk.hex(mastra.green)('fast')} ${models.fast}`,\n );\n this.renderStep('omPack');\n this.tui.requestRender();\n }\n\n // ---------------------------------------------------------------------------\n // Step: OM pack\n // ---------------------------------------------------------------------------\n\n private preferMatchingOmPack(providerId: string): void {\n if (this.options.previous?.omPackId) return;\n const matchingPack = this.options.omPacks.find(pack => pack.id === providerId);\n if (matchingPack) this.selectedOmPack = matchingPack;\n }\n\n private renderOmPack(): void {\n const omPacks = this.options.omPacks;\n\n // If no OM packs at all (unlikely — would mean zero supported providers),\n // skip to next step\n if (omPacks.length === 0) {\n this.renderStep('yolo');\n return;\n }\n\n const box = this.makeBox();\n box.addChild(new Text(theme.bold(theme.fg('accent', '🧠 Observational Memory')), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('text', 'Choose the model for observational memory:'), 0, 0));\n box.addChild(new Text(theme.fg('dim', 'https://mastra.ai/docs/memory/observational-memory'), 0, 0));\n box.addChild(new Spacer(1));\n\n const prevOmId = this.options.previous?.omPackId ?? null;\n const items: SelectItem[] = omPacks.map(p => ({\n value: p.id,\n label: ` ${p.name} ${theme.fg('dim', p.description)}${p.id === prevOmId ? theme.fg('dim', ' (current)') : ''}`,\n }));\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n\n // Pre-select the previous choice, or the pack matching the connected provider\n const selectedOmId = prevOmId ?? this.selectedOmPack?.id ?? null;\n const selectedOmIdx = selectedOmId ? omPacks.findIndex(p => p.id === selectedOmId) : -1;\n if (selectedOmIdx > 0) this.selectList.setSelectedIndex(selectedOmIdx);\n\n this.selectList.onSelect = (item: SelectItem) => {\n const pack = omPacks.find(p => p.id === item.value) ?? omPacks[0]!;\n if (pack.id === 'custom') {\n this.runCustomOmFlow();\n } else {\n this.selectedOmPack = pack;\n this.collapseStep(`Observational memory → ${theme.bold(this.selectedOmPack.name)}`);\n this.renderStep('yolo');\n }\n };\n this.selectList.onCancel = () => {\n this.collapseStep(`Observational memory → ${theme.bold(this.selectedOmPack.name)} (default)`);\n this.renderStep('yolo');\n };\n\n box.addChild(this.selectList);\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc use default'), 0, 0));\n }\n\n private async runCustomOmFlow(): Promise<void> {\n this.selectList = undefined;\n this.collapseStep(`Observational memory → ${theme.bold('Custom')}`);\n\n const modelId = await this.options.onSelectModel('Select model for observational memory');\n if (modelId) {\n this.selectedOmPack = { id: 'custom', name: 'Custom', description: 'User-selected model', modelId };\n this.collapseStep(`Observational memory → ${theme.bold('Custom')} ${modelId}`);\n } else {\n // Cancelled — fall back to first non-custom pack\n const fallback = this.options.omPacks.find(p => p.id !== 'custom');\n if (fallback) {\n this.selectedOmPack = fallback;\n this.collapseStep(`Observational memory → ${theme.bold(fallback.name)} (cancelled custom)`);\n } else {\n this.collapseStep(`Observational memory → ${theme.bold('Custom')} (cancelled)`);\n }\n }\n this.renderStep('yolo');\n this.tui.requestRender();\n }\n\n // ---------------------------------------------------------------------------\n // Step: YOLO mode\n // ---------------------------------------------------------------------------\n\n private renderYolo(): void {\n const box = this.makeBox();\n box.addChild(new Text(theme.bold(theme.fg('accent', '⚡ Tool Approval')), 0, 0));\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('text', 'YOLO mode auto-approves all tool calls (edits, commands, etc).'), 0, 0));\n box.addChild(new Text(theme.fg('text', 'You can toggle this anytime with Ctrl+Y or /yolo.'), 0, 0));\n box.addChild(new Spacer(1));\n\n const prevYolo = this.options.previous?.yolo ?? null;\n const currentOn = prevYolo === true ? theme.fg('dim', ' (current)') : '';\n const currentOff = prevYolo === false ? theme.fg('dim', ' (current)') : '';\n const items: SelectItem[] = [\n {\n value: 'on',\n label: ` ${theme.fg('success', 'Enable YOLO')} ${theme.fg('dim', '(recommended — auto-approve everything)')}${currentOn}`,\n },\n {\n value: 'off',\n label: ` ${theme.fg('warning', 'Disable YOLO')} ${theme.fg('dim', '(ask before each tool call)')}${currentOff}`,\n },\n ];\n\n this.selectList = new SelectList(items, items.length, getSelectListTheme());\n\n // Pre-select the previously chosen YOLO setting\n if (prevYolo === false) this.selectList.setSelectedIndex(1);\n this.selectList.onSelect = (item: SelectItem) => {\n this.selectedYolo = item.value === 'on';\n const label = this.selectedYolo ? 'enabled' : 'disabled';\n this.collapseStep(`YOLO mode → ${theme.bold(label)}`);\n this.renderStep('done');\n };\n this.selectList.onCancel = () => {\n this.collapseStep(`YOLO mode → ${theme.bold('enabled')} (default)`);\n this.renderStep('done');\n };\n\n box.addChild(this.selectList);\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('dim', '↑↓ navigate · Enter select · Esc use default'), 0, 0));\n }\n\n // ---------------------------------------------------------------------------\n // Step: Done\n // ---------------------------------------------------------------------------\n\n private renderDone(): void {\n this._finished = true;\n const box = this.makeBox();\n box.addChild(new Text(theme.bold(theme.fg('success', '✓ Setup complete!')), 0, 0));\n box.addChild(new Spacer(1));\n\n const lines = [\n `Model pack: ${theme.bold(this.selectedModePack.name)}`,\n ` ${chalk.hex(mastra.blue)('plan')} → ${this.selectedModePack.models.plan}`,\n ` ${chalk.hex(mastra.purple)('build')} → ${this.selectedModePack.models.build}`,\n ` ${chalk.hex(mastra.green)('fast')} → ${this.selectedModePack.models.fast}`,\n `Observational memory: ${theme.bold(this.selectedOmPack.name)}`,\n `YOLO mode: ${theme.bold(this.selectedYolo ? 'enabled' : 'disabled')}`,\n ];\n for (const line of lines) {\n box.addChild(new Text(theme.fg('text', line), 0, 0));\n }\n box.addChild(new Spacer(1));\n box.addChild(new Text(theme.fg('dim', 'Type a message to start coding, or use /help for commands.'), 0, 0));\n\n this.options.onComplete({\n modePack: this.selectedModePack,\n omPack: this.selectedOmPack,\n yolo: this.selectedYolo,\n loginRequested: this.loginRequested,\n loginProvider: this.loginProvider,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Collapse a completed step into a single summary line\n // ---------------------------------------------------------------------------\n\n private collapseStep(summary: string): void {\n if (!this.stepBox) return;\n this.stepBox.clear();\n this.stepBox.setBgFn((text: string) => theme.bg('overlayBg', text));\n this.stepBox.addChild(new Text(`${theme.fg('success', '✓')} ${theme.fg('text', summary)}`, 0, 0));\n this.selectList = undefined;\n this.activeInlineQuestion = undefined;\n }\n\n // ---------------------------------------------------------------------------\n // Input handling\n // ---------------------------------------------------------------------------\n\n handleInput(data: string): void {\n if (this._finished) return;\n\n if (this.activeInlineQuestion) {\n this.activeInlineQuestion.handleInput(data);\n return;\n }\n\n if (this.selectList) {\n this.selectList.handleInput(data);\n return;\n }\n }\n}\n","/**\n * ASCII art banner for the Mastra Code TUI header.\n * Renders \"MASTRA CODE\" or \"MASTRA\" in block-letter art with a green gradient.\n */\nimport chalk from 'chalk';\n\nimport { theme } from '../theme.js';\n\n// Mastra brand green gradient stops (left → right)\nconst GRADIENT_STOPS = ['#085314', '#0d8020', '#16c858', '#62f69d', '#a1fac7'];\n\n// Full \"MASTRA CODE\" banner (42 chars wide)\nconst FULL_ART = [\n '█▀▄▀█ ▄▀█ █▀ ▀█▀ █▀█ ▄▀█ █▀▀ █▀█ █▀▄ █▀▀',\n '█ ▀ █ █▀█ ▀█ █ █▀▄ █▀█ █ █ █ █ █ █▀▀',\n '▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀',\n];\n\n// Short \"MASTRA\" banner (24 chars wide)\nconst SHORT_ART = ['█▀▄▀█ ▄▀█ █▀ ▀█▀ █▀█ ▄▀█', '█ ▀ █ █▀█ ▀█ █ █▀▄ █▀█', '▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀ ▀'];\n\n/**\n * Interpolate between two hex colors.\n */\nfunction lerpColor(hex1: string, hex2: string, t: number): [number, number, number] {\n const r1 = parseInt(hex1.slice(1, 3), 16);\n const g1 = parseInt(hex1.slice(3, 5), 16);\n const b1 = parseInt(hex1.slice(5, 7), 16);\n const r2 = parseInt(hex2.slice(1, 3), 16);\n const g2 = parseInt(hex2.slice(3, 5), 16);\n const b2 = parseInt(hex2.slice(5, 7), 16);\n return [Math.round(r1 + (r2 - r1) * t), Math.round(g1 + (g2 - g1) * t), Math.round(b1 + (b2 - b1) * t)];\n}\n\n/**\n * Color a single character based on its horizontal position in the gradient.\n */\nfunction gradientChar(ch: string, colIdx: number, totalCols: number): string {\n if (ch === ' ') return ' ';\n const t = totalCols <= 1 ? 0.5 : colIdx / (totalCols - 1);\n const segmentCount = GRADIENT_STOPS.length - 1;\n const segment = Math.min(Math.floor(t * segmentCount), segmentCount - 1);\n const frac = t * segmentCount - segment;\n const [r, g, b] = lerpColor(GRADIENT_STOPS[segment]!, GRADIENT_STOPS[segment + 1]!, frac);\n return chalk.rgb(r, g, b)(ch);\n}\n\n/**\n * Apply left-to-right purple gradient to a line of text.\n */\nfunction colorLine(line: string): string {\n const chars = [...line];\n return chars.map((ch, i) => gradientChar(ch, i, chars.length)).join('');\n}\n\n/**\n * Render the banner header for the TUI.\n *\n * @param version - App version string (e.g. \"0.2.0\")\n * @param appName - App name. Block art is only used for \"Mastra Code\" (default).\n * @returns Styled multi-line string ready for display.\n */\nexport function renderBanner(version: string, appName?: string): string {\n const name = appName || 'Mastra Code';\n\n // Custom app names get the simple text format (no Mastra branding)\n if (name !== 'Mastra Code') {\n return theme.fg('accent', '◆') + ' ' + theme.bold(theme.fg('accent', name)) + theme.fg('dim', ` v${version}`);\n }\n\n const cols = process.stdout.columns || 80;\n\n // Narrow terminal — compact single line\n if (cols < 30) {\n return (\n theme.fg('accent', '◆') + ' ' + theme.bold(theme.fg('accent', 'Mastra Code')) + theme.fg('dim', ` v${version}`)\n );\n }\n\n // Select art based on available width\n const art = cols >= 50 ? FULL_ART : SHORT_ART;\n const coloredLines = art.map(line => colorLine(line));\n\n // Append version below the art\n coloredLines.push(theme.fg('dim', `v${version}`));\n\n return coloredLines.join('\\n');\n}\n","/**\n * Live work/idle-time indicator shown above the user input.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport type { TUIState } from '../state.js';\nimport { formatStatusDuration } from '../status-duration.js';\nimport { BOX_INDENT, theme } from '../theme.js';\n\nexport { formatStatusDuration } from '../status-duration.js';\n\nconst MINUTE_MS = 60_000;\n\nexport class IdleCounterComponent extends Container {\n private timingState?: Pick<TUIState, 'lastAgentRunDurationMs' | 'lastAgentRunEndedAt' | 'lastAgentRunEndReason'>;\n private textChild: Text;\n\n constructor() {\n super();\n this.textChild = new Text('', BOX_INDENT, 0);\n this.addChild(this.textChild);\n }\n\n setTimingState(\n timingState: Pick<TUIState, 'lastAgentRunDurationMs' | 'lastAgentRunEndedAt' | 'lastAgentRunEndReason'> | undefined,\n now = Date.now(),\n ): void {\n this.timingState = timingState;\n this.update(now);\n }\n\n update(now = Date.now()): void {\n const segments = this.timingState ? formatIdleStatusTimingSegments(this.timingState, now) : null;\n if (!segments) {\n this.textChild.setText('');\n return;\n }\n\n const idle = segments.idle ? theme.fg('dim', segments.idle) : '';\n this.textChild.setText(idle ? ` ${idle}` : '');\n }\n\n render(width: number): string[] {\n const rendered = super.render(width);\n return rendered.length > 0 ? rendered : [''];\n }\n}\n\ntype IdleStatusTimingState = Pick<TUIState, 'lastAgentRunDurationMs' | 'lastAgentRunEndedAt' | 'lastAgentRunEndReason'>;\n\nexport function formatIdleStatusTimingSegments(\n state: IdleStatusTimingState,\n now = Date.now(),\n): { summary: string; idle: string } | null {\n if (state.lastAgentRunEndedAt === undefined) {\n return null;\n }\n\n const idleMs = now - state.lastAgentRunEndedAt;\n const idle = idleMs >= MINUTE_MS ? `${formatStatusDuration(idleMs)} idle` : '';\n return idle ? { summary: '', idle } : null;\n}\n\nexport function formatIdleStatusTiming(state: IdleStatusTimingState, now = Date.now()): string {\n const segments = formatIdleStatusTimingSegments(state, now);\n if (!segments) return '';\n return segments.summary && segments.idle\n ? `${segments.summary} · ${segments.idle}`\n : segments.summary || segments.idle;\n}\n","/**\n * Simple progress indicator component for single operations.\n * Shows a compact progress display with spinner and status text.\n */\n\nimport { Container, Text } from '@earendil-works/pi-tui';\nimport { theme } from '../theme.js';\n\nexport interface SimpleProgressOptions {\n prefix?: string;\n showElapsed?: boolean;\n showPercentage?: boolean;\n}\n\n/**\n * Lightweight progress indicator for simple operations.\n * Features:\n * - Animated spinner\n * - Custom status text\n * - Optional elapsed time\n * - Optional percentage display\n */\nexport class SimpleProgressComponent extends Container {\n private status: string = '';\n private progress?: number;\n private startTime: number;\n private spinnerFrame = 0;\n private lastRenderTime = 0;\n private isActive = false;\n private options: Required<SimpleProgressOptions>;\n\n constructor(options: SimpleProgressOptions = {}) {\n super();\n this.options = {\n prefix: '',\n showElapsed: true,\n showPercentage: true,\n ...options,\n };\n this.startTime = Date.now();\n }\n\n /**\n * Start showing progress with initial status.\n */\n start(status: string): void {\n this.status = status;\n this.isActive = true;\n this.startTime = Date.now();\n this.rebuild();\n }\n\n /**\n * Update the status text.\n */\n updateStatus(status: string): void {\n this.status = status;\n this.rebuild();\n }\n\n /**\n * Update the progress percentage (0-100).\n */\n updateProgress(progress: number): void {\n this.progress = Math.min(100, Math.max(0, progress));\n this.rebuild();\n }\n\n /**\n * Mark the operation as complete.\n */\n complete(message?: string): void {\n this.isActive = false;\n this.status = message || 'Complete';\n this.progress = 100;\n this.rebuild();\n }\n\n /**\n * Mark the operation as failed.\n */\n fail(error: string): void {\n this.isActive = false;\n this.status = error;\n this.rebuild();\n }\n\n private rebuild(): void {\n this.clear();\n\n if (!this.status) return;\n\n const now = Date.now();\n\n // Update spinner animation\n if (this.isActive && now - this.lastRenderTime > 100) {\n this.spinnerFrame = (this.spinnerFrame + 1) % 10;\n this.lastRenderTime = now;\n }\n\n let text = '';\n\n // Add prefix if provided\n if (this.options.prefix) {\n text += this.options.prefix + ' ';\n }\n\n // Add spinner or status icon\n if (this.isActive) {\n const spinner = this.getSpinner();\n text += theme.fg('accent', spinner) + ' ';\n } else if (this.progress === 100) {\n text += theme.fg('success', '✓') + ' ';\n } else {\n text += theme.fg('error', '✗') + ' ';\n }\n\n // Add status text\n text += this.status;\n\n // Add progress percentage if enabled and available\n if (this.options.showPercentage && this.progress !== undefined) {\n text += theme.fg('dim', ` (${this.progress}%)`);\n }\n\n // Add elapsed time if enabled\n if (this.options.showElapsed && this.isActive) {\n const elapsed = Math.floor((now - this.startTime) / 1000);\n text += theme.fg('dim', ` ${elapsed}s`);\n }\n\n this.addChild(new Text(text, 0, 0));\n }\n private getSpinner(): string {\n const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n return frames[this.spinnerFrame]!;\n }\n\n render(maxWidth: number): string[] {\n this.rebuild();\n return super.render(maxWidth);\n }\n}\n\n/**\n * Create a temporary progress indicator that auto-hides when complete.\n * Useful for quick operations that need feedback.\n */\nexport class TemporaryProgressComponent extends SimpleProgressComponent {\n private hideTimeout?: NodeJS.Timeout;\n private hideDelay: number;\n\n constructor(options: SimpleProgressOptions & { hideDelay?: number } = {}) {\n super(options);\n this.hideDelay = options.hideDelay || 2000;\n }\n\n complete(message?: string): void {\n super.complete(message);\n this.hideTimeout = setTimeout(() => {\n this.clear();\n }, this.hideDelay);\n }\n\n fail(error: string): void {\n super.fail(error);\n this.hideTimeout = setTimeout(() => {\n this.clear();\n }, this.hideDelay * 2); // Show errors longer\n }\n\n override clear(): void {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n this.hideTimeout = undefined;\n }\n super.clear();\n }\n}\n","/**\n * TUI setup: keyboard shortcuts, layout building, autocomplete, key handlers.\n */\nimport { execFileSync } from 'node:child_process';\n\nimport { CombinedAutocompleteProvider, Spacer, Text } from '@earendil-works/pi-tui';\nimport type { SlashCommand } from '@earendil-works/pi-tui';\nimport { getUserId } from '@mastra/code-sdk/utils/project';\nimport { loadCustomCommands } from '@mastra/code-sdk/utils/slash-command-loader';\nimport { ThreadLockError } from '@mastra/code-sdk/utils/thread-lock';\nimport type { AgentControllerEventListener } from '@mastra/core/agent-controller';\nimport { isUserInvocable } from './commands/skill-filters.js';\nimport { renderBanner } from './components/banner.js';\nimport { IdleCounterComponent } from './components/idle-counter.js';\nimport { SimpleProgressComponent } from './components/simple-progress.js';\nimport { TaskProgressComponent } from './components/task-progress.js';\nimport { showError, showInfo } from './display.js';\nimport { isGoalJudgeInputLocked, showGoalJudgeInputLockInfo } from './goal-input-lock.js';\nimport { askModalQuestion } from './modal-question.js';\nimport { showModalOverlay } from './overlay.js';\nimport type { TUIState } from './state.js';\nimport { updateStatusLine } from './status-line.js';\nimport { theme } from './theme.js';\n\n// =============================================================================\n// Keyboard Shortcuts\n// =============================================================================\n\nexport function setupKeyboardShortcuts(\n state: TUIState,\n callbacks: {\n stop: () => void;\n doubleCtrlCMs: number;\n queueFollowUpMessage: (text: string) => void;\n },\n): void {\n // Ctrl+C / Escape - abort if running, clear input if idle, double-tap always exits\n state.editor.onAction('clear', () => {\n const now = Date.now();\n if (now - state.lastCtrlCTime < callbacks.doubleCtrlCMs) {\n // Double Ctrl+C → exit\n callbacks.stop();\n process.exit(0);\n }\n state.lastCtrlCTime = now;\n\n if (abortActiveGoalJudge(state)) {\n return;\n }\n\n if (state.pendingApprovalDismiss) {\n // Dismiss active approval dialogs by declining the gated tool. Do not abort\n // the run: the decline is delivered through the normal approval resume path.\n state.pendingApprovalDismiss();\n state.activeInlinePlanApproval = undefined;\n state.activeInlineQuestion = undefined;\n state.pendingInlineQuestions.length = 0;\n return;\n } else if (state.session.run.isRunning() || state.session.suspensions.hasPending()) {\n // Clean up active inline components on abort. suspensions.hasPending() covers\n // the case where the run is parked in a tool suspend() (e.g. ask_user) —\n // isRunning() is false there because the AbortController was nulled, but the\n // run is still pending and must be abortable.\n state.activeInlinePlanApproval = undefined;\n state.activeInlineQuestion = undefined;\n state.pendingInlineQuestions.length = 0;\n state.pendingAskUserComponents?.clear();\n state.userInitiatedAbort = true;\n state.hookManager?.runInterrupt('user_interrupt').catch(() => {});\n state.session.abort();\n } else {\n const current = state.editor.getText();\n if (current.length > 0) {\n state.lastClearedText = current;\n state.editor.setText('');\n }\n state.ui.requestRender();\n }\n });\n\n // Ctrl+Z - suspend process (SIGTSTP)\n state.editor.onAction('suspend', () => {\n if (process.platform === 'win32') {\n showInfo(state, 'Suspend is not supported on Windows');\n return;\n }\n\n state.ui.stop();\n const onContinue = () => {\n state.ui.start();\n state.ui.requestRender();\n };\n process.once('SIGCONT', onContinue);\n try {\n process.kill(process.pid, 'SIGTSTP');\n } catch {\n process.off('SIGCONT', onContinue);\n state.ui.start();\n state.ui.requestRender();\n showError(state, 'Unable to suspend in the current terminal');\n }\n });\n\n // Alt+Z - undo last clear (restore editor text)\n state.editor.onAction('undo', () => {\n if (state.lastClearedText && state.editor.getText().length === 0) {\n state.editor.setText(state.lastClearedText);\n state.lastClearedText = '';\n state.ui.requestRender();\n }\n });\n\n // Ctrl+D - exit when editor is empty\n state.editor.onCtrlD = () => {\n callbacks.stop();\n process.exit(0);\n };\n\n // Ctrl+T - toggle thinking blocks visibility\n state.editor.onAction('toggleThinking', () => {\n state.hideThinkingBlock = !state.hideThinkingBlock;\n state.ui.requestRender();\n });\n\n // Ctrl+E - expand/collapse tool outputs\n state.editor.onAction('expandTools', () => {\n state.toolOutputExpanded = !state.toolOutputExpanded;\n for (const tool of state.allToolComponents) {\n tool.setExpanded(state.toolOutputExpanded);\n }\n for (const sc of state.allSlashCommandComponents) {\n sc.setExpanded(state.toolOutputExpanded);\n }\n for (const reminder of state.allSystemReminderComponents) {\n reminder.setExpanded(state.toolOutputExpanded);\n }\n for (const shell of state.allShellComponents) {\n shell.setExpanded(state.toolOutputExpanded);\n }\n state.ui.requestRender();\n });\n\n // Shift+Tab - cycle controller modes\n state.editor.onAction('cycleMode', async () => {\n // Block mode switching while the agent is active or plan approval is pending\n if (state.session.run.isRunning()) {\n showInfo(state, 'Wait for the agent to finish first');\n return;\n }\n if (state.activeInlinePlanApproval) {\n showInfo(state, 'Resolve the plan approval first');\n return;\n }\n\n const modes = state.controller.listModes();\n if (modes.length <= 1) return;\n const currentId = state.session.mode.get();\n const currentIndex = modes.findIndex(m => m.id === currentId);\n const nextIndex = (currentIndex + 1) % modes.length;\n const nextMode = modes[nextIndex]!;\n await state.session.mode.switch({ modeId: nextMode.id });\n });\n\n // Ctrl+Y - toggle YOLO mode\n state.editor.onAction('toggleYolo', () => {\n const current = (state.session.state.get() as any)?.yolo === true;\n void state.session.state.set({ yolo: !current } as any);\n showInfo(state, current ? 'YOLO mode off' : 'YOLO mode on');\n });\n\n // Enter - submit immediately. The submit handler decides whether active input\n // should be sent as a signal or queued for cases signals cannot handle.\n state.editor.onAction('followUp', () => {\n if (isGoalJudgeInputLocked(state)) {\n showGoalJudgeInputLockInfo(state);\n state.ui.requestRender();\n return true;\n }\n\n state.editor.onSubmit?.(state.editor.getExpandedText());\n return true;\n });\n\n // Ctrl+F - explicitly queue a follow-up while a run is active. Enter now sends\n // normal messages as signals during active runs; this preserves manual FIFO\n // queueing for slash commands, image messages, and messages the user wants to\n // hold until the current run finishes.\n state.editor.onAction('queueFollowUp', () => {\n if (isGoalJudgeInputLocked(state)) {\n showGoalJudgeInputLockInfo(state);\n state.ui.requestRender();\n return true;\n }\n\n const text = state.editor.getExpandedText();\n if (!state.session.run.isRunning()) {\n state.editor.onSubmit?.(text);\n return true;\n }\n\n const trimmedText = text.trim();\n if (!trimmedText) {\n return true;\n }\n\n state.editor.addToHistory(text);\n state.editor.setText('');\n callbacks.queueFollowUpMessage(text);\n return true;\n });\n}\n\nfunction abortActiveGoalJudge(state: TUIState): boolean {\n const activeGoalJudge = state.activeGoalJudge;\n if (!activeGoalJudge) return false;\n\n state.userInitiatedAbort = true;\n state.hookManager?.runInterrupt('goal_judge_interrupt').catch(() => {});\n activeGoalJudge.abortController.abort();\n activeGoalJudge.component.setInterrupted();\n // Esc during an in-loop goal evaluation pauses the goal so it does not\n // continue on the next iteration. Abort the active controller run too: the core\n // scorer owns the judge stream, so the TUI-local controller alone only changes\n // the visual component and lets the judge continue in the background.\n state.session.abort();\n // Persist the paused state immediately so a thread switch or exit before the\n // next save does not reload the old active objective and effectively undo the\n // pause. `saveToThread` is best-effort, so run it fire-and-forget to keep this\n // abort handler synchronous.\n state.goalManager.pause('Judge evaluation was interrupted.');\n void state.goalManager.saveToThread(state);\n state.activeGoalJudge = undefined;\n state.ui.requestRender();\n return true;\n}\n\n// =============================================================================\n// Layout\n// =============================================================================\n\nexport function buildLayout(state: TUIState, refreshModelAuthStatus: () => Promise<void>): void {\n // Add header\n const appName = state.options.appName || 'Mastra Code';\n const version = state.options.version || '0.1.0';\n\n const banner = renderBanner(version, appName);\n\n // Project frontmatter\n const frontmatter = [\n `Project: ${state.projectInfo.name}`,\n `Resource ID: ${state.projectInfo.resourceId}`,\n state.projectInfo.gitBranch ? `Branch: ${state.projectInfo.gitBranch}` : null,\n state.projectInfo.isWorktree ? `Worktree of: ${state.projectInfo.mainRepoPath}` : null,\n `User: ${getUserId(state.projectInfo.rootPath)}`,\n ]\n .filter(Boolean)\n .map(line => theme.fg('muted', line as string))\n .join('\\n');\n\n const sep = theme.fg('dim', ' · ');\n const hintParts: string[] = [];\n if (state.controller.listModes().length > 1) {\n hintParts.push(`${theme.fg('accent', '⇧+Tab')} ${theme.fg('muted', 'cycle modes')}`);\n }\n hintParts.push(`${theme.fg('accent', '/help')} ${theme.fg('muted', 'info & shortcuts')}`);\n const instructions = ` ${hintParts.join(sep)}`;\n\n state.ui.addChild(new Spacer(1));\n state.ui.addChild(new Text(banner, 1, 0));\n state.ui.addChild(new Text(frontmatter, 1, 0));\n state.ui.addChild(new Spacer(1));\n state.ui.addChild(new Text(instructions, 0, 0));\n state.ui.addChild(new Spacer(1));\n\n // Add main containers\n state.ui.addChild(state.chatContainer);\n // Task progress (between chat and editor, visible only when tasks exist)\n state.taskProgress = new TaskProgressComponent();\n state.taskProgress.setQuietMode(state.quietMode);\n state.ui.addChild(state.taskProgress);\n state.ui.addChild(state.editorContainer);\n state.idleCounter = new IdleCounterComponent();\n state.editorContainer.addChild(state.idleCounter);\n state.editorContainer.addChild(state.editor);\n\n // Add footer with two-line status\n state.statusLine = new Text('', 0, 0);\n state.memoryStatusLine = new Text('', 0, 0);\n state.footer.addChild(state.statusLine);\n state.footer.addChild(state.memoryStatusLine);\n state.ui.addChild(state.footer);\n updateStatusLine(state);\n refreshModelAuthStatus();\n\n // Set focus to editor\n state.ui.setFocus(state.editor);\n}\n\n// =============================================================================\n// Autocomplete\n// =============================================================================\n\n/** Detect the fd binary (fast file finder) for @ fuzzy file autocomplete */\nfunction detectFdPath(): string | null {\n const whichCmd = process.platform === 'win32' ? 'where' : 'which';\n for (const bin of ['fd', 'fdfind']) {\n try {\n const resolved = execFileSync(whichCmd, [bin], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })\n .trim()\n .split(/\\r?\\n/)[0];\n if (resolved) return resolved;\n } catch {\n // not found, try next\n }\n }\n return null;\n}\n\nexport function setupAutocomplete(state: TUIState): void {\n const slashCommands: SlashCommand[] = [\n { name: 'new', description: 'Start a new thread' },\n { name: 'clone', description: 'Clone the current thread' },\n { name: 'thread', description: 'Show current thread info' },\n { name: 'threads', description: 'Switch between threads' },\n { name: 'models', description: 'Switch model pack' },\n { name: 'custom-providers', description: 'Manage custom providers and models' },\n { name: 'subagents', description: 'Configure subagent model defaults' },\n { name: 'memory', description: 'Configure Observational Memory' },\n { name: 'om', description: 'Alias for /memory' },\n { name: 'think', description: 'Set thinking (off|low|medium|high|xhigh|status)' },\n { name: 'login', description: 'Login with OAuth provider' },\n { name: 'skills', description: 'List available skills' },\n { name: 'skill/', description: 'Activate a skill by name' },\n { name: 'cost', description: 'Show token usage and estimated costs' },\n { name: 'diff', description: 'Show modified files or git diff' },\n { name: 'name', description: 'Rename current thread' },\n {\n name: 'resource',\n description: 'Show/switch resource ID (tag for sharing)',\n },\n { name: 'logout', description: 'Logout from OAuth provider' },\n { name: 'hooks', description: 'Show/reload configured hooks' },\n { name: 'mcp', description: 'Show/reload MCP server connections' },\n {\n name: 'thread:tag-dir',\n description: 'Tag current thread with this directory',\n },\n {\n name: 'sandbox',\n description: 'Manage allowed paths (add/remove directories)',\n },\n {\n name: 'permissions',\n description: 'View/manage tool approval permissions',\n },\n {\n name: 'settings',\n description: 'General settings (notifications, YOLO, thinking)',\n },\n {\n name: 'yolo',\n description: 'Toggle YOLO mode (auto-approve all tools)',\n },\n {\n name: 'voice',\n description: 'Manage push-to-talk voice input (engine, provider, model)',\n },\n { name: 'review', description: 'Review a GitHub pull request' },\n { name: 'report-issue', description: 'Open or browse mastracode issues' },\n { name: 'setup', description: 'Re-run the setup wizard' },\n { name: 'browser', description: 'Configure browser automation' },\n { name: 'theme', description: 'Switch color theme (auto/dark/light)' },\n { name: 'update', description: 'Check for and install updates' },\n { name: 'api-keys', description: 'Manage API keys for model providers' },\n { name: 'plugins', description: 'Manage Mastra Code plugins' },\n { name: 'observability', description: 'Configure cloud observability' },\n {\n name: 'github',\n description: 'Subscribe/sync/debug GitHub PR signals',\n getArgumentCompletions: (argumentPrefix: string) =>\n [\n { value: 'subscribe', label: 'subscribe', description: 'Subscribe this thread to a GitHub PR' },\n { value: 'unsubscribe', label: 'unsubscribe', description: 'Unsubscribe this thread from a GitHub PR' },\n { value: 'sync', label: 'sync', description: 'Immediately sync subscribed GitHub PRs' },\n { value: 'debug', label: 'debug', description: 'Show GitHub signal subscription debug info' },\n ].filter(command => command.value.startsWith(argumentPrefix.toLowerCase())),\n },\n {\n name: 'goal',\n description: 'Set/manage persistent goal (Ralph loop)',\n getArgumentCompletions: (argumentPrefix: string) =>\n [\n { value: 'status', label: 'status', description: 'Show current goal status' },\n { value: 'pause', label: 'pause', description: 'Pause the goal continuation loop' },\n { value: 'resume', label: 'resume', description: 'Resume the current goal' },\n { value: 'clear', label: 'clear', description: 'Clear the current goal' },\n { value: 'judge', label: 'judge', description: 'Set the goal judge model and max attempts' },\n ].filter(command => command.value.startsWith(argumentPrefix.toLowerCase())),\n },\n {\n name: 'prune',\n description: 'Prune old storage data (closes the TUI, shows progress)',\n getArgumentCompletions: (argumentPrefix: string) =>\n [\n { value: 'vacuum', label: 'vacuum', description: 'Prune, then VACUUM to reclaim disk space' },\n { value: 'keep-memory', label: 'keep-memory', description: 'Keep chat history (messages/threads)' },\n ].filter(command => command.value.startsWith(argumentPrefix.toLowerCase())),\n },\n { name: 'exit', description: 'Exit the TUI' },\n { name: 'help', description: 'Show available commands' },\n ];\n\n // Only show /mode if there's more than one mode\n const modes = state.controller.listModes();\n if (modes.length > 1) {\n slashCommands.push({ name: 'mode', description: 'Switch agent mode' });\n }\n\n // Add custom slash commands to the list with // prefixes so they remain\n // visually distinct from built-in slash commands in autocomplete.\n for (const customCmd of state.customSlashCommands) {\n slashCommands.push({\n name: `/${customCmd.name}`,\n description: customCmd.description || `Custom: ${customCmd.name}`,\n });\n if (customCmd.goal) {\n slashCommands.push({\n name: `goal/${customCmd.name}`,\n description: customCmd.description ? `Goal: ${customCmd.description}` : `Goal: ${customCmd.name}`,\n });\n }\n }\n\n for (const skill of state.skillCommands) {\n slashCommands.push({\n name: `skill/${skill.name}`,\n description: skill.description ? `Skill: ${skill.description}` : `Skill: ${skill.name}`,\n });\n }\n\n for (const skill of state.goalSkillCommands) {\n slashCommands.push({\n name: `goal/${skill.name}`,\n description: skill.description ? `Goal skill: ${skill.description}` : `Goal skill: ${skill.name}`,\n });\n }\n\n const fdPath = detectFdPath();\n state.autocompleteProvider = new CombinedAutocompleteProvider(slashCommands, process.cwd(), fdPath);\n state.editor.setAutocompleteProvider(state.autocompleteProvider);\n}\n\n// =============================================================================\n// Custom Slash Commands Loading\n// =============================================================================\n\nexport async function loadCustomSlashCommands(state: TUIState): Promise<void> {\n try {\n const sessionState = state.session.state.get() as { configDir?: string; pluginCommandPaths?: string[] } | undefined;\n const configDir = sessionState?.configDir;\n // Load from all sources (global and local)\n const globalCommands = await loadCustomCommands(undefined, configDir);\n const localCommands = await loadCustomCommands(process.cwd(), configDir, sessionState?.pluginCommandPaths ?? []);\n\n // Merge commands, with local taking precedence over global for same names\n const commandMap = new Map<string, (typeof globalCommands)[number]>();\n\n // Add global commands first\n for (const cmd of globalCommands) {\n commandMap.set(cmd.name, cmd);\n }\n\n // Add local commands (will override global if same name)\n for (const cmd of localCommands) {\n commandMap.set(cmd.name, cmd);\n }\n\n state.customSlashCommands = Array.from(commandMap.values());\n } catch {\n state.customSlashCommands = [];\n }\n // Skills load via `refreshSkillsAutocomplete` so this never blocks on workspace resolution.\n}\n\n/**\n * Populate `state.skillCommands` and `state.goalSkillCommands` from the\n * workspace. Safe to call before the workspace is resolved (returns empty\n * lists) and again later once it is (resolves and refreshes).\n */\nexport async function loadSkillCommands(state: TUIState): Promise<void> {\n try {\n let workspace = state.controller.getWorkspace() ?? state.workspace;\n if (!workspace && state.controller.hasWorkspace()) {\n workspace = await state.controller.resolveWorkspace({ session: state.session });\n }\n if (!workspace?.skills) {\n state.skillCommands = [];\n state.goalSkillCommands = [];\n return;\n }\n const skills = (await workspace.skills.list()).filter(isUserInvocable);\n state.skillCommands = skills;\n state.goalSkillCommands = skills.filter(skill => skill.metadata?.goal === true);\n } catch {\n state.skillCommands = [];\n state.goalSkillCommands = [];\n }\n}\n\n/** Reload skills and rebuild the autocomplete provider. */\nexport async function refreshSkillsAutocomplete(state: TUIState): Promise<void> {\n await loadSkillCommands(state);\n setupAutocomplete(state);\n}\n\n// =============================================================================\n// Key Handlers\n// =============================================================================\n\nexport function setupKeyHandlers(\n state: TUIState,\n callbacks: {\n stop: () => void;\n doubleCtrlCMs: number;\n },\n): () => void {\n // Handle Ctrl+C via process signal (backup for when editor doesn't capture it)\n const sigintHandler = () => {\n const now = Date.now();\n if (now - state.lastCtrlCTime < callbacks.doubleCtrlCMs) {\n callbacks.stop();\n process.exit(0);\n }\n state.lastCtrlCTime = now;\n if (abortActiveGoalJudge(state)) {\n return;\n }\n if (state.pendingApprovalDismiss) {\n state.pendingApprovalDismiss();\n state.activeInlinePlanApproval = undefined;\n state.activeInlineQuestion = undefined;\n state.pendingInlineQuestions.length = 0;\n return;\n }\n\n if (state.session.run.isRunning() || state.session.suspensions.hasPending()) {\n state.activeInlinePlanApproval = undefined;\n state.activeInlineQuestion = undefined;\n state.pendingInlineQuestions.length = 0;\n state.pendingAskUserComponents?.clear();\n state.userInitiatedAbort = true;\n state.hookManager?.runInterrupt('process_sigint').catch(() => {});\n state.session.abort();\n }\n };\n process.on('SIGINT', sigintHandler);\n\n // Use onDebug callback for Shift+Ctrl+D\n state.ui.onDebug = () => {\n // Toggle debug mode or show debug info\n // Currently unused - could add debug panel in future\n };\n\n return () => {\n process.off('SIGINT', sigintHandler);\n };\n}\n\n// =============================================================================\n// AgentController Subscription\n// =============================================================================\n\nexport function subscribeToAgentController(state: TUIState, handleEvent: (event: any) => Promise<void>): void {\n let eventQueue = Promise.resolve();\n const listener: AgentControllerEventListener = event => {\n eventQueue = eventQueue.then(async () => {\n try {\n await handleEvent(event);\n } catch (err) {\n // Log but don't crash — individual event errors shouldn't kill the process\n const msg = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n process.stderr.write(`[event error] ${event.type}: ${msg}\\n`);\n if (stack) process.stderr.write(stack + '\\n');\n }\n });\n return eventQueue;\n };\n state.unsubscribe = state.session.subscribe(listener);\n}\n\n// =============================================================================\n// Terminal Title\n// =============================================================================\n\nexport function updateTerminalTitle(state: TUIState): void {\n const appName = state.options.appName || 'Mastra Code';\n const cwd = process.cwd().split('/').pop() || '';\n state.ui.terminal.setTitle(`${appName} - ${cwd}`);\n}\n\n// =============================================================================\n// Thread Selection\n// =============================================================================\n\nexport async function promptForThreadSelection(state: TUIState): Promise<void> {\n const currentPath = state.projectInfo.rootPath;\n const currentResourceId = state.session.identity.getResourceId();\n\n const allThreads = await state.session.thread.list();\n const activeThreadId = state.session.thread.getId();\n\n // Filter to threads explicitly tagged for the current working directory.\n const taggedThreads = allThreads.filter(t => {\n const threadPath = t.metadata?.projectPath as string | undefined;\n return !!threadPath && threadPath === currentPath;\n });\n const threads: typeof taggedThreads = [];\n for (const thread of taggedThreads) {\n const isActiveBlankThread = thread.id === activeThreadId && !thread.title;\n if (isActiveBlankThread) {\n const messages = await state.session.thread.listMessages({ threadId: thread.id, limit: 1 });\n if (messages.length === 0) continue;\n }\n threads.push(thread);\n }\n\n if (threads.length === 0) {\n const driftCandidates = (\n await state.session.thread.list({\n allResources: true,\n metadata: { projectPath: currentPath },\n })\n ).filter(t => t.resourceId !== currentResourceId);\n const [thread] = [...driftCandidates].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n\n if (thread) {\n const answer = await askModalQuestion(state.ui, {\n question: [\n 'This directory is tagged on a different resource.',\n '',\n `Project: ${currentPath}`,\n `Thread: ${thread.title || thread.id}`,\n `Old resource: ${thread.resourceId}`,\n `Current resource: ${currentResourceId}`,\n '',\n 'Clone this thread into the current resource and resume the clone?',\n ].join('\\n'),\n options: [{ label: 'Clone and resume' }, { label: 'Start fresh' }],\n selectedOptionLabel: 'Clone and resume',\n allowCustomResponse: false,\n overlay: { widthPercent: 80, maxHeight: '70%' },\n });\n\n if (answer === 'Clone and resume') {\n const progress = new SimpleProgressComponent({ showElapsed: false, showPercentage: false });\n progress.start('Cloning thread into the current resource...');\n showModalOverlay(state.ui, progress, { widthPercent: 70, maxHeight: '40%', minHeightPercent: 0.35 });\n state.ui.requestRender();\n\n try {\n await new Promise(resolve => setTimeout(resolve, 50));\n progress.updateStatus('Loading cloned thread...');\n state.ui.requestRender();\n await state.session.thread.cloneToCurrentResource({\n threadId: thread.id,\n expectedResourceId: thread.resourceId,\n expectedProjectPath: currentPath,\n });\n } finally {\n state.ui.hideOverlay();\n state.ui.requestRender();\n }\n return;\n }\n }\n\n // No existing threads for this path - defer creation until first message\n state.pendingNewThread = true;\n return;\n }\n\n // Sort by most recent\n const sortedThreads = [...threads].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n\n // Try each in order until one is unlocked\n for (const thread of sortedThreads) {\n try {\n await state.session.thread.switch({ threadId: thread.id });\n if (!thread.metadata?.projectPath) {\n await state.session.thread.setSetting({ key: 'projectPath', value: currentPath });\n }\n return;\n } catch (error) {\n if (error instanceof ThreadLockError) {\n continue; // Try the next one\n }\n throw error;\n }\n }\n\n // All directory threads are locked — silently start a new thread\n state.pendingNewThread = true;\n}\n\n// =============================================================================\n// Existing Tasks\n// =============================================================================\n\nexport async function renderExistingTasks(state: TUIState): Promise<void> {\n try {\n const tasks = state.session.displayState.get().tasks;\n\n if (tasks.length > 0 && state.taskProgress) {\n state.taskProgress.updateTasks(tasks);\n state.ui.requestRender();\n }\n } catch {\n // Silently ignore task rendering errors\n }\n}\n","/**\n * Streaming shell output component for the shell passthrough (! command).\n * Shows a bordered box with live stdout/stderr and a status footer.\n */\n\nimport { Text } from '@earendil-works/pi-tui';\nimport { theme } from '../theme.js';\nimport { truncateAnsi } from './ansi.js';\nimport type { ChatSpacingKind } from './chat-spacing.js';\nimport { WidthAwareContainer } from './width-aware-container.js';\n\nconst MAX_LINES = 200;\nconst COLLAPSED_LINES = 20;\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const seconds = ms / 1000;\n return seconds < 60 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds / 60)}m${Math.floor(seconds % 60)}s`;\n}\n\nexport class ShellStreamComponent extends WidthAwareContainer {\n private command: string;\n private lines: string[] = [];\n private trailingPartial = '';\n private exitCode?: number;\n private startTime = Date.now();\n private expanded = false;\n\n constructor(command: string) {\n super();\n this.command = command;\n this.rebuild();\n }\n\n appendOutput(text: string): void {\n const combined = this.trailingPartial + text;\n const parts = combined.split('\\n');\n // Last element is either '' (if text ended with \\n) or an incomplete line\n this.trailingPartial = parts.pop()!;\n this.lines.push(...parts);\n if (this.lines.length > MAX_LINES) {\n this.lines = this.lines.slice(-MAX_LINES);\n }\n this.rebuild();\n }\n\n setExpanded(expanded: boolean): void {\n this.expanded = expanded;\n this.rebuild();\n }\n\n isExpanded(): boolean {\n return this.expanded;\n }\n\n finish(exitCode: number): void {\n // Flush any trailing partial line\n if (this.trailingPartial) {\n this.lines.push(this.trailingPartial);\n this.trailingPartial = '';\n if (this.lines.length > MAX_LINES) {\n this.lines = this.lines.slice(-MAX_LINES);\n }\n }\n this.exitCode = exitCode;\n this.rebuild();\n }\n\n protected rebuildForWidth(termWidth: number): void {\n this.clear();\n\n const border = (char: string) => theme.bold(theme.fg('accent', char));\n const maxLineWidth = termWidth - 6;\n\n const done = this.exitCode !== undefined;\n const statusIcon = done\n ? this.exitCode === 0\n ? theme.fg('success', ' ✓')\n : theme.fg('error', ' ✗')\n : theme.fg('muted', ' ⋯');\n\n const durationStr = done ? theme.fg('muted', ` ${formatDuration(Date.now() - this.startTime)}`) : '';\n const footerText = `${theme.bold(theme.fg('toolTitle', '$'))} ${theme.fg('accent', this.command)}${durationStr}${statusIcon}`;\n\n // Top border\n this.addChild(new Text(border('╭──'), 0, 0));\n\n // Output lines with left border\n const displayLines = [...this.lines];\n // Include trailing partial if still streaming\n if (this.trailingPartial && !done) {\n displayLines.push(this.trailingPartial);\n }\n // Remove leading empty lines\n while (displayLines.length > 0 && displayLines[0] === '') displayLines.shift();\n\n if (displayLines.length > 0) {\n const maxVisible = this.expanded ? MAX_LINES : COLLAPSED_LINES;\n const truncated = displayLines.length > maxVisible;\n const visibleLines = truncated ? displayLines.slice(-maxVisible) : displayLines;\n\n const borderedLines = visibleLines.map(line => {\n const truncatedLine = truncateAnsi(line, maxLineWidth);\n return border('│') + ' ' + truncatedLine;\n });\n\n if (truncated) {\n const remaining = displayLines.length - maxVisible;\n const action = this.expanded ? 'collapse' : 'expand';\n borderedLines.push(border('│') + ' ' + theme.fg('muted', `... ${remaining} more lines (Ctrl+E to ${action})`));\n }\n\n const displayOutput = borderedLines.join('\\n');\n if (displayOutput.trim()) {\n this.addChild(new Text(displayOutput, 0, 0));\n }\n }\n\n // Bottom border with command info\n this.addChild(new Text(`${border('╰──')} ${footerText}`, 0, 0));\n\n // Show exit code if non-zero\n if (done && this.exitCode !== 0) {\n this.addChild(new Text(theme.fg('error', ` Exit code: ${this.exitCode}`), 0, 0));\n }\n\n this.invalidate();\n }\n\n getChatSpacingKind(): ChatSpacingKind {\n return 'other';\n }\n}\n","export interface ShellPassthroughResult {\n exitCode?: number | null;\n failed?: boolean;\n stderr?: string;\n shortMessage?: string;\n message?: string;\n}\n\nexport interface ShellPassthroughCompletion {\n exitCode: number;\n diagnostic?: string;\n}\n\nfunction nonEmptyMessage(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nexport function resolveShellPassthroughCompletion(result: ShellPassthroughResult): ShellPassthroughCompletion {\n if (typeof result.exitCode === 'number') {\n return { exitCode: result.exitCode };\n }\n\n if (!result.failed) {\n return { exitCode: 0 };\n }\n\n return {\n exitCode: 1,\n diagnostic:\n nonEmptyMessage(result.shortMessage) ?? nonEmptyMessage(result.message) ?? nonEmptyMessage(result.stderr),\n };\n}\n","import type { ShellPassthroughSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { resolveShellPassthroughInvocation } from './shell-config.js';\n\nconst SHELL_COMMAND_TIMEOUT_MS = 30_000;\n\nexport async function createShellPassthroughSubprocess(\n command: string,\n settings: ShellPassthroughSettings,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform | string = process.platform,\n cwd: string = process.cwd(),\n) {\n const { execa } = await import('execa');\n const invocation = resolveShellPassthroughInvocation(command, settings, env, platform);\n const options = {\n cwd,\n reject: false,\n timeout: SHELL_COMMAND_TIMEOUT_MS,\n env: {\n ...env,\n FORCE_COLOR: '1',\n },\n };\n\n if (invocation.kind === 'default') {\n return {\n invocation,\n subprocess: execa(command, {\n ...options,\n shell: true,\n }),\n };\n }\n\n return {\n invocation,\n subprocess: execa(invocation.executable, invocation.args, {\n ...options,\n shell: false,\n ...(invocation.family === 'cmd' && platform === 'win32' ? { windowsVerbatimArguments: true } : {}),\n }),\n };\n}\n","/**\n * Shell passthrough: execute a shell command and display the output in the TUI.\n * Streams stdout/stderr in real-time using a bordered box that rebuilds on each chunk.\n */\nimport { loadSettings } from '@mastra/code-sdk/onboarding/settings';\nimport { insertChatComponentWithBoundarySpacing } from './chat-boundary-reconciliation.js';\nimport { ShellStreamComponent } from './components/shell-output.js';\nimport { showError, showInfo } from './display.js';\nimport { resolveShellPassthroughCompletion } from './shell-result.js';\nimport { createShellPassthroughSubprocess } from './shell-runner.js';\nimport type { TUIState } from './state.js';\n\nexport async function handleShellPassthrough(state: TUIState, command: string): Promise<void> {\n if (!command) {\n showInfo(state, 'Usage: !<command> (e.g., !ls -la)');\n return;\n }\n\n const component = new ShellStreamComponent(command);\n if (state.toolOutputExpanded) {\n component.setExpanded(true);\n }\n state.allShellComponents.push(component);\n insertChatComponentWithBoundarySpacing(state.chatContainer, component);\n state.ui.requestRender();\n\n try {\n const { invocation, subprocess } = await createShellPassthroughSubprocess(command, loadSettings().shellPassthrough);\n for (const warning of invocation.warnings) {\n showInfo(state, `Shell passthrough: ${warning}`);\n }\n\n // Stream stdout/stderr as it arrives\n if (subprocess.stdout) {\n subprocess.stdout.setEncoding('utf8');\n subprocess.stdout.on('data', (chunk: string) => {\n component.appendOutput(chunk);\n state.ui.requestRender();\n });\n }\n if (subprocess.stderr) {\n subprocess.stderr.setEncoding('utf8');\n subprocess.stderr.on('data', (chunk: string) => {\n component.appendOutput(chunk);\n state.ui.requestRender();\n });\n }\n\n // Wait for the process to complete\n const result = await subprocess;\n const completion = resolveShellPassthroughCompletion(result);\n if (completion.diagnostic) {\n component.appendOutput(`${completion.diagnostic}\\n`);\n }\n\n component.finish(completion.exitCode);\n state.ui.requestRender();\n } catch (error) {\n component.finish(1);\n state.ui.requestRender();\n showError(state, error instanceof Error ? error.message : 'Shell command failed');\n }\n}\n","/**\n * Main TUI class for Mastra Code.\n * Wires the AgentController to pi-tui components for a full interactive experience.\n */\nimport { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport type { Component } from '@earendil-works/pi-tui';\nimport { getOAuthProviders } from '@mastra/code-sdk/auth/storage';\nimport {\n getAvailableModePacks,\n getAvailableOmPacks,\n selectPreferredOMPack,\n ONBOARDING_VERSION,\n loadSettings,\n saveSettings,\n} from '@mastra/code-sdk/onboarding/index';\nimport type { ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/index';\nimport {\n resolveThreadActiveModelPackId,\n THREAD_ACTIVE_MODEL_PACK_ID_KEY,\n MASTRA_GATEWAY_PROVIDER,\n} from '@mastra/code-sdk/onboarding/settings';\nimport type { LoadedPlugin } from '@mastra/code-sdk/plugins/types';\nimport {\n detectPackageManager,\n fetchChangelog,\n fetchLatestVersion,\n isNewerVersion,\n performUpdate,\n} from '@mastra/code-sdk/utils/update-check';\nimport type { AgentSignalAttributes } from '@mastra/core/agent';\nimport type { AgentControllerEvent, MastraDBMessage } from '@mastra/core/agent-controller';\nimport type { Workspace } from '@mastra/core/workspace';\nimport { insertChatComponentWithBoundarySpacing } from './chat-boundary-reconciliation.js';\nimport { dispatchSlashCommand } from './command-dispatch.js';\nimport { startGoalWithDefaults } from './commands/goal.js';\n\nimport type { SlashCommandContext } from './commands/types.js';\nimport { AskQuestionInlineComponent } from './components/ask-question-inline.js';\nimport { LoginDialogComponent } from './components/login-dialog.js';\nimport { promptAuthMode } from './components/login-mode-selector.js';\nimport { ModelSelectorComponent } from './components/model-selector.js';\nimport type { ModelItem } from './components/model-selector.js';\nimport { GradientAnimator } from './components/obi-loader.js';\nimport type { IToolExecutionComponent } from './components/tool-execution-interface.js';\nimport { showError, showInfo, showFormattedError, notify } from './display.js';\nimport { dispatchEvent } from './event-dispatch.js';\nimport { isGoalJudgeInputLocked, showGoalJudgeInputLockInfo } from './goal-input-lock.js';\nimport type { EventHandlerContext } from './handlers/types.js';\nimport { askModalQuestion } from './modal-question.js';\nimport { applyOMModelToSession, seedOMDefaultAfterLogin } from './om-defaults.js';\nimport type { OnboardingResult } from './onboarding-inline.js';\nimport { OnboardingInlineComponent } from './onboarding-inline.js';\nimport { showModalOverlay } from './overlay.js';\nimport { promptForApiKeyIfNeeded } from './prompt-api-key.js';\n\nimport {\n addPendingUserMessage,\n addUserMessage,\n removePendingUserMessage,\n renderClearedTasksInline,\n renderCompletedTasksInline,\n renderExistingMessages,\n renderTaskDeltaInline,\n} from './render-messages.js';\nimport { flushRender, requestRender } from './render-scheduler.js';\nimport {\n setupKeyboardShortcuts,\n buildLayout,\n setupAutocomplete,\n loadCustomSlashCommands,\n refreshSkillsAutocomplete,\n setupKeyHandlers,\n subscribeToAgentController,\n updateTerminalTitle,\n promptForThreadSelection,\n renderExistingTasks,\n} from './setup.js';\nimport { handleShellPassthrough } from './shell.js';\nimport type { MastraTUIOptions, TUIState } from './state.js';\nimport { createTUIState, getGithubPrSubscriptionsFromMetadata } from './state.js';\nimport { updateStatusLine } from './status-line.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type { MastraTUIOptions } from './state.js';\n\n// =============================================================================\n// MastraTUI Class\n// =============================================================================\n\n/**\n * Delivery option attributes applied to user-message signals. When the signal is delivered to an\n * active run it is tagged as while-active; when it starts a new run it is a message.\n * The LLM sees these as XML attributes on the `<user-message>` element.\n */\ntype GithubPollingChangedHandler = (event: { threadId: string; resourceId: string; running: boolean }) => void;\ntype GithubSignalsWithPollingEvents = { onPollingChanged?: (handler: GithubPollingChangedHandler) => void };\n\nconst USER_SIGNAL_DELIVERY_OPTIONS: {\n ifActive: { attributes: AgentSignalAttributes };\n ifIdle: { attributes: AgentSignalAttributes };\n} = {\n ifActive: { attributes: { delivery: 'while-active' } },\n ifIdle: { attributes: { delivery: 'message' } },\n};\n\nconst USER_MESSAGE_APPROVAL_INTERRUPT = {\n reason: 'interrupted_by_user_message',\n message: 'The pending tool approval was declined because the user sent a new message.',\n};\n\n/** How often to recheck for updates during a long-running session (ms). */\nconst UPDATE_RECHECK_INTERVAL_MS = 45 * 60 * 1_000; // 45 minutes\nconst IMAGE_PLACEHOLDER_PATTERN = /\\[image\\]\\s*/g;\nconst CAFFEINATE_ARGS = ['-i', '-m'];\n\nexport async function syncInitialThreadState(state: TUIState): Promise<void> {\n const initThreadId = state.session.thread.getId();\n if (!initThreadId) return;\n\n const initThreads = await state.session.thread.list();\n const initThread = initThreads.find(t => t.id === initThreadId);\n if (initThread?.title) {\n state.currentThreadTitle = initThread.title;\n }\n const metadata = initThread?.metadata as Record<string, unknown> | undefined;\n state.activeGithubPrSubscriptions = getGithubPrSubscriptionsFromMetadata(metadata);\n // Prefer the durable ThreadState objective; fall back to the legacy\n // thread-metadata goal for threads created before the migration.\n await state.goalManager.loadFromThread(state);\n if (!state.goalManager.getGoal()) {\n state.goalManager.loadFromThreadMetadata(metadata);\n }\n}\n\nfunction shouldUseCaffeinate(): boolean {\n return process.platform === 'darwin' && process.env.MASTRACODE_DISABLE_CAFFEINATE !== '1';\n}\n\nexport function consumePendingImages(\n text: string,\n pendingImages: TUIState['pendingImages'],\n): { content: string; images?: TUIState['pendingImages'] } {\n const imageMarkerCount = text.match(/\\[image\\]/g)?.length ?? 0;\n const images = imageMarkerCount > 0 ? pendingImages.slice(0, imageMarkerCount) : undefined;\n\n return {\n content: text.replace(IMAGE_PLACEHOLDER_PATTERN, '').trim(),\n images: images && images.length > 0 ? images : undefined,\n };\n}\n\nexport class MastraTUI {\n private state: TUIState;\n private updateCheckTimer: ReturnType<typeof setInterval> | null = null;\n private statusTimingTimer: ReturnType<typeof setInterval> | null = null;\n private hasShownUpdateBanner = false;\n private caffeinateProcess: ChildProcess | null = null;\n private cleanupKeyHandlers?: () => void;\n private cleanupPluginReloadListener?: () => void;\n private cleanupPluginUpdateListener?: () => void;\n private lastStreamError: string | null = null;\n\n private static readonly DOUBLE_CTRL_C_MS = 500;\n\n constructor(options: MastraTUIOptions) {\n this.state = createTUIState(options);\n\n options.githubSignals?.onSubscriptionsChanged(event => {\n const currentThreadId = this.state.session?.thread?.getId?.();\n const currentResourceId = this.state.session?.identity?.getResourceId?.();\n if (event.threadId !== currentThreadId || (currentResourceId && event.resourceId !== currentResourceId)) return;\n this.state.activeGithubPrSubscriptions = event.subscriptions.map(subscription => ({\n owner: subscription.owner,\n repo: subscription.repo,\n prNumber: subscription.number,\n lastSyncStatus: subscription.lastSyncStatus,\n lastNotificationKind: subscription.lastNotificationKind,\n lastNotificationPriority: subscription.lastNotificationPriority,\n }));\n updateStatusLine(this.state);\n flushRender(this.state);\n });\n\n (options.githubSignals as GithubSignalsWithPollingEvents | undefined)?.onPollingChanged?.(event => {\n const currentThreadId = this.state.session?.thread?.getId?.();\n const currentResourceId = this.state.session?.identity?.getResourceId?.();\n if (event.threadId !== currentThreadId || (currentResourceId && event.resourceId !== currentResourceId)) return;\n if (!this.state.githubPrGradientAnimator) {\n this.state.githubPrGradientAnimator = new GradientAnimator(() => {\n updateStatusLine(this.state);\n requestRender(this.state);\n });\n }\n this.state.githubPrPollingActive = event.running;\n if (event.running) this.state.githubPrGradientAnimator.start();\n else this.state.githubPrGradientAnimator.stop();\n updateStatusLine(this.state);\n flushRender(this.state);\n });\n\n // Load user preferences\n const savedSettings = loadSettings();\n this.state.quietMode = savedSettings.preferences.quietMode;\n this.state.quietModeMaxToolPreviewLines = savedSettings.preferences.quietModeMaxToolPreviewLines;\n\n // Override editor input handling to check for active inline components\n const originalHandleInput = this.state.editor.handleInput.bind(this.state.editor);\n this.state.editor.handleInput = (data: string) => {\n // If there's an active plan approval, route input to it. Ctrl+C still\n // aborts: in raw mode the terminal delivers it as \\x03 to the editor (the\n // process SIGINT never fires), so the inline component would otherwise\n // swallow it and leave the suspended submit_plan run parked. Fall through\n // to the editor's Ctrl+C handler (which clears inline state and aborts).\n if (this.state.activeInlinePlanApproval) {\n if (data !== '\\x03') {\n this.state.activeInlinePlanApproval.handleInput(data);\n return;\n }\n }\n // If there's an active inline question, route input to it (same Ctrl+C\n // pass-through as plan approval above).\n else if (this.state.activeInlineQuestion) {\n if (data !== '\\x03') {\n this.state.activeInlineQuestion.handleInput(data);\n return;\n }\n }\n // If onboarding is active, route input there\n if (this.state.activeOnboarding) {\n // Ctrl+C during onboarding — cancel it\n if (data === '\\x03') {\n this.state.activeOnboarding.cancel();\n this.state.activeOnboarding = undefined;\n // Fall through to let the editor's 'clear' action fire\n } else {\n this.state.activeOnboarding.handleInput(data);\n return;\n }\n }\n // Otherwise, handle normally\n originalHandleInput(data);\n };\n\n // Wire clipboard image paste\n this.state.editor.onImagePaste = image => {\n this.state.pendingImages.push(image);\n this.state.editor.insertTextAtCursor?.('[image] ');\n flushRender(this.state);\n };\n this.state.editor.getPromptAnimator = () => this.state.gradientAnimator;\n\n setupKeyboardShortcuts(this.state, {\n stop: () => this.stop(),\n doubleCtrlCMs: MastraTUI.DOUBLE_CTRL_C_MS,\n queueFollowUpMessage: text => this.queueFollowUpMessage(text),\n });\n }\n\n // ===========================================================================\n // Public API\n // ===========================================================================\n\n /**\n * Run the TUI. This is the main entry point.\n */\n async run(): Promise<void> {\n await this.init();\n\n // Run SessionStart hooks (fire and forget)\n const hookMgr = this.state.hookManager;\n if (hookMgr) {\n hookMgr.runSessionStart().catch(() => {});\n }\n\n // Process initial message if provided (e.g. piped stdin content).\n // Runs the same validation as interactive input: model check, prompt hooks.\n if (this.state.options.initialMessage) {\n const msg = this.state.options.initialMessage;\n\n if (!this.state.session.model.hasSelection()) {\n showInfo(this.state, 'No model selected. Use /models to select a model, or /login to authenticate.');\n } else {\n const messageId = `user-${Date.now()}`;\n addUserMessage(this.state, {\n id: messageId,\n role: 'user',\n content: { format: 2, parts: [{ type: 'text', text: msg }] },\n createdAt: new Date(),\n });\n flushRender(this.state);\n\n const allowed = await this.runUserPromptHook(msg);\n if (!allowed) {\n const comp = this.state.messageComponentsById.get(messageId);\n if (comp) {\n this.state.chatContainer.removeChild(comp as never);\n this.state.messageComponentsById.delete(messageId);\n flushRender(this.state);\n }\n } else {\n try {\n if (this.state.pendingNewThread) {\n await this.state.session.thread.create();\n this.state.pendingNewThread = false;\n }\n this.fireMessage(msg);\n } catch (error) {\n this.state.pendingNewThread = false;\n showError(this.state, error instanceof Error ? error.message : 'Failed to start thread');\n }\n }\n }\n }\n\n // Main interactive loop — never blocks on streaming,\n // so the editor stays responsive for queued follow-ups.\n while (true) {\n const userInput = await this.getUserInput();\n // allow space as transparent continue (for recovering from api errors manually)\n if (!userInput.trim() && userInput !== ' ') continue;\n\n try {\n const pendingNewThread = this.state.pendingNewThread;\n\n // Handle slash commands\n if (userInput.startsWith('/')) {\n const handled = await this.handleSlashCommand(userInput);\n if (handled) continue;\n }\n\n // Handle shell passthrough (! prefix)\n if (userInput.startsWith('!')) {\n await handleShellPassthrough(this.state, userInput.slice(1).trim());\n continue;\n }\n\n // Check if a model is selected (sync — fast, no reason to defer)\n if (!this.state.session.model.hasSelection()) {\n showInfo(this.state, 'No model selected. Use /models to select a model, or /login to authenticate.');\n continue;\n }\n\n const { content, images } = consumePendingImages(userInput, this.state.pendingImages);\n this.state.pendingImages = [];\n\n const optimisticMessageId = this.renderOptimisticUserMessage(content, images);\n const allowed = await this.runUserPromptHook(userInput);\n if (!allowed) {\n this.removeOptimisticUserMessage(optimisticMessageId);\n continue;\n }\n\n this.sendOptimisticSignal(content, images, optimisticMessageId, pendingNewThread);\n } catch (error) {\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n }\n }\n }\n\n /**\n * Fire off a message without blocking the main loop.\n * Errors are handled via controller events.\n */\n private fireMessage(content: string, images?: Array<{ data: string; mimeType: string }>): void {\n this.clearStatusTimingTicker();\n const files = images?.map(img => ({ data: img.data, mediaType: img.mimeType }));\n this.state.session.sendMessage({ content, files }).catch(error => {\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n });\n }\n\n private createUserSignalMessage(\n content: string,\n images?: Array<{ data: string; mimeType: string }>,\n id = '',\n ): MastraDBMessage {\n return {\n id,\n role: 'user',\n content: {\n format: 2,\n parts: [\n { type: 'text', text: content },\n ...(images?.map(img => ({ type: 'file' as const, data: img.data, mimeType: img.mimeType })) ?? []),\n ],\n },\n createdAt: new Date(),\n };\n }\n\n private createUserSignalContent(content: string, images?: Array<{ data: string; mimeType: string }>) {\n return images?.length\n ? [\n { type: 'text' as const, text: content },\n ...images.map(img => ({ type: 'file' as const, data: img.data, mediaType: img.mimeType })),\n ]\n : content;\n }\n\n private renderOptimisticUserMessage(content: string, images?: Array<{ data: string; mimeType: string }>): string {\n const messageId = `user-${Date.now()}`;\n const isInterjection = this.state.session.stream.isActive();\n addUserMessage(this.state, this.createUserSignalMessage(content, images, messageId), {\n ...(isInterjection ? { label: 'steer' } : {}),\n });\n flushRender(this.state);\n return messageId;\n }\n\n private removeOptimisticUserMessage(messageId: string): void {\n const component = this.state.messageComponentsById.get(messageId);\n if (!component) return;\n this.state.chatContainer.removeChild(component as never);\n this.state.messageComponentsById.delete(messageId);\n flushRender(this.state);\n }\n\n private remapOptimisticUserMessage(optimisticMessageId: string, signalId: string): void {\n if (optimisticMessageId === signalId) return;\n const component = this.state.messageComponentsById.get(optimisticMessageId);\n if (!component) return;\n this.state.messageComponentsById.delete(optimisticMessageId);\n this.state.messageComponentsById.set(signalId, component);\n }\n\n private createPendingNewThread(): Promise<void> | undefined {\n if (!this.state.pendingNewThread) return undefined;\n this.state.pendingNewThread = false;\n return this.state.session.thread.create().then(() => undefined);\n }\n\n private sendOptimisticSignal(\n content: string,\n images: Array<{ data: string; mimeType: string }> | undefined,\n optimisticMessageId: string,\n pendingNewThread: boolean,\n ): void {\n const send = () => {\n this.clearStatusTimingTicker();\n this.state.analytics?.capture('mastracode_prompt_submitted', {\n threadId: this.state.session.thread.getId(),\n resourceId: this.state.session.identity.getResourceId(),\n mode: this.state.session.mode.get(),\n hasImages: Boolean(images?.length),\n isFirstPromptInThread: pendingNewThread,\n pendingNewThread,\n });\n\n const signal = this.state.session.sendSignal({\n content: this.createUserSignalContent(content, images),\n ...USER_SIGNAL_DELIVERY_OPTIONS,\n });\n this.remapOptimisticUserMessage(optimisticMessageId, signal.id);\n signal.accepted.catch((error: unknown) => {\n this.removeOptimisticUserMessage(signal.id);\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n });\n };\n\n const pendingThread = this.createPendingNewThread();\n if (!pendingThread) {\n send();\n return;\n }\n\n pendingThread.then(send).catch((error: unknown) => {\n this.removeOptimisticUserMessage(optimisticMessageId);\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n });\n }\n\n private signalMessage(content: string, images?: Array<{ data: string; mimeType: string }>): void {\n const hasActiveRun = this.state.session.stream.isActive();\n\n const send = () => {\n this.clearStatusTimingTicker();\n if (hasActiveRun) {\n this.state.pendingApprovalDismiss?.(USER_MESSAGE_APPROVAL_INTERRUPT);\n }\n\n const signal = this.state.session.sendSignal({\n content: this.createUserSignalContent(content, images),\n ...USER_SIGNAL_DELIVERY_OPTIONS,\n });\n\n if (hasActiveRun) {\n addPendingUserMessage(this.state, signal.id, content, images, { isInterjection: true });\n } else {\n addUserMessage(this.state, this.createUserSignalMessage(content, images, signal.id));\n }\n\n signal.accepted.catch((error: unknown) => {\n if (hasActiveRun) {\n removePendingUserMessage(this.state, signal.id);\n } else {\n this.removeOptimisticUserMessage(signal.id);\n }\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n });\n };\n\n const pendingThread = this.createPendingNewThread();\n if (!pendingThread) {\n send();\n return;\n }\n\n pendingThread.then(send).catch((error: unknown) => {\n showError(this.state, error instanceof Error ? error.message : 'Unknown error');\n });\n }\n\n private queueFollowUpMessage(text: string): void {\n if (text.startsWith('/')) {\n const messageId = `queued-slash-${Date.now()}-${this.state.pendingSlashCommands.length}`;\n this.state.pendingSlashCommands.push(text);\n this.state.pendingSlashCommandMessageIds.push(messageId);\n this.state.pendingQueuedActions.push('slash');\n addPendingUserMessage(this.state, messageId, text);\n updateStatusLine(this.state);\n return;\n }\n\n const { content, images } = consumePendingImages(text, this.state.pendingImages);\n this.state.pendingImages = [];\n\n this.state.pendingFollowUpMessages.push({ content, images });\n this.state.pendingQueuedActions.push('message');\n updateStatusLine(this.state);\n flushRender(this.state);\n }\n\n /**\n * Stop the TUI and clean up.\n */\n stop(): void {\n this.stopCaffeinate();\n\n // Run SessionEnd hooks (best-effort, don't await)\n const hookMgr = this.state.hookManager;\n if (hookMgr) {\n hookMgr.runSessionEnd().catch(() => {});\n }\n\n if (this.updateCheckTimer) {\n clearInterval(this.updateCheckTimer);\n this.updateCheckTimer = null;\n }\n\n this.clearStatusTimingTicker();\n\n if (this.cleanupKeyHandlers) {\n this.cleanupKeyHandlers();\n this.cleanupKeyHandlers = undefined;\n }\n\n if (this.cleanupPluginReloadListener) {\n this.cleanupPluginReloadListener();\n this.cleanupPluginReloadListener = undefined;\n }\n\n if (this.cleanupPluginUpdateListener) {\n this.cleanupPluginUpdateListener();\n this.cleanupPluginUpdateListener = undefined;\n }\n\n if (this.state.unsubscribe) {\n this.state.unsubscribe();\n }\n this.state.renderScheduler?.dispose();\n this.state.ui.stop();\n }\n\n private async refreshPluginRuntimeState(plugins: LoadedPlugin[]): Promise<void> {\n const activePlugins = plugins.filter(plugin => plugin.status === 'active');\n this.state.session.state.set({\n pluginSkillPaths: activePlugins.flatMap(plugin => plugin.skillPaths ?? []),\n pluginCommandPaths: activePlugins.flatMap(plugin => plugin.commandPaths ?? []),\n pluginInstructions: activePlugins.flatMap(plugin => (plugin.instructions ? [plugin.instructions] : [])),\n });\n await loadCustomSlashCommands(this.state);\n await refreshSkillsAutocomplete(this.state);\n }\n\n // ===========================================================================\n // Initialization\n // ===========================================================================\n\n private async init(): Promise<void> {\n if (this.state.isInitialized) return;\n\n // Initialize controller (but don't select thread yet)\n await this.state.controller.init();\n await this.state.controller.getMastra()?.startWorkers();\n\n if (this.state.pluginManager && !this.cleanupPluginReloadListener) {\n this.cleanupPluginReloadListener = this.state.pluginManager.onReload(plugins =>\n this.refreshPluginRuntimeState(plugins).catch(err => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[plugin runtime refresh] ${msg}\\n`);\n }),\n );\n }\n\n if (this.state.pluginManager && !this.cleanupPluginUpdateListener) {\n this.cleanupPluginUpdateListener = this.state.pluginManager.onGithubPluginsUpdated(pluginNames => {\n if (pluginNames.length === 0) return;\n const label = pluginNames.length === 1 ? 'Plugin' : 'Plugins';\n showInfo(this.state, `${label} updated to the latest version: ${pluginNames.join(', ')}`);\n });\n }\n\n // Load custom slash commands\n await loadCustomSlashCommands(this.state);\n\n // Install autocomplete immediately; refresh once the workspace resolves.\n setupAutocomplete(this.state);\n refreshSkillsAutocomplete(this.state).catch(err => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[skill autocomplete refresh] ${msg}\\n`);\n });\n\n // Build UI layout\n buildLayout(this.state, () => this.refreshModelAuthStatus());\n\n // Setup key handlers\n this.cleanupKeyHandlers = setupKeyHandlers(this.state, {\n stop: () => this.stop(),\n doubleCtrlCMs: MastraTUI.DOUBLE_CTRL_C_MS,\n });\n\n // Start the UI before thread selection so resource-drift prompts can render.\n this.state.ui.start();\n\n // Check for existing threads and prompt for resume\n await promptForThreadSelection(this.state);\n\n // Subscribe to controller events\n subscribeToAgentController(this.state, event => this.handleEvent(event));\n // Restore escape-as-cancel setting from persisted state\n const escState = this.state.session.state.get() as any;\n if (escState?.escapeAsCancel === false) {\n this.state.editor.escapeEnabled = false;\n }\n\n // Load OM progress now that we're subscribed (the event during\n // thread selection fired before we were listening).\n // This emits om_status → display_state_changed → updateStatusLine.\n await this.state.controller.loadOMProgress(this.state.session);\n\n // Sync current thread metadata — the thread_changed event from\n // promptForThreadSelection fired before we subscribed above.\n await syncInitialThreadState(this.state);\n\n this.state.isInitialized = true;\n\n // Start MCP connections now that the TUI owns the terminal.\n if (this.state.mcpManager?.hasServers()) {\n this.state.mcpManager\n .initInBackground()\n .then(result => {\n for (const s of result.failed) {\n if (s.needsAuth) {\n showInfo(this.state, `MCP: \\u26a0 \"${s.name}\" needs authentication \\u2192 run /mcp to authenticate`);\n } else {\n showInfo(this.state, `MCP: Failed to connect to \"${s.name}\": ${s.error}`);\n }\n }\n for (const s of result.skipped) {\n showInfo(this.state, `MCP: Skipped \"${s.name}\": ${s.reason}`);\n }\n })\n .catch(error => {\n showInfo(this.state, `MCP: Initialization failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n }\n\n // Set terminal title\n updateTerminalTitle(this.state);\n // Render existing messages\n await this.renderExistingMessagesAndSeedIdleCounter();\n // Render existing tasks if any\n await renderExistingTasks(this.state);\n\n if (this.shouldShowOnboarding()) {\n await this.showOnboarding();\n }\n\n await this.showQuietModePreferencePromptIfNeeded();\n\n // Check for updates after first render so network latency never blocks startup.\n void this.checkForUpdate().catch(() => {});\n\n // Periodically recheck for updates during long-running sessions (passive only)\n this.updateCheckTimer = setInterval(() => {\n void this.checkForUpdate(/* passive */ true);\n }, UPDATE_RECHECK_INTERVAL_MS);\n }\n\n private async refreshModelAuthStatus(): Promise<void> {\n this.state.modelAuthStatus = await this.state.controller.getCurrentModelAuthStatus(this.state.session);\n updateStatusLine(this.state);\n }\n\n private updateIdleStatusLine(now = Date.now()): void {\n this.state.idleCounter?.setTimingState(this.state, now);\n requestRender(this.state);\n }\n\n private updateActiveStatusTiming(now = Date.now()): void {\n this.state.idleCounter?.setTimingState(this.state, now);\n updateStatusLine(this.state);\n requestRender(this.state);\n }\n\n private startActiveStatusTimingTicker(): void {\n this.clearStatusTimingTicker();\n this.updateActiveStatusTiming();\n this.statusTimingTimer = setInterval(() => {\n if (this.state.agentRunStartedAt === undefined) {\n this.clearStatusTimingTicker(false);\n return;\n }\n this.updateActiveStatusTiming();\n }, 1_000);\n }\n\n private startIdleStatusTimingTicker(): void {\n this.clearStatusTimingTicker();\n this.updateIdleStatusLine();\n this.statusTimingTimer = setInterval(() => {\n this.updateIdleStatusLine();\n }, 60_000);\n }\n\n private async renderExistingMessagesAndSeedIdleCounter(): Promise<void> {\n await renderExistingMessages(this.state);\n\n if (this.state.session.run.isRunning()) {\n this.clearStatusTimingTicker();\n return;\n }\n\n if (this.state.lastRenderedMessageAt === undefined) {\n this.clearStatusTimingTicker();\n return;\n }\n\n this.state.lastAgentRunEndedAt = this.state.lastRenderedMessageAt;\n this.startIdleStatusTimingTicker();\n }\n\n private clearStatusTimingTicker(clearDisplay = true): void {\n if (this.statusTimingTimer) {\n clearInterval(this.statusTimingTimer);\n this.statusTimingTimer = null;\n }\n if (clearDisplay) {\n this.state.idleCounter?.setTimingState(undefined);\n requestRender(this.state);\n }\n }\n\n // ===========================================================================\n // Event Handling\n // ===========================================================================\n\n /** Cached event context – built once, reused for every event. */\n private _ectx: EventHandlerContext | undefined;\n\n private getEventContext(): EventHandlerContext {\n if (!this._ectx) {\n this._ectx = this.buildEventContext();\n }\n return this._ectx;\n }\n\n private async handleEvent(event: AgentControllerEvent): Promise<void> {\n if (event.type === 'agent_start') {\n this.clearStatusTimingTicker();\n this.startCaffeinate();\n this.lastStreamError = null;\n this.beginLifecycleRun();\n }\n\n if (event.type === 'error' && 'error' in event && !event.retryable) {\n // Only capture errors that look like stream/agent failures, not OM or tool errors\n const msg = event.error?.message || String(event.error);\n const isOmError = /observational memory/i.test(msg);\n if (!isOmError) {\n this.lastStreamError = msg;\n }\n }\n\n try {\n this.fireLifecycleHooksForEvent(event);\n await dispatchEvent(event, this.getEventContext(), this.state);\n this.captureAgentControllerAnalytics(event);\n\n if (event.type === 'thread_created') {\n await this.syncThreadActivePackMetadata(event.thread);\n } else if (event.type === 'thread_changed') {\n await this.syncThreadActivePackMetadata();\n }\n\n if (event.type === 'agent_start' && this.state.agentRunStartedAt !== undefined) {\n this.startActiveStatusTimingTicker();\n }\n\n if (event.type === 'agent_end') {\n const stopReason = event.reason === 'aborted' ? 'aborted' : event.reason === 'error' ? 'error' : 'complete';\n this.startIdleStatusTimingTicker();\n await this.runAgentEndHook(event.reason ?? 'complete');\n await this.runStopHook(stopReason);\n\n if (event.reason === 'error' && this.lastStreamError) {\n this.emitErrorFeedback(this.lastStreamError);\n this.lastStreamError = null;\n }\n }\n } finally {\n if (event.type === 'agent_end') {\n this.stopCaffeinate();\n this.endLifecycleRun();\n }\n }\n }\n\n private captureAgentControllerAnalytics(event: AgentControllerEvent): void {\n const analytics = this.state.analytics;\n if (!analytics) {\n return;\n }\n\n if (event.type === 'thread_created') {\n analytics.capture('mastracode_thread_changed', {\n action: 'created',\n threadId: event.thread.id,\n resourceId: event.thread.resourceId,\n mode: this.state.session.mode.get(),\n hasTitle: Boolean(event.thread.title),\n });\n return;\n }\n\n if (event.type === 'thread_changed') {\n analytics.capture('mastracode_thread_changed', {\n action: 'switched',\n threadId: event.threadId,\n previousThreadId: event.previousThreadId,\n resourceId: this.state.session.identity.getResourceId(),\n mode: this.state.session.mode.get(),\n });\n return;\n }\n\n if (event.type === 'model_changed') {\n analytics.capture('mastracode_model_changed', {\n modelId: event.modelId,\n scope: event.scope,\n mode: event.modeId ?? this.state.session.mode.get(),\n threadId: this.state.session.thread.getId(),\n resourceId: this.state.session.identity.getResourceId(),\n });\n }\n }\n\n private emitErrorFeedback(errorMessage: string): void {\n const controller = this.state.controller;\n const traceId = this.state.session.run.getTraceId() ?? undefined;\n const runId = this.state.session.getCurrentRunId() ?? undefined;\n const threadId = this.state.session.thread.getId() ?? undefined;\n\n if (!traceId && !runId && !threadId) return;\n\n const mastra = controller.getMastra();\n const observability = mastra?.observability;\n if (!observability?.addFeedback) return;\n\n const comment = errorMessage.length > 500 ? errorMessage.slice(0, 500) + '…' : errorMessage;\n\n observability\n .addFeedback({\n traceId,\n correlationContext: { traceId, runId },\n feedback: {\n feedbackType: 'thumbs',\n feedbackSource: 'mastracode',\n feedbackUserId: 'system',\n value: 0,\n comment: `Stream error: ${comment}`,\n metadata: {\n ...(threadId ? { threadId } : {}),\n ...(runId ? { runId } : {}),\n autoGenerated: true,\n },\n },\n })\n .catch(() => {\n // Fire-and-forget — don't let feedback failures affect the TUI\n });\n }\n\n private startCaffeinate(): void {\n if (!shouldUseCaffeinate() || this.caffeinateProcess) {\n return;\n }\n\n try {\n const child = spawn('caffeinate', CAFFEINATE_ARGS, {\n stdio: 'ignore',\n });\n\n child.once('error', () => {\n if (this.caffeinateProcess === child) {\n this.caffeinateProcess = null;\n }\n });\n\n child.once('exit', () => {\n if (this.caffeinateProcess === child) {\n this.caffeinateProcess = null;\n }\n });\n\n this.caffeinateProcess = child;\n } catch {\n this.caffeinateProcess = null;\n }\n }\n\n private stopCaffeinate(): void {\n const child = this.caffeinateProcess;\n if (!child) {\n return;\n }\n\n this.caffeinateProcess = null;\n child.kill();\n }\n\n private async buildProviderAccess(): Promise<ProviderAccess> {\n const models = await this.state.controller.listAvailableModels();\n const hasEnv = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (storageProviderId: string): ProviderAccessLevel => {\n const cred = this.state.authStorage?.get(storageProviderId);\n if (cred?.type === 'oauth') return 'oauth';\n if (cred?.type === 'api_key' && cred.key.trim().length > 0) return 'apikey';\n return false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai-codex'),\n cerebras: hasEnv('cerebras') ? ('apikey' as const) : false,\n google: hasEnv('google') ? ('apikey' as const) : false,\n deepseek: hasEnv('deepseek') ? ('apikey' as const) : false,\n 'github-copilot': accessLevel('github-copilot'),\n };\n // Gateway covers all providers\n const mgKey =\n this.state.authStorage?.getStoredApiKey(MASTRA_GATEWAY_PROVIDER) ?? process.env['MASTRA_GATEWAY_API_KEY'];\n if (mgKey) {\n if (!access.anthropic) access.anthropic = 'apikey';\n if (!access.openai) access.openai = 'apikey';\n }\n // Include all other providers that have API keys configured\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider) && m.hasApiKey) {\n access[m.provider] = 'apikey';\n seen.add(m.provider);\n }\n }\n return access;\n }\n\n private async syncThreadActivePackMetadata(thread?: {\n id: string;\n metadata?: Record<string, unknown>;\n }): Promise<void> {\n const settings = loadSettings();\n const currentThreadId = this.state.session.thread.getId();\n if (!currentThreadId) return;\n\n const resolvedThread =\n thread?.id === currentThreadId\n ? thread\n : (await this.state.session.thread.list()).find(t => t.id === currentThreadId);\n const access = await this.buildProviderAccess();\n const packs = getAvailableModePacks(access, settings.customModelPacks).filter(p => p.id !== 'custom');\n const resolvedPackId = resolveThreadActiveModelPackId(\n settings,\n packs,\n resolvedThread?.metadata as Record<string, unknown> | undefined,\n );\n\n if (resolvedPackId && settings.models.activeModelPackId !== resolvedPackId) {\n // Re-read settings to avoid overwriting concurrent changes\n const fresh = loadSettings();\n if (fresh.models.activeModelPackId !== resolvedPackId) {\n fresh.models.activeModelPackId = resolvedPackId;\n saveSettings(fresh);\n }\n }\n }\n\n private showHookWarnings(event: string, warnings: string[]): void {\n for (const warning of warnings) {\n showInfo(this.state, `[${event}] ${warning}`);\n }\n }\n\n private beginLifecycleRun(): void {\n const hookMgr = this.state.hookManager;\n if (!hookMgr) return;\n const runId = randomUUID();\n hookMgr.setRunId(runId);\n hookMgr.runAgentStart().catch(() => {});\n }\n\n private fireLifecycleHooksForEvent(event: AgentControllerEvent): void {\n const hookMgr = this.state.hookManager;\n if (!hookMgr) return;\n switch (event.type) {\n case 'tool_approval_required':\n hookMgr.runPermissionRequest('tool_approval', event.toolCallId, event.toolName, event.args).catch(() => {});\n break;\n case 'tool_suspended': {\n const payload = (event.suspendPayload ?? {}) as Record<string, unknown>;\n if (event.toolName === 'request_access' || payload.kind === 'sandbox_access_request') {\n hookMgr.runPermissionRequest('sandbox_access', event.toolCallId, event.toolName, payload).catch(() => {});\n } else if (event.toolName === 'submit_plan') {\n hookMgr.runPermissionRequest('plan_approval', event.toolCallId, event.toolName, payload).catch(() => {});\n }\n break;\n }\n case 'subagent_start':\n hookMgr\n .runSubagentStart(event.toolCallId, event.agentType, event.task, event.modelId, event.forked)\n .catch(() => {});\n break;\n case 'subagent_end':\n hookMgr\n .runSubagentEnd(event.toolCallId, event.agentType, event.result, event.isError, event.durationMs)\n .catch(() => {});\n break;\n }\n }\n\n private async runAgentEndHook(reason: 'complete' | 'aborted' | 'error' | 'suspended'): Promise<void> {\n const hookMgr = this.state.hookManager;\n if (!hookMgr) return;\n try {\n const result = await hookMgr.runAgentEnd(reason);\n this.showHookWarnings('AgentEnd', result.warnings);\n } catch (error) {\n showError(this.state, `AgentEnd hook failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n private endLifecycleRun(): void {\n const hookMgr = this.state.hookManager;\n hookMgr?.clearRunId();\n }\n\n private async runStopHook(stopReason: 'complete' | 'aborted' | 'error'): Promise<void> {\n const hookMgr = this.state.hookManager;\n if (!hookMgr) return;\n\n try {\n const result = await hookMgr.runStop(undefined, stopReason);\n this.showHookWarnings('Stop', result.warnings);\n if (!result.allowed && result.blockReason) {\n showError(this.state, `Stop hook blocked: ${result.blockReason}`);\n }\n } catch (error) {\n showError(this.state, `Stop hook failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n private async runUserPromptHook(userInput: string): Promise<boolean> {\n const hookMgr = this.state.hookManager;\n if (!hookMgr) return true;\n\n try {\n const result = await hookMgr.runUserPromptSubmit(userInput);\n this.showHookWarnings('UserPromptSubmit', result.warnings);\n\n if (!result.allowed) {\n showError(this.state, result.blockReason || 'Blocked by UserPromptSubmit hook');\n return false;\n }\n\n return true;\n } catch (error) {\n showError(this.state, `UserPromptSubmit hook failed: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n // ===========================================================================\n /**\n * Insert a child into the chat container before any follow-up user messages.\n * If no follow-ups are pending, appends to end.\n */\n private addChildBeforeFollowUps(child: Component): void {\n const firstPinned = [\n ...this.state.followUpComponents,\n ...this.state.pendingSignalMessageComponentsById.values(),\n ].find(pinned =>\n this.state.chatContainer.children.includes(('component' in pinned ? pinned.component : pinned) as any),\n );\n\n if (firstPinned) {\n const component = 'component' in firstPinned ? firstPinned.component : firstPinned;\n const idx = this.state.chatContainer.children.indexOf(component as any);\n if (idx >= 0) {\n insertChatComponentWithBoundarySpacing(this.state.chatContainer, child, idx);\n return;\n }\n }\n insertChatComponentWithBoundarySpacing(this.state.chatContainer, child);\n }\n\n // ===========================================================================\n // User Input\n // ===========================================================================\n\n private getUserInput(): Promise<string> {\n return new Promise(resolve => {\n this.state.editor.onSubmit = (text: string) => {\n if (isGoalJudgeInputLocked(this.state)) {\n this.state.editor.setText(text);\n showGoalJudgeInputLockInfo(this.state);\n flushRender(this.state);\n return;\n }\n\n // Add to history for arrow up/down navigation (skip empty)\n if (text.trim()) {\n this.state.editor.addToHistory(text);\n }\n this.state.editor.setText('');\n\n if (this.state.session.run.isRunning()) {\n if (text.startsWith('/')) {\n // Run slash commands immediately — they are either settings\n // commands (no agent interaction) or agent-facing commands the\n // user explicitly chose to run mid-stream. Use Ctrl+F to\n // queue instead.\n this.handleSlashCommand(text).catch(error => {\n showError(this.state, error instanceof Error ? error.message : 'Slash command failed');\n });\n return;\n }\n\n if (text.startsWith('!')) {\n // Shell passthrough runs locally and never touches the agent, so\n // run it immediately instead of steering the active run with it.\n void handleShellPassthrough(this.state, text.slice(1).trim());\n return;\n }\n\n const { content, images } = consumePendingImages(text, this.state.pendingImages);\n this.state.pendingImages = [];\n if (images?.length) {\n this.state.pendingImages = images;\n this.queueFollowUpMessage(text);\n return;\n }\n\n this.signalMessage(content);\n return;\n }\n\n resolve(text);\n };\n });\n }\n\n /**\n * Get the workspace, preferring controller-owned workspace over the direct option.\n */\n private getResolvedWorkspace(): Workspace | undefined {\n return this.state.controller.getWorkspace() ?? this.state.workspace;\n }\n\n // ===========================================================================\n // Observational Memory Settings\n // ===========================================================================\n\n // ===========================================================================\n // Login Selector\n // ===========================================================================\n\n // ===========================================================================\n // Slash Commands\n // ===========================================================================\n\n private buildCommandContext(): SlashCommandContext {\n return {\n state: this.state,\n controller: this.state.controller,\n session: this.state.session,\n hookManager: this.state.hookManager,\n mcpManager: this.state.mcpManager,\n pluginManager: this.state.pluginManager,\n analytics: this.state.analytics,\n authStorage: this.state.authStorage,\n customSlashCommands: this.state.customSlashCommands,\n showInfo: msg => showInfo(this.state, msg),\n showError: msg => showError(this.state, msg),\n updateStatusLine: () => updateStatusLine(this.state),\n stop: () => this.stop(),\n getResolvedWorkspace: () => this.getResolvedWorkspace(),\n addUserMessage: msg => addUserMessage(this.state, msg),\n renderExistingMessages: () => this.renderExistingMessagesAndSeedIdleCounter(),\n showOnboarding: () => this.showOnboarding(),\n };\n }\n\n private buildEventContext(): EventHandlerContext {\n return {\n state: this.state,\n showInfo: msg => showInfo(this.state, msg),\n showError: msg => showError(this.state, msg),\n showFormattedError: event => showFormattedError(this.state, event),\n updateStatusLine: () => updateStatusLine(this.state),\n notify: (reason, message) => notify(this.state, reason, message),\n analytics: this.state.analytics,\n handleSlashCommand: input => this.handleSlashCommand(input),\n addUserMessage: msg => addUserMessage(this.state, msg),\n addChildBeforeFollowUps: child => this.addChildBeforeFollowUps(child),\n fireMessage: (content, images) => this.fireMessage(content, images),\n startGoal: (objective, cancelMessage, options) =>\n startGoalWithDefaults(this.buildCommandContext(), objective, cancelMessage, options),\n queueFollowUpMessage: content => this.queueFollowUpMessage(content),\n renderExistingMessages: () => this.renderExistingMessagesAndSeedIdleCounter(),\n renderClearedTasksInline: (clearedTasks, insertIndex) =>\n renderClearedTasksInline(this.state, clearedTasks, insertIndex),\n renderCompletedTasksInline: (completedTasks, insertIndex) =>\n renderCompletedTasksInline(this.state, completedTasks, insertIndex),\n renderTaskDeltaInline: (previousTasks, nextTasks, insertIndex) =>\n renderTaskDeltaInline(this.state, previousTasks, nextTasks, insertIndex),\n refreshModelAuthStatus: () => this.refreshModelAuthStatus(),\n };\n }\n\n private async handleSlashCommand(input: string): Promise<boolean> {\n return dispatchSlashCommand(input, this.state, () => this.buildCommandContext());\n }\n\n // ===========================================================================\n // Login (used by onboarding)\n // ===========================================================================\n\n async performLogin(providerId: string): Promise<void> {\n const provider = getOAuthProviders().find(p => p.id === providerId);\n const providerName = provider?.name || providerId;\n\n if (!this.state.authStorage) {\n showError(this.state, 'Auth storage not configured');\n return;\n }\n\n const authMode = await promptAuthMode(this.state.ui, providerName, provider?.authModes);\n if (authMode === null) {\n // User cancelled at the mode-selection step.\n return;\n }\n\n return new Promise(resolve => {\n const dialog = new LoginDialogComponent(this.state.ui, providerId, (success, message) => {\n this.state.ui.hideOverlay();\n if (success) {\n showInfo(this.state, `Successfully logged in to ${providerName}`);\n } else if (message) {\n showInfo(this.state, message);\n }\n resolve();\n });\n\n showModalOverlay(this.state.ui, dialog, { widthPercent: 0.8, maxHeight: '60%' });\n dialog.focused = true;\n\n this.state\n .authStorage!.login(providerId, {\n onAuth: (info: { url: string; instructions?: string }) => {\n dialog.showAuth(info.url, info.instructions);\n },\n onPrompt: async (prompt: { message: string; placeholder?: string }) => {\n return dialog.showPrompt(prompt.message, prompt.placeholder);\n },\n onProgress: (message: string) => {\n dialog.showProgress(message);\n },\n signal: dialog.signal,\n authMode,\n })\n .then(async () => {\n this.state.ui.hideOverlay();\n\n const { PROVIDER_DEFAULT_MODELS } = await import('@mastra/code-sdk/auth/storage');\n const defaultModel = PROVIDER_DEFAULT_MODELS[providerId as keyof typeof PROVIDER_DEFAULT_MODELS];\n if (defaultModel) {\n await this.state.session.model.switch({ modelId: defaultModel });\n showInfo(this.state, `Logged in to ${providerName} - switched to ${defaultModel}`);\n } else {\n showInfo(this.state, `Successfully logged in to ${providerName}`);\n }\n await seedOMDefaultAfterLogin(this.state, providerId, message => showInfo(this.state, message));\n\n resolve();\n })\n .catch((error: Error) => {\n this.state.ui.hideOverlay();\n if (error.message !== 'Login cancelled') {\n showError(this.state, `Failed to login: ${error.message}`);\n }\n resolve();\n });\n });\n }\n\n // ===========================================================================\n // Onboarding\n // ===========================================================================\n\n async showOnboarding(): Promise<void> {\n const allProviders = getOAuthProviders();\n const authProviders = allProviders.map(p => ({\n label: p.name,\n value: p.id,\n loggedIn: this.state.authStorage?.isLoggedIn(p.id) ?? false,\n }));\n\n const access = await this.buildProviderAccess();\n const hasProviderAccess = Object.values(access).some(Boolean);\n\n const savedSettings = loadSettings();\n const modePacks = getAvailableModePacks(access, savedSettings.customModelPacks);\n const omPacks = getAvailableOmPacks(access);\n const preferredOmPack = selectPreferredOMPack(access, savedSettings.models.activeModelPackId ?? undefined);\n\n let prevModePackId = savedSettings.onboarding.modePackId;\n if (prevModePackId === 'custom' && savedSettings.models.activeModelPackId?.startsWith('custom:')) {\n prevModePackId = savedSettings.models.activeModelPackId;\n }\n const previous = savedSettings.onboarding.completedAt\n ? {\n modePackId: prevModePackId,\n omPackId: savedSettings.onboarding.omPackId,\n yolo: savedSettings.preferences.yolo,\n }\n : undefined;\n\n return new Promise<void>(resolve => {\n const component = new OnboardingInlineComponent({\n tui: this.state.ui,\n authProviders,\n modePacks,\n omPacks,\n preferredOmPackId: preferredOmPack?.id,\n hasProviderAccess,\n previous,\n onComplete: async (result: OnboardingResult) => {\n this.state.activeOnboarding = undefined;\n this.state.ui.hideOverlay();\n await this.applyOnboardingResult(result);\n resolve();\n },\n onCancel: () => {\n this.state.activeOnboarding = undefined;\n this.state.ui.hideOverlay();\n const settings = loadSettings();\n if (!settings.onboarding.completedAt) {\n settings.onboarding.skippedAt = new Date().toISOString();\n settings.onboarding.version = ONBOARDING_VERSION;\n saveSettings(settings);\n }\n resolve();\n },\n onLogin: (providerId: string, done: () => void) => {\n this.performLogin(providerId).then(async () => {\n try {\n const updatedAccess = await this.buildProviderAccess();\n const updatedHasAccess = Object.values(updatedAccess).some(Boolean);\n component.updateModePacks(getAvailableModePacks(updatedAccess, savedSettings.customModelPacks));\n const updatedOmPacks = getAvailableOmPacks(updatedAccess);\n const preferred = selectPreferredOMPack(updatedAccess, providerId);\n component.updateOmPacks(updatedOmPacks, preferred?.id);\n component.updateHasProviderAccess(updatedHasAccess);\n } catch (err) {\n console.error('Failed to refresh provider access after login:', err);\n } finally {\n done();\n }\n });\n },\n onSelectModel: async (title: string, modeColor?: string): Promise<string | undefined> => {\n const availableModels = await this.state.controller.listAvailableModels();\n if (availableModels.length === 0) return undefined;\n\n return new Promise<string | undefined>(resolveModel => {\n const selector = new ModelSelectorComponent({\n tui: this.state.ui,\n models: availableModels,\n currentModelId: undefined,\n title,\n titleColor: modeColor,\n onSelect: async (model: ModelItem) => {\n this.state.ui.hideOverlay();\n await promptForApiKeyIfNeeded(this.state.ui, model, this.state.authStorage);\n resolveModel(model.id);\n },\n onCancel: () => {\n this.state.ui.hideOverlay();\n resolveModel(undefined);\n },\n });\n\n showModalOverlay(this.state.ui, selector, { maxHeight: '75%' });\n selector.focused = true;\n });\n },\n });\n\n this.state.activeOnboarding = component;\n showModalOverlay(this.state.ui, component, { maxHeight: '80%' });\n component.focused = true;\n });\n }\n\n private async applyOnboardingResult(result: OnboardingResult): Promise<void> {\n const controller = this.state.controller;\n const modePack = result.modePack;\n const modes = controller.listModes();\n\n for (const mode of modes) {\n const modelId = (modePack.models as Record<string, string>)[mode.id];\n if (modelId) {\n (mode as any).defaultModelId = modelId;\n await this.state.session.thread.setSetting({\n key: `modeModelId_${mode.id}`,\n value: modelId,\n });\n }\n }\n\n const currentModeId = this.state.session.mode.get();\n const currentModeModel = (modePack.models as Record<string, string>)[currentModeId];\n if (currentModeModel) {\n await this.state.session.model.switch({ modelId: currentModeModel });\n }\n\n const subagentModeMap: Record<string, string> = { explore: 'fast', plan: 'plan', execute: 'build' };\n for (const [agentType, modeId] of Object.entries(subagentModeMap)) {\n const saModelId = (modePack.models as Record<string, string>)[modeId];\n if (saModelId) {\n await this.state.session.subagents.model.set({ modelId: saModelId, agentType });\n }\n }\n\n // With no reachable provider the OM step only offers an empty custom pack;\n // recording that non-choice would block every later provider-aware seed.\n const omPack = result.omPack.modelId ? result.omPack : undefined;\n if (omPack) await applyOMModelToSession(this.state, omPack.modelId);\n await this.state.session.state.set({ yolo: result.yolo });\n\n const settings = loadSettings();\n settings.onboarding.completedAt = new Date().toISOString();\n settings.onboarding.skippedAt = null;\n settings.onboarding.version = ONBOARDING_VERSION;\n settings.onboarding.omPackId = omPack?.id ?? null;\n\n const modeDefaults: Record<string, string> = {};\n for (const mode of modes) {\n const modelId = (modePack.models as Record<string, string>)[mode.id];\n if (modelId) modeDefaults[mode.id] = modelId;\n }\n\n let activeModePackId = modePack.id;\n if (modePack.id === 'custom' || modePack.id.startsWith('custom:')) {\n const customName =\n modePack.id === 'custom' ? modePack.name?.trim() || 'Custom' : modePack.id.slice('custom:'.length) || 'Custom';\n activeModePackId = `custom:${customName}`;\n const entry = { name: customName, models: modeDefaults, createdAt: new Date().toISOString() };\n const idx = settings.customModelPacks.findIndex(p => p.name === customName);\n if (idx >= 0) {\n settings.customModelPacks[idx] = entry;\n } else {\n settings.customModelPacks.push(entry);\n }\n settings.models.modeDefaults = modeDefaults;\n } else {\n settings.models.modeDefaults = {};\n }\n\n settings.onboarding.modePackId = activeModePackId;\n settings.models.activeModelPackId = activeModePackId;\n if (this.state.session.thread.getId()) {\n await this.state.session.thread.setSetting({ key: THREAD_ACTIVE_MODEL_PACK_ID_KEY, value: activeModePackId });\n }\n\n settings.models.activeOmPackId = omPack?.id ?? null;\n settings.models.omModelOverride = omPack?.id === 'custom' ? omPack.modelId : null;\n // Clear any per-role overrides from prior /om use so the newly-selected\n // pack (or custom modelId above) applies to both observer and reflector.\n settings.models.observerModelOverride = null;\n settings.models.reflectorModelOverride = null;\n settings.preferences.yolo = result.yolo;\n\n // Clear any manual subagent overrides so they derive from the active pack\n settings.models.subagentModels = {};\n\n saveSettings(settings);\n\n updateStatusLine(this.state);\n await this.refreshModelAuthStatus();\n }\n\n private shouldShowOnboarding(): boolean {\n const settings = loadSettings();\n const ob = settings.onboarding;\n if (ob.completedAt || ob.skippedAt) {\n return ob.version < ONBOARDING_VERSION;\n }\n return true;\n }\n\n private applyQuietModePreference(enabled: boolean, previewLineLimit = this.state.quietModeMaxToolPreviewLines): void {\n const settings = loadSettings();\n settings.preferences.quietMode = enabled;\n settings.preferences.quietModeMaxToolPreviewLines = previewLineLimit;\n settings.onboarding.quietModePreferenceSelected = true;\n saveSettings(settings);\n\n this.state.quietMode = enabled;\n this.state.quietModeMaxToolPreviewLines = previewLineLimit;\n this.state.taskProgress?.setQuietMode(enabled);\n\n const tools = this.state.allToolComponents.filter(\n (tool): tool is IToolExecutionComponent => typeof tool.setQuietModeDisplay === 'function',\n );\n const color = this.state.session?.mode.resolve().metadata?.color;\n const modeColor = typeof color === 'string' ? color : undefined;\n for (const tool of tools) {\n tool.setCompactToolModeColor?.(modeColor);\n tool.setQuietModeDisplay?.(enabled ? 'quiet' : 'normal');\n tool.setQuietPreviewLineLimit?.(previewLineLimit);\n }\n flushRender(this.state);\n }\n\n private parseQuietPreviewLineAnswer(answer: string | null): number {\n if (answer === 'None') return 0;\n const match = answer?.match(/^(\\d+)/);\n return match ? Number(match[1]) : this.state.quietModeMaxToolPreviewLines;\n }\n\n async showQuietModePreferencePromptIfNeeded(): Promise<void> {\n const settings = loadSettings();\n if (settings.onboarding.quietModePreferenceSelected) return;\n\n const answer = await askModalQuestion(this.state.ui, {\n question:\n 'Try compact quiet mode?\\n\\nQuiet mode keeps tool calls and task progress compact so long sessions are easier to scan.',\n options: [\n { label: 'Enable quiet mode', description: 'Use compact rendering by default' },\n { label: 'Keep classic mode', description: 'Keep the current full rendering' },\n ],\n allowCustomResponse: false,\n selectedOptionLabel: 'Enable quiet mode',\n overlay: { maxHeight: '50%' },\n });\n\n if (answer !== 'Enable quiet mode') {\n this.applyQuietModePreference(false);\n return;\n }\n\n const previewLineAnswer = await askModalQuestion(this.state.ui, {\n question: 'How many quiet-mode tool preview lines should be shown?\\n\\nYou can change this later in /settings.',\n options: [\n { label: 'None', description: 'Hide compact tool detail previews' },\n { label: '1 line', description: 'Show the latest preview line' },\n { label: '2 lines', description: 'Default' },\n { label: '4 lines', description: 'Show more streaming detail' },\n { label: '8 lines', description: 'Show the most detail' },\n ],\n allowCustomResponse: false,\n selectedOptionLabel: '2 lines',\n overlay: { maxHeight: '50%' },\n });\n\n this.applyQuietModePreference(true, this.parseQuietPreviewLineAnswer(previewLineAnswer));\n }\n\n // ===========================================================================\n // Auto-Update\n // ===========================================================================\n\n /**\n * Check npm for a newer version and prompt the user to update.\n * - If the user previously dismissed this version, show a passive note instead.\n * - If the fetch fails or we're already up-to-date, silently return.\n * @param passive When true, only show an info message (used for periodic rechecks).\n */\n private async checkForUpdate(passive = false): Promise<void> {\n if (process.env.MASTRACODE_DISABLE_UPDATE_CHECK === '1') return;\n\n const currentVersion = this.state.options.version;\n if (!currentVersion) return;\n\n const latestVersion = await fetchLatestVersion();\n if (!latestVersion || !isNewerVersion(currentVersion, latestVersion)) return;\n\n // Passive mode or previously dismissed — show info message only once\n if (passive) {\n if (!this.hasShownUpdateBanner) {\n this.hasShownUpdateBanner = true;\n showInfo(\n this.state,\n `Update available: v${latestVersion} (current: v${currentVersion}). Run /update to update.`,\n );\n }\n return;\n }\n\n const settings = loadSettings();\n\n // User previously dismissed this exact version — show passive banner note only once\n if (settings.updateDismissedVersion && !isNewerVersion(settings.updateDismissedVersion, latestVersion)) {\n if (!this.hasShownUpdateBanner) {\n this.hasShownUpdateBanner = true;\n showInfo(\n this.state,\n `Update available: v${latestVersion} (current: v${currentVersion}). Run /update to update.`,\n );\n }\n return;\n }\n\n const [pm, changelog] = await Promise.all([detectPackageManager(), fetchChangelog(latestVersion)]);\n\n // Prompt the user (and mark banner as shown so periodic checks don't repeat it)\n this.hasShownUpdateBanner = true;\n await this.showUpdatePrompt(currentVersion, latestVersion, pm, changelog);\n }\n\n /**\n * Show a Y/N prompt offering to auto-update (inline in the chat flow).\n */\n private async showUpdatePrompt(\n currentVersion: string,\n latestVersion: string,\n pm: Awaited<ReturnType<typeof detectPackageManager>>,\n changelog: string | null,\n ): Promise<void> {\n let question = `A new version of Mastra Code is available: v${latestVersion} (current: v${currentVersion}).`;\n if (changelog) {\n question += `\\n\\nWhat's new:\\n${changelog}`;\n }\n question += `\\n\\nWould you like to update now?`;\n\n const answer = await new Promise<string | null>(resolve => {\n const component = new AskQuestionInlineComponent(\n {\n question,\n options: [\n { label: 'Yes', description: 'Update and restart' },\n { label: 'No', description: 'Skip this version' },\n ],\n allowCustomResponse: false,\n onSubmit: answer => {\n this.state.activeInlineQuestion = undefined;\n resolve(answer);\n },\n onCancel: () => {\n this.state.activeInlineQuestion = undefined;\n resolve(null);\n },\n },\n this.state.ui,\n );\n\n insertChatComponentWithBoundarySpacing(this.state.chatContainer, component);\n this.state.activeInlineQuestion = component;\n component.focused = true;\n flushRender(this.state);\n });\n\n if (answer === 'Yes') {\n showInfo(this.state, `Updating to v${latestVersion}…`);\n const outcome = await performUpdate(pm, latestVersion);\n if (outcome.status === 'updated') {\n // Printed after TUI teardown — a message rendered inside it is lost in the exit race.\n this.stop();\n console.info(outcome.message);\n process.exit(0);\n } else {\n showError(this.state, outcome.message);\n }\n } else {\n // User declined — save the dismissed version\n const settings = loadSettings();\n settings.updateDismissedVersion = latestVersion;\n saveSettings(settings);\n if (answer === 'No') {\n showInfo(this.state, `Update skipped. Run /update to update later.`);\n }\n }\n }\n}\n"],"mappings":"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"}