@within-7/minto 0.3.6 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{cli.js → cli.cjs} +25 -23
- package/dist/commands/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +110 -0
- package/dist/commands/language.js.map +7 -0
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/new.js +56 -0
- package/dist/commands/new.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +251 -16
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +7 -0
- package/dist/commands/setup.js +596 -109
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +292 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/status.js +75 -7
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +154 -180
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js +6 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/Config.js +9 -8
- package/dist/components/Config.js.map +2 -2
- package/dist/components/HeaderBar.js +2 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +166 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +46 -44
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/Logo.js +5 -2
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +6 -5
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +5 -4
- 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/ModelConfig.js +13 -12
- 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/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +77 -44
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +12 -8
- package/dist/components/SensitiveFileWarning.js.map +2 -2
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +117 -0
- package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
- package/dist/components/TabbedListView/SearchInput.js +23 -0
- package/dist/components/TabbedListView/SearchInput.js.map +7 -0
- package/dist/components/TabbedListView/TabBar.js +20 -0
- package/dist/components/TabbedListView/TabBar.js.map +7 -0
- package/dist/components/TabbedListView/TabbedListView.js +246 -0
- package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
- package/dist/components/TabbedListView/index.js +11 -0
- package/dist/components/TabbedListView/index.js.map +7 -0
- package/dist/components/TabbedListView/types.js +1 -0
- package/dist/components/TabbedListView/types.js.map +7 -0
- package/dist/components/TodoChangeBlock.js +6 -5
- package/dist/components/TodoChangeBlock.js.map +3 -3
- package/dist/components/TodoPanel.js +6 -3
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TrustDialog.js +6 -5
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
- package/dist/constants/macros.js +1 -1
- package/dist/constants/macros.js.map +1 -1
- package/dist/constants/product.js +2 -2
- package/dist/constants/product.js.map +1 -1
- package/dist/constants/prompts.js +17 -0
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/toolInputExamples.js +5 -1
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/tokenStatsManager.js +5 -0
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +56 -0
- package/dist/entrypoints/bootstrap.js.map +7 -0
- package/dist/entrypoints/cli.js +164 -23
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/history.js +75 -15
- package/dist/history.js.map +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/i18n/locales/en.js +582 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +582 -1
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/messages.js +11 -0
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +9 -0
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +45 -7
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/customCommands.js +44 -16
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +179 -1
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/prompt.js +21 -0
- package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +14 -9
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +12 -6
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/types/PermissionMode.js +30 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/plugin.js +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +103 -0
- package/dist/utils/agentHookExecutor.js.map +7 -0
- package/dist/utils/agentLoader.js +272 -32
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js +134 -0
- package/dist/utils/agentMemory.js.map +7 -0
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +52 -24
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configPaths.js +199 -0
- package/dist/utils/configPaths.js.map +7 -0
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/historyManager.js +234 -0
- package/dist/utils/historyManager.js.map +7 -0
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messages.js +13 -8
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/migration/index.js +37 -0
- package/dist/utils/migration/index.js.map +7 -0
- package/dist/utils/migration/migrateHistory.js +273 -0
- package/dist/utils/migration/migrateHistory.js.map +7 -0
- package/dist/utils/migration/migrateTodos.js +323 -0
- package/dist/utils/migration/migrateTodos.js.map +7 -0
- package/dist/utils/pasteCache.js +309 -0
- package/dist/utils/pasteCache.js.map +7 -0
- package/dist/utils/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +54 -28
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/sessionIndex.js +192 -0
- package/dist/utils/sessionIndex.js.map +7 -0
- package/dist/utils/sessionTracker.js +170 -0
- package/dist/utils/sessionTracker.js.map +7 -0
- package/dist/utils/skillLoader.js +103 -5
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stats.js +417 -0
- package/dist/utils/stats.js.map +7 -0
- package/dist/utils/stringSubstitution.js +106 -0
- package/dist/utils/stringSubstitution.js.map +7 -0
- package/dist/utils/teamConfig.js +156 -14
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/todoStorage.js +51 -19
- package/dist/utils/todoStorage.js.map +2 -2
- 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 +71 -28
- package/scripts/{postinstall.js → postinstall.cjs} +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/commands/agents/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Type definitions for the agents command\n */\nimport type { AgentConfig } from '@utils/agentLoader'\n\nexport const AGENT_LOCATIONS = {\n USER: 'user',\n PROJECT: 'project',\n BUILT_IN: 'built-in',\n ALL: 'all',\n} as const\n\nexport type AgentLocation =\n (typeof AGENT_LOCATIONS)[keyof typeof AGENT_LOCATIONS]\n\nexport type ModeType =\n | 'list-agents'\n | 'create-location'\n | 'create-method'\n | 'create-generate'\n | 'create-type'\n | 'create-description'\n | 'create-tools'\n | 'create-model'\n | 'create-color'\n | 'create-prompt'\n | 'create-confirm'\n | 'agent-menu'\n | 'view-agent'\n | 'edit-agent'\n | 'edit-tools'\n | 'edit-model'\n | 'edit-color'\n | 'delete-confirm'\n\nexport type ModeState = {\n mode: ModeType\n location?: AgentLocation\n selectedAgent?: AgentConfig\n previousMode?: ModeState\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport type CreateState = {\n location: AgentLocation | null\n agentType: string\n method: 'generate' | 'manual' | null\n generationPrompt: string\n whenToUse: string\n selectedTools: string[]\n selectedModel: string | null\n selectedColor: string | null\n systemPrompt: string\n isGenerating: boolean\n wasGenerated: boolean\n isAIGenerated: boolean\n error: string | null\n warnings: string[]\n agentTypeCursor: number\n whenToUseCursor: number\n promptCursor: number\n generationPromptCursor: number\n}\n\nexport type Tool = {\n name: string\n description?: string | (() => Promise<string>)\n}\n\nexport type GeneratedAgent = {\n identifier: string\n whenToUse: string\n systemPrompt: string\n suggestedTools?: string[]\n suggestedModel?: string\n}\n"],
|
|
5
|
-
"mappings": "AAKO,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,KAAK;AACP;",
|
|
4
|
+
"sourcesContent": ["/**\n * Type definitions for the agents command\n */\nimport type { AgentConfig } from '@utils/agentLoader'\n\nexport const AGENT_LOCATIONS = {\n USER: 'user',\n PROJECT: 'project',\n PLUGIN: 'plugin',\n BUILT_IN: 'built-in',\n ALL: 'all',\n} as const\n\nexport type AgentLocation =\n (typeof AGENT_LOCATIONS)[keyof typeof AGENT_LOCATIONS]\n\nexport type ModeType =\n | 'list-agents'\n | 'create-location'\n | 'create-method'\n | 'create-generate'\n | 'create-type'\n | 'create-description'\n | 'create-tools'\n | 'create-model'\n | 'create-color'\n | 'create-prompt'\n | 'create-confirm'\n | 'agent-menu'\n | 'view-agent'\n | 'edit-agent'\n | 'edit-tools'\n | 'edit-model'\n | 'edit-color'\n | 'delete-confirm'\n\nexport type ModeState = {\n mode: ModeType\n location?: AgentLocation\n selectedAgent?: AgentConfig\n previousMode?: ModeState\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport type CreateState = {\n location: AgentLocation | null\n agentType: string\n method: 'generate' | 'manual' | null\n generationPrompt: string\n whenToUse: string\n selectedTools: string[]\n selectedModel: string | null\n selectedColor: string | null\n systemPrompt: string\n isGenerating: boolean\n wasGenerated: boolean\n isAIGenerated: boolean\n error: string | null\n warnings: string[]\n agentTypeCursor: number\n whenToUseCursor: number\n promptCursor: number\n generationPromptCursor: number\n}\n\nexport type Tool = {\n name: string\n description?: string | (() => Promise<string>)\n}\n\nexport type GeneratedAgent = {\n identifier: string\n whenToUse: string\n systemPrompt: string\n suggestedTools?: string[]\n suggestedModel?: string\n}\n"],
|
|
5
|
+
"mappings": "AAKO,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,KAAK;AACP;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,11 +3,13 @@ import {
|
|
|
3
3
|
unlinkSync,
|
|
4
4
|
mkdirSync,
|
|
5
5
|
existsSync,
|
|
6
|
-
renameSync
|
|
6
|
+
renameSync,
|
|
7
|
+
openSync,
|
|
8
|
+
closeSync
|
|
7
9
|
} from "fs";
|
|
8
10
|
import { join, resolve, relative, isAbsolute } from "path";
|
|
9
|
-
import { homedir } from "os";
|
|
10
|
-
import {
|
|
11
|
+
import { homedir, tmpdir } from "os";
|
|
12
|
+
import { spawnSync } from "child_process";
|
|
11
13
|
import { getCwd } from "../../../utils/state.js";
|
|
12
14
|
import { AGENT_LOCATIONS, FOLDER_CONFIG } from "../constants.js";
|
|
13
15
|
function getAgentDirectory(location) {
|
|
@@ -24,6 +26,9 @@ function getAgentFilePath(agent) {
|
|
|
24
26
|
if (agent.location === "built-in") {
|
|
25
27
|
throw new Error("Cannot get file path for built-in agents");
|
|
26
28
|
}
|
|
29
|
+
if (agent.sourcePath) {
|
|
30
|
+
return agent.sourcePath;
|
|
31
|
+
}
|
|
27
32
|
const dir = getAgentDirectory(agent.location);
|
|
28
33
|
return join(dir, `${agent.agentType}.md`);
|
|
29
34
|
}
|
|
@@ -103,7 +108,7 @@ async function deleteAgent(agent) {
|
|
|
103
108
|
const filePath = getAgentFilePath(agent);
|
|
104
109
|
unlinkSync(filePath);
|
|
105
110
|
}
|
|
106
|
-
|
|
111
|
+
function openInEditor(filePath) {
|
|
107
112
|
const resolvedPath = resolve(filePath);
|
|
108
113
|
const projectDir = process.cwd();
|
|
109
114
|
const homeDir = homedir();
|
|
@@ -120,41 +125,95 @@ async function openInEditor(filePath) {
|
|
|
120
125
|
if (!resolvedPath.endsWith(".md")) {
|
|
121
126
|
throw new Error("Invalid file type: Only .md files are allowed");
|
|
122
127
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
const child = spawn(command, args, {
|
|
142
|
-
detached: true,
|
|
143
|
-
stdio: "ignore",
|
|
128
|
+
if (!existsSync(resolvedPath)) {
|
|
129
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
130
|
+
}
|
|
131
|
+
const editor = process.env.VISUAL || process.env.EDITOR || "vi";
|
|
132
|
+
let ttyFd;
|
|
133
|
+
try {
|
|
134
|
+
ttyFd = openSync("/dev/tty", "r");
|
|
135
|
+
} catch {
|
|
136
|
+
ttyFd = void 0;
|
|
137
|
+
}
|
|
138
|
+
if (typeof process.stdin.setRawMode === "function") {
|
|
139
|
+
process.stdin.setRawMode(false);
|
|
140
|
+
}
|
|
141
|
+
process.stdin.pause();
|
|
142
|
+
try {
|
|
143
|
+
const result = spawnSync(editor, [resolvedPath], {
|
|
144
|
+
stdio: [ttyFd ?? "inherit", "inherit", "inherit"],
|
|
144
145
|
shell: false
|
|
145
146
|
});
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
147
|
+
if (result.error) {
|
|
148
|
+
throw new Error(`Failed to open editor: ${result.error.message}`);
|
|
149
|
+
}
|
|
150
|
+
if (result.status !== 0) {
|
|
151
|
+
throw new Error(`Editor exited with code ${result.status}`);
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
if (ttyFd !== void 0) {
|
|
155
|
+
try {
|
|
156
|
+
closeSync(ttyFd);
|
|
157
|
+
} catch {
|
|
155
158
|
}
|
|
159
|
+
}
|
|
160
|
+
process.stdin.resume();
|
|
161
|
+
if (typeof process.stdin.setRawMode === "function") {
|
|
162
|
+
process.stdin.setRawMode(true);
|
|
163
|
+
}
|
|
164
|
+
process.stdout.emit("resize");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function viewInPager(agent) {
|
|
168
|
+
const content = generateAgentFileContent(
|
|
169
|
+
agent.agentType,
|
|
170
|
+
agent.whenToUse,
|
|
171
|
+
agent.tools,
|
|
172
|
+
agent.systemPrompt,
|
|
173
|
+
agent.model_name,
|
|
174
|
+
agent.color
|
|
175
|
+
);
|
|
176
|
+
const filePath = join(
|
|
177
|
+
tmpdir(),
|
|
178
|
+
`minto-agent-${agent.agentType}-${Date.now()}.md`
|
|
179
|
+
);
|
|
180
|
+
writeFileSync(filePath, content, "utf-8");
|
|
181
|
+
const pager = process.env.PAGER || "less";
|
|
182
|
+
let ttyFd;
|
|
183
|
+
try {
|
|
184
|
+
ttyFd = openSync("/dev/tty", "r");
|
|
185
|
+
} catch {
|
|
186
|
+
ttyFd = void 0;
|
|
187
|
+
}
|
|
188
|
+
if (typeof process.stdin.setRawMode === "function") {
|
|
189
|
+
process.stdin.setRawMode(false);
|
|
190
|
+
}
|
|
191
|
+
process.stdin.pause();
|
|
192
|
+
try {
|
|
193
|
+
const result = spawnSync(pager, [filePath], {
|
|
194
|
+
stdio: [ttyFd ?? "inherit", "inherit", "inherit"],
|
|
195
|
+
shell: false
|
|
156
196
|
});
|
|
157
|
-
|
|
197
|
+
if (result.error) {
|
|
198
|
+
throw new Error(`Failed to open pager: ${result.error.message}`);
|
|
199
|
+
}
|
|
200
|
+
} finally {
|
|
201
|
+
if (ttyFd !== void 0) {
|
|
202
|
+
try {
|
|
203
|
+
closeSync(ttyFd);
|
|
204
|
+
} catch {
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
unlinkSync(filePath);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
process.stdin.resume();
|
|
212
|
+
if (typeof process.stdin.setRawMode === "function") {
|
|
213
|
+
process.stdin.setRawMode(true);
|
|
214
|
+
}
|
|
215
|
+
process.stdout.emit("resize");
|
|
216
|
+
}
|
|
158
217
|
}
|
|
159
218
|
async function updateAgent(agent, description, tools, systemPrompt, color, model) {
|
|
160
219
|
if (agent.location === "built-in") {
|
|
@@ -180,6 +239,7 @@ export {
|
|
|
180
239
|
getAgentFilePath,
|
|
181
240
|
openInEditor,
|
|
182
241
|
saveAgent,
|
|
183
|
-
updateAgent
|
|
242
|
+
updateAgent,
|
|
243
|
+
viewInPager
|
|
184
244
|
};
|
|
185
245
|
//# sourceMappingURL=fileOperations.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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": "AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,SAAS,UAAU,kBAAkB;AACpD,SAAS,
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["/**\n * File system operations for agents\n */\nimport {\n writeFileSync,\n unlinkSync,\n mkdirSync,\n existsSync,\n renameSync,\n openSync,\n closeSync,\n} from 'fs'\nimport { join, resolve, relative, isAbsolute } from 'path'\nimport { homedir, tmpdir } from 'os'\nimport { spawnSync } 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 // Use sourcePath if available (works for user/project/plugin agents)\n if (agent.sourcePath) {\n return agent.sourcePath\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 terminal editor (vim/vi) inline.\n * Uses $VISUAL / $EDITOR env vars with fallback to vi.\n * Runs synchronously \u2014 blocks until the editor exits.\n */\nexport function openInEditor(filePath: string): 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 // Ensure the file exists before opening (agent may have been created in-memory)\n if (!existsSync(resolvedPath)) {\n throw new Error(`File not found: ${resolvedPath}`)\n }\n\n const editor = process.env.VISUAL || process.env.EDITOR || 'vi'\n\n // Open /dev/tty directly so the editor gets a fresh fd for keyboard input,\n // bypassing Node/Ink's stdin listeners which would otherwise consume keystrokes.\n let ttyFd: number | undefined\n try {\n ttyFd = openSync('/dev/tty', 'r')\n } catch {\n ttyFd = undefined\n }\n\n // Release terminal from Ink's raw mode so the editor gets normal input\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(false)\n }\n process.stdin.pause()\n\n try {\n const result = spawnSync(editor, [resolvedPath], {\n stdio: [ttyFd ?? 'inherit', 'inherit', 'inherit'],\n shell: false,\n })\n if (result.error) {\n throw new Error(`Failed to open editor: ${result.error.message}`)\n }\n if (result.status !== 0) {\n throw new Error(`Editor exited with code ${result.status}`)\n }\n } finally {\n // Close the tty fd if we opened one\n if (ttyFd !== undefined) {\n try {\n closeSync(ttyFd)\n } catch {\n // Ignore close errors\n }\n }\n // Restore stdin for Ink: resume + raw mode\n process.stdin.resume()\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(true)\n }\n // Do NOT clearScreen() here \u2014 editors (vi/vim/nano) use the alternate\n // screen buffer, which automatically restores the original terminal\n // content on exit. clearScreen() would destroy that restored UI.\n // Emit resize to let Ink recalculate layout in case terminal was resized.\n process.stdout.emit('resize')\n }\n}\n\n/**\n * View agent details in a terminal pager (less/more).\n * Always generates a temp file from in-memory config \u2014 works for all\n * agent locations (built-in, plugin, user, project) regardless of\n * whether the physical .md file exists.\n * Runs synchronously \u2014 blocks until the pager exits.\n */\nexport function viewInPager(agent: AgentConfig): void {\n // Generate temp file from in-memory config for all agent types\n const content = generateAgentFileContent(\n agent.agentType,\n agent.whenToUse,\n agent.tools,\n agent.systemPrompt,\n agent.model_name,\n agent.color,\n )\n const filePath = join(\n tmpdir(),\n `minto-agent-${agent.agentType}-${Date.now()}.md`,\n )\n writeFileSync(filePath, content, 'utf-8')\n\n const pager = process.env.PAGER || 'less'\n\n // Open /dev/tty directly so the pager gets a fresh fd for keyboard input,\n // bypassing Node/Ink's stdin listeners which would otherwise consume keystrokes.\n let ttyFd: number | undefined\n try {\n ttyFd = openSync('/dev/tty', 'r')\n } catch {\n // Fallback: if /dev/tty is not available, try inheriting stdin\n ttyFd = undefined\n }\n\n // Release terminal from Ink's raw mode\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(false)\n }\n process.stdin.pause()\n\n try {\n const result = spawnSync(pager, [filePath], {\n stdio: [ttyFd ?? 'inherit', 'inherit', 'inherit'],\n shell: false,\n })\n if (result.error) {\n throw new Error(`Failed to open pager: ${result.error.message}`)\n }\n } finally {\n // Close the tty fd if we opened one\n if (ttyFd !== undefined) {\n try {\n closeSync(ttyFd)\n } catch {\n // Ignore close errors\n }\n }\n // Clean up temp file\n try {\n unlinkSync(filePath)\n } catch {\n // Ignore cleanup errors\n }\n // Restore stdin for Ink: resume + raw mode\n process.stdin.resume()\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(true)\n }\n // Do NOT clearScreen() here \u2014 less uses the alternate screen buffer,\n // which automatically restores the original terminal content on exit.\n // clearScreen() would destroy that restored UI.\n // Emit resize to let Ink recalculate layout in case terminal was resized.\n process.stdout.emit('resize')\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": []
|
|
7
7
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
saveAgent,
|
|
7
7
|
deleteAgent,
|
|
8
8
|
openInEditor,
|
|
9
|
+
viewInPager,
|
|
9
10
|
updateAgent
|
|
10
11
|
} from "./fileOperations.js";
|
|
11
12
|
export {
|
|
@@ -16,6 +17,7 @@ export {
|
|
|
16
17
|
getAgentFilePath,
|
|
17
18
|
openInEditor,
|
|
18
19
|
saveAgent,
|
|
19
|
-
updateAgent
|
|
20
|
+
updateAgent,
|
|
21
|
+
viewInPager
|
|
20
22
|
};
|
|
21
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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;",
|
|
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 viewInPager,\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,EACA;AAAA,OACK;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/context.js
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
2
|
import { getMessagesGetter } from "../messages.js";
|
|
4
3
|
import { countTokens } from "../utils/tokens.js";
|
|
5
4
|
import { getModelManager } from "../utils/model.js";
|
|
6
5
|
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const empty = width - filled;
|
|
10
|
-
const filledChar = "\u2588";
|
|
11
|
-
const emptyChar = "\u2591";
|
|
12
|
-
return filledChar.repeat(filled) + emptyChar.repeat(empty);
|
|
13
|
-
}
|
|
14
|
-
function getUsageColor(percent) {
|
|
15
|
-
if (percent < 50) return "green";
|
|
16
|
-
if (percent < 80) return "yellow";
|
|
17
|
-
return "red";
|
|
18
|
-
}
|
|
6
|
+
import { InfoPanel } from "../components/InfoPanel/index.js";
|
|
7
|
+
import { t } from "../i18n/index.js";
|
|
19
8
|
function formatTokens(tokens) {
|
|
20
9
|
if (tokens >= 1e6) {
|
|
21
10
|
return `${(tokens / 1e6).toFixed(1)}M`;
|
|
@@ -31,24 +20,59 @@ function estimateRemainingTurns(usedTokens, maxTokens, messageCount) {
|
|
|
31
20
|
const remaining = maxTokens - usedTokens;
|
|
32
21
|
return Math.max(0, Math.floor(remaining / avgPerTurn));
|
|
33
22
|
}
|
|
34
|
-
|
|
35
|
-
tokenInfo
|
|
36
|
-
}) => {
|
|
23
|
+
function buildSections(tokenInfo) {
|
|
37
24
|
const { usedTokens, maxTokens, messageCount, modelName } = tokenInfo;
|
|
38
25
|
const percent = Math.min(100, usedTokens / maxTokens * 100);
|
|
39
|
-
const color = getUsageColor(percent);
|
|
40
26
|
const remainingTurns = estimateRemainingTurns(
|
|
41
27
|
usedTokens,
|
|
42
28
|
maxTokens,
|
|
43
29
|
messageCount
|
|
44
30
|
);
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
const items = [
|
|
32
|
+
{
|
|
33
|
+
label: t("commands.context.tokens"),
|
|
34
|
+
value: `${formatTokens(usedTokens)} / ${formatTokens(maxTokens)}`,
|
|
35
|
+
progress: { percent, width: 20 }
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
label: t("commands.context.remaining"),
|
|
39
|
+
value: `${formatTokens(maxTokens - usedTokens)} tokens`
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
label: t("commands.context.messages"),
|
|
43
|
+
value: String(messageCount)
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: t("commands.context.estTurns"),
|
|
47
|
+
value: `~${remainingTurns}`
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
if (percent >= 95) {
|
|
51
|
+
items.push({
|
|
52
|
+
label: "\u26A0",
|
|
53
|
+
value: t("commands.context.criticalUsage"),
|
|
54
|
+
valueColor: SEMANTIC_COLORS.error
|
|
55
|
+
});
|
|
56
|
+
} else if (percent >= 70) {
|
|
57
|
+
items.push({
|
|
58
|
+
label: "\u26A0",
|
|
59
|
+
value: t("commands.context.highUsage"),
|
|
60
|
+
valueColor: "#FFB86C"
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return [
|
|
64
|
+
{
|
|
65
|
+
title: t("commands.context.contextUsage"),
|
|
66
|
+
items
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
}
|
|
47
70
|
const command = {
|
|
48
71
|
name: "context",
|
|
49
72
|
description: "Visualize current context usage with token counts and estimates",
|
|
50
73
|
isEnabled: true,
|
|
51
74
|
isHidden: false,
|
|
75
|
+
hidePromptInput: true,
|
|
52
76
|
type: "local-jsx",
|
|
53
77
|
aliases: ["ctx"],
|
|
54
78
|
userFacingName() {
|
|
@@ -68,14 +92,21 @@ const command = {
|
|
|
68
92
|
}
|
|
69
93
|
} catch {
|
|
70
94
|
}
|
|
71
|
-
const
|
|
95
|
+
const sections = buildSections({
|
|
72
96
|
usedTokens,
|
|
73
97
|
maxTokens,
|
|
74
98
|
messageCount: messages.length,
|
|
75
99
|
modelName
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
});
|
|
101
|
+
return /* @__PURE__ */ React.createElement(
|
|
102
|
+
InfoPanel,
|
|
103
|
+
{
|
|
104
|
+
title: t("commands.context.title"),
|
|
105
|
+
subtitle: modelName,
|
|
106
|
+
sections,
|
|
107
|
+
onClose: onDone
|
|
108
|
+
}
|
|
109
|
+
);
|
|
79
110
|
}
|
|
80
111
|
};
|
|
81
112
|
var context_default = command;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/context.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Context Visualization Command\n *\n * Shows a visual representation of current context usage\n * with token counts, progress bars, and estimates.\n */\n\nimport React from 'react'\nimport
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Context Visualization Command\n *\n * Shows a visual representation of current context usage\n * with token counts, progress bars, and estimates.\n * Uses InfoPanel for consistent UI.\n */\n\nimport React from 'react'\nimport type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport { getMessagesGetter } from '@messages'\nimport { countTokens } from '@utils/tokens'\nimport { getModelManager } from '@utils/model'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { InfoPanel } from '@components/InfoPanel'\nimport type { InfoSection, InfoItem } from '@components/InfoPanel'\nimport { t } from '@i18n'\n\n/**\n * Format token count with k/M suffix\n */\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) {\n return `${(tokens / 1_000_000).toFixed(1)}M`\n }\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}k`\n }\n return tokens.toString()\n}\n\n/**\n * Estimate remaining turns based on average token usage\n */\nfunction estimateRemainingTurns(\n usedTokens: number,\n maxTokens: number,\n messageCount: number,\n): number {\n if (messageCount < 2) return Math.floor((maxTokens - usedTokens) / 2000)\n const avgPerTurn = usedTokens / (messageCount / 2)\n const remaining = maxTokens - usedTokens\n return Math.max(0, Math.floor(remaining / avgPerTurn))\n}\n\nfunction buildSections(tokenInfo: {\n usedTokens: number\n maxTokens: number\n messageCount: number\n modelName: string\n}): InfoSection[] {\n const { usedTokens, maxTokens, messageCount, modelName } = tokenInfo\n const percent = Math.min(100, (usedTokens / maxTokens) * 100)\n const remainingTurns = estimateRemainingTurns(\n usedTokens,\n maxTokens,\n messageCount,\n )\n\n const items: InfoItem[] = [\n {\n label: t('commands.context.tokens'),\n value: `${formatTokens(usedTokens)} / ${formatTokens(maxTokens)}`,\n progress: { percent, width: 20 },\n },\n {\n label: t('commands.context.remaining'),\n value: `${formatTokens(maxTokens - usedTokens)} tokens`,\n },\n {\n label: t('commands.context.messages'),\n value: String(messageCount),\n },\n {\n label: t('commands.context.estTurns'),\n value: `~${remainingTurns}`,\n },\n ]\n\n // Warning items\n if (percent >= 95) {\n items.push({\n label: '\\u26A0',\n value: t('commands.context.criticalUsage'),\n valueColor: SEMANTIC_COLORS.error,\n })\n } else if (percent >= 70) {\n items.push({\n label: '\\u26A0',\n value: t('commands.context.highUsage'),\n valueColor: '#FFB86C',\n })\n }\n\n return [\n {\n title: t('commands.context.contextUsage'),\n items,\n },\n ]\n}\n\nconst command: Command = {\n name: 'context',\n description:\n 'Visualize current context usage with token counts and estimates',\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n type: 'local-jsx',\n aliases: ['ctx'],\n\n userFacingName() {\n return this.name\n },\n\n async call(onDone) {\n const messages = getMessagesGetter()()\n const usedTokens = countTokens(messages)\n\n let maxTokens = 200_000\n let modelName = 'unknown'\n\n try {\n const modelManager = getModelManager()\n const profile = modelManager.resolveModel('main')\n if (profile) {\n maxTokens = profile.contextLength || maxTokens\n modelName = profile.name || profile.modelName\n }\n } catch {\n // Use defaults\n }\n\n const sections = buildSections({\n usedTokens,\n maxTokens,\n messageCount: messages.length,\n modelName,\n })\n\n return (\n <InfoPanel\n title={t('commands.context.title')}\n subtitle={modelName}\n sections={sections}\n onClose={onDone}\n />\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|