@within-7/minto 0.2.0 → 0.3.0
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 +22 -24
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/context.js +2 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +2 -1
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/mcp-interactive.js +7 -6
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +3 -2
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +4 -3
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/sandbox.js +4 -3
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/CollapsibleHint.js +2 -1
- package/dist/components/CollapsibleHint.js.map +2 -2
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +8 -11
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +23 -67
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +4 -3
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +26 -13
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +3 -2
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/PromptInput.js +88 -75
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +71 -22
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +4 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +7 -4
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +14 -11
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoPanel.js +44 -26
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +4 -3
- package/dist/components/TreeConnector.js.map +2 -2
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +17 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +8 -4
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +2 -1
- package/dist/components/messages/GroupRenderer.js.map +2 -2
- package/dist/components/messages/NestedTasksPreview.js +13 -1
- package/dist/components/messages/NestedTasksPreview.js.map +2 -2
- package/dist/components/messages/ParallelTasksGroupView.js +4 -3
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +35 -15
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskOutputContent.js +9 -6
- package/dist/components/messages/TaskOutputContent.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/colors.js +90 -72
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/costTracker.js +9 -18
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +2 -2
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
- package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
- package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
- package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
- package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/entrypoints/cli.js +115 -87
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +30 -6
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useLogMessages.js +12 -1
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/i18n/locales/en.js +6 -5
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +6 -5
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/permissions.js +28 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +78 -4
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +23 -3
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/claude.js +54 -3
- package/dist/services/claude.js.map +2 -2
- package/dist/services/intelligentCompactor.js +1 -1
- package/dist/services/intelligentCompactor.js.map +2 -2
- package/dist/services/mcpClient.js +81 -25
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +58 -17
- package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +22 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +178 -34
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +6 -3
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +4 -2
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +1 -1
- package/dist/tools/PlanModeTool/prompt.js.map +1 -1
- package/dist/tools/SkillTool/SkillTool.js +4 -3
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +8 -0
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/config.js +47 -5
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/permissions/filesystem.js +5 -1
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +9 -9
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +5 -4
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +9 -7
- package/dist/hooks/useCancelRequest.js +0 -31
- package/dist/hooks/useCancelRequest.js.map +0 -7
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
import { DEFAULT_ESTIMATION_CONFIG } from "./tokenStats.js";
|
|
3
|
+
class TokenStatsManagerImpl extends EventEmitter {
|
|
4
|
+
static instance = null;
|
|
5
|
+
// Global aggregated stats
|
|
6
|
+
globalStats = this.createEmptyStats();
|
|
7
|
+
// Per-agent stats (agentId → stats)
|
|
8
|
+
agentStats = /* @__PURE__ */ new Map();
|
|
9
|
+
// Per-request records (requestId → record) - for debugging, with LRU eviction
|
|
10
|
+
requestRecords = /* @__PURE__ */ new Map();
|
|
11
|
+
// Configuration
|
|
12
|
+
static MAX_REQUEST_RECORDS = 1e3;
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.setMaxListeners(100);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the singleton instance
|
|
19
|
+
*/
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!TokenStatsManagerImpl.instance) {
|
|
22
|
+
TokenStatsManagerImpl.instance = new TokenStatsManagerImpl();
|
|
23
|
+
}
|
|
24
|
+
return TokenStatsManagerImpl.instance;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Record token usage from an API response
|
|
28
|
+
*
|
|
29
|
+
* This is the PRIMARY entry point - called from claude.ts
|
|
30
|
+
* after every API response.
|
|
31
|
+
*
|
|
32
|
+
* @param usage - Raw token usage from API
|
|
33
|
+
* @param costUSD - Calculated cost in USD
|
|
34
|
+
* @param model - Model name used
|
|
35
|
+
* @param context - Optional tracking context (agentId, toolUseId)
|
|
36
|
+
*/
|
|
37
|
+
recordUsage(usage, costUSD, model, context) {
|
|
38
|
+
const record = {
|
|
39
|
+
inputTokens: usage.inputTokens,
|
|
40
|
+
outputTokens: usage.outputTokens,
|
|
41
|
+
cacheCreationTokens: usage.cacheCreationTokens ?? 0,
|
|
42
|
+
cacheReadTokens: usage.cacheReadTokens ?? 0,
|
|
43
|
+
totalTokens: usage.inputTokens + usage.outputTokens,
|
|
44
|
+
estimatedCostUSD: costUSD,
|
|
45
|
+
source: "api",
|
|
46
|
+
timestamp: Date.now(),
|
|
47
|
+
model
|
|
48
|
+
};
|
|
49
|
+
this.aggregateInto(this.globalStats, record);
|
|
50
|
+
if (context?.agentId) {
|
|
51
|
+
let stats = this.agentStats.get(context.agentId);
|
|
52
|
+
if (!stats) {
|
|
53
|
+
stats = this.createEmptyStats();
|
|
54
|
+
this.agentStats.set(context.agentId, stats);
|
|
55
|
+
}
|
|
56
|
+
this.aggregateInto(stats, record);
|
|
57
|
+
}
|
|
58
|
+
const requestId = context?.toolUseId ?? `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
59
|
+
this.requestRecords.set(requestId, record);
|
|
60
|
+
if (this.requestRecords.size > TokenStatsManagerImpl.MAX_REQUEST_RECORDS) {
|
|
61
|
+
const oldestKey = this.requestRecords.keys().next().value;
|
|
62
|
+
if (oldestKey) this.requestRecords.delete(oldestKey);
|
|
63
|
+
}
|
|
64
|
+
const scope = context?.agentId ? { type: "agent", agentId: context.agentId } : { type: "global" };
|
|
65
|
+
this.emitEvent({
|
|
66
|
+
eventType: "usage_recorded",
|
|
67
|
+
scope,
|
|
68
|
+
usage: record,
|
|
69
|
+
aggregated: context?.agentId ? this.agentStats.get(context.agentId) : this.globalStats,
|
|
70
|
+
globalStats: this.globalStats
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Estimate token count from text
|
|
75
|
+
*
|
|
76
|
+
* Uses a simple character-based estimation. This is a fallback
|
|
77
|
+
* when the API doesn't return token counts.
|
|
78
|
+
*
|
|
79
|
+
* @param text - Text to estimate tokens for
|
|
80
|
+
* @returns Estimated token count
|
|
81
|
+
*/
|
|
82
|
+
estimateTokens(text) {
|
|
83
|
+
return Math.ceil(text.length / DEFAULT_ESTIMATION_CONFIG.charsPerToken);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Record estimated usage when API doesn't return token counts
|
|
87
|
+
*
|
|
88
|
+
* This is used as a fallback for APIs that don't return usage data.
|
|
89
|
+
*
|
|
90
|
+
* @param inputText - Input text (prompt)
|
|
91
|
+
* @param outputText - Output text (completion)
|
|
92
|
+
* @param model - Model name
|
|
93
|
+
* @param context - Optional tracking context
|
|
94
|
+
*/
|
|
95
|
+
recordEstimatedUsage(inputText, outputText, model, context) {
|
|
96
|
+
const inputTokens = this.estimateTokens(inputText);
|
|
97
|
+
const outputTokens = this.estimateTokens(outputText);
|
|
98
|
+
const costUSD = inputTokens / 1e6 * DEFAULT_ESTIMATION_CONFIG.defaultInputCostPerMillion + outputTokens / 1e6 * DEFAULT_ESTIMATION_CONFIG.defaultOutputCostPerMillion;
|
|
99
|
+
const record = {
|
|
100
|
+
inputTokens,
|
|
101
|
+
outputTokens,
|
|
102
|
+
cacheCreationTokens: 0,
|
|
103
|
+
cacheReadTokens: 0,
|
|
104
|
+
totalTokens: inputTokens + outputTokens,
|
|
105
|
+
estimatedCostUSD: costUSD,
|
|
106
|
+
source: "estimated",
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
model
|
|
109
|
+
};
|
|
110
|
+
this.aggregateInto(this.globalStats, record);
|
|
111
|
+
if (context?.agentId) {
|
|
112
|
+
let stats = this.agentStats.get(context.agentId);
|
|
113
|
+
if (!stats) {
|
|
114
|
+
stats = this.createEmptyStats();
|
|
115
|
+
this.agentStats.set(context.agentId, stats);
|
|
116
|
+
}
|
|
117
|
+
this.aggregateInto(stats, record);
|
|
118
|
+
}
|
|
119
|
+
this.emitEvent({
|
|
120
|
+
eventType: "usage_recorded",
|
|
121
|
+
scope: { type: "global" },
|
|
122
|
+
usage: record,
|
|
123
|
+
aggregated: this.globalStats,
|
|
124
|
+
globalStats: this.globalStats
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// ===== Getters =====
|
|
128
|
+
/**
|
|
129
|
+
* Get global aggregated statistics
|
|
130
|
+
*/
|
|
131
|
+
getGlobalStats() {
|
|
132
|
+
return this.cloneStats(this.globalStats);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get statistics for a specific agent
|
|
136
|
+
*
|
|
137
|
+
* @param agentId - Agent ID to get stats for
|
|
138
|
+
* @returns Agent stats or null if not found
|
|
139
|
+
*/
|
|
140
|
+
getAgentStats(agentId) {
|
|
141
|
+
const stats = this.agentStats.get(agentId);
|
|
142
|
+
return stats ? this.cloneStats(stats) : null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get all agent statistics
|
|
146
|
+
*/
|
|
147
|
+
getAllAgentStats() {
|
|
148
|
+
const result = /* @__PURE__ */ new Map();
|
|
149
|
+
for (const [agentId, stats] of this.agentStats) {
|
|
150
|
+
result.set(agentId, this.cloneStats(stats));
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get a specific request record
|
|
156
|
+
*/
|
|
157
|
+
getRequestRecord(requestId) {
|
|
158
|
+
return this.requestRecords.get(requestId) ?? null;
|
|
159
|
+
}
|
|
160
|
+
// ===== Backward Compatibility Layer =====
|
|
161
|
+
/**
|
|
162
|
+
* Get total tokens (for costTracker.getTokenCounts compatibility)
|
|
163
|
+
*
|
|
164
|
+
* This method provides backward compatibility with the existing
|
|
165
|
+
* costTracker.getTokenCounts() interface.
|
|
166
|
+
*/
|
|
167
|
+
getTokenCounts() {
|
|
168
|
+
return {
|
|
169
|
+
input: this.globalStats.totalInputTokens,
|
|
170
|
+
output: this.globalStats.totalOutputTokens,
|
|
171
|
+
cacheCreation: this.globalStats.totalCacheCreationTokens,
|
|
172
|
+
cacheRead: this.globalStats.totalCacheReadTokens,
|
|
173
|
+
total: this.globalStats.grandTotalTokens
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// ===== Event Subscription =====
|
|
177
|
+
/**
|
|
178
|
+
* Subscribe to all stats updates
|
|
179
|
+
*
|
|
180
|
+
* @param callback - Called when any stats change
|
|
181
|
+
* @returns Unsubscribe function
|
|
182
|
+
*/
|
|
183
|
+
onStatsUpdate(callback) {
|
|
184
|
+
this.on("stats_update", callback);
|
|
185
|
+
return () => this.off("stats_update", callback);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Subscribe to updates for a specific agent
|
|
189
|
+
*
|
|
190
|
+
* @param agentId - Agent ID to subscribe to
|
|
191
|
+
* @param callback - Called when agent stats change
|
|
192
|
+
* @returns Unsubscribe function
|
|
193
|
+
*/
|
|
194
|
+
onAgentStatsUpdate(agentId, callback) {
|
|
195
|
+
const handler = (event) => {
|
|
196
|
+
if (event.scope.type === "agent" && event.scope.agentId === agentId) {
|
|
197
|
+
callback(event.aggregated);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
this.on("stats_update", handler);
|
|
201
|
+
return () => this.off("stats_update", handler);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Subscribe to global stats updates only
|
|
205
|
+
*
|
|
206
|
+
* @param callback - Called when global stats change
|
|
207
|
+
* @returns Unsubscribe function
|
|
208
|
+
*/
|
|
209
|
+
onGlobalStatsUpdate(callback) {
|
|
210
|
+
const handler = (event) => {
|
|
211
|
+
callback(event.globalStats);
|
|
212
|
+
};
|
|
213
|
+
this.on("stats_update", handler);
|
|
214
|
+
return () => this.off("stats_update", handler);
|
|
215
|
+
}
|
|
216
|
+
// ===== Agent Lifecycle =====
|
|
217
|
+
/**
|
|
218
|
+
* Mark an agent's scope as completed
|
|
219
|
+
*
|
|
220
|
+
* This emits a scope_completed event and optionally
|
|
221
|
+
* cleans up the agent's stats from memory.
|
|
222
|
+
*
|
|
223
|
+
* @param agentId - Agent ID to complete
|
|
224
|
+
* @param cleanup - Whether to remove from memory (default: false)
|
|
225
|
+
*/
|
|
226
|
+
completeAgentScope(agentId, cleanup = false) {
|
|
227
|
+
const stats = this.agentStats.get(agentId);
|
|
228
|
+
if (!stats) return;
|
|
229
|
+
this.emitEvent({
|
|
230
|
+
eventType: "scope_completed",
|
|
231
|
+
scope: { type: "agent", agentId },
|
|
232
|
+
aggregated: stats,
|
|
233
|
+
globalStats: this.globalStats
|
|
234
|
+
});
|
|
235
|
+
if (cleanup) {
|
|
236
|
+
this.agentStats.delete(agentId);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// ===== Internal Methods =====
|
|
240
|
+
createEmptyStats() {
|
|
241
|
+
return {
|
|
242
|
+
totalInputTokens: 0,
|
|
243
|
+
totalOutputTokens: 0,
|
|
244
|
+
totalCacheCreationTokens: 0,
|
|
245
|
+
totalCacheReadTokens: 0,
|
|
246
|
+
grandTotalTokens: 0,
|
|
247
|
+
totalCostUSD: 0,
|
|
248
|
+
requestCount: 0,
|
|
249
|
+
byModel: /* @__PURE__ */ new Map()
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
aggregateInto(stats, record) {
|
|
253
|
+
stats.totalInputTokens += record.inputTokens;
|
|
254
|
+
stats.totalOutputTokens += record.outputTokens;
|
|
255
|
+
stats.totalCacheCreationTokens += record.cacheCreationTokens;
|
|
256
|
+
stats.totalCacheReadTokens += record.cacheReadTokens;
|
|
257
|
+
stats.grandTotalTokens += record.totalTokens;
|
|
258
|
+
stats.totalCostUSD += record.estimatedCostUSD;
|
|
259
|
+
stats.requestCount += 1;
|
|
260
|
+
if (!stats.firstRequestTime) {
|
|
261
|
+
stats.firstRequestTime = record.timestamp;
|
|
262
|
+
}
|
|
263
|
+
stats.lastRequestTime = record.timestamp;
|
|
264
|
+
const modelStats = stats.byModel.get(record.model);
|
|
265
|
+
if (modelStats) {
|
|
266
|
+
modelStats.inputTokens += record.inputTokens;
|
|
267
|
+
modelStats.outputTokens += record.outputTokens;
|
|
268
|
+
modelStats.totalTokens += record.totalTokens;
|
|
269
|
+
modelStats.estimatedCostUSD += record.estimatedCostUSD;
|
|
270
|
+
modelStats.requestCount += 1;
|
|
271
|
+
} else {
|
|
272
|
+
stats.byModel.set(record.model, {
|
|
273
|
+
model: record.model,
|
|
274
|
+
inputTokens: record.inputTokens,
|
|
275
|
+
outputTokens: record.outputTokens,
|
|
276
|
+
totalTokens: record.totalTokens,
|
|
277
|
+
estimatedCostUSD: record.estimatedCostUSD,
|
|
278
|
+
requestCount: 1
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
cloneStats(stats) {
|
|
283
|
+
return {
|
|
284
|
+
...stats,
|
|
285
|
+
byModel: new Map(stats.byModel)
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
emitEvent(event) {
|
|
289
|
+
this.emit("stats_update", event);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Reset all stats (for testing only)
|
|
293
|
+
*/
|
|
294
|
+
resetForTests() {
|
|
295
|
+
if (process.env.NODE_ENV !== "test") {
|
|
296
|
+
throw new Error("resetForTests can only be called in tests");
|
|
297
|
+
}
|
|
298
|
+
this.reset();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Reset all statistics
|
|
302
|
+
*
|
|
303
|
+
* Called by costTracker.resetStateForTests() for backward compatibility.
|
|
304
|
+
*/
|
|
305
|
+
reset() {
|
|
306
|
+
this.globalStats = this.createEmptyStats();
|
|
307
|
+
this.agentStats.clear();
|
|
308
|
+
this.requestRecords.clear();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const tokenStatsManager = TokenStatsManagerImpl.getInstance();
|
|
312
|
+
function recordTokenUsage(usage, costUSD, model, context) {
|
|
313
|
+
tokenStatsManager.recordUsage(usage, costUSD, model, context);
|
|
314
|
+
}
|
|
315
|
+
function getGlobalTokenStats() {
|
|
316
|
+
return tokenStatsManager.getGlobalStats();
|
|
317
|
+
}
|
|
318
|
+
function getAgentTokenStats(agentId) {
|
|
319
|
+
return tokenStatsManager.getAgentStats(agentId);
|
|
320
|
+
}
|
|
321
|
+
function estimateTokenCount(text) {
|
|
322
|
+
return tokenStatsManager.estimateTokens(text);
|
|
323
|
+
}
|
|
324
|
+
export {
|
|
325
|
+
estimateTokenCount,
|
|
326
|
+
getAgentTokenStats,
|
|
327
|
+
getGlobalTokenStats,
|
|
328
|
+
recordTokenUsage,
|
|
329
|
+
tokenStatsManager
|
|
330
|
+
};
|
|
331
|
+
//# sourceMappingURL=tokenStatsManager.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/tokenStatsManager.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Token Statistics Manager\n *\n * Centralized token statistics tracking for the entire application.\n * This is the single source of truth for all token usage data.\n *\n * Architecture:\n * - Singleton pattern for global access\n * - Event-driven updates for real-time UI\n * - Hierarchical aggregation (global \u2192 agent \u2192 request)\n * - Backward compatible with existing costTracker\n *\n * Usage:\n * ```typescript\n * import { tokenStatsManager, recordTokenUsage } from '@core/tokenStatsManager'\n *\n * // Record usage from API response\n * recordTokenUsage(\n * { inputTokens: 100, outputTokens: 50 },\n * 0.0015,\n * 'gpt-4',\n * { agentId: 'agent-123' }\n * )\n *\n * // Get global stats\n * const stats = tokenStatsManager.getGlobalStats()\n *\n * // Subscribe to updates\n * const unsubscribe = tokenStatsManager.onStatsUpdate((event) => {\n * console.log('Stats updated:', event)\n * })\n * ```\n */\n\nimport { EventEmitter } from 'events'\nimport type {\n TokenUsageRecord,\n AggregatedTokenStats,\n TokenStatsScope,\n TokenStatsEvent,\n TokenTrackingContext,\n RawTokenUsage,\n ModelTokenStats,\n} from './tokenStats'\nimport { DEFAULT_ESTIMATION_CONFIG } from './tokenStats'\n\n/**\n * TokenStatsManager - Centralized token statistics tracking\n */\nclass TokenStatsManagerImpl extends EventEmitter {\n private static instance: TokenStatsManagerImpl | null = null\n\n // Global aggregated stats\n private globalStats: AggregatedTokenStats = this.createEmptyStats()\n\n // Per-agent stats (agentId \u2192 stats)\n private agentStats: Map<string, AggregatedTokenStats> = new Map()\n\n // Per-request records (requestId \u2192 record) - for debugging, with LRU eviction\n private requestRecords: Map<string, TokenUsageRecord> = new Map()\n\n // Configuration\n private static readonly MAX_REQUEST_RECORDS = 1000\n\n private constructor() {\n super()\n this.setMaxListeners(100)\n }\n\n /**\n * Get the singleton instance\n */\n static getInstance(): TokenStatsManagerImpl {\n if (!TokenStatsManagerImpl.instance) {\n TokenStatsManagerImpl.instance = new TokenStatsManagerImpl()\n }\n return TokenStatsManagerImpl.instance\n }\n\n /**\n * Record token usage from an API response\n *\n * This is the PRIMARY entry point - called from claude.ts\n * after every API response.\n *\n * @param usage - Raw token usage from API\n * @param costUSD - Calculated cost in USD\n * @param model - Model name used\n * @param context - Optional tracking context (agentId, toolUseId)\n */\n recordUsage(\n usage: RawTokenUsage,\n costUSD: number,\n model: string,\n context?: TokenTrackingContext,\n ): void {\n const record: TokenUsageRecord = {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheCreationTokens: usage.cacheCreationTokens ?? 0,\n cacheReadTokens: usage.cacheReadTokens ?? 0,\n totalTokens: usage.inputTokens + usage.outputTokens,\n estimatedCostUSD: costUSD,\n source: 'api',\n timestamp: Date.now(),\n model,\n }\n\n // Update global stats\n this.aggregateInto(this.globalStats, record)\n\n // Update agent stats if in agent context\n if (context?.agentId) {\n let stats = this.agentStats.get(context.agentId)\n if (!stats) {\n stats = this.createEmptyStats()\n this.agentStats.set(context.agentId, stats)\n }\n this.aggregateInto(stats, record)\n }\n\n // Store request record (with LRU eviction)\n const requestId =\n context?.toolUseId ??\n `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n this.requestRecords.set(requestId, record)\n if (this.requestRecords.size > TokenStatsManagerImpl.MAX_REQUEST_RECORDS) {\n const oldestKey = this.requestRecords.keys().next().value\n if (oldestKey) this.requestRecords.delete(oldestKey)\n }\n\n // Emit event for UI updates\n const scope: TokenStatsScope = context?.agentId\n ? { type: 'agent', agentId: context.agentId }\n : { type: 'global' }\n\n this.emitEvent({\n eventType: 'usage_recorded',\n scope,\n usage: record,\n aggregated: context?.agentId\n ? this.agentStats.get(context.agentId)!\n : this.globalStats,\n globalStats: this.globalStats,\n })\n }\n\n /**\n * Estimate token count from text\n *\n * Uses a simple character-based estimation. This is a fallback\n * when the API doesn't return token counts.\n *\n * @param text - Text to estimate tokens for\n * @returns Estimated token count\n */\n estimateTokens(text: string): number {\n return Math.ceil(text.length / DEFAULT_ESTIMATION_CONFIG.charsPerToken)\n }\n\n /**\n * Record estimated usage when API doesn't return token counts\n *\n * This is used as a fallback for APIs that don't return usage data.\n *\n * @param inputText - Input text (prompt)\n * @param outputText - Output text (completion)\n * @param model - Model name\n * @param context - Optional tracking context\n */\n recordEstimatedUsage(\n inputText: string,\n outputText: string,\n model: string,\n context?: TokenTrackingContext,\n ): void {\n const inputTokens = this.estimateTokens(inputText)\n const outputTokens = this.estimateTokens(outputText)\n\n const costUSD =\n (inputTokens / 1_000_000) *\n DEFAULT_ESTIMATION_CONFIG.defaultInputCostPerMillion +\n (outputTokens / 1_000_000) *\n DEFAULT_ESTIMATION_CONFIG.defaultOutputCostPerMillion\n\n const record: TokenUsageRecord = {\n inputTokens,\n outputTokens,\n cacheCreationTokens: 0,\n cacheReadTokens: 0,\n totalTokens: inputTokens + outputTokens,\n estimatedCostUSD: costUSD,\n source: 'estimated',\n timestamp: Date.now(),\n model,\n }\n\n // Update global stats\n this.aggregateInto(this.globalStats, record)\n\n // Update agent stats if in context\n if (context?.agentId) {\n let stats = this.agentStats.get(context.agentId)\n if (!stats) {\n stats = this.createEmptyStats()\n this.agentStats.set(context.agentId, stats)\n }\n this.aggregateInto(stats, record)\n }\n\n // Emit event\n this.emitEvent({\n eventType: 'usage_recorded',\n scope: { type: 'global' },\n usage: record,\n aggregated: this.globalStats,\n globalStats: this.globalStats,\n })\n }\n\n // ===== Getters =====\n\n /**\n * Get global aggregated statistics\n */\n getGlobalStats(): AggregatedTokenStats {\n return this.cloneStats(this.globalStats)\n }\n\n /**\n * Get statistics for a specific agent\n *\n * @param agentId - Agent ID to get stats for\n * @returns Agent stats or null if not found\n */\n getAgentStats(agentId: string): AggregatedTokenStats | null {\n const stats = this.agentStats.get(agentId)\n return stats ? this.cloneStats(stats) : null\n }\n\n /**\n * Get all agent statistics\n */\n getAllAgentStats(): Map<string, AggregatedTokenStats> {\n const result = new Map<string, AggregatedTokenStats>()\n for (const [agentId, stats] of this.agentStats) {\n result.set(agentId, this.cloneStats(stats))\n }\n return result\n }\n\n /**\n * Get a specific request record\n */\n getRequestRecord(requestId: string): TokenUsageRecord | null {\n return this.requestRecords.get(requestId) ?? null\n }\n\n // ===== Backward Compatibility Layer =====\n\n /**\n * Get total tokens (for costTracker.getTokenCounts compatibility)\n *\n * This method provides backward compatibility with the existing\n * costTracker.getTokenCounts() interface.\n */\n getTokenCounts(): {\n input: number\n output: number\n cacheCreation: number\n cacheRead: number\n total: number\n } {\n return {\n input: this.globalStats.totalInputTokens,\n output: this.globalStats.totalOutputTokens,\n cacheCreation: this.globalStats.totalCacheCreationTokens,\n cacheRead: this.globalStats.totalCacheReadTokens,\n total: this.globalStats.grandTotalTokens,\n }\n }\n\n // ===== Event Subscription =====\n\n /**\n * Subscribe to all stats updates\n *\n * @param callback - Called when any stats change\n * @returns Unsubscribe function\n */\n onStatsUpdate(callback: (event: TokenStatsEvent) => void): () => void {\n this.on('stats_update', callback)\n return () => this.off('stats_update', callback)\n }\n\n /**\n * Subscribe to updates for a specific agent\n *\n * @param agentId - Agent ID to subscribe to\n * @param callback - Called when agent stats change\n * @returns Unsubscribe function\n */\n onAgentStatsUpdate(\n agentId: string,\n callback: (stats: AggregatedTokenStats) => void,\n ): () => void {\n const handler = (event: TokenStatsEvent) => {\n if (event.scope.type === 'agent' && event.scope.agentId === agentId) {\n callback(event.aggregated)\n }\n }\n this.on('stats_update', handler)\n return () => this.off('stats_update', handler)\n }\n\n /**\n * Subscribe to global stats updates only\n *\n * @param callback - Called when global stats change\n * @returns Unsubscribe function\n */\n onGlobalStatsUpdate(\n callback: (stats: AggregatedTokenStats) => void,\n ): () => void {\n const handler = (event: TokenStatsEvent) => {\n callback(event.globalStats)\n }\n this.on('stats_update', handler)\n return () => this.off('stats_update', handler)\n }\n\n // ===== Agent Lifecycle =====\n\n /**\n * Mark an agent's scope as completed\n *\n * This emits a scope_completed event and optionally\n * cleans up the agent's stats from memory.\n *\n * @param agentId - Agent ID to complete\n * @param cleanup - Whether to remove from memory (default: false)\n */\n completeAgentScope(agentId: string, cleanup: boolean = false): void {\n const stats = this.agentStats.get(agentId)\n if (!stats) return\n\n this.emitEvent({\n eventType: 'scope_completed',\n scope: { type: 'agent', agentId },\n aggregated: stats,\n globalStats: this.globalStats,\n })\n\n if (cleanup) {\n this.agentStats.delete(agentId)\n }\n }\n\n // ===== Internal Methods =====\n\n private createEmptyStats(): AggregatedTokenStats {\n return {\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCacheCreationTokens: 0,\n totalCacheReadTokens: 0,\n grandTotalTokens: 0,\n totalCostUSD: 0,\n requestCount: 0,\n byModel: new Map(),\n }\n }\n\n private aggregateInto(\n stats: AggregatedTokenStats,\n record: TokenUsageRecord,\n ): void {\n stats.totalInputTokens += record.inputTokens\n stats.totalOutputTokens += record.outputTokens\n stats.totalCacheCreationTokens += record.cacheCreationTokens\n stats.totalCacheReadTokens += record.cacheReadTokens\n stats.grandTotalTokens += record.totalTokens\n stats.totalCostUSD += record.estimatedCostUSD\n stats.requestCount += 1\n\n if (!stats.firstRequestTime) {\n stats.firstRequestTime = record.timestamp\n }\n stats.lastRequestTime = record.timestamp\n\n // Update per-model breakdown\n const modelStats = stats.byModel.get(record.model)\n if (modelStats) {\n modelStats.inputTokens += record.inputTokens\n modelStats.outputTokens += record.outputTokens\n modelStats.totalTokens += record.totalTokens\n modelStats.estimatedCostUSD += record.estimatedCostUSD\n modelStats.requestCount += 1\n } else {\n stats.byModel.set(record.model, {\n model: record.model,\n inputTokens: record.inputTokens,\n outputTokens: record.outputTokens,\n totalTokens: record.totalTokens,\n estimatedCostUSD: record.estimatedCostUSD,\n requestCount: 1,\n })\n }\n }\n\n private cloneStats(stats: AggregatedTokenStats): AggregatedTokenStats {\n return {\n ...stats,\n byModel: new Map(stats.byModel),\n }\n }\n\n private emitEvent(event: TokenStatsEvent): void {\n this.emit('stats_update', event)\n }\n\n /**\n * Reset all stats (for testing only)\n */\n resetForTests(): void {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('resetForTests can only be called in tests')\n }\n this.reset()\n }\n\n /**\n * Reset all statistics\n *\n * Called by costTracker.resetStateForTests() for backward compatibility.\n */\n reset(): void {\n this.globalStats = this.createEmptyStats()\n this.agentStats.clear()\n this.requestRecords.clear()\n }\n}\n\n// Export singleton instance\nexport const tokenStatsManager = TokenStatsManagerImpl.getInstance()\n\n// ===== Convenience Functions =====\n\n/**\n * Record token usage from an API response\n *\n * This is the main function to call from claude.ts after each API response.\n */\nexport function recordTokenUsage(\n usage: RawTokenUsage,\n costUSD: number,\n model: string,\n context?: TokenTrackingContext,\n): void {\n tokenStatsManager.recordUsage(usage, costUSD, model, context)\n}\n\n/**\n * Get global token statistics\n */\nexport function getGlobalTokenStats(): AggregatedTokenStats {\n return tokenStatsManager.getGlobalStats()\n}\n\n/**\n * Get token statistics for a specific agent\n */\nexport function getAgentTokenStats(\n agentId: string,\n): AggregatedTokenStats | null {\n return tokenStatsManager.getAgentStats(agentId)\n}\n\n/**\n * Estimate token count from text\n */\nexport function estimateTokenCount(text: string): number {\n return tokenStatsManager.estimateTokens(text)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/entrypoints/cli.js
CHANGED
|
@@ -52,7 +52,9 @@ import { dateToFilename, logError, parseLogFilename } from "../utils/log.js";
|
|
|
52
52
|
import { initDebugLogger } from "../utils/debugLogger.js";
|
|
53
53
|
import { Onboarding } from "../components/Onboarding.js";
|
|
54
54
|
import { TrustDialog } from "../components/TrustDialog.js";
|
|
55
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
checkHasTrustDialogAccepted
|
|
57
|
+
} from "../utils/config.js";
|
|
56
58
|
import { isDefaultSlowAndCapableModel } from "../utils/model.js";
|
|
57
59
|
import { LogList } from "../screens/LogList.js";
|
|
58
60
|
import { ResumeConversation } from "../screens/ResumeConversation.js";
|
|
@@ -98,6 +100,7 @@ import { showInvalidConfigDialog } from "../components/InvalidConfigDialog.js";
|
|
|
98
100
|
import { ConfigParseError } from "../utils/errors.js";
|
|
99
101
|
import { grantReadPermissionForOriginalDir } from "../utils/permissions/filesystem.js";
|
|
100
102
|
import { MACRO } from "../constants/macros.js";
|
|
103
|
+
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
101
104
|
function completeOnboarding() {
|
|
102
105
|
const config = getGlobalConfig();
|
|
103
106
|
saveGlobalConfig({
|
|
@@ -366,8 +369,12 @@ ${commandList}`
|
|
|
366
369
|
"Print response and exit (useful for pipes)",
|
|
367
370
|
() => true
|
|
368
371
|
).option(
|
|
369
|
-
"--
|
|
370
|
-
"Enable
|
|
372
|
+
"--smart",
|
|
373
|
+
"Enable Smart safety mode (dangerous operations need confirmation)",
|
|
374
|
+
() => true
|
|
375
|
+
).option(
|
|
376
|
+
"--strict",
|
|
377
|
+
"Enable Strict safety mode (all write operations need confirmation)",
|
|
371
378
|
() => true
|
|
372
379
|
).option(
|
|
373
380
|
"-n, --new",
|
|
@@ -388,7 +395,8 @@ ${commandList}`
|
|
|
388
395
|
verbose,
|
|
389
396
|
enableArchitect,
|
|
390
397
|
print,
|
|
391
|
-
|
|
398
|
+
smart,
|
|
399
|
+
strict,
|
|
392
400
|
new: startNew,
|
|
393
401
|
resume: selectResume,
|
|
394
402
|
lang
|
|
@@ -396,8 +404,11 @@ ${commandList}`
|
|
|
396
404
|
if (lang && isLanguageSupported(lang)) {
|
|
397
405
|
setLanguage(lang);
|
|
398
406
|
}
|
|
399
|
-
|
|
400
|
-
|
|
407
|
+
const envSafetyMode = process.env.MINTO_SAFETY_MODE;
|
|
408
|
+
const safetyMode = envSafetyMode ? envSafetyMode : strict ? "strict" : smart ? "smart" : "yolo";
|
|
409
|
+
const safeMode = safetyMode !== "yolo";
|
|
410
|
+
await showSetupScreens(safeMode, print, rawModeSupported);
|
|
411
|
+
await setup(cwd2, safeMode);
|
|
401
412
|
assertMinVersion();
|
|
402
413
|
const [tools, mcpClients] = await Promise.all([
|
|
403
414
|
getTools(
|
|
@@ -421,7 +432,8 @@ ${commandList}`
|
|
|
421
432
|
prompt: inputPrompt,
|
|
422
433
|
cwd: cwd2,
|
|
423
434
|
tools,
|
|
424
|
-
safeMode
|
|
435
|
+
safeMode,
|
|
436
|
+
safetyMode
|
|
425
437
|
});
|
|
426
438
|
console.log(response);
|
|
427
439
|
process.exit(0);
|
|
@@ -496,6 +508,11 @@ ${commandList}`
|
|
|
496
508
|
{
|
|
497
509
|
const { render } = await import("ink");
|
|
498
510
|
const { REPL } = await import("../screens/REPL.js");
|
|
511
|
+
if (process.stdout.isTTY) {
|
|
512
|
+
await new Promise((resolve) => {
|
|
513
|
+
process.stdout.write("\x1B[?25h\n", () => resolve());
|
|
514
|
+
});
|
|
515
|
+
}
|
|
499
516
|
render(
|
|
500
517
|
/* @__PURE__ */ React.createElement(
|
|
501
518
|
REPL,
|
|
@@ -509,7 +526,8 @@ ${commandList}`
|
|
|
509
526
|
shouldShowPromptInput: true,
|
|
510
527
|
verbose,
|
|
511
528
|
tools,
|
|
512
|
-
safeMode
|
|
529
|
+
safeMode,
|
|
530
|
+
safetyMode,
|
|
513
531
|
mcpClients,
|
|
514
532
|
isDefaultModel,
|
|
515
533
|
initialUpdateVersion: updateInfo.version,
|
|
@@ -980,7 +998,7 @@ ${commandList}`
|
|
|
980
998
|
onSubmit: handleConfirm
|
|
981
999
|
}
|
|
982
1000
|
))
|
|
983
|
-
), /* @__PURE__ */ React2.createElement(Box, { marginTop: 0, marginLeft: 3 }, /* @__PURE__ */ React2.createElement(Text, {
|
|
1001
|
+
), /* @__PURE__ */ React2.createElement(Box, { marginTop: 0, marginLeft: 3 }, /* @__PURE__ */ React2.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Space to select \xB7 Enter to confirm \xB7 Esc to cancel")), isFinished && /* @__PURE__ */ React2.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React2.createElement(Text, { color: theme.success }, "Successfully imported", " ", importResults.filter((r) => r.success).length, " MCP server to local config.")));
|
|
984
1002
|
}
|
|
985
1003
|
const { unmount } = render(/* @__PURE__ */ React2.createElement(ClaudeDesktopImport, null));
|
|
986
1004
|
setTimeout(() => {
|
|
@@ -1065,98 +1083,108 @@ ${commandList}`
|
|
|
1065
1083
|
"[identifier]",
|
|
1066
1084
|
"A number (0, 1, 2, etc.) or file path to resume a specific conversation"
|
|
1067
1085
|
).option("-c, --cwd <cwd>", "The current working directory", String, cwd()).option("-e, --enable-architect", "Enable the Architect tool", () => true).option("-v, --verbose", "Do not truncate message output", () => true).option(
|
|
1068
|
-
"--
|
|
1069
|
-
"Enable
|
|
1086
|
+
"--smart",
|
|
1087
|
+
"Enable Smart safety mode (dangerous operations need confirmation)",
|
|
1070
1088
|
() => true
|
|
1071
|
-
).
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1089
|
+
).option(
|
|
1090
|
+
"--strict",
|
|
1091
|
+
"Enable Strict safety mode (all write operations need confirmation)",
|
|
1092
|
+
() => true
|
|
1093
|
+
).action(
|
|
1094
|
+
async (identifier, { cwd: cwd2, enableArchitect, smart, strict, verbose }) => {
|
|
1095
|
+
const envSafetyMode = process.env.MINTO_SAFETY_MODE;
|
|
1096
|
+
const safetyMode = envSafetyMode ? envSafetyMode : strict ? "strict" : smart ? "smart" : "yolo";
|
|
1097
|
+
const safeMode = safetyMode !== "yolo";
|
|
1098
|
+
await setup(cwd2, safeMode);
|
|
1099
|
+
assertMinVersion();
|
|
1100
|
+
const [tools, commands2, logs, mcpClients] = await Promise.all([
|
|
1101
|
+
getTools(
|
|
1102
|
+
enableArchitect ?? getCurrentProjectConfig().enableArchitectTool
|
|
1103
|
+
),
|
|
1104
|
+
getCommands(),
|
|
1105
|
+
loadLogList(CACHE_PATHS.messages()),
|
|
1106
|
+
getClients()
|
|
1107
|
+
]);
|
|
1108
|
+
if (identifier !== void 0) {
|
|
1109
|
+
const number = Math.abs(parseInt(identifier));
|
|
1110
|
+
const isNumber = !isNaN(number);
|
|
1111
|
+
let messages, date, forkNumber;
|
|
1112
|
+
try {
|
|
1113
|
+
if (isNumber) {
|
|
1114
|
+
const log = logs[number];
|
|
1115
|
+
if (!log) {
|
|
1116
|
+
console.error("No conversation found at index", number);
|
|
1117
|
+
process.exit(1);
|
|
1118
|
+
}
|
|
1119
|
+
messages = await loadMessagesFromLog(log.fullPath, tools);
|
|
1120
|
+
({ date, forkNumber } = log);
|
|
1121
|
+
} else {
|
|
1122
|
+
if (!existsSync(identifier)) {
|
|
1123
|
+
console.error("File does not exist:", identifier);
|
|
1124
|
+
process.exit(1);
|
|
1125
|
+
}
|
|
1126
|
+
messages = await loadMessagesFromLog(identifier, tools);
|
|
1127
|
+
const pathSegments = identifier.split("/");
|
|
1128
|
+
const filename = pathSegments[pathSegments.length - 1] ?? "unknown";
|
|
1129
|
+
({ date, forkNumber } = parseLogFilename(filename));
|
|
1092
1130
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
if (!
|
|
1097
|
-
|
|
1098
|
-
process.exit(1);
|
|
1131
|
+
const fork = getNextAvailableLogForkNumber(date, forkNumber ?? 1, 0);
|
|
1132
|
+
const isDefaultModel = await isDefaultSlowAndCapableModel();
|
|
1133
|
+
const forkRawModeCheck = validateRawModeSupport(process.stdin);
|
|
1134
|
+
if (!forkRawModeCheck.supported) {
|
|
1135
|
+
requireRawModeOrExit(process.stdin, true);
|
|
1099
1136
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1137
|
+
{
|
|
1138
|
+
const { render } = await import("ink");
|
|
1139
|
+
const { REPL } = await import("../screens/REPL.js");
|
|
1140
|
+
render(
|
|
1141
|
+
/* @__PURE__ */ React.createElement(
|
|
1142
|
+
REPL,
|
|
1143
|
+
{
|
|
1144
|
+
initialPrompt: "",
|
|
1145
|
+
messageLogName: date,
|
|
1146
|
+
initialForkNumber: fork,
|
|
1147
|
+
shouldShowPromptInput: true,
|
|
1148
|
+
verbose,
|
|
1149
|
+
commands: commands2,
|
|
1150
|
+
tools,
|
|
1151
|
+
safeMode,
|
|
1152
|
+
safetyMode,
|
|
1153
|
+
initialMessages: messages,
|
|
1154
|
+
mcpClients,
|
|
1155
|
+
isDefaultModel,
|
|
1156
|
+
fallbackMode: false
|
|
1157
|
+
}
|
|
1158
|
+
),
|
|
1159
|
+
{ exitOnCtrlC: false }
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
} catch (error) {
|
|
1163
|
+
logError(`Failed to load conversation: ${error}`);
|
|
1164
|
+
process.exit(1);
|
|
1110
1165
|
}
|
|
1111
|
-
|
|
1166
|
+
} else {
|
|
1167
|
+
const context2 = {};
|
|
1168
|
+
(async () => {
|
|
1112
1169
|
const { render } = await import("ink");
|
|
1113
|
-
const {
|
|
1114
|
-
render(
|
|
1170
|
+
const { unmount } = render(
|
|
1115
1171
|
/* @__PURE__ */ React.createElement(
|
|
1116
|
-
|
|
1172
|
+
ResumeConversation,
|
|
1117
1173
|
{
|
|
1118
|
-
|
|
1119
|
-
messageLogName: date,
|
|
1120
|
-
initialForkNumber: fork,
|
|
1121
|
-
shouldShowPromptInput: true,
|
|
1122
|
-
verbose,
|
|
1174
|
+
context: context2,
|
|
1123
1175
|
commands: commands2,
|
|
1176
|
+
logs,
|
|
1124
1177
|
tools,
|
|
1125
|
-
|
|
1126
|
-
initialMessages: messages,
|
|
1127
|
-
mcpClients,
|
|
1128
|
-
isDefaultModel,
|
|
1129
|
-
fallbackMode: false
|
|
1178
|
+
verbose
|
|
1130
1179
|
}
|
|
1131
1180
|
),
|
|
1132
|
-
|
|
1181
|
+
renderContextWithExitOnCtrlC
|
|
1133
1182
|
);
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
logError(`Failed to load conversation: ${error}`);
|
|
1137
|
-
process.exit(1);
|
|
1183
|
+
context2.unmount = unmount;
|
|
1184
|
+
})();
|
|
1138
1185
|
}
|
|
1139
|
-
} else {
|
|
1140
|
-
const context2 = {};
|
|
1141
|
-
(async () => {
|
|
1142
|
-
const { render } = await import("ink");
|
|
1143
|
-
const { unmount } = render(
|
|
1144
|
-
/* @__PURE__ */ React.createElement(
|
|
1145
|
-
ResumeConversation,
|
|
1146
|
-
{
|
|
1147
|
-
context: context2,
|
|
1148
|
-
commands: commands2,
|
|
1149
|
-
logs,
|
|
1150
|
-
tools,
|
|
1151
|
-
verbose
|
|
1152
|
-
}
|
|
1153
|
-
),
|
|
1154
|
-
renderContextWithExitOnCtrlC
|
|
1155
|
-
);
|
|
1156
|
-
context2.unmount = unmount;
|
|
1157
|
-
})();
|
|
1158
1186
|
}
|
|
1159
|
-
|
|
1187
|
+
);
|
|
1160
1188
|
program.command("error").description(
|
|
1161
1189
|
"View error logs. Optionally provide a number (0, -1, -2, etc.) to display a specific log."
|
|
1162
1190
|
).argument(
|