@within-7/minto 0.1.5 → 0.1.6
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 +2342 -0
- package/dist/commands/agents/AgentsCommand.js.map +7 -0
- package/dist/commands/agents/constants.js +58 -0
- package/dist/commands/agents/constants.js.map +7 -0
- package/dist/commands/agents/index.js +37 -0
- package/dist/commands/agents/index.js.map +7 -0
- package/dist/commands/agents/types.js +10 -0
- package/dist/commands/agents/types.js.map +7 -0
- package/dist/commands/agents/utils/fileOperations.js +185 -0
- package/dist/commands/agents/utils/fileOperations.js.map +7 -0
- package/dist/commands/agents/utils/index.js +21 -0
- package/dist/commands/agents/utils/index.js.map +7 -0
- package/dist/commands/bug.js +2 -2
- package/dist/commands/bug.js.map +2 -2
- package/dist/commands/compact.js +5 -5
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/ctx_viz.js +55 -22
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/mcp-interactive.js +11 -11
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +94 -32
- package/dist/commands/model.js.map +3 -3
- package/dist/commands/plugin/AddMarketplaceForm.js +49 -21
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +38 -26
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +24 -8
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +3 -1
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +16 -7
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +84 -39
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +7 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +16 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +4 -2
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +12 -6
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +14 -5
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin/example-usage.js.map +2 -2
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +226 -46
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/refreshCommands.js +6 -3
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +2 -1
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/setup.js +19 -5
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/terminalSetup.js +2 -2
- package/dist/commands/terminalSetup.js.map +1 -1
- package/dist/commands.js +14 -30
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +10 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +5 -1
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/Config.js +17 -4
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/CustomSelect/select-option.js +4 -1
- package/dist/components/CustomSelect/select-option.js.map +2 -2
- package/dist/components/Help.js +6 -8
- package/dist/components/Help.js.map +2 -2
- package/dist/components/Logo.js +1 -1
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +2030 -0
- package/dist/components/ModelSelector/ModelSelector.js.map +7 -0
- package/dist/components/ModelSelector/ScreenContainer.js +27 -0
- package/dist/components/ModelSelector/ScreenContainer.js.map +7 -0
- package/dist/components/ModelSelector/constants.js +37 -0
- package/dist/components/ModelSelector/constants.js.map +7 -0
- package/dist/components/ModelSelector/hooks/index.js +5 -0
- package/dist/components/ModelSelector/hooks/index.js.map +7 -0
- package/dist/components/ModelSelector/hooks/useEscapeNavigation.js +21 -0
- package/dist/components/ModelSelector/hooks/useEscapeNavigation.js.map +7 -0
- package/dist/components/ModelSelector/index.js +17 -0
- package/dist/components/ModelSelector/index.js.map +7 -0
- package/dist/components/ModelSelector/types.js +1 -0
- package/dist/components/ModelSelector/types.js.map +7 -0
- package/dist/components/PressEnterToContinue.js +1 -1
- package/dist/components/PressEnterToContinue.js.map +2 -2
- package/dist/components/ProjectOnboarding.js +1 -1
- package/dist/components/ProjectOnboarding.js.map +2 -2
- package/dist/components/PromptInput.js +88 -37
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/QuitSummary.js +17 -10
- package/dist/components/QuitSummary.js.map +2 -2
- package/dist/components/SentryErrorBoundary.js.map +2 -2
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js.map +1 -1
- package/dist/components/TodoItem.js.map +1 -1
- package/dist/components/binary-feedback/BinaryFeedbackOption.js +1 -3
- package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +2 -2
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +1 -1
- package/dist/components/messages/AssistantToolUseMessage.js +3 -1
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/TaskProgressMessage.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/utils.js.map +2 -2
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +2 -2
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +2 -2
- package/dist/components/permissions/hooks.js.map +2 -2
- package/dist/constants/modelCapabilities.js +1 -1
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/prompts.js.map +1 -1
- package/dist/constants/timing.js +34 -0
- package/dist/constants/timing.js.map +7 -0
- package/dist/entrypoints/cli.js +128 -33
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/entrypoints/mcp.js +13 -18
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useCancelRequest.js.map +1 -1
- package/dist/hooks/useHistorySearch.js.map +2 -2
- package/dist/hooks/useLogStartupTime.js.map +2 -2
- package/dist/hooks/usePermissionRequestLogging.js.map +2 -2
- package/dist/hooks/useTextInput.js.map +1 -1
- package/dist/hooks/useUnifiedCompletion.js +493 -394
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/index.js.map +2 -2
- package/dist/permissions.js +4 -7
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +6 -1
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +72 -36
- package/dist/screens/REPL.js.map +2 -2
- package/dist/screens/ResumeConversation.js +2 -1
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/adapters/base.js.map +2 -2
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +3 -1
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/claude.js +327 -328
- package/dist/services/claude.js.map +2 -2
- package/dist/services/customCommands.js +6 -1
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/fileFreshness.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +20 -7
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +6 -12
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/mcpClient.js +29 -2
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/mentionProcessor.js +23 -10
- package/dist/services/mentionProcessor.js.map +2 -2
- package/dist/services/modelAdapterFactory.js.map +2 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +109 -72
- package/dist/services/openai.js.map +3 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +14 -8
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js.map +1 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +1 -4
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +4 -1
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js +3 -1
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/SkillTool/SkillTool.js +12 -6
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +14 -5
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/ThinkTool/ThinkTool.js +6 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +23 -3
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +6 -3
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js +3 -1
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/searchProviders.js +15 -6
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools.js +4 -1
- package/dist/tools.js.map +2 -2
- package/dist/types/core.js +1 -0
- package/dist/types/core.js.map +7 -0
- package/dist/types/hooks.js +1 -4
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js +8 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/plugin.js +9 -6
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/BackgroundShellManager.js +76 -10
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/PersistentShell.js +7 -2
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/advancedFuzzyMatcher.js +4 -1
- package/dist/utils/advancedFuzzyMatcher.js.map +2 -2
- package/dist/utils/agentLoader.js +69 -35
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentStorage.js.map +2 -2
- package/dist/utils/async.js +163 -0
- package/dist/utils/async.js.map +7 -0
- package/dist/utils/autoUpdater.js +8 -2
- package/dist/utils/autoUpdater.js.map +2 -2
- package/dist/utils/commands.js +23 -11
- package/dist/utils/commands.js.map +2 -2
- package/dist/utils/commonUnixCommands.js +3 -1
- package/dist/utils/commonUnixCommands.js.map +2 -2
- package/dist/utils/compressionMode.js.map +2 -2
- package/dist/utils/config.js +30 -14
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +82 -0
- package/dist/utils/envConfig.js.map +7 -0
- package/dist/utils/errorHandling.js +89 -0
- package/dist/utils/errorHandling.js.map +7 -0
- package/dist/utils/expertChatStorage.js.map +2 -2
- package/dist/utils/fuzzyMatcher.js +13 -7
- package/dist/utils/fuzzyMatcher.js.map +2 -2
- package/dist/utils/hookManager.js +14 -4
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/log.js.map +2 -2
- package/dist/utils/marketplaceManager.js +44 -9
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messageContextManager.js.map +1 -1
- package/dist/utils/messages.js +6 -3
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +3 -1
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +3 -15
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +41 -13
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/pluginRegistry.js.map +2 -2
- package/dist/utils/pluginValidator.js +71 -49
- package/dist/utils/pluginValidator.js.map +2 -2
- package/dist/utils/ptyCompat.js.map +2 -2
- package/dist/utils/roundConverter.js.map +2 -2
- package/dist/utils/secureFile.js +43 -14
- package/dist/utils/secureFile.js.map +2 -2
- package/dist/utils/sessionState.js.map +2 -2
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/teamConfig.js +7 -4
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/theme.js.map +2 -2
- package/dist/utils/thinking.js.map +2 -2
- package/dist/utils/unaryLogging.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeFileSync,
|
|
3
|
+
unlinkSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
existsSync,
|
|
6
|
+
renameSync
|
|
7
|
+
} from "fs";
|
|
8
|
+
import { join, resolve, relative, isAbsolute } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
import { spawn } from "child_process";
|
|
11
|
+
import { getCwd } from "../../../utils/state.js";
|
|
12
|
+
import { AGENT_LOCATIONS, FOLDER_CONFIG } from "../constants.js";
|
|
13
|
+
function getAgentDirectory(location) {
|
|
14
|
+
if (location === AGENT_LOCATIONS.BUILT_IN || location === AGENT_LOCATIONS.ALL) {
|
|
15
|
+
throw new Error(`Cannot get directory path for ${location} agents`);
|
|
16
|
+
}
|
|
17
|
+
if (location === AGENT_LOCATIONS.USER) {
|
|
18
|
+
return join(homedir(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR);
|
|
19
|
+
} else {
|
|
20
|
+
return join(getCwd(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getAgentFilePath(agent) {
|
|
24
|
+
if (agent.location === "built-in") {
|
|
25
|
+
throw new Error("Cannot get file path for built-in agents");
|
|
26
|
+
}
|
|
27
|
+
const dir = getAgentDirectory(agent.location);
|
|
28
|
+
return join(dir, `${agent.agentType}.md`);
|
|
29
|
+
}
|
|
30
|
+
function ensureDirectoryExists(location) {
|
|
31
|
+
const dir = getAgentDirectory(location);
|
|
32
|
+
if (!existsSync(dir)) {
|
|
33
|
+
mkdirSync(dir, { recursive: true });
|
|
34
|
+
}
|
|
35
|
+
return dir;
|
|
36
|
+
}
|
|
37
|
+
function generateAgentFileContent(agentType, description, tools, systemPrompt, model, color) {
|
|
38
|
+
const descriptionLines = description.split("\n");
|
|
39
|
+
const formattedDescription = descriptionLines.length > 1 ? `|
|
|
40
|
+
${descriptionLines.join("\n ")}` : JSON.stringify(description);
|
|
41
|
+
const lines = [
|
|
42
|
+
"---",
|
|
43
|
+
`name: ${agentType}`,
|
|
44
|
+
`description: ${formattedDescription}`
|
|
45
|
+
];
|
|
46
|
+
if (tools) {
|
|
47
|
+
if (tools === "*") {
|
|
48
|
+
lines.push(`tools: "*"`);
|
|
49
|
+
} else if (Array.isArray(tools) && tools.length > 0) {
|
|
50
|
+
lines.push(`tools: [${tools.map((t) => `"${t}"`).join(", ")}]`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (model) {
|
|
54
|
+
lines.push(`model: ${model}`);
|
|
55
|
+
}
|
|
56
|
+
if (color) {
|
|
57
|
+
lines.push(`color: ${color}`);
|
|
58
|
+
}
|
|
59
|
+
lines.push("---", "", systemPrompt);
|
|
60
|
+
return lines.join("\n");
|
|
61
|
+
}
|
|
62
|
+
async function saveAgent(location, agentType, description, tools, systemPrompt, model, color, throwIfExists = true) {
|
|
63
|
+
if (location === AGENT_LOCATIONS.BUILT_IN) {
|
|
64
|
+
throw new Error("Cannot save built-in agents");
|
|
65
|
+
}
|
|
66
|
+
ensureDirectoryExists(location);
|
|
67
|
+
const filePath = join(getAgentDirectory(location), `${agentType}.md`);
|
|
68
|
+
const tempFile = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`;
|
|
69
|
+
const toolsForFile = Array.isArray(tools) && tools.length === 1 && tools[0] === "*" ? "*" : tools;
|
|
70
|
+
const content = generateAgentFileContent(
|
|
71
|
+
agentType,
|
|
72
|
+
description,
|
|
73
|
+
toolsForFile,
|
|
74
|
+
systemPrompt,
|
|
75
|
+
model,
|
|
76
|
+
color
|
|
77
|
+
);
|
|
78
|
+
try {
|
|
79
|
+
writeFileSync(tempFile, content, { encoding: "utf-8", flag: "wx" });
|
|
80
|
+
if (throwIfExists && existsSync(filePath)) {
|
|
81
|
+
try {
|
|
82
|
+
unlinkSync(tempFile);
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Agent file already exists: ${filePath}`);
|
|
86
|
+
}
|
|
87
|
+
renameSync(tempFile, filePath);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
try {
|
|
90
|
+
if (existsSync(tempFile)) {
|
|
91
|
+
unlinkSync(tempFile);
|
|
92
|
+
}
|
|
93
|
+
} catch (cleanupError) {
|
|
94
|
+
console.warn("Failed to cleanup temp file:", cleanupError);
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function deleteAgent(agent) {
|
|
100
|
+
if (agent.location === "built-in") {
|
|
101
|
+
throw new Error("Cannot delete built-in agents");
|
|
102
|
+
}
|
|
103
|
+
const filePath = getAgentFilePath(agent);
|
|
104
|
+
unlinkSync(filePath);
|
|
105
|
+
}
|
|
106
|
+
async function openInEditor(filePath) {
|
|
107
|
+
const resolvedPath = resolve(filePath);
|
|
108
|
+
const projectDir = process.cwd();
|
|
109
|
+
const homeDir = homedir();
|
|
110
|
+
const isSub = (base, target) => {
|
|
111
|
+
const rel = relative(resolve(base), resolve(target));
|
|
112
|
+
if (!rel || rel === "") return true;
|
|
113
|
+
if (rel.startsWith("..")) return false;
|
|
114
|
+
if (isAbsolute(rel)) return false;
|
|
115
|
+
return true;
|
|
116
|
+
};
|
|
117
|
+
if (!isSub(projectDir, resolvedPath) && !isSub(homeDir, resolvedPath)) {
|
|
118
|
+
throw new Error("Access denied: File path outside allowed directories");
|
|
119
|
+
}
|
|
120
|
+
if (!resolvedPath.endsWith(".md")) {
|
|
121
|
+
throw new Error("Invalid file type: Only .md files are allowed");
|
|
122
|
+
}
|
|
123
|
+
return new Promise((resolve2, reject) => {
|
|
124
|
+
const platform = process.platform;
|
|
125
|
+
let command;
|
|
126
|
+
let args;
|
|
127
|
+
switch (platform) {
|
|
128
|
+
case "darwin":
|
|
129
|
+
command = "open";
|
|
130
|
+
args = [resolvedPath];
|
|
131
|
+
break;
|
|
132
|
+
case "win32":
|
|
133
|
+
command = "cmd";
|
|
134
|
+
args = ["/c", "start", "", resolvedPath];
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
command = "xdg-open";
|
|
138
|
+
args = [resolvedPath];
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
const child = spawn(command, args, {
|
|
142
|
+
detached: true,
|
|
143
|
+
stdio: "ignore",
|
|
144
|
+
shell: false
|
|
145
|
+
});
|
|
146
|
+
child.unref();
|
|
147
|
+
child.on("error", (error) => {
|
|
148
|
+
reject(new Error(`Failed to open editor: ${error.message}`));
|
|
149
|
+
});
|
|
150
|
+
child.on("exit", (code) => {
|
|
151
|
+
if (code === 0) {
|
|
152
|
+
resolve2();
|
|
153
|
+
} else {
|
|
154
|
+
reject(new Error(`Editor exited with code ${code}`));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async function updateAgent(agent, description, tools, systemPrompt, color, model) {
|
|
160
|
+
if (agent.location === "built-in") {
|
|
161
|
+
throw new Error("Cannot update built-in agents");
|
|
162
|
+
}
|
|
163
|
+
const toolsForFile = tools.length === 1 && tools[0] === "*" ? "*" : tools;
|
|
164
|
+
const content = generateAgentFileContent(
|
|
165
|
+
agent.agentType,
|
|
166
|
+
description,
|
|
167
|
+
toolsForFile,
|
|
168
|
+
systemPrompt,
|
|
169
|
+
model,
|
|
170
|
+
color
|
|
171
|
+
);
|
|
172
|
+
const filePath = getAgentFilePath(agent);
|
|
173
|
+
writeFileSync(filePath, content, { encoding: "utf-8", flag: "w" });
|
|
174
|
+
}
|
|
175
|
+
export {
|
|
176
|
+
deleteAgent,
|
|
177
|
+
ensureDirectoryExists,
|
|
178
|
+
generateAgentFileContent,
|
|
179
|
+
getAgentDirectory,
|
|
180
|
+
getAgentFilePath,
|
|
181
|
+
openInEditor,
|
|
182
|
+
saveAgent,
|
|
183
|
+
updateAgent
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=fileOperations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/commands/agents/utils/fileOperations.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * File system operations for agents\n */\nimport {\n writeFileSync,\n unlinkSync,\n mkdirSync,\n existsSync,\n renameSync,\n} from 'fs'\nimport { join, resolve, relative, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { spawn } from 'child_process'\nimport { getCwd } from '@utils/state'\nimport type { AgentConfig } from '@utils/agentLoader'\nimport { AGENT_LOCATIONS, FOLDER_CONFIG } from '../constants'\nimport type { AgentLocation } from '../types'\n\n/**\n * Get the directory path for agents of a specific location\n */\nexport function getAgentDirectory(location: AgentLocation): string {\n if (\n location === AGENT_LOCATIONS.BUILT_IN ||\n location === AGENT_LOCATIONS.ALL\n ) {\n throw new Error(`Cannot get directory path for ${location} agents`)\n }\n\n if (location === AGENT_LOCATIONS.USER) {\n return join(homedir(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR)\n } else {\n return join(getCwd(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR)\n }\n}\n\n/**\n * Get the file path for an agent\n */\nexport function getAgentFilePath(agent: AgentConfig): string {\n if (agent.location === 'built-in') {\n throw new Error('Cannot get file path for built-in agents')\n }\n const dir = getAgentDirectory(agent.location as AgentLocation)\n return join(dir, `${agent.agentType}.md`)\n}\n\n/**\n * Ensure the agent directory exists\n */\nexport function ensureDirectoryExists(location: AgentLocation): string {\n const dir = getAgentDirectory(location)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n return dir\n}\n\n/**\n * Generate agent file content in markdown format with YAML frontmatter\n */\nexport function generateAgentFileContent(\n agentType: string,\n description: string,\n tools: string[] | '*',\n systemPrompt: string,\n model?: string,\n color?: string,\n): string {\n // Use YAML multi-line string for description to avoid escaping issues\n const descriptionLines = description.split('\\n')\n const formattedDescription =\n descriptionLines.length > 1\n ? `|\\n ${descriptionLines.join('\\n ')}`\n : JSON.stringify(description)\n\n const lines = [\n '---',\n `name: ${agentType}`,\n `description: ${formattedDescription}`,\n ]\n\n if (tools) {\n if (tools === '*') {\n lines.push(`tools: \"*\"`)\n } else if (Array.isArray(tools) && tools.length > 0) {\n lines.push(`tools: [${tools.map(t => `\"${t}\"`).join(', ')}]`)\n }\n }\n\n if (model) {\n lines.push(`model: ${model}`)\n }\n\n if (color) {\n lines.push(`color: ${color}`)\n }\n\n lines.push('---', '', systemPrompt)\n return lines.join('\\n')\n}\n\n/**\n * Save an agent to file\n */\nexport async function saveAgent(\n location: AgentLocation,\n agentType: string,\n description: string,\n tools: string[],\n systemPrompt: string,\n model?: string,\n color?: string,\n throwIfExists: boolean = true,\n): Promise<void> {\n if (location === AGENT_LOCATIONS.BUILT_IN) {\n throw new Error('Cannot save built-in agents')\n }\n\n ensureDirectoryExists(location)\n\n const filePath = join(getAgentDirectory(location), `${agentType}.md`)\n const tempFile = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`\n\n // Ensure tools is properly typed for file saving\n const toolsForFile: string[] | '*' =\n Array.isArray(tools) && tools.length === 1 && tools[0] === '*' ? '*' : tools\n const content = generateAgentFileContent(\n agentType,\n description,\n toolsForFile,\n systemPrompt,\n model,\n color,\n )\n\n try {\n // Write to temp file first using 'wx' to avoid overwriting\n writeFileSync(tempFile, content, { encoding: 'utf-8', flag: 'wx' })\n\n // Atomic check if target file exists\n if (throwIfExists && existsSync(filePath)) {\n // Clean up temp file\n try {\n unlinkSync(tempFile)\n } catch {\n // Ignore cleanup errors\n }\n throw new Error(`Agent file already exists: ${filePath}`)\n }\n\n // Atomic rename (on most filesystems, rename is atomic)\n renameSync(tempFile, filePath)\n } catch (error) {\n // Ensure temp file is cleaned up\n try {\n if (existsSync(tempFile)) {\n unlinkSync(tempFile)\n }\n } catch (cleanupError) {\n console.warn('Failed to cleanup temp file:', cleanupError)\n }\n throw error\n }\n}\n\n/**\n * Delete an agent file\n */\nexport async function deleteAgent(agent: AgentConfig): Promise<void> {\n if (agent.location === 'built-in') {\n throw new Error('Cannot delete built-in agents')\n }\n\n const filePath = getAgentFilePath(agent)\n unlinkSync(filePath)\n}\n\n/**\n * Open file in system editor - secure version to prevent command injection\n */\nexport async function openInEditor(filePath: string): Promise<void> {\n // Security validation: ensure path is in allowed directories\n const resolvedPath = resolve(filePath)\n const projectDir = process.cwd()\n const homeDir = homedir()\n\n const isSub = (base: string, target: string) => {\n const rel = relative(resolve(base), resolve(target))\n if (!rel || rel === '') return true\n if (rel.startsWith('..')) return false\n if (isAbsolute(rel)) return false\n return true\n }\n\n if (!isSub(projectDir, resolvedPath) && !isSub(homeDir, resolvedPath)) {\n throw new Error('Access denied: File path outside allowed directories')\n }\n\n // Validate file extension\n if (!resolvedPath.endsWith('.md')) {\n throw new Error('Invalid file type: Only .md files are allowed')\n }\n\n return new Promise((resolve, reject) => {\n const platform = process.platform\n let command: string\n let args: string[]\n\n // Use spawn instead of exec to avoid shell injection\n switch (platform) {\n case 'darwin':\n command = 'open'\n args = [resolvedPath]\n break\n case 'win32':\n command = 'cmd'\n args = ['/c', 'start', '', resolvedPath]\n break\n default:\n command = 'xdg-open'\n args = [resolvedPath]\n break\n }\n\n // Use spawn instead of exec to avoid shell interpretation\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n shell: false,\n })\n\n child.unref()\n\n child.on('error', error => {\n reject(new Error(`Failed to open editor: ${error.message}`))\n })\n\n child.on('exit', code => {\n if (code === 0) {\n resolve()\n } else {\n reject(new Error(`Editor exited with code ${code}`))\n }\n })\n })\n}\n\n/**\n * Update an existing agent\n */\nexport async function updateAgent(\n agent: AgentConfig,\n description: string,\n tools: string[] | '*',\n systemPrompt: string,\n color?: string,\n model?: string,\n): Promise<void> {\n if (agent.location === 'built-in') {\n throw new Error('Cannot update built-in agents')\n }\n\n const toolsForFile = tools.length === 1 && tools[0] === '*' ? '*' : tools\n const content = generateAgentFileContent(\n agent.agentType,\n description,\n toolsForFile,\n systemPrompt,\n model,\n color,\n )\n const filePath = getAgentFilePath(agent)\n\n writeFileSync(filePath, content, { encoding: 'utf-8', flag: 'w' })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["resolve"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAgentDirectory,
|
|
3
|
+
getAgentFilePath,
|
|
4
|
+
ensureDirectoryExists,
|
|
5
|
+
generateAgentFileContent,
|
|
6
|
+
saveAgent,
|
|
7
|
+
deleteAgent,
|
|
8
|
+
openInEditor,
|
|
9
|
+
updateAgent
|
|
10
|
+
} from "./fileOperations.js";
|
|
11
|
+
export {
|
|
12
|
+
deleteAgent,
|
|
13
|
+
ensureDirectoryExists,
|
|
14
|
+
generateAgentFileContent,
|
|
15
|
+
getAgentDirectory,
|
|
16
|
+
getAgentFilePath,
|
|
17
|
+
openInEditor,
|
|
18
|
+
saveAgent,
|
|
19
|
+
updateAgent
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/commands/agents/utils/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Utility exports for the agents command\n */\nexport {\n getAgentDirectory,\n getAgentFilePath,\n ensureDirectoryExists,\n generateAgentFileContent,\n saveAgent,\n deleteAgent,\n openInEditor,\n updateAgent,\n} from './fileOperations'\n"],
|
|
5
|
+
"mappings": "AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/commands/bug.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Bug } from "../components/Bug.js";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import { PRODUCT_NAME } from "../constants/product.js";
|
|
4
3
|
const bug = {
|
|
5
4
|
type: "local-jsx",
|
|
6
5
|
name: "bug",
|
|
7
|
-
description: `
|
|
6
|
+
description: `Report bugs or submit feedback via GitHub Issues`,
|
|
8
7
|
isEnabled: true,
|
|
9
8
|
isHidden: false,
|
|
9
|
+
aliases: ["feedback", "report"],
|
|
10
10
|
async call(onDone) {
|
|
11
11
|
return /* @__PURE__ */ React.createElement(Bug, { onDone });
|
|
12
12
|
},
|
package/dist/commands/bug.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/bug.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Command } from '@commands'\nimport { Bug } from '@components/Bug'\nimport * as React from 'react'\nimport { PRODUCT_NAME } from '@constants/product'\n\nconst bug = {\n type: 'local-jsx',\n name: 'bug',\n description: `
|
|
5
|
-
"mappings": "AACA,SAAS,WAAW;AACpB,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import { Command } from '@commands'\nimport { Bug } from '@components/Bug'\nimport * as React from 'react'\nimport { PRODUCT_NAME } from '@constants/product'\n\nconst bug = {\n type: 'local-jsx',\n name: 'bug',\n description: `Report bugs or submit feedback via GitHub Issues`,\n isEnabled: true,\n isHidden: false,\n aliases: ['feedback', 'report'],\n async call(onDone) {\n return <Bug onDone={onDone} />\n },\n userFacingName() {\n return 'bug'\n },\n} satisfies Command\n\nexport default bug\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,WAAW;AACpB,YAAY,WAAW;AAGvB,MAAM,MAAM;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS,CAAC,YAAY,QAAQ;AAAA,EAC9B,MAAM,KAAK,QAAQ;AACjB,WAAO,oCAAC,OAAI,QAAgB;AAAA,EAC9B;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AACF;AAEA,IAAO,cAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/compact.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { getContext } from "../context.js";
|
|
2
2
|
import { getMessagesGetter, getMessagesSetter } from "../messages.js";
|
|
3
3
|
import { API_ERROR_MESSAGE_PREFIX, queryLLM } from "../services/claude.js";
|
|
4
|
-
import {
|
|
5
|
-
createUserMessage,
|
|
6
|
-
normalizeMessagesForAPI
|
|
7
|
-
} from "../utils/messages.js";
|
|
4
|
+
import { createUserMessage, normalizeMessagesForAPI } from "../utils/messages.js";
|
|
8
5
|
import { getCodeStyle } from "../utils/style.js";
|
|
9
6
|
import { clearTerminal } from "../utils/terminal.js";
|
|
10
7
|
import { resetReminderSession } from "../services/systemReminder.js";
|
|
11
8
|
import { resetFileFreshnessSession } from "../services/fileFreshness.js";
|
|
12
9
|
import { getCompressionPrompt } from "../constants/compressionPrompts.js";
|
|
13
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getCompressionMode,
|
|
12
|
+
getCompressionModeDescription
|
|
13
|
+
} from "../utils/compressionMode.js";
|
|
14
14
|
const compact = {
|
|
15
15
|
type: "local",
|
|
16
16
|
name: "compact",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/compact.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from '@commands'\nimport { getContext } from '@context'\nimport { getMessagesGetter, getMessagesSetter } from '@messages'\nimport { API_ERROR_MESSAGE_PREFIX, queryLLM } from '@services/claude'\nimport {
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB,yBAAyB;AACrD,SAAS,0BAA0B,gBAAgB;AACnD
|
|
4
|
+
"sourcesContent": ["import { Command } from '@commands'\nimport { getContext } from '@context'\nimport { getMessagesGetter, getMessagesSetter } from '@messages'\nimport { API_ERROR_MESSAGE_PREFIX, queryLLM } from '@services/claude'\nimport { createUserMessage, normalizeMessagesForAPI } from '@utils/messages'\nimport { getCodeStyle } from '@utils/style'\nimport { clearTerminal } from '@utils/terminal'\nimport { resetReminderSession } from '@services/systemReminder'\nimport { resetFileFreshnessSession } from '@services/fileFreshness'\nimport { getCompressionPrompt } from '@constants/compressionPrompts'\nimport {\n getCompressionMode,\n getCompressionModeDescription,\n} from '@utils/compressionMode'\n\nconst compact = {\n type: 'local',\n name: 'compact',\n description: 'Clear conversation history but keep a summary in context',\n isEnabled: true,\n isHidden: false,\n async call(\n _,\n {\n options: { tools },\n abortController,\n setForkConvoWithMessagesOnTheNextRender,\n },\n ) {\n const messages = getMessagesGetter()()\n\n // Get the compression prompt based on current mode (business or code)\n const compressionMode = getCompressionMode()\n const compressionPrompt = getCompressionPrompt(compressionMode)\n const modeDescription = getCompressionModeDescription(compressionMode)\n\n const summaryRequest = createUserMessage(compressionPrompt)\n\n const summaryResponse = await queryLLM(\n normalizeMessagesForAPI([...messages, summaryRequest]),\n [\n 'You are a helpful AI assistant tasked with creating comprehensive conversation summaries that preserve all essential context for continuing development work.',\n ],\n 0,\n tools,\n abortController.signal,\n {\n safeMode: false,\n model: 'main', // \u4F7F\u7528\u6A21\u578B\u6307\u9488\uFF0C\u8BA9queryLLM\u7EDF\u4E00\u89E3\u6790\n prependCLISysprompt: true,\n },\n )\n\n const content = summaryResponse.message.content\n const summary =\n typeof content === 'string'\n ? content\n : content.length > 0 && content[0]?.type === 'text'\n ? content[0].text\n : null\n\n if (!summary) {\n throw new Error(\n `Failed to generate conversation summary - response did not contain valid text content - ${summaryResponse}`,\n )\n } else if (summary.startsWith(API_ERROR_MESSAGE_PREFIX)) {\n throw new Error(summary)\n }\n\n summaryResponse.message.usage = {\n input_tokens: 0,\n output_tokens: summaryResponse.message.usage.output_tokens,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: 0,\n }\n\n await clearTerminal()\n getMessagesSetter()([])\n setForkConvoWithMessagesOnTheNextRender([\n createUserMessage(\n `Context has been compressed using ${compressionMode === 'business' ? '9-section Business Consulting' : '8-section Code Development'} algorithm. Mode: ${modeDescription}. All essential information has been preserved for seamless continuation.`,\n ),\n summaryResponse,\n ])\n getContext.cache.clear?.()\n getCodeStyle.cache.clear?.()\n resetFileFreshnessSession()\n\n // Reset reminder and file freshness sessions to clean up state\n resetReminderSession()\n\n return '' // not used, just for typesafety. TODO: avoid this hack\n },\n userFacingName() {\n return 'compact'\n },\n} satisfies Command\n\nexport default compact\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB,yBAAyB;AACrD,SAAS,0BAA0B,gBAAgB;AACnD,SAAS,mBAAmB,+BAA+B;AAC3D,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAC1C,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,MAAM,UAAU;AAAA,EACd,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM,KACJ,GACA;AAAA,IACE,SAAS,EAAE,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,EACF,GACA;AACA,UAAM,WAAW,kBAAkB,EAAE;AAGrC,UAAM,kBAAkB,mBAAmB;AAC3C,UAAM,oBAAoB,qBAAqB,eAAe;AAC9D,UAAM,kBAAkB,8BAA8B,eAAe;AAErE,UAAM,iBAAiB,kBAAkB,iBAAiB;AAE1D,UAAM,kBAAkB,MAAM;AAAA,MAC5B,wBAAwB,CAAC,GAAG,UAAU,cAAc,CAAC;AAAA,MACrD;AAAA,QACE;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB;AAAA,QACE,UAAU;AAAA,QACV,OAAO;AAAA;AAAA,QACP,qBAAqB;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,QAAQ;AACxC,UAAM,UACJ,OAAO,YAAY,WACf,UACA,QAAQ,SAAS,KAAK,QAAQ,CAAC,GAAG,SAAS,SACzC,QAAQ,CAAC,EAAE,OACX;AAER,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,2FAA2F,eAAe;AAAA,MAC5G;AAAA,IACF,WAAW,QAAQ,WAAW,wBAAwB,GAAG;AACvD,YAAM,IAAI,MAAM,OAAO;AAAA,IACzB;AAEA,oBAAgB,QAAQ,QAAQ;AAAA,MAC9B,cAAc;AAAA,MACd,eAAe,gBAAgB,QAAQ,MAAM;AAAA,MAC7C,6BAA6B;AAAA,MAC7B,yBAAyB;AAAA,IAC3B;AAEA,UAAM,cAAc;AACpB,sBAAkB,EAAE,CAAC,CAAC;AACtB,4CAAwC;AAAA,MACtC;AAAA,QACE,qCAAqC,oBAAoB,aAAa,kCAAkC,4BAA4B,qBAAqB,eAAe;AAAA,MAC1K;AAAA,MACA;AAAA,IACF,CAAC;AACD,eAAW,MAAM,QAAQ;AACzB,iBAAa,MAAM,QAAQ;AAC3B,8BAA0B;AAG1B,yBAAqB;AAErB,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AACF;AAEA,IAAO,kBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/ctx_viz.js
CHANGED
|
@@ -4,7 +4,17 @@ import { getContext } from "../context.js";
|
|
|
4
4
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5
5
|
import { getMessagesGetter } from "../messages.js";
|
|
6
6
|
import { PROJECT_FILE } from "../constants/product.js";
|
|
7
|
-
|
|
7
|
+
import { countTokens } from "../utils/tokens.js";
|
|
8
|
+
function estimateStringTokens(text) {
|
|
9
|
+
if (!text) return 0;
|
|
10
|
+
const cjkPattern = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g;
|
|
11
|
+
const cjkMatches = text.match(cjkPattern);
|
|
12
|
+
const cjkCount = cjkMatches ? cjkMatches.length : 0;
|
|
13
|
+
const nonCjkCount = text.length - cjkCount;
|
|
14
|
+
const cjkTokens = cjkCount / 1.5;
|
|
15
|
+
const nonCjkTokens = nonCjkCount / 4;
|
|
16
|
+
return Math.ceil(cjkTokens + nonCjkTokens);
|
|
17
|
+
}
|
|
8
18
|
function getContextSections(text) {
|
|
9
19
|
const sections = [];
|
|
10
20
|
const firstContextIndex = text.indexOf("<context");
|
|
@@ -44,18 +54,23 @@ function getContextSections(text) {
|
|
|
44
54
|
}
|
|
45
55
|
return sections;
|
|
46
56
|
}
|
|
47
|
-
function formatTokenCount(
|
|
48
|
-
|
|
57
|
+
function formatTokenCount(tokens) {
|
|
58
|
+
if (tokens < 1e3) {
|
|
59
|
+
return `${tokens}`;
|
|
60
|
+
}
|
|
49
61
|
const k = tokens / 1e3;
|
|
50
62
|
return `${Math.round(k * 10) / 10}k`;
|
|
51
63
|
}
|
|
52
64
|
function formatByteCount(bytes) {
|
|
65
|
+
if (bytes < 1024) {
|
|
66
|
+
return `${bytes}b`;
|
|
67
|
+
}
|
|
53
68
|
const kb = bytes / 1024;
|
|
54
69
|
return `${Math.round(kb * 10) / 10}kb`;
|
|
55
70
|
}
|
|
56
|
-
function createSummaryTable(systemText, systemSections, tools, messages) {
|
|
71
|
+
function createSummaryTable(systemText, systemSections, tools, messages, actualMessageTokens) {
|
|
57
72
|
const table = new Table({
|
|
58
|
-
head: ["Component", "Tokens", "Size", "%
|
|
73
|
+
head: ["Component", "Tokens (est.)", "Size", "% Tokens"],
|
|
59
74
|
style: { head: ["bold"] },
|
|
60
75
|
chars: {
|
|
61
76
|
mid: "\u2500",
|
|
@@ -66,52 +81,63 @@ function createSummaryTable(systemText, systemSections, tools, messages) {
|
|
|
66
81
|
});
|
|
67
82
|
const messagesStr = JSON.stringify(messages);
|
|
68
83
|
const toolsStr = JSON.stringify(tools);
|
|
69
|
-
const
|
|
70
|
-
const
|
|
84
|
+
const systemTokens = estimateStringTokens(systemText);
|
|
85
|
+
const toolsTokens = estimateStringTokens(toolsStr);
|
|
86
|
+
const messageTokens = actualMessageTokens > 0 ? actualMessageTokens : estimateStringTokens(messagesStr);
|
|
87
|
+
const totalTokens = systemTokens + toolsTokens + messageTokens;
|
|
88
|
+
const getPercentage = (tokens) => totalTokens > 0 ? `${Math.round(tokens / totalTokens * 100)}%` : "0%";
|
|
71
89
|
table.push([
|
|
72
90
|
"System prompt",
|
|
73
|
-
formatTokenCount(
|
|
91
|
+
formatTokenCount(systemTokens),
|
|
74
92
|
formatByteCount(systemText.length),
|
|
75
|
-
getPercentage(
|
|
93
|
+
getPercentage(systemTokens)
|
|
76
94
|
]);
|
|
77
95
|
for (const section of systemSections) {
|
|
96
|
+
const sectionTokens = estimateStringTokens(section.content);
|
|
78
97
|
table.push([
|
|
79
98
|
` ${section.title}`,
|
|
80
|
-
formatTokenCount(
|
|
99
|
+
formatTokenCount(sectionTokens),
|
|
81
100
|
formatByteCount(section.content.length),
|
|
82
|
-
getPercentage(
|
|
101
|
+
getPercentage(sectionTokens)
|
|
83
102
|
]);
|
|
84
103
|
}
|
|
85
104
|
table.push([
|
|
86
105
|
"Tool definitions",
|
|
87
|
-
formatTokenCount(
|
|
106
|
+
formatTokenCount(toolsTokens),
|
|
88
107
|
formatByteCount(toolsStr.length),
|
|
89
|
-
getPercentage(
|
|
108
|
+
getPercentage(toolsTokens)
|
|
90
109
|
]);
|
|
91
110
|
for (const tool of tools) {
|
|
111
|
+
const toolTokens = estimateStringTokens(tool.description);
|
|
92
112
|
table.push([
|
|
93
113
|
` ${tool.name}`,
|
|
94
|
-
formatTokenCount(
|
|
114
|
+
formatTokenCount(toolTokens),
|
|
95
115
|
formatByteCount(tool.description.length),
|
|
96
|
-
getPercentage(
|
|
116
|
+
getPercentage(toolTokens)
|
|
97
117
|
]);
|
|
98
118
|
}
|
|
119
|
+
const messageLabel = actualMessageTokens > 0 ? "Messages (actual)" : "Messages (est.)";
|
|
99
120
|
table.push(
|
|
100
121
|
[
|
|
101
|
-
|
|
102
|
-
formatTokenCount(
|
|
122
|
+
messageLabel,
|
|
123
|
+
formatTokenCount(messageTokens),
|
|
103
124
|
formatByteCount(messagesStr.length),
|
|
104
|
-
getPercentage(
|
|
125
|
+
getPercentage(messageTokens)
|
|
105
126
|
],
|
|
106
|
-
[
|
|
127
|
+
[
|
|
128
|
+
"Total",
|
|
129
|
+
formatTokenCount(totalTokens),
|
|
130
|
+
formatByteCount(systemText.length + toolsStr.length + messagesStr.length),
|
|
131
|
+
"100%"
|
|
132
|
+
]
|
|
107
133
|
);
|
|
108
134
|
return table.toString();
|
|
109
135
|
}
|
|
110
136
|
const command = {
|
|
111
137
|
name: "ctx-viz",
|
|
112
|
-
description: "Show token usage breakdown for the current conversation context",
|
|
138
|
+
description: "[Developer] Show token usage breakdown for the current conversation context",
|
|
113
139
|
isEnabled: true,
|
|
114
|
-
isHidden:
|
|
140
|
+
isHidden: true,
|
|
115
141
|
type: "local",
|
|
116
142
|
userFacingName() {
|
|
117
143
|
return this.name;
|
|
@@ -141,8 +167,15 @@ ${schema}`
|
|
|
141
167
|
};
|
|
142
168
|
});
|
|
143
169
|
const messages = getMessagesGetter()();
|
|
170
|
+
const actualMessageTokens = countTokens(messages);
|
|
144
171
|
const sections = getContextSections(systemPrompt);
|
|
145
|
-
return createSummaryTable(
|
|
172
|
+
return createSummaryTable(
|
|
173
|
+
systemPrompt,
|
|
174
|
+
sections,
|
|
175
|
+
tools,
|
|
176
|
+
messages,
|
|
177
|
+
actualMessageTokens
|
|
178
|
+
);
|
|
146
179
|
}
|
|
147
180
|
};
|
|
148
181
|
var ctx_viz_default = command;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/ctx_viz.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport Table from 'cli-table3'\nimport { getSystemPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport { getMessagesGetter } from '@messages'\nimport { PROJECT_FILE } from '@constants/product'\n
|
|
5
|
-
"mappings": "AAEA,OAAO,WAAW;AAClB,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;
|
|
4
|
+
"sourcesContent": ["import type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport Table from 'cli-table3'\nimport { getSystemPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport { getMessagesGetter } from '@messages'\nimport { PROJECT_FILE } from '@constants/product'\nimport { countTokens } from '@utils/tokens'\n\n/**\n * Estimate token count for a string.\n * Uses a heuristic that accounts for different character types:\n * - ASCII/Latin: ~4 characters per token\n * - CJK (Chinese/Japanese/Korean): ~1.5 characters per token\n * - Mixed content: weighted average\n */\nfunction estimateStringTokens(text: string): number {\n if (!text) return 0\n\n // Count CJK characters (Chinese, Japanese, Korean)\n const cjkPattern = /[\\u4e00-\\u9fff\\u3040-\\u309f\\u30a0-\\u30ff\\uac00-\\ud7af]/g\n const cjkMatches = text.match(cjkPattern)\n const cjkCount = cjkMatches ? cjkMatches.length : 0\n const nonCjkCount = text.length - cjkCount\n\n // Estimate tokens: CJK ~1.5 chars/token, ASCII ~4 chars/token\n const cjkTokens = cjkCount / 1.5\n const nonCjkTokens = nonCjkCount / 4\n\n return Math.ceil(cjkTokens + nonCjkTokens)\n}\n\ninterface Section {\n title: string\n content: string\n}\n\ninterface ToolSummary {\n name: string\n description: string\n}\n\nfunction getContextSections(text: string): Section[] {\n const sections: Section[] = []\n\n // Find first <context> tag\n const firstContextIndex = text.indexOf('<context')\n\n // Everything before first tag is Core Sysprompt\n if (firstContextIndex > 0) {\n const coreSysprompt = text.slice(0, firstContextIndex).trim()\n if (coreSysprompt) {\n sections.push({\n title: 'Core Sysprompt',\n content: coreSysprompt,\n })\n }\n }\n\n let currentPos = firstContextIndex\n let nonContextContent = ''\n\n const regex = /<context\\s+name=\"([^\"]*)\">([\\s\\S]*?)<\\/context>/g\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(text)) !== null) {\n // Collect text between context tags\n if (match.index > currentPos) {\n nonContextContent += text.slice(currentPos, match.index)\n }\n\n const [, name = 'Unnamed Section', content = ''] = match\n sections.push({\n title: name === 'codeStyle' ? `CodeStyle + ${PROJECT_FILE}'s` : name,\n content: content.trim(),\n })\n\n currentPos = match.index + match[0].length\n }\n\n // Collect remaining text after last tag\n if (currentPos < text.length) {\n nonContextContent += text.slice(currentPos)\n }\n\n // Add non-contextualized content if present\n const trimmedNonContext = nonContextContent.trim()\n if (trimmedNonContext) {\n sections.push({\n title: 'Non-contextualized Content',\n content: trimmedNonContext,\n })\n }\n\n return sections\n}\n\nfunction formatTokenCount(tokens: number): string {\n if (tokens < 1000) {\n return `${tokens}`\n }\n const k = tokens / 1000\n return `${Math.round(k * 10) / 10}k`\n}\n\nfunction formatByteCount(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes}b`\n }\n const kb = bytes / 1024\n return `${Math.round(kb * 10) / 10}kb`\n}\n\nfunction createSummaryTable(\n systemText: string,\n systemSections: Section[],\n tools: ToolSummary[],\n messages: unknown,\n actualMessageTokens: number,\n): string {\n const table = new Table({\n head: ['Component', 'Tokens (est.)', 'Size', '% Tokens'],\n style: { head: ['bold'] },\n chars: {\n mid: '\u2500',\n 'left-mid': '\u251C',\n 'mid-mid': '\u253C',\n 'right-mid': '\u2524',\n },\n })\n\n const messagesStr = JSON.stringify(messages)\n const toolsStr = JSON.stringify(tools)\n\n // Estimate tokens for each component\n const systemTokens = estimateStringTokens(systemText)\n const toolsTokens = estimateStringTokens(toolsStr)\n // Use actual token count for messages if available, otherwise estimate\n const messageTokens =\n actualMessageTokens > 0\n ? actualMessageTokens\n : estimateStringTokens(messagesStr)\n\n // Calculate total tokens for percentages\n const totalTokens = systemTokens + toolsTokens + messageTokens\n const getPercentage = (tokens: number) =>\n totalTokens > 0 ? `${Math.round((tokens / totalTokens) * 100)}%` : '0%'\n\n // System prompt and its sections\n table.push([\n 'System prompt',\n formatTokenCount(systemTokens),\n formatByteCount(systemText.length),\n getPercentage(systemTokens),\n ])\n for (const section of systemSections) {\n const sectionTokens = estimateStringTokens(section.content)\n table.push([\n ` ${section.title}`,\n formatTokenCount(sectionTokens),\n formatByteCount(section.content.length),\n getPercentage(sectionTokens),\n ])\n }\n\n // Tools\n table.push([\n 'Tool definitions',\n formatTokenCount(toolsTokens),\n formatByteCount(toolsStr.length),\n getPercentage(toolsTokens),\n ])\n for (const tool of tools) {\n const toolTokens = estimateStringTokens(tool.description)\n table.push([\n ` ${tool.name}`,\n formatTokenCount(toolTokens),\n formatByteCount(tool.description.length),\n getPercentage(toolTokens),\n ])\n }\n\n // Messages and total\n const messageLabel =\n actualMessageTokens > 0 ? 'Messages (actual)' : 'Messages (est.)'\n table.push(\n [\n messageLabel,\n formatTokenCount(messageTokens),\n formatByteCount(messagesStr.length),\n getPercentage(messageTokens),\n ],\n [\n 'Total',\n formatTokenCount(totalTokens),\n formatByteCount(systemText.length + toolsStr.length + messagesStr.length),\n '100%',\n ],\n )\n\n return table.toString()\n}\n\nconst command: Command = {\n name: 'ctx-viz',\n description:\n '[Developer] Show token usage breakdown for the current conversation context',\n isEnabled: true,\n isHidden: true,\n type: 'local',\n\n userFacingName() {\n return this.name\n },\n\n async call(_args: string, cmdContext: { options: { tools: Tool[] } }) {\n // Get tools and system prompt with injected context\n const [systemPromptRaw, sysContext] = await Promise.all([\n getSystemPrompt(),\n getContext(),\n ])\n\n const rawTools = cmdContext.options.tools\n\n // Full system prompt with context sections injected\n let systemPrompt = systemPromptRaw.join('\\n')\n for (const [name, content] of Object.entries(sysContext)) {\n systemPrompt += `\\n<context name=\"${name}\">${content}</context>`\n }\n\n // Get full tool definitions including prompts and schemas\n const tools = rawTools.map(t => {\n // Get full prompt and schema\n const fullPrompt = t.prompt({ safeMode: false })\n const schema = JSON.stringify(\n 'inputJSONSchema' in t && t.inputJSONSchema\n ? t.inputJSONSchema\n : zodToJsonSchema(t.inputSchema),\n )\n\n return {\n name: t.name,\n description: `${fullPrompt}\\n\\nSchema:\\n${schema}`,\n }\n })\n\n // Get current messages from REPL\n const messages = getMessagesGetter()()\n\n // Get actual token count from API usage if available\n const actualMessageTokens = countTokens(messages)\n\n const sections = getContextSections(systemPrompt)\n return createSummaryTable(\n systemPrompt,\n sections,\n tools,\n messages,\n actualMessageTokens,\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
getMcpServer
|
|
10
10
|
} from "../services/mcpClient.js";
|
|
11
11
|
import { SimpleSpinner } from "../components/Spinner.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
getCurrentProjectConfig,
|
|
14
|
+
saveCurrentProjectConfig
|
|
15
|
+
} from "../utils/config.js";
|
|
13
16
|
const MainMenu = ({ onNavigate, onExit }) => {
|
|
14
17
|
const theme = getTheme();
|
|
15
18
|
const options = [
|
|
@@ -68,9 +71,12 @@ const ServerList = ({ onNavigate, onBack }) => {
|
|
|
68
71
|
};
|
|
69
72
|
loadServers();
|
|
70
73
|
}, []);
|
|
71
|
-
const handleServerSelect = useCallback(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
const handleServerSelect = useCallback(
|
|
75
|
+
(serverName) => {
|
|
76
|
+
onNavigate({ screen: "server-details", serverName });
|
|
77
|
+
},
|
|
78
|
+
[onNavigate]
|
|
79
|
+
);
|
|
74
80
|
useInput((input, key) => {
|
|
75
81
|
if (key.escape) onBack();
|
|
76
82
|
});
|
|
@@ -97,13 +103,7 @@ const ServerList = ({ onNavigate, onBack }) => {
|
|
|
97
103
|
padding: 1
|
|
98
104
|
},
|
|
99
105
|
/* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "MCP Servers")),
|
|
100
|
-
/* @__PURE__ */ React.createElement(
|
|
101
|
-
Select,
|
|
102
|
-
{
|
|
103
|
-
options,
|
|
104
|
-
onChange: handleServerSelect
|
|
105
|
-
}
|
|
106
|
-
),
|
|
106
|
+
/* @__PURE__ */ React.createElement(Select, { options, onChange: handleServerSelect }),
|
|
107
107
|
/* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "ESC"), " to go back"))
|
|
108
108
|
);
|
|
109
109
|
};
|