@openbuilder/cli 0.50.17 → 0.50.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/chunks/{Banner-D4tqKfzA.js → Banner-ClJs6QcI.js} +3 -4
  2. package/dist/chunks/{Banner-D4tqKfzA.js.map → Banner-ClJs6QcI.js.map} +1 -1
  3. package/dist/chunks/_commonjsHelpers-DcsQGttR.js +32 -0
  4. package/dist/chunks/_commonjsHelpers-DcsQGttR.js.map +1 -0
  5. package/dist/chunks/{init-tui-BNzk_7Yx.js → init-tui-DDxZYe9B.js} +54 -55
  6. package/dist/chunks/{init-tui-BNzk_7Yx.js.map → init-tui-DDxZYe9B.js.map} +1 -1
  7. package/dist/chunks/{init-CZoN6soU.js → init-zX5aX-qn.js} +5 -6
  8. package/dist/chunks/{init-CZoN6soU.js.map → init-zX5aX-qn.js.map} +1 -1
  9. package/dist/chunks/{main-tui-CTgDJWmu.js → main-tui-B5GJ49Bp.js} +43 -44
  10. package/dist/chunks/{main-tui-CTgDJWmu.js.map → main-tui-B5GJ49Bp.js.map} +1 -1
  11. package/dist/chunks/{run-DAEiNzrf.js → run-CaSootos.js} +33 -34
  12. package/dist/chunks/{run-DAEiNzrf.js.map → run-CaSootos.js.map} +1 -1
  13. package/dist/chunks/{start-BygPCbvw.js → start-B4P27nZ7.js} +46 -47
  14. package/dist/chunks/{start-BygPCbvw.js.map → start-B4P27nZ7.js.map} +1 -1
  15. package/dist/chunks/theme-BF4W2Gwm.js +2300 -0
  16. package/dist/chunks/theme-BF4W2Gwm.js.map +1 -0
  17. package/dist/chunks/{useBuildState-CdBSu9y_.js → useBuildState-BZuezCb6.js} +33 -35
  18. package/dist/chunks/{useBuildState-CdBSu9y_.js.map → useBuildState-BZuezCb6.js.map} +1 -1
  19. package/dist/cli/index.js +5 -5
  20. package/dist/instrument.js +1 -29
  21. package/dist/instrument.js.map +1 -1
  22. package/package.json +1 -1
  23. package/dist/chunks/theme-DhorI2Hb.js +0 -44
  24. package/dist/chunks/theme-DhorI2Hb.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
  import { existsSync, mkdirSync, createWriteStream, writeFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { Box, Text, useApp, useStdout, useInput, render } from 'ink';
5
- import React, { useState, useMemo, useEffect } from 'react';
5
+ import { j as jsxRuntimeExports, r as reactExports, R as React } from './theme-BF4W2Gwm.js';
6
6
  import * as p from '@clack/prompts';
7
7
  import pc from 'picocolors';
8
8
  import { c as configManager } from './config-manager-BkbjtN-H.js';
@@ -11,18 +11,17 @@ import { killProcessOnPort, killProcessTree } from './process-killer-CaUL7Kpl.js
11
11
  import { e as errors, C as CLIError } from './cli-error-BjQwvWtK.js';
12
12
  import { spawn } from 'node:child_process';
13
13
  import EventEmitter from 'node:events';
14
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
15
14
  import TextInput from 'ink-text-input';
16
15
  import { exec } from 'child_process';
17
16
  import { platform } from 'os';
18
- import { u as useBuildState, B as BuildPanel } from './useBuildState-CdBSu9y_.js';
17
+ import { u as useBuildState, B as BuildPanel } from './useBuildState-BZuezCb6.js';
19
18
  import 'chalk';
20
19
  import { i as initRunnerLogger, s as setFileLoggerTuiMode } from './runner-logger-instance-nDWv2h2T.js';
20
+ import './_commonjsHelpers-DcsQGttR.js';
21
21
  import 'conf';
22
22
  import 'node:os';
23
23
  import 'node:fs/promises';
24
24
  import 'node:util';
25
- import './theme-DhorI2Hb.js';
26
25
 
27
26
  /**
28
27
  * ServiceManager - Manages lifecycle and state of Web App, Broker, and Runner
@@ -378,7 +377,7 @@ function Banner() {
378
377
  { open: '╚██████╔╝██║ ███████╗██║ ╚████║', builder: '██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║' },
379
378
  { open: ' ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝', builder: '╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝' },
380
379
  ];
381
- return (jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: 2, children: lines.map((line, index) => (jsxs(Box, { children: [jsx(Text, { color: colors.cyan, children: line.open }), jsx(Text, { color: colors.brightPurple, children: line.builder })] }, index))) }));
380
+ return (jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: 2, children: lines.map((line, index) => (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: line.open }), jsxRuntimeExports.jsx(Text, { color: colors.brightPurple, children: line.builder })] }, index))) }));
382
381
  }
383
382
 
384
383
  // Base colors that don't change with theme
@@ -620,32 +619,32 @@ function openBrowser(url) {
620
619
  function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
621
620
  const { exit } = useApp();
622
621
  const { stdout } = useStdout();
623
- const [view, setView] = useState('dashboard');
624
- const [services, setServices] = useState([]);
625
- const [logs, setLogs] = useState([]);
626
- const [isShuttingDown, setIsShuttingDown] = useState(false);
627
- const [serviceFilter, setServiceFilter] = useState(null);
628
- const [scrollOffset, setScrollOffset] = useState(0);
629
- const [autoScroll, setAutoScroll] = useState(true);
630
- const [searchMode, setSearchMode] = useState(false);
631
- const [searchQuery, setSearchQuery] = useState('');
632
- const [isVerbose, setIsVerbose] = useState(false);
633
- const [logIdCounter, setLogIdCounter] = useState(0);
634
- const [filterMode, setFilterMode] = useState('all');
635
- const [fullLogSearchMode, setFullLogSearchMode] = useState(false);
636
- const [fullLogSearchQuery, setFullLogSearchQuery] = useState('');
637
- const [fullLogScrollOffset, setFullLogScrollOffset] = useState(0);
622
+ const [view, setView] = reactExports.useState('dashboard');
623
+ const [services, setServices] = reactExports.useState([]);
624
+ const [logs, setLogs] = reactExports.useState([]);
625
+ const [isShuttingDown, setIsShuttingDown] = reactExports.useState(false);
626
+ const [serviceFilter, setServiceFilter] = reactExports.useState(null);
627
+ const [scrollOffset, setScrollOffset] = reactExports.useState(0);
628
+ const [autoScroll, setAutoScroll] = reactExports.useState(true);
629
+ const [searchMode, setSearchMode] = reactExports.useState(false);
630
+ const [searchQuery, setSearchQuery] = reactExports.useState('');
631
+ const [isVerbose, setIsVerbose] = reactExports.useState(false);
632
+ const [logIdCounter, setLogIdCounter] = reactExports.useState(0);
633
+ const [filterMode, setFilterMode] = reactExports.useState('all');
634
+ const [fullLogSearchMode, setFullLogSearchMode] = reactExports.useState(false);
635
+ const [fullLogSearchQuery, setFullLogSearchQuery] = reactExports.useState('');
636
+ const [fullLogScrollOffset, setFullLogScrollOffset] = reactExports.useState(0);
638
637
  // Theme state - load from config, default to 'sentry'
639
638
  const savedTheme = configManager.get('ui')?.theme;
640
- const [selectedTheme, setSelectedTheme] = useState(savedTheme || 'sentry');
641
- const [previewTheme, setPreviewTheme] = useState(null);
642
- const [themeBeforePreview, setThemeBeforePreview] = useState(null);
639
+ const [selectedTheme, setSelectedTheme] = reactExports.useState(savedTheme || 'sentry');
640
+ const [previewTheme, setPreviewTheme] = reactExports.useState(null);
641
+ const [themeBeforePreview, setThemeBeforePreview] = reactExports.useState(null);
643
642
  // Build state - tracks active builds and todos from the RunnerLogger
644
643
  const [buildState] = useBuildState();
645
644
  // Get current theme colors - use preview theme if active, otherwise selected theme
646
645
  const activeThemeName = previewTheme || selectedTheme;
647
646
  const theme = THEMES[activeThemeName];
648
- const themeColors = useMemo(() => ({
647
+ const themeColors = reactExports.useMemo(() => ({
649
648
  primary: theme.colors.primary,
650
649
  secondary: theme.colors.secondary,
651
650
  accent: theme.colors.accent,
@@ -668,10 +667,10 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
668
667
  // 20/80 split when build panel is shown, otherwise full width
669
668
  const buildPanelWidth = Math.floor(terminalWidth * 0.2);
670
669
  const logPanelWidth = showBuildPanel ? terminalWidth - buildPanelWidth : terminalWidth;
671
- const allServicesRunning = useMemo(() => {
670
+ const allServicesRunning = reactExports.useMemo(() => {
672
671
  return services.length > 0 && services.every(s => s.status === 'running');
673
672
  }, [services]);
674
- useEffect(() => {
673
+ reactExports.useEffect(() => {
675
674
  const handleStatusChange = () => {
676
675
  setServices(serviceManager.getAllStates());
677
676
  };
@@ -681,7 +680,7 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
681
680
  serviceManager.off('service:status-change', handleStatusChange);
682
681
  };
683
682
  }, [serviceManager]);
684
- useEffect(() => {
683
+ reactExports.useEffect(() => {
685
684
  const handleServiceOutput = (name, output, stream) => {
686
685
  const lines = output.split('\n').filter(line => line.trim());
687
686
  setLogIdCounter(prev => {
@@ -718,7 +717,7 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
718
717
  serviceManager.off('service:output', handleServiceOutput);
719
718
  };
720
719
  }, [serviceManager]);
721
- const filteredLogs = useMemo(() => {
720
+ const filteredLogs = reactExports.useMemo(() => {
722
721
  let filtered = logs;
723
722
  // By default, hide internal/debug logs unless verbose mode is on
724
723
  if (!isVerbose) {
@@ -736,7 +735,7 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
736
735
  }
737
736
  return filtered;
738
737
  }, [logs, serviceFilter, searchQuery, isVerbose]);
739
- const fullLogFilteredLogs = useMemo(() => {
738
+ const fullLogFilteredLogs = reactExports.useMemo(() => {
740
739
  let filtered = logs;
741
740
  if (filterMode === 'errors') {
742
741
  filtered = filtered.filter(log => log.level === 'error' || log.level === 'warn');
@@ -762,22 +761,22 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
762
761
  }, [logs, filterMode, fullLogSearchQuery]);
763
762
  const visibleLines = Math.max(1, contentHeight - 3);
764
763
  const fullLogVisibleLines = Math.max(1, terminalHeight - 6);
765
- useEffect(() => {
764
+ reactExports.useEffect(() => {
766
765
  if (autoScroll && filteredLogs.length > 0) {
767
766
  const maxScroll = Math.max(0, filteredLogs.length - visibleLines);
768
767
  setScrollOffset(maxScroll);
769
768
  }
770
769
  }, [filteredLogs.length, autoScroll, visibleLines]);
771
- useEffect(() => {
770
+ reactExports.useEffect(() => {
772
771
  if (view === 'fullLog') {
773
772
  const maxScroll = Math.max(0, fullLogFilteredLogs.length - fullLogVisibleLines);
774
773
  setFullLogScrollOffset(maxScroll);
775
774
  }
776
775
  }, [fullLogFilteredLogs.length, view, fullLogVisibleLines]);
777
- const displayedLogs = useMemo(() => {
776
+ const displayedLogs = reactExports.useMemo(() => {
778
777
  return filteredLogs.slice(scrollOffset, scrollOffset + visibleLines);
779
778
  }, [filteredLogs, scrollOffset, visibleLines]);
780
- const fullLogDisplayedLogs = useMemo(() => {
779
+ const fullLogDisplayedLogs = reactExports.useMemo(() => {
781
780
  return fullLogFilteredLogs.slice(fullLogScrollOffset, fullLogScrollOffset + fullLogVisibleLines);
782
781
  }, [fullLogFilteredLogs, fullLogScrollOffset, fullLogVisibleLines]);
783
782
  // Save theme to config and update state
@@ -992,28 +991,28 @@ function Dashboard({ serviceManager, apiUrl, webPort, logFilePath }) {
992
991
  const index = lowerText.indexOf(lowerQuery);
993
992
  if (index === -1)
994
993
  return text;
995
- return (jsxs(Fragment, { children: [text.slice(0, index), jsx(Text, { backgroundColor: baseColors.warning, color: "black", children: text.slice(index, index + query.length) }), text.slice(index + query.length)] }));
994
+ return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [text.slice(0, index), jsxRuntimeExports.jsx(Text, { backgroundColor: baseColors.warning, color: "black", children: text.slice(index, index + query.length) }), text.slice(index + query.length)] }));
996
995
  };
997
996
  // Full log view
998
997
  if (view === 'fullLog') {
999
- return (jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsx(Text, { color: themeColors.primary, bold: true, children: "LOGS" }), jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: "Search: " }), fullLogSearchMode ? (jsx(Box, { borderStyle: "round", borderColor: themeColors.primary, paddingX: 1, children: jsx(TextInput, { value: fullLogSearchQuery, onChange: setFullLogSearchQuery, placeholder: "type to search..." }) })) : (jsxs(Text, { color: fullLogSearchQuery ? themeColors.text : themeColors.textMuted, children: ["[", fullLogSearchQuery || 'none', "]"] })), jsx(Text, { color: themeColors.textMuted, children: " [/]" })] })] }), jsx(Box, { flexDirection: "column", flexGrow: 1, borderStyle: "single", borderColor: themeColors.muted, borderTop: false, borderBottom: false, paddingX: 1, children: fullLogDisplayedLogs.map((log) => (jsx(FullLogEntryRow, { log: log, maxWidth: terminalWidth - 4, searchQuery: fullLogSearchQuery, highlightSearch: highlightSearch, themeColors: themeColors }, log.id))) }), jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxs(Box, { children: [jsx(Shortcut, { letter: "l", label: "dashboard", color: themeColors.primary }), jsx(Shortcut, { letter: "/", label: "search", color: themeColors.primary }), jsx(Shortcut, { letter: "f", label: `filter: ${filterMode}`, color: themeColors.primary }), jsx(Shortcut, { letter: "b", label: "browser", color: themeColors.primary }), jsx(Shortcut, { letter: "q", label: "quit", color: themeColors.primary })] }), jsxs(Text, { color: themeColors.textMuted, children: [fullLogScrollOffset + 1, "-", Math.min(fullLogScrollOffset + fullLogVisibleLines, fullLogFilteredLogs.length), "/", fullLogFilteredLogs.length] })] })] }));
998
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [jsxRuntimeExports.jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxRuntimeExports.jsx(Text, { color: themeColors.primary, bold: true, children: "LOGS" }), jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: "Search: " }), fullLogSearchMode ? (jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: themeColors.primary, paddingX: 1, children: jsxRuntimeExports.jsx(TextInput, { value: fullLogSearchQuery, onChange: setFullLogSearchQuery, placeholder: "type to search..." }) })) : (jsxRuntimeExports.jsxs(Text, { color: fullLogSearchQuery ? themeColors.text : themeColors.textMuted, children: ["[", fullLogSearchQuery || 'none', "]"] })), jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: " [/]" })] })] }), jsxRuntimeExports.jsx(Box, { flexDirection: "column", flexGrow: 1, borderStyle: "single", borderColor: themeColors.muted, borderTop: false, borderBottom: false, paddingX: 1, children: fullLogDisplayedLogs.map((log) => (jsxRuntimeExports.jsx(FullLogEntryRow, { log: log, maxWidth: terminalWidth - 4, searchQuery: fullLogSearchQuery, highlightSearch: highlightSearch, themeColors: themeColors }, log.id))) }), jsxRuntimeExports.jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Shortcut, { letter: "l", label: "dashboard", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "/", label: "search", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "f", label: `filter: ${filterMode}`, color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "b", label: "browser", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "q", label: "quit", color: themeColors.primary })] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: [fullLogScrollOffset + 1, "-", Math.min(fullLogScrollOffset + fullLogVisibleLines, fullLogFilteredLogs.length), "/", fullLogFilteredLogs.length] })] })] }));
1000
999
  }
1001
1000
  // Theme Selector overlay
1002
1001
  if (view === 'themeSelector') {
1003
- return (jsxs(Box, { flexDirection: "column", height: terminalHeight, width: terminalWidth, children: [jsx(Banner, {}), jsx(Box, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: themeColors.primary, paddingX: 3, paddingY: 1, width: 40, children: [jsx(Box, { justifyContent: "center", marginBottom: 1, children: jsx(Text, { color: themeColors.primary, bold: true, children: "Select Theme" }) }), THEME_ORDER.map((themeName) => {
1002
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", height: terminalHeight, width: terminalWidth, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: jsxRuntimeExports.jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: themeColors.primary, paddingX: 3, paddingY: 1, width: 40, children: [jsxRuntimeExports.jsx(Box, { justifyContent: "center", marginBottom: 1, children: jsxRuntimeExports.jsx(Text, { color: themeColors.primary, bold: true, children: "Select Theme" }) }), THEME_ORDER.map((themeName) => {
1004
1003
  const t = THEMES[themeName];
1005
1004
  const isSelected = themeName === previewTheme;
1006
- return (jsxs(Box, { paddingY: 0, children: [jsx(Text, { color: isSelected ? t.colors.primary : themeColors.textMuted, children: isSelected ? '▸ ' : ' ' }), jsx(Text, { color: isSelected ? t.colors.primary : themeColors.textDim, bold: isSelected, children: t.label }), jsxs(Text, { color: themeColors.textMuted, children: [" - ", t.description] })] }, themeName));
1007
- }), jsx(Box, { marginTop: 1, justifyContent: "center", children: jsxs(Text, { color: themeColors.textMuted, children: [jsx(Text, { color: themeColors.primary, children: "\u2191\u2193" }), " navigate", jsx(Text, { color: themeColors.primary, children: " Enter" }), " select", jsx(Text, { color: themeColors.primary, children: " Esc" }), " cancel"] }) })] }) })] }));
1005
+ return (jsxRuntimeExports.jsxs(Box, { paddingY: 0, children: [jsxRuntimeExports.jsx(Text, { color: isSelected ? t.colors.primary : themeColors.textMuted, children: isSelected ? '▸ ' : ' ' }), jsxRuntimeExports.jsx(Text, { color: isSelected ? t.colors.primary : themeColors.textDim, bold: isSelected, children: t.label }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: [" - ", t.description] })] }, themeName));
1006
+ }), jsxRuntimeExports.jsx(Box, { marginTop: 1, justifyContent: "center", children: jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: [jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "\u2191\u2193" }), " navigate", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: " Enter" }), " select", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: " Esc" }), " cancel"] }) })] }) })] }));
1008
1007
  }
1009
1008
  // Help/Menu view
1010
1009
  if (view === 'help') {
1011
- return (jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [jsx(Banner, {}), jsxs(Box, { flexDirection: "column", padding: 2, children: [jsx(Text, { color: themeColors.primary, bold: true, children: "Help & Keyboard Shortcuts" }), jsx(Text, { children: " " }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "Ctrl+T" }), " Change theme"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "b" }), " Open in browser"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "l" }), " Full log view"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "/" }), " Search logs"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "f" }), " Filter by service"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "v" }), " Toggle verbose mode"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "r" }), " Restart services"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "c" }), " Clear logs"] }), jsxs(Text, { color: themeColors.textDim, children: [" ", jsx(Text, { color: themeColors.primary, children: "q" }), " Quit"] }), jsx(Text, { children: " " }), jsxs(Text, { color: themeColors.textMuted, children: ["Current theme: ", jsx(Text, { color: themeColors.primary, children: theme.label })] }), jsx(Text, { children: " " }), jsxs(Text, { color: themeColors.textMuted, children: ["Press ", jsx(Text, { color: themeColors.primary, children: "Esc" }), " to return to dashboard"] })] })] }));
1010
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", padding: 2, children: [jsxRuntimeExports.jsx(Text, { color: themeColors.primary, bold: true, children: "Help & Keyboard Shortcuts" }), jsxRuntimeExports.jsx(Text, { children: " " }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "Ctrl+T" }), " Change theme"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "b" }), " Open in browser"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "l" }), " Full log view"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "/" }), " Search logs"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "f" }), " Filter by service"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "v" }), " Toggle verbose mode"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "r" }), " Restart services"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "c" }), " Clear logs"] }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "q" }), " Quit"] }), jsxRuntimeExports.jsx(Text, { children: " " }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["Current theme: ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: theme.label })] }), jsxRuntimeExports.jsx(Text, { children: " " }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["Press ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "Esc" }), " to return to dashboard"] })] })] }));
1012
1011
  }
1013
1012
  // Check for available update (set by auto-update check in index.ts)
1014
1013
  const updateAvailable = process.env.OPENBUILDER_UPDATE_AVAILABLE;
1015
1014
  // Main dashboard view
1016
- return (jsxs(Box, { flexDirection: "column", height: terminalHeight, width: terminalWidth, children: [jsx(Banner, {}), updateAvailable && (jsxs(Box, { justifyContent: "center", paddingY: 0, children: [jsx(Text, { color: baseColors.cyan, children: "\u2B06 Update available: " }), jsx(Text, { color: baseColors.success, children: updateAvailable }), jsx(Text, { color: themeColors.textMuted, children: " \u2014 Run " }), jsx(Text, { color: baseColors.cyan, children: "openbuilder upgrade" }), jsx(Text, { color: themeColors.textMuted, children: " to update" })] })), jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxs(Text, { color: themeColors.textMuted, children: ["Web: ", jsxs(Text, { color: themeColors.primary, children: ["localhost:", webPort] }), ' • ', "Mode: ", jsx(Text, { color: themeColors.primary, children: "Local" }), ' • ', "Theme: ", jsx(Text, { color: themeColors.primary, children: theme.label })] }), jsxs(Box, { children: [jsx(Text, { color: allServicesRunning ? baseColors.success : baseColors.warning, children: allServicesRunning ? symbols.filledDot : symbols.hollowDot }), jsxs(Text, { color: themeColors.textDim, children: [' ', allServicesRunning ? 'All Services Running' : 'Starting...'] })] })] }), jsxs(Box, { flexGrow: 1, height: contentHeight, children: [showBuildPanel && (jsx(BuildPanel, { build: buildState.currentBuild, width: buildPanelWidth, height: contentHeight })), jsxs(Box, { flexDirection: "column", width: logPanelWidth, height: contentHeight, borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, children: [jsxs(Box, { justifyContent: "space-between", marginBottom: 0, children: [jsx(Text, { color: themeColors.primary, bold: true, children: "LOGS" }), jsxs(Box, { children: [serviceFilter && (jsxs(Text, { color: themeColors.textMuted, children: ["filter: ", jsx(Text, { color: baseColors.warning, children: serviceFilter }), " "] })), jsxs(Text, { color: themeColors.textMuted, children: ["[verbose: ", isVerbose ? 'on' : 'off', "]"] })] })] }), jsx(Box, { flexDirection: "column", flexGrow: 1, children: displayedLogs.length === 0 ? (jsx(Box, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: jsx(Text, { color: themeColors.textMuted, children: "Waiting for logs..." }) })) : (displayedLogs.map((log) => (jsx(LogEntryRow, { log: log, maxWidth: logPanelWidth - 4, themeColors: themeColors }, log.id)))) }), filteredLogs.length > visibleLines && (jsx(Box, { justifyContent: "flex-end", children: jsxs(Text, { color: themeColors.textMuted, children: [scrollOffset + 1, "-", Math.min(scrollOffset + visibleLines, filteredLogs.length), "/", filteredLogs.length, autoScroll ? ' (auto)' : ''] }) }))] })] }), jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxs(Box, { children: [jsx(Text, { color: allServicesRunning ? baseColors.success : baseColors.warning, children: allServicesRunning ? symbols.filledDot : symbols.hollowDot }), jsxs(Text, { color: themeColors.textDim, children: [' ', isShuttingDown ? 'Shutting down...' : allServicesRunning ? 'Ready' : 'Starting'] })] }), searchMode ? (jsxs(Box, { children: [jsx(Text, { color: themeColors.primary, children: "/" }), jsx(TextInput, { value: searchQuery, onChange: setSearchQuery, onSubmit: () => setSearchMode(false), placeholder: "Search... (Enter to apply, Esc to cancel)" })] })) : (jsxs(Box, { children: [jsx(Shortcut, { letter: "b", label: "browser", color: themeColors.primary }), jsx(Shortcut, { letter: "l", label: "logs", color: themeColors.primary }), jsx(Shortcut, { letter: "/", label: "search", color: themeColors.primary }), jsx(Shortcut, { letter: "?", label: "menu", color: themeColors.primary }), jsx(Shortcut, { letter: "q", label: "quit", color: themeColors.primary })] }))] })] }));
1015
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", height: terminalHeight, width: terminalWidth, children: [jsxRuntimeExports.jsx(Banner, {}), updateAvailable && (jsxRuntimeExports.jsxs(Box, { justifyContent: "center", paddingY: 0, children: [jsxRuntimeExports.jsx(Text, { color: baseColors.cyan, children: "\u2B06 Update available: " }), jsxRuntimeExports.jsx(Text, { color: baseColors.success, children: updateAvailable }), jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: " \u2014 Run " }), jsxRuntimeExports.jsx(Text, { color: baseColors.cyan, children: "openbuilder upgrade" }), jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: " to update" })] })), jsxRuntimeExports.jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["Web: ", jsxRuntimeExports.jsxs(Text, { color: themeColors.primary, children: ["localhost:", webPort] }), ' • ', "Mode: ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "Local" }), ' • ', "Theme: ", jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: theme.label })] }), jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: allServicesRunning ? baseColors.success : baseColors.warning, children: allServicesRunning ? symbols.filledDot : symbols.hollowDot }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [' ', allServicesRunning ? 'All Services Running' : 'Starting...'] })] })] }), jsxRuntimeExports.jsxs(Box, { flexGrow: 1, height: contentHeight, children: [showBuildPanel && (jsxRuntimeExports.jsx(BuildPanel, { build: buildState.currentBuild, width: buildPanelWidth, height: contentHeight })), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", width: logPanelWidth, height: contentHeight, borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, children: [jsxRuntimeExports.jsxs(Box, { justifyContent: "space-between", marginBottom: 0, children: [jsxRuntimeExports.jsx(Text, { color: themeColors.primary, bold: true, children: "LOGS" }), jsxRuntimeExports.jsxs(Box, { children: [serviceFilter && (jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["filter: ", jsxRuntimeExports.jsx(Text, { color: baseColors.warning, children: serviceFilter }), " "] })), jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["[verbose: ", isVerbose ? 'on' : 'off', "]"] })] })] }), jsxRuntimeExports.jsx(Box, { flexDirection: "column", flexGrow: 1, children: displayedLogs.length === 0 ? (jsxRuntimeExports.jsx(Box, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: "Waiting for logs..." }) })) : (displayedLogs.map((log) => (jsxRuntimeExports.jsx(LogEntryRow, { log: log, maxWidth: logPanelWidth - 4, themeColors: themeColors }, log.id)))) }), filteredLogs.length > visibleLines && (jsxRuntimeExports.jsx(Box, { justifyContent: "flex-end", children: jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: [scrollOffset + 1, "-", Math.min(scrollOffset + visibleLines, filteredLogs.length), "/", filteredLogs.length, autoScroll ? ' (auto)' : ''] }) }))] })] }), jsxRuntimeExports.jsxs(Box, { borderStyle: "single", borderColor: themeColors.muted, paddingX: 1, justifyContent: "space-between", children: [jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: allServicesRunning ? baseColors.success : baseColors.warning, children: allServicesRunning ? symbols.filledDot : symbols.hollowDot }), jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [' ', isShuttingDown ? 'Shutting down...' : allServicesRunning ? 'Ready' : 'Starting'] })] }), searchMode ? (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: "/" }), jsxRuntimeExports.jsx(TextInput, { value: searchQuery, onChange: setSearchQuery, onSubmit: () => setSearchMode(false), placeholder: "Search... (Enter to apply, Esc to cancel)" })] })) : (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Shortcut, { letter: "b", label: "browser", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "l", label: "logs", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "/", label: "search", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "?", label: "menu", color: themeColors.primary }), jsxRuntimeExports.jsx(Shortcut, { letter: "q", label: "quit", color: themeColors.primary })] }))] })] }));
1017
1016
  }
1018
1017
  function LogEntryRow({ log, maxWidth, themeColors }) {
1019
1018
  const levelColors = {
@@ -1041,12 +1040,12 @@ function LogEntryRow({ log, maxWidth, themeColors }) {
1041
1040
  if (log.toolName) {
1042
1041
  // If we have a displayMessage, use it (it's already user-friendly)
1043
1042
  if (log.displayMessage) {
1044
- return (jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsx(Text, { color: themeColors.text, children: log.displayMessage })] }));
1043
+ return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxRuntimeExports.jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsxRuntimeExports.jsx(Text, { color: themeColors.text, children: log.displayMessage })] }));
1045
1044
  }
1046
1045
  // Fallback to showing tool name
1047
- return (jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsx(Text, { color: themeColors.text, children: log.toolName })] }));
1046
+ return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxRuntimeExports.jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsxRuntimeExports.jsx(Text, { color: themeColors.text, children: log.toolName })] }));
1048
1047
  }
1049
- return (jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsxs(Text, { color: color, children: [" ", icon, " "] }), jsx(Text, { color: log.level === 'error' || log.level === 'warn' ? color : themeColors.text, children: truncatedMessage })] }));
1048
+ return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxRuntimeExports.jsxs(Text, { color: serviceColor, children: [" [", log.service.substring(0, 3), "]"] }), jsxRuntimeExports.jsxs(Text, { color: color, children: [" ", icon, " "] }), jsxRuntimeExports.jsx(Text, { color: log.level === 'error' || log.level === 'warn' ? color : themeColors.text, children: truncatedMessage })] }));
1050
1049
  }
1051
1050
  function FullLogEntryRow({ log, maxWidth, searchQuery, highlightSearch, themeColors }) {
1052
1051
  const levelColors = {
@@ -1065,12 +1064,12 @@ function FullLogEntryRow({ log, maxWidth, searchQuery, highlightSearch, themeCol
1065
1064
  const icon = log.emoji || levelIcons[log.level];
1066
1065
  const color = levelColors[log.level];
1067
1066
  if (log.toolName) {
1068
- return (jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxs(Text, { color: serviceColor, children: [" [", log.service, "]"] }), jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsx(Text, { color: themeColors.text, children: highlightSearch(log.toolName, searchQuery) }), log.content && (jsxs(Text, { color: themeColors.textDim, children: [" ", highlightSearch(log.content.replace(`tool-input-available: ${log.toolName}`, '').trim(), searchQuery)] }))] }));
1067
+ return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxRuntimeExports.jsxs(Text, { color: serviceColor, children: [" [", log.service, "]"] }), jsxRuntimeExports.jsx(Text, { color: themeColors.primary, children: " \uD83D\uDD27 " }), jsxRuntimeExports.jsx(Text, { color: themeColors.text, children: highlightSearch(log.toolName, searchQuery) }), log.content && (jsxRuntimeExports.jsxs(Text, { color: themeColors.textDim, children: [" ", highlightSearch(log.content.replace(`tool-input-available: ${log.toolName}`, '').trim(), searchQuery)] }))] }));
1069
1068
  }
1070
- return (jsxs(Box, { children: [jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxs(Text, { color: serviceColor, children: [" [", log.service, "]"] }), jsxs(Text, { color: color, children: [" ", icon, " "] }), log.tag && jsxs(Text, { color: themeColors.textMuted, children: ["[", log.tag, "] "] }), jsx(Text, { color: log.level === 'error' || log.level === 'warn' ? color : themeColors.text, children: highlightSearch(log.content || log.message, searchQuery) })] }));
1069
+ return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: themeColors.textMuted, children: formatTime(log.timestamp) }), jsxRuntimeExports.jsxs(Text, { color: serviceColor, children: [" [", log.service, "]"] }), jsxRuntimeExports.jsxs(Text, { color: color, children: [" ", icon, " "] }), log.tag && jsxRuntimeExports.jsxs(Text, { color: themeColors.textMuted, children: ["[", log.tag, "] "] }), jsxRuntimeExports.jsx(Text, { color: log.level === 'error' || log.level === 'warn' ? color : themeColors.text, children: highlightSearch(log.content || log.message, searchQuery) })] }));
1071
1070
  }
1072
1071
  function Shortcut({ letter, label, color }) {
1073
- return (jsxs(Box, { marginRight: 2, children: [jsx(Text, { color: baseColors.dimGray, children: "[" }), jsx(Text, { color: color, children: letter }), jsx(Text, { color: baseColors.dimGray, children: "]" }), jsx(Text, { color: baseColors.gray, children: label })] }));
1072
+ return (jsxRuntimeExports.jsxs(Box, { marginRight: 2, children: [jsxRuntimeExports.jsx(Text, { color: baseColors.dimGray, children: "[" }), jsxRuntimeExports.jsx(Text, { color: color, children: letter }), jsxRuntimeExports.jsx(Text, { color: baseColors.dimGray, children: "]" }), jsxRuntimeExports.jsx(Text, { color: baseColors.gray, children: label })] }));
1074
1073
  }
1075
1074
 
1076
1075
  /**
@@ -1705,4 +1704,4 @@ async function startCommand(options) {
1705
1704
  }
1706
1705
 
1707
1706
  export { startCommand };
1708
- //# sourceMappingURL=start-BygPCbvw.js.map
1707
+ //# sourceMappingURL=start-B4P27nZ7.js.map