@within-7/minto 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +138 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js.map +1 -1
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +5 -5
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +122 -47
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +32 -0
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/i18n/locales/en.js +300 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +301 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +9 -6
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/types/PermissionMode.js.map +1 -1
- package/dist/types/plugin.js +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +67 -13
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +1 -23
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +48 -25
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/skillLoader.js +18 -6
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/teamConfig.js +153 -13
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/stats.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Stats Command\n *\n * Displays usage statistics including messages, sessions, tool calls,\n * and token usage with ASCII visualization charts.\n *\n * Usage:\n * /stats - Show today's statistics and overview\n * /stats --week - Show this week's statistics\n * /stats --month - Show this month's statistics\n * /stats --models - Show model usage details\n * /stats --tools - Show tool usage details\n */\n\nimport React from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport type { Command } from '@commands'\nimport { t } from '@i18n'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport {\n getStats,\n getTodayStats,\n getStatsForDays,\n getModelUsageStats,\n getToolUsageStats,\n type DailyActivity,\n type ModelUsage,\n type ToolUsage,\n type StatsData,\n} from '@utils/stats'\nimport { PressEnterToContinue } from '@components/PressEnterToContinue'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Render an ASCII progress bar\n */\nfunction renderProgressBar(\n value: number,\n max: number,\n width: number = 40,\n): string {\n if (max === 0) return '\u2591'.repeat(width)\n const filled = Math.min(Math.round((value / max) * width), width)\n const empty = width - filled\n return '\u2588'.repeat(filled) + '\u2591'.repeat(empty)\n}\n\n/**\n * Format number with thousands separator\n */\nfunction formatNumber(n: number): string {\n return n.toLocaleString()\n}\n\n/**\n * Format number with K/M suffix for large numbers\n */\nfunction formatCompactNumber(n: number): string {\n if (n >= 1_000_000) {\n return `${(n / 1_000_000).toFixed(1)}M`\n }\n if (n >= 1_000) {\n return `${(n / 1_000).toFixed(1)}K`\n }\n return n.toString()\n}\n\n/**\n * Format cost in USD\n */\nfunction formatCost(cost: number): string {\n if (cost < 0.01) {\n return `$${cost.toFixed(4)}`\n }\n return `$${cost.toFixed(2)}`\n}\n\n/**\n * Get today's date string in YYYY-MM-DD format\n */\nfunction getTodayString(): string {\n return new Date().toISOString().split('T')[0]!\n}\n\n/**\n * Calculate percentage safely (avoid division by zero)\n */\nfunction safePercentage(value: number, total: number): number {\n if (total === 0) return 0\n return Math.round((value / total) * 100)\n}\n\n/**\n * Sum daily stats for a period\n */\nfunction sumDailyStats(days: DailyActivity[]): DailyActivity {\n return days.reduce(\n (acc, day) => ({\n date: '',\n messageCount: acc.messageCount + day.messageCount,\n sessionCount: acc.sessionCount + day.sessionCount,\n toolCallCount: acc.toolCallCount + day.toolCallCount,\n tokensUsed: acc.tokensUsed + day.tokensUsed,\n costEstimate: acc.costEstimate + day.costEstimate,\n }),\n {\n date: '',\n messageCount: 0,\n sessionCount: 0,\n toolCallCount: 0,\n tokensUsed: 0,\n costEstimate: 0,\n },\n )\n}\n\n// ============================================================================\n// UI Components\n// ============================================================================\n\ninterface StatRowProps {\n label: string\n value: number\n max: number\n barWidth?: number\n comparison?: number\n suffix?: string\n}\n\n/**\n * Render a single stat row with progress bar\n */\nfunction StatRow({\n label,\n value,\n max,\n barWidth = 20,\n comparison,\n suffix,\n}: StatRowProps) {\n const bar = renderProgressBar(value, max, barWidth)\n const formattedValue = formatNumber(value)\n const paddedLabel = label.padEnd(12)\n const paddedValue = formattedValue.padStart(8)\n\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>{paddedLabel}</Text>\n <Text color={SEMANTIC_COLORS.primary}>{paddedValue}</Text>\n <Text color={SEMANTIC_COLORS.dim}> </Text>\n <Text color={BRAND_GRADIENT.START}>{bar}</Text>\n {comparison !== undefined && comparison !== 0 && (\n <Text\n color={\n comparison > 0 ? SEMANTIC_COLORS.success : SEMANTIC_COLORS.error\n }\n >\n {' '}\n ({comparison > 0 ? '+' : ''}\n {comparison} {t('commands.stats.vsYesterday')})\n </Text>\n )}\n {suffix && <Text color={SEMANTIC_COLORS.dim}> {suffix}</Text>}\n </Box>\n )\n}\n\ninterface ModelRowProps {\n key?: string\n model: ModelUsage\n totalCalls: number\n barWidth?: number\n}\n\n/**\n * Render a model usage row\n */\nfunction ModelRow({ model, totalCalls, barWidth = 40 }: ModelRowProps) {\n const percentage = safePercentage(model.calls, totalCalls)\n const bar = renderProgressBar(model.calls, totalCalls, barWidth)\n const displayName =\n model.model.length > 14 ? model.model.slice(0, 11) + '...' : model.model\n\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>{displayName.padEnd(14)}</Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {String(percentage).padStart(3)}%\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> </Text>\n <Text color={BRAND_GRADIENT.MIDDLE}>{bar}</Text>\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n ({formatNumber(model.calls)} {t('commands.stats.calls')})\n </Text>\n </Box>\n )\n}\n\ninterface ToolRowProps {\n key?: string\n tool: ToolUsage\n rank: number\n}\n\n/**\n * Render a tool usage row\n */\nfunction ToolRow({ tool, rank }: ToolRowProps) {\n const successRate = safePercentage(tool.successCount, tool.calls)\n const displayName =\n tool.toolName.length > 16\n ? tool.toolName.slice(0, 13) + '...'\n : tool.toolName\n\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>{String(rank).padStart(2)}. </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{displayName.padEnd(16)}</Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(tool.calls).padStart(6)}\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> {t('commands.stats.calls')}</Text>\n {tool.errorCount > 0 && (\n <Text color={SEMANTIC_COLORS.error}> ({successRate}% success)</Text>\n )}\n </Box>\n )\n}\n\ninterface StatsDisplayProps {\n stats: StatsData\n today: DailyActivity | null\n yesterday: DailyActivity | null\n weekStats: DailyActivity\n showWeek: boolean\n showMonth: boolean\n showModels: boolean\n showTools: boolean\n onClose: () => void\n}\n\n/**\n * Main stats display component\n */\nfunction StatsDisplay({\n stats,\n today,\n yesterday,\n weekStats,\n showWeek,\n showMonth,\n showModels,\n showTools,\n onClose,\n}: StatsDisplayProps) {\n useInput((_, key) => {\n if (key.return || key.escape) onClose()\n })\n\n const modelStats = getModelUsageStats()\n const toolStats = getToolUsageStats()\n const totalModelCalls = modelStats.reduce((sum, m) => sum + m.calls, 0)\n\n // Calculate comparison values\n const msgDiff =\n today && yesterday ? today.messageCount - yesterday.messageCount : undefined\n const sessionDiff =\n today && yesterday ? today.sessionCount - yesterday.sessionCount : undefined\n const toolDiff =\n today && yesterday\n ? today.toolCallCount - yesterday.toolCallCount\n : undefined\n const tokenDiff =\n today && yesterday ? today.tokensUsed - yesterday.tokensUsed : undefined\n\n // Find max values for progress bars\n const maxMsg = Math.max(\n today?.messageCount ?? 0,\n yesterday?.messageCount ?? 0,\n 1,\n )\n const maxSession = Math.max(\n today?.sessionCount ?? 0,\n yesterday?.sessionCount ?? 0,\n 1,\n )\n const maxTool = Math.max(\n today?.toolCallCount ?? 0,\n yesterday?.toolCallCount ?? 0,\n 1,\n )\n const maxToken = Math.max(\n today?.tokensUsed ?? 0,\n yesterday?.tokensUsed ?? 0,\n 1,\n )\n\n // Check if we have any data\n const hasData =\n stats.lifetime.totalMessages > 0 || stats.lifetime.totalSessions > 0\n\n if (!hasData) {\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={BRAND_GRADIENT.START}>\n {t('commands.stats.title')}\n </Text>\n </Box>\n <Text color={SEMANTIC_COLORS.dim}>{t('commands.stats.noData')}</Text>\n <Box marginTop={1}>\n <PressEnterToContinue />\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n {/* Header */}\n <Box marginBottom={1}>\n <Text bold color={BRAND_GRADIENT.START}>\n {t('commands.stats.title')}\n </Text>\n </Box>\n\n {/* Divider */}\n <Text color={SEMANTIC_COLORS.dim}>{'\u2500'.repeat(65)}</Text>\n\n {/* Today's Stats */}\n {!showWeek && !showMonth && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>\n {t('commands.stats.today')} ({getTodayString()})\n </Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n <StatRow\n label={t('commands.stats.messages')}\n value={today?.messageCount ?? 0}\n max={maxMsg * 1.2}\n comparison={msgDiff}\n />\n <StatRow\n label={t('commands.stats.sessions')}\n value={today?.sessionCount ?? 0}\n max={maxSession * 1.2}\n comparison={sessionDiff}\n />\n <StatRow\n label={t('commands.stats.toolCalls')}\n value={today?.toolCallCount ?? 0}\n max={maxTool * 1.2}\n comparison={toolDiff}\n />\n <StatRow\n label={t('commands.stats.tokens')}\n value={today?.tokensUsed ?? 0}\n max={maxToken * 1.2}\n comparison={tokenDiff}\n />\n </Box>\n </Box>\n )}\n\n {/* Week Stats */}\n {(showWeek || !showMonth) && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>{t('commands.stats.thisWeek')}</Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalMessages').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(weekStats.messageCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalSessions').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(weekStats.sessionCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalTools').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(weekStats.toolCallCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.estCost').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatCost(weekStats.costEstimate)}\n </Text>\n </Box>\n </Box>\n </Box>\n )}\n\n {/* Month Stats */}\n {showMonth && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>{t('commands.stats.thisMonth')}</Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n {(() => {\n const monthStats = sumDailyStats(getStatsForDays(30))\n return (\n <>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalMessages').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(monthStats.messageCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalSessions').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(monthStats.sessionCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalTools').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(monthStats.toolCallCount)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.estCost').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatCost(monthStats.costEstimate)}\n </Text>\n </Box>\n </>\n )\n })()}\n </Box>\n </Box>\n )}\n\n {/* Model Usage */}\n {(showModels || (!showWeek && !showMonth && !showTools)) &&\n modelStats.length > 0 && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>{t('commands.stats.modelUsage')}</Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n {modelStats.slice(0, 5).map(model => (\n <ModelRow\n key={model.model}\n model={model}\n totalCalls={totalModelCalls}\n />\n ))}\n </Box>\n </Box>\n )}\n\n {/* Tool Usage */}\n {(showTools || (!showWeek && !showMonth && !showModels)) &&\n toolStats.length > 0 && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>{t('commands.stats.topTools')}</Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n {toolStats.slice(0, 5).map((tool, index) => (\n <ToolRow key={tool.toolName} tool={tool} rank={index + 1} />\n ))}\n </Box>\n </Box>\n )}\n\n {/* Lifetime Stats */}\n {!showWeek && !showMonth && !showModels && !showTools && (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold>{t('commands.stats.lifetime')}</Text>\n </Box>\n <Box paddingLeft={2} flexDirection=\"column\">\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalMessages').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(stats.lifetime.totalMessages)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalSessions').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(stats.lifetime.totalSessions)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.totalTools').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatNumber(stats.lifetime.totalToolCalls)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.tokens').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatCompactNumber(stats.lifetime.totalTokens)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.estCost').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.primary}>\n {formatCost(stats.lifetime.totalCost)}\n </Text>\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.secondary}>\n {t('commands.stats.firstUsed').padEnd(16)}\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>\n {stats.lifetime.firstUsed.split('T')[0]}\n </Text>\n </Box>\n </Box>\n </Box>\n )}\n\n {/* Footer Divider */}\n <Text color={SEMANTIC_COLORS.dim}>{'\u2500'.repeat(65)}</Text>\n\n {/* Press Enter to continue */}\n <Box marginTop={1}>\n <PressEnterToContinue />\n </Box>\n </Box>\n )\n}\n\n// ============================================================================\n// Command Definition\n// ============================================================================\n\ninterface ParsedArgs {\n week: boolean\n month: boolean\n models: boolean\n tools: boolean\n}\n\n/**\n * Parse command arguments\n */\nfunction parseArgs(args: string): ParsedArgs {\n const trimmed = args.trim().toLowerCase()\n return {\n week: trimmed.includes('--week') || trimmed.includes('-w'),\n month: trimmed.includes('--month') || trimmed.includes('-m'),\n models: trimmed.includes('--models'),\n tools: trimmed.includes('--tools'),\n }\n}\n\nconst command: Command = {\n name: 'stats',\n description: t('commands.stats.description'),\n isEnabled: true,\n isHidden: false,\n type: 'local-jsx',\n\n userFacingName() {\n return this.name\n },\n\n async call(onDone, _context, args) {\n const parsedArgs = parseArgs(args ?? '')\n const stats = getStats()\n const today = getTodayStats()\n\n // Get yesterday's stats for comparison\n const recentDays = getStatsForDays(2)\n const yesterday = recentDays.length >= 2 ? (recentDays[1] ?? null) : null\n\n // Get week stats\n const weekStats = sumDailyStats(getStatsForDays(7))\n\n return (\n <StatsDisplay\n stats={stats}\n today={today}\n yesterday={yesterday}\n weekStats={weekStats}\n showWeek={parsedArgs.week}\n showMonth={parsedArgs.month}\n showModels={parsedArgs.models}\n showTools={parsedArgs.tools}\n onClose={onDone}\n />\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Stats Command\n *\n * Displays usage statistics using InfoPanel for consistent UI.\n *\n * Usage:\n * /stats - Show today's statistics and overview\n * /stats --week - Show this week's statistics\n * /stats --month - Show this month's statistics\n * /stats --models - Show model usage details\n * /stats --tools - Show tool usage details\n */\n\nimport React from 'react'\nimport type { Command } from '@commands'\nimport { t } from '@i18n'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport {\n getStats,\n getTodayStats,\n getStatsForDays,\n getModelUsageStats,\n getToolUsageStats,\n type DailyActivity,\n} from '@utils/stats'\nimport { InfoPanel } from '@components/InfoPanel'\nimport type { InfoSection, InfoItem } from '@components/InfoPanel'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction formatNumber(n: number): string {\n return n.toLocaleString()\n}\n\nfunction formatCompactNumber(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`\n return n.toString()\n}\n\nfunction formatCost(cost: number): string {\n if (cost < 0.01) return `$${cost.toFixed(4)}`\n return `$${cost.toFixed(2)}`\n}\n\nfunction getTodayString(): string {\n return new Date().toISOString().split('T')[0]!\n}\n\nfunction safePercentage(value: number, total: number): number {\n if (total === 0) return 0\n return Math.round((value / total) * 100)\n}\n\nfunction sumDailyStats(days: DailyActivity[]): DailyActivity {\n return days.reduce(\n (acc, day) => ({\n date: '',\n messageCount: acc.messageCount + day.messageCount,\n sessionCount: acc.sessionCount + day.sessionCount,\n toolCallCount: acc.toolCallCount + day.toolCallCount,\n tokensUsed: acc.tokensUsed + day.tokensUsed,\n costEstimate: acc.costEstimate + day.costEstimate,\n }),\n {\n date: '',\n messageCount: 0,\n sessionCount: 0,\n toolCallCount: 0,\n tokensUsed: 0,\n costEstimate: 0,\n },\n )\n}\n\n// ============================================================================\n// Section Builders\n// ============================================================================\n\nfunction buildTodaySection(\n today: DailyActivity | null,\n yesterday: DailyActivity | null,\n): InfoSection {\n const maxMsg = Math.max(\n today?.messageCount ?? 0,\n yesterday?.messageCount ?? 0,\n 1,\n )\n const maxSession = Math.max(\n today?.sessionCount ?? 0,\n yesterday?.sessionCount ?? 0,\n 1,\n )\n const maxTool = Math.max(\n today?.toolCallCount ?? 0,\n yesterday?.toolCallCount ?? 0,\n 1,\n )\n const maxToken = Math.max(\n today?.tokensUsed ?? 0,\n yesterday?.tokensUsed ?? 0,\n 1,\n )\n\n const msgDiff =\n today && yesterday ? today.messageCount - yesterday.messageCount : undefined\n const sessionDiff =\n today && yesterday ? today.sessionCount - yesterday.sessionCount : undefined\n const toolDiff =\n today && yesterday\n ? today.toolCallCount - yesterday.toolCallCount\n : undefined\n const tokenDiff =\n today && yesterday ? today.tokensUsed - yesterday.tokensUsed : undefined\n\n return {\n title: `${t('commands.stats.today')} (${getTodayString()})`,\n items: [\n {\n label: t('commands.stats.messages'),\n value: formatNumber(today?.messageCount ?? 0),\n progress: {\n percent: safePercentage(today?.messageCount ?? 0, maxMsg * 1.2),\n width: 20,\n },\n delta:\n msgDiff !== undefined\n ? { value: msgDiff, label: t('commands.stats.vsYesterday') }\n : undefined,\n },\n {\n label: t('commands.stats.sessions'),\n value: formatNumber(today?.sessionCount ?? 0),\n progress: {\n percent: safePercentage(today?.sessionCount ?? 0, maxSession * 1.2),\n width: 20,\n },\n delta:\n sessionDiff !== undefined\n ? { value: sessionDiff, label: t('commands.stats.vsYesterday') }\n : undefined,\n },\n {\n label: t('commands.stats.toolCalls'),\n value: formatNumber(today?.toolCallCount ?? 0),\n progress: {\n percent: safePercentage(today?.toolCallCount ?? 0, maxTool * 1.2),\n width: 20,\n },\n delta:\n toolDiff !== undefined\n ? { value: toolDiff, label: t('commands.stats.vsYesterday') }\n : undefined,\n },\n {\n label: t('commands.stats.tokens'),\n value: formatNumber(today?.tokensUsed ?? 0),\n progress: {\n percent: safePercentage(today?.tokensUsed ?? 0, maxToken * 1.2),\n width: 20,\n },\n delta:\n tokenDiff !== undefined\n ? { value: tokenDiff, label: t('commands.stats.vsYesterday') }\n : undefined,\n },\n ],\n }\n}\n\nfunction buildPeriodSection(title: string, stats: DailyActivity): InfoSection {\n return {\n title,\n items: [\n {\n label: t('commands.stats.totalMessages'),\n value: formatNumber(stats.messageCount),\n },\n {\n label: t('commands.stats.totalSessions'),\n value: formatNumber(stats.sessionCount),\n },\n {\n label: t('commands.stats.totalTools'),\n value: formatNumber(stats.toolCallCount),\n },\n {\n label: t('commands.stats.estCost'),\n value: formatCost(stats.costEstimate),\n },\n ],\n }\n}\n\nfunction buildModelSection(): InfoSection | null {\n const modelStats = getModelUsageStats()\n if (modelStats.length === 0) return null\n\n const totalCalls = modelStats.reduce((sum, m) => sum + m.calls, 0)\n const items: InfoItem[] = modelStats.slice(0, 5).map(model => {\n const percentage = safePercentage(model.calls, totalCalls)\n const displayName =\n model.model.length > 14 ? model.model.slice(0, 11) + '...' : model.model\n return {\n label: displayName,\n value: `${formatNumber(model.calls)} ${t('commands.stats.calls')}`,\n progress: {\n percent: percentage,\n width: 20,\n color: BRAND_GRADIENT.MIDDLE,\n },\n }\n })\n\n return { title: t('commands.stats.modelUsage'), items }\n}\n\nfunction buildToolSection(): InfoSection | null {\n const toolStats = getToolUsageStats()\n if (toolStats.length === 0) return null\n\n const items: InfoItem[] = toolStats.slice(0, 5).map((tool, index) => {\n const successRate = safePercentage(tool.successCount, tool.calls)\n const displayName =\n tool.toolName.length > 16\n ? tool.toolName.slice(0, 13) + '...'\n : tool.toolName\n return {\n label: `${index + 1}. ${displayName}`,\n value: `${formatNumber(tool.calls)} ${t('commands.stats.calls')}${tool.errorCount > 0 ? ` (${successRate}% success)` : ''}`,\n }\n })\n\n return { title: t('commands.stats.topTools'), items }\n}\n\nfunction buildLifetimeSection(): InfoSection {\n const stats = getStats()\n return {\n title: t('commands.stats.lifetime'),\n items: [\n {\n label: t('commands.stats.totalMessages'),\n value: formatNumber(stats.lifetime.totalMessages),\n },\n {\n label: t('commands.stats.totalSessions'),\n value: formatNumber(stats.lifetime.totalSessions),\n },\n {\n label: t('commands.stats.totalTools'),\n value: formatNumber(stats.lifetime.totalToolCalls),\n },\n {\n label: t('commands.stats.tokens'),\n value: formatCompactNumber(stats.lifetime.totalTokens),\n },\n {\n label: t('commands.stats.estCost'),\n value: formatCost(stats.lifetime.totalCost),\n },\n {\n label: t('commands.stats.firstUsed'),\n value: stats.lifetime.firstUsed.split('T')[0] || '',\n valueColor: SEMANTIC_COLORS.dim,\n },\n ],\n }\n}\n\n// ============================================================================\n// Command Definition\n// ============================================================================\n\ninterface ParsedArgs {\n week: boolean\n month: boolean\n models: boolean\n tools: boolean\n}\n\nfunction parseArgs(args: string): ParsedArgs {\n const trimmed = args.trim().toLowerCase()\n return {\n week: trimmed.includes('--week') || trimmed.includes('-w'),\n month: trimmed.includes('--month') || trimmed.includes('-m'),\n models: trimmed.includes('--models'),\n tools: trimmed.includes('--tools'),\n }\n}\n\nconst command: Command = {\n name: 'stats',\n description: t('commands.stats.description'),\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n type: 'local-jsx',\n\n userFacingName() {\n return this.name\n },\n\n async call(onDone, _context, args) {\n const parsedArgs = parseArgs(args ?? '')\n const stats = getStats()\n const today = getTodayStats()\n\n const hasData =\n stats.lifetime.totalMessages > 0 || stats.lifetime.totalSessions > 0\n\n if (!hasData) {\n return (\n <InfoPanel\n title={t('commands.stats.title')}\n sections={[\n {\n title: t('commands.stats.today'),\n items: [\n {\n label: '',\n value: t('commands.stats.noData'),\n valueColor: SEMANTIC_COLORS.dim,\n },\n ],\n },\n ]}\n onClose={onDone}\n />\n )\n }\n\n const recentDays = getStatsForDays(2)\n const yesterday = recentDays.length >= 2 ? (recentDays[1] ?? null) : null\n const weekStats = sumDailyStats(getStatsForDays(7))\n\n const sections: InfoSection[] = []\n\n // Today's stats\n if (!parsedArgs.week && !parsedArgs.month) {\n sections.push(buildTodaySection(today, yesterday))\n }\n\n // Week stats\n if (parsedArgs.week || !parsedArgs.month) {\n sections.push(buildPeriodSection(t('commands.stats.thisWeek'), weekStats))\n }\n\n // Month stats\n if (parsedArgs.month) {\n const monthStats = sumDailyStats(getStatsForDays(30))\n sections.push(\n buildPeriodSection(t('commands.stats.thisMonth'), monthStats),\n )\n }\n\n // Model usage\n if (\n parsedArgs.models ||\n (!parsedArgs.week && !parsedArgs.month && !parsedArgs.tools)\n ) {\n const modelSection = buildModelSection()\n if (modelSection) sections.push(modelSection)\n }\n\n // Tool usage\n if (\n parsedArgs.tools ||\n (!parsedArgs.week && !parsedArgs.month && !parsedArgs.models)\n ) {\n const toolSection = buildToolSection()\n if (toolSection) sections.push(toolSection)\n }\n\n // Lifetime stats\n if (\n !parsedArgs.week &&\n !parsedArgs.month &&\n !parsedArgs.models &&\n !parsedArgs.tools\n ) {\n sections.push(buildLifetimeSection())\n }\n\n return (\n <InfoPanel\n title={t('commands.stats.title')}\n sections={sections}\n onClose={onDone}\n />\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/status.js
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Box, Text, useInput } from "ink";
|
|
3
2
|
import { getModelManager } from "../utils/model.js";
|
|
4
3
|
import { getCwd } from "../utils/state.js";
|
|
5
4
|
import { MACRO } from "../constants/macros.js";
|
|
6
5
|
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
status,
|
|
10
|
-
onClose
|
|
11
|
-
}) => {
|
|
12
|
-
useInput((_, key) => {
|
|
13
|
-
if (key.return || key.escape) onClose();
|
|
14
|
-
});
|
|
15
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, "Minto Status")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Version Info"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Minto: "), /* @__PURE__ */ React.createElement(Text, { color: "green" }, "v", status.version)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Node.js: "), /* @__PURE__ */ React.createElement(Text, null, status.nodeVersion)), status.bunVersion && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Bun: "), /* @__PURE__ */ React.createElement(Text, null, status.bunVersion)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Platform: "), /* @__PURE__ */ React.createElement(Text, null, status.platform)))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Environment"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "CWD: "), /* @__PURE__ */ React.createElement(Text, null, status.cwd)))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Configuration"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2, flexDirection: "column" }, status.modelInfo ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Model: "), /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, status.modelInfo.name)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Provider: "), /* @__PURE__ */ React.createElement(Text, null, status.modelInfo.provider)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Context: "), /* @__PURE__ */ React.createElement(Text, null, (status.modelInfo.contextLength / 1e3).toFixed(0), "k tokens"))) : /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "No model configured"))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "API Connection"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Status: "), status.apiConnected ? /* @__PURE__ */ React.createElement(Text, { color: "green" }, "\u25CF Connected") : /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u25CB Not connected")))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(PressEnterToContinue, null)));
|
|
16
|
-
};
|
|
6
|
+
import { InfoPanel } from "../components/InfoPanel/index.js";
|
|
7
|
+
import { t } from "../i18n/index.js";
|
|
17
8
|
async function getStatusInfo() {
|
|
18
9
|
let modelInfo = null;
|
|
19
10
|
let apiConnected = false;
|
|
@@ -44,18 +35,89 @@ async function getStatusInfo() {
|
|
|
44
35
|
apiConnected
|
|
45
36
|
};
|
|
46
37
|
}
|
|
38
|
+
function buildSections(status) {
|
|
39
|
+
const sections = [];
|
|
40
|
+
const versionItems = [
|
|
41
|
+
{
|
|
42
|
+
label: "Minto",
|
|
43
|
+
value: `v${status.version}`,
|
|
44
|
+
valueColor: SEMANTIC_COLORS.success
|
|
45
|
+
},
|
|
46
|
+
{ label: "Node.js", value: status.nodeVersion }
|
|
47
|
+
];
|
|
48
|
+
if (status.bunVersion) {
|
|
49
|
+
versionItems.push({ label: "Bun", value: status.bunVersion });
|
|
50
|
+
}
|
|
51
|
+
versionItems.push({ label: "Platform", value: status.platform });
|
|
52
|
+
sections.push({
|
|
53
|
+
title: t("commands.status.versionInfo"),
|
|
54
|
+
items: versionItems
|
|
55
|
+
});
|
|
56
|
+
sections.push({
|
|
57
|
+
title: t("commands.status.environment"),
|
|
58
|
+
items: [{ label: "CWD", value: status.cwd }]
|
|
59
|
+
});
|
|
60
|
+
if (status.modelInfo) {
|
|
61
|
+
sections.push({
|
|
62
|
+
title: t("commands.status.modelConfiguration"),
|
|
63
|
+
items: [
|
|
64
|
+
{
|
|
65
|
+
label: "Model",
|
|
66
|
+
value: status.modelInfo.name,
|
|
67
|
+
valueColor: SEMANTIC_COLORS.info
|
|
68
|
+
},
|
|
69
|
+
{ label: "Provider", value: status.modelInfo.provider },
|
|
70
|
+
{
|
|
71
|
+
label: "Context",
|
|
72
|
+
value: `${(status.modelInfo.contextLength / 1e3).toFixed(0)}k tokens`
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
sections.push({
|
|
78
|
+
title: t("commands.status.modelConfiguration"),
|
|
79
|
+
items: [
|
|
80
|
+
{
|
|
81
|
+
label: "Status",
|
|
82
|
+
value: t("commands.status.notConfigured"),
|
|
83
|
+
valueColor: "#FFB86C"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
sections.push({
|
|
89
|
+
title: t("commands.status.apiConnection"),
|
|
90
|
+
items: [
|
|
91
|
+
{
|
|
92
|
+
label: "Status",
|
|
93
|
+
value: status.apiConnected ? `\u25CF ${t("commands.status.connected")}` : `\u25CB ${t("commands.status.notConnected")}`,
|
|
94
|
+
valueColor: status.apiConnected ? SEMANTIC_COLORS.success : SEMANTIC_COLORS.error
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
});
|
|
98
|
+
return sections;
|
|
99
|
+
}
|
|
47
100
|
const command = {
|
|
48
101
|
name: "status",
|
|
49
|
-
description: "
|
|
102
|
+
description: t("commands.status.description"),
|
|
50
103
|
isEnabled: true,
|
|
51
104
|
isHidden: false,
|
|
105
|
+
hidePromptInput: true,
|
|
52
106
|
type: "local-jsx",
|
|
53
107
|
userFacingName() {
|
|
54
108
|
return this.name;
|
|
55
109
|
},
|
|
56
110
|
async call(onDone) {
|
|
57
111
|
const status = await getStatusInfo();
|
|
58
|
-
|
|
112
|
+
const sections = buildSections(status);
|
|
113
|
+
return /* @__PURE__ */ React.createElement(
|
|
114
|
+
InfoPanel,
|
|
115
|
+
{
|
|
116
|
+
title: t("commands.status.title"),
|
|
117
|
+
sections,
|
|
118
|
+
onClose: onDone
|
|
119
|
+
}
|
|
120
|
+
);
|
|
59
121
|
}
|
|
60
122
|
};
|
|
61
123
|
var status_default = command;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/status.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Status Command\n *\n * Shows version information, connection status, and system health.\n */\n\nimport React from 'react'\nimport
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Status Command\n *\n * Shows version information, connection status, and system health.\n * Uses InfoPanel for consistent UI.\n */\n\nimport React from 'react'\nimport type { Command } from '@commands'\nimport { getModelManager } from '@utils/model'\nimport { getCwd } from '@utils/state'\nimport { MACRO } from '@constants/macros'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { InfoPanel } from '@components/InfoPanel'\nimport type { InfoSection } from '@components/InfoPanel'\nimport { t } from '@i18n'\n\ninterface StatusInfo {\n version: string\n nodeVersion: string\n bunVersion: string | null\n platform: string\n cwd: string\n modelInfo: {\n name: string\n provider: string\n contextLength: number\n } | null\n apiConnected: boolean\n}\n\nasync function getStatusInfo(): Promise<StatusInfo> {\n let modelInfo: StatusInfo['modelInfo'] = null\n let apiConnected = false\n\n try {\n const modelManager = getModelManager()\n const profile = modelManager.resolveModel('main')\n if (profile) {\n modelInfo = {\n name: profile.name || profile.modelName,\n provider: profile.provider || 'anthropic',\n contextLength: profile.contextLength || 200_000,\n }\n apiConnected = true\n }\n } catch {\n // Model not configured\n }\n\n let bunVersion: string | null = null\n if (typeof Bun !== 'undefined') {\n bunVersion = Bun.version\n }\n\n return {\n version: MACRO.VERSION,\n nodeVersion: process.version,\n bunVersion,\n platform: `${process.platform} (${process.arch})`,\n cwd: getCwd(),\n modelInfo,\n apiConnected,\n }\n}\n\nfunction buildSections(status: StatusInfo): InfoSection[] {\n const sections: InfoSection[] = []\n\n // Version Info\n const versionItems = [\n {\n label: 'Minto',\n value: `v${status.version}`,\n valueColor: SEMANTIC_COLORS.success,\n },\n { label: 'Node.js', value: status.nodeVersion },\n ]\n if (status.bunVersion) {\n versionItems.push({ label: 'Bun', value: status.bunVersion })\n }\n versionItems.push({ label: 'Platform', value: status.platform })\n sections.push({\n title: t('commands.status.versionInfo'),\n items: versionItems,\n })\n\n // Environment\n sections.push({\n title: t('commands.status.environment'),\n items: [{ label: 'CWD', value: status.cwd }],\n })\n\n // Model Configuration\n if (status.modelInfo) {\n sections.push({\n title: t('commands.status.modelConfiguration'),\n items: [\n {\n label: 'Model',\n value: status.modelInfo.name,\n valueColor: SEMANTIC_COLORS.info,\n },\n { label: 'Provider', value: status.modelInfo.provider },\n {\n label: 'Context',\n value: `${(status.modelInfo.contextLength / 1000).toFixed(0)}k tokens`,\n },\n ],\n })\n } else {\n sections.push({\n title: t('commands.status.modelConfiguration'),\n items: [\n {\n label: 'Status',\n value: t('commands.status.notConfigured'),\n valueColor: '#FFB86C',\n },\n ],\n })\n }\n\n // API Connection\n sections.push({\n title: t('commands.status.apiConnection'),\n items: [\n {\n label: 'Status',\n value: status.apiConnected\n ? `\\u25CF ${t('commands.status.connected')}`\n : `\\u25CB ${t('commands.status.notConnected')}`,\n valueColor: status.apiConnected\n ? SEMANTIC_COLORS.success\n : SEMANTIC_COLORS.error,\n },\n ],\n })\n\n return sections\n}\n\nconst command: Command = {\n name: 'status',\n description: t('commands.status.description'),\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n type: 'local-jsx',\n\n userFacingName() {\n return this.name\n },\n\n async call(onDone) {\n const status = await getStatusInfo()\n const sections = buildSections(status)\n\n return (\n <InfoPanel\n title={t('commands.status.title')}\n sections={sections}\n onClose={onDone}\n />\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "AAOA,OAAO,WAAW;AAElB,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAE1B,SAAS,SAAS;AAgBlB,eAAe,gBAAqC;AAClD,MAAI,YAAqC;AACzC,MAAI,eAAe;AAEnB,MAAI;AACF,UAAM,eAAe,gBAAgB;AACrC,UAAM,UAAU,aAAa,aAAa,MAAM;AAChD,QAAI,SAAS;AACX,kBAAY;AAAA,QACV,MAAM,QAAQ,QAAQ,QAAQ;AAAA,QAC9B,UAAU,QAAQ,YAAY;AAAA,QAC9B,eAAe,QAAQ,iBAAiB;AAAA,MAC1C;AACA,qBAAe;AAAA,IACjB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI,aAA4B;AAChC,MAAI,OAAO,QAAQ,aAAa;AAC9B,iBAAa,IAAI;AAAA,EACnB;AAEA,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,aAAa,QAAQ;AAAA,IACrB;AAAA,IACA,UAAU,GAAG,QAAQ,QAAQ,KAAK,QAAQ,IAAI;AAAA,IAC9C,KAAK,OAAO;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAAmC;AACxD,QAAM,WAA0B,CAAC;AAGjC,QAAM,eAAe;AAAA,IACnB;AAAA,MACE,OAAO;AAAA,MACP,OAAO,IAAI,OAAO,OAAO;AAAA,MACzB,YAAY,gBAAgB;AAAA,IAC9B;AAAA,IACA,EAAE,OAAO,WAAW,OAAO,OAAO,YAAY;AAAA,EAChD;AACA,MAAI,OAAO,YAAY;AACrB,iBAAa,KAAK,EAAE,OAAO,OAAO,OAAO,OAAO,WAAW,CAAC;AAAA,EAC9D;AACA,eAAa,KAAK,EAAE,OAAO,YAAY,OAAO,OAAO,SAAS,CAAC;AAC/D,WAAS,KAAK;AAAA,IACZ,OAAO,EAAE,6BAA6B;AAAA,IACtC,OAAO;AAAA,EACT,CAAC;AAGD,WAAS,KAAK;AAAA,IACZ,OAAO,EAAE,6BAA6B;AAAA,IACtC,OAAO,CAAC,EAAE,OAAO,OAAO,OAAO,OAAO,IAAI,CAAC;AAAA,EAC7C,CAAC;AAGD,MAAI,OAAO,WAAW;AACpB,aAAS,KAAK;AAAA,MACZ,OAAO,EAAE,oCAAoC;AAAA,MAC7C,OAAO;AAAA,QACL;AAAA,UACE,OAAO;AAAA,UACP,OAAO,OAAO,UAAU;AAAA,UACxB,YAAY,gBAAgB;AAAA,QAC9B;AAAA,QACA,EAAE,OAAO,YAAY,OAAO,OAAO,UAAU,SAAS;AAAA,QACtD;AAAA,UACE,OAAO;AAAA,UACP,OAAO,IAAI,OAAO,UAAU,gBAAgB,KAAM,QAAQ,CAAC,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,aAAS,KAAK;AAAA,MACZ,OAAO,EAAE,oCAAoC;AAAA,MAC7C,OAAO;AAAA,QACL;AAAA,UACE,OAAO;AAAA,UACP,OAAO,EAAE,+BAA+B;AAAA,UACxC,YAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,WAAS,KAAK;AAAA,IACZ,OAAO,EAAE,+BAA+B;AAAA,IACxC,OAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,OAAO,OAAO,eACV,UAAU,EAAE,2BAA2B,CAAC,KACxC,UAAU,EAAE,8BAA8B,CAAC;AAAA,QAC/C,YAAY,OAAO,eACf,gBAAgB,UAChB,gBAAgB;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,MAAM,UAAmB;AAAA,EACvB,MAAM;AAAA,EACN,aAAa,EAAE,6BAA6B;AAAA,EAC5C,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,MAAM;AAAA,EAEN,iBAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,KAAK,QAAQ;AACjB,UAAM,SAAS,MAAM,cAAc;AACnC,UAAM,WAAW,cAAc,MAAM;AAErC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,uBAAuB;AAAA,QAChC;AAAA,QACA,SAAS;AAAA;AAAA,IACX;AAAA,EAEJ;AACF;AAEA,IAAO,iBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|