UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

64 lines 9.67 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { existsSync } from 'fs'; import { Box, Text } from 'ink'; import { memo } from 'react'; import { TitledBoxWithPreferences } from '../components/ui/titled-box.js'; import { confDirMap } from '../config/index.js'; import { getThemeColors, themes } from '../config/themes.js'; import { PATH_LENGTH_NARROW_TERMINAL, PATH_LENGTH_NORMAL_TERMINAL, } from '../constants.js'; import { useResponsiveTerminal } from '../hooks/useTerminalWidth.js'; // Get CWD once at module load time const cwd = process.cwd(); // Using UpdateInfo from '../types/utils.js' for type consistency export default memo(function Status({ provider, model, theme, updateInfo, agentsMdLoaded, mcpServersStatus, lspServersStatus, customCommandsCount, preferencesLoaded, vscodeMode, vscodePort, vscodeRequestedPort, contextUsage, autoCompactInfo, }) { const { boxWidth, isNarrow, truncatePath } = useResponsiveTerminal(); const colors = getThemeColors(theme); // Check for AGENTS.md synchronously if not provided const hasAgentsMd = agentsMdLoaded ?? existsSync(`${cwd}/AGENTS.md`); // Connection status calculations const mcpStatus = mcpServersStatus || []; const lspStatus = lspServersStatus || []; const mcpConnected = mcpStatus.filter(s => s.status === 'connected').length; const lspConnected = lspStatus.filter(s => s.status === 'connected').length; const mcpTotal = mcpStatus.length; const lspTotal = lspStatus.length; // Get status color const getStatusColor = (connected, total) => { if (total === 0) return colors.secondary; if (connected === total) return colors.success; if (connected > 0) return colors.warning; return colors.error; }; // VS Code port status const showPortWarning = vscodeMode && vscodePort && vscodeRequestedPort && vscodePort !== vscodeRequestedPort; // Calculate max path length based on terminal size const maxPathLength = isNarrow ? PATH_LENGTH_NARROW_TERMINAL : PATH_LENGTH_NORMAL_TERMINAL; return (_jsx(_Fragment, { children: isNarrow ? (_jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: colors.info, paddingY: 1, paddingX: 2, children: [_jsxs(Text, { color: colors.info, children: [_jsx(Text, { bold: true, children: "CWD: " }), truncatePath(cwd, maxPathLength)] }), _jsxs(Text, { color: colors.success, children: [_jsx(Text, { bold: true, children: "Model: " }), model] }), _jsxs(Text, { color: colors.primary, children: [_jsx(Text, { bold: true, children: "Theme: " }), themes[theme].displayName] }), hasAgentsMd ? (_jsx(Text, { color: colors.secondary, italic: true, children: "\u2713 AGENTS.md" })) : (_jsx(Text, { color: colors.secondary, italic: true, children: "\u2717 No AGENTS.md" })), preferencesLoaded && (_jsx(Text, { color: colors.secondary, children: "\u2713 Preferences loaded" })), customCommandsCount !== undefined && customCommandsCount > 0 && (_jsxs(Text, { color: colors.secondary, children: ["\u2713 ", customCommandsCount, " custom commands"] })), vscodeMode && vscodePort && (_jsx(Text, { color: showPortWarning ? colors.warning : colors.secondary, children: showPortWarning ? `⚠ VS Code: port ${vscodeRequestedPort}→${vscodePort}` : `✓ VS Code: port ${vscodePort}` })), mcpTotal > 0 && (_jsxs(Text, { color: mcpConnected === mcpTotal ? colors.secondary : getStatusColor(mcpConnected, mcpTotal), children: [mcpConnected === mcpTotal ? '✓ ' : '', "MCP: ", mcpConnected, "/", mcpTotal, " connected"] })), lspTotal > 0 && (_jsxs(Text, { color: lspConnected === lspTotal ? colors.secondary : getStatusColor(lspConnected, lspTotal), children: [lspConnected === lspTotal ? '✓ ' : '', "LSP: ", lspConnected, "/", lspTotal, " connected"] })), contextUsage && contextUsage.contextLimit && (_jsxs(Text, { color: colors.info, children: [_jsx(Text, { bold: true, children: "Context: " }), contextUsage.currentTokens.toLocaleString(), "/", contextUsage.contextLimit.toLocaleString(), " (", Math.round(contextUsage.percentUsed), "%)"] })), autoCompactInfo && (_jsxs(Text, { color: colors.secondary, children: ["Auto-Compact: ", autoCompactInfo.enabled ? '✓' : '✗', autoCompactInfo.hasOverrides && ' (override)'] })), updateInfo?.hasUpdate && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: colors.warning, children: ["\u26A0 v", updateInfo.currentVersion, " \u2192 v", updateInfo.latestVersion] }), updateInfo.updateCommand ? (_jsxs(Text, { color: colors.secondary, children: ["\u21B3 Run: /update or ", updateInfo.updateCommand] })) : updateInfo.updateMessage ? (_jsx(Text, { color: colors.secondary, children: updateInfo.updateMessage })) : null] }))] })) : ( /* Normal/Wide terminal: full layout with TitledBoxWithPreferences */ _jsxs(TitledBoxWithPreferences, { title: "Status", width: boxWidth, borderColor: colors.info, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: colors.info, children: [_jsx(Text, { bold: true, children: "CWD: " }), truncatePath(cwd, maxPathLength)] }), _jsxs(Text, { color: colors.info, children: [_jsx(Text, { bold: true, children: "Config: " }), truncatePath(confDirMap['agents.config.json'], maxPathLength)] }), _jsxs(Text, { color: colors.success, children: [_jsx(Text, { bold: true, children: "Provider: " }), provider, ", ", _jsx(Text, { bold: true, children: "Model: " }), model] }), _jsxs(Text, { color: colors.primary, children: [_jsx(Text, { bold: true, children: "Theme: " }), themes[theme].displayName] }), hasAgentsMd ? (_jsx(Text, { color: colors.secondary, italic: true, children: _jsx(Text, { children: "\u21B3 Using AGENTS.md. Project initialized" }) })) : (_jsx(Text, { color: colors.secondary, italic: true, children: "\u21B3 No AGENTS.md file found, run `/init` to initialize this directory" })), preferencesLoaded && (_jsx(Text, { color: colors.secondary, children: "\u2713 Preferences loaded" })), customCommandsCount !== undefined && customCommandsCount > 0 && (_jsxs(Text, { color: colors.secondary, children: ["\u2713 ", customCommandsCount, " custom commands loaded"] })), vscodeMode && vscodePort && (_jsx(Text, { color: showPortWarning ? colors.warning : colors.secondary, children: showPortWarning ? `⚠ VS Code server on port ${vscodePort} (requested ${vscodeRequestedPort} was in use)` : `✓ VS Code server listening on port ${vscodePort}` })), mcpTotal > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: mcpConnected === mcpTotal ? colors.secondary : getStatusColor(mcpConnected, mcpTotal), children: [mcpConnected === mcpTotal ? '✓ ' : '', "MCP: ", mcpConnected, "/", mcpTotal, " connected"] }), mcpConnected < mcpTotal && (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: mcpStatus .filter(s => s.status === 'failed') .map(server => (_jsxs(Text, { color: colors.error, children: ["\u2022 ", server.name, ":", ' ', server.errorMessage || 'Connection failed'] }, server.name))) }))] })), lspTotal > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: lspConnected === lspTotal ? colors.secondary : getStatusColor(lspConnected, lspTotal), children: [lspConnected === lspTotal ? '✓ ' : '', "LSP: ", lspConnected, "/", lspTotal, " connected"] }), lspConnected < lspTotal && (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: lspStatus .filter(s => s.status === 'failed') .map(server => (_jsxs(Text, { color: colors.error, children: ["\u2022 ", server.name, ":", ' ', server.errorMessage || 'Connection failed'] }, server.name))) }))] })), contextUsage && contextUsage.contextLimit && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: colors.info, children: [_jsx(Text, { bold: true, children: "Context: " }), contextUsage.currentTokens.toLocaleString(), "/", contextUsage.contextLimit.toLocaleString(), " tokens (", Math.round(contextUsage.percentUsed), "%)"] }), contextUsage.percentUsed >= 60 && (_jsx(Text, { color: colors.warning, italic: true, children: "\u21B3 Consider using /compact to reduce context usage" }))] })), autoCompactInfo && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: colors.secondary, children: [_jsx(Text, { bold: true, children: "Auto-Compact: " }), autoCompactInfo.enabled ? '✓ enabled' : '✗ disabled', autoCompactInfo.hasOverrides && ' (session override)'] }), autoCompactInfo.enabled && (_jsxs(Text, { color: colors.secondary, italic: true, children: ["\u21B3 Threshold: ", autoCompactInfo.threshold, "%, Mode:", ' ', autoCompactInfo.mode] }))] })), updateInfo?.hasUpdate && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: colors.warning, children: [_jsx(Text, { bold: true, children: "Update Available: " }), "v", updateInfo.currentVersion, " \u2192 v", updateInfo.latestVersion] }), updateInfo.updateCommand ? (_jsxs(Text, { color: colors.secondary, children: ["\u21B3 Run: /update or ", updateInfo.updateCommand] })) : updateInfo.updateMessage ? (_jsx(Text, { color: colors.secondary, children: updateInfo.updateMessage })) : null] }))] })) })); }); //# sourceMappingURL=status.js.map