snow-ai 0.3.36 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/agents/codebaseIndexAgent.js +1 -0
  2. package/dist/agents/codebaseReviewAgent.d.ts +61 -0
  3. package/dist/agents/codebaseReviewAgent.js +301 -0
  4. package/dist/agents/promptOptimizeAgent.d.ts +54 -0
  5. package/dist/agents/promptOptimizeAgent.js +268 -0
  6. package/dist/api/anthropic.js +1 -0
  7. package/dist/api/chat.js +1 -0
  8. package/dist/api/embedding.js +1 -0
  9. package/dist/api/gemini.js +2 -1
  10. package/dist/api/responses.js +1 -0
  11. package/dist/api/systemPrompt.d.ts +1 -5
  12. package/dist/api/systemPrompt.js +168 -100
  13. package/dist/app.js +14 -6
  14. package/dist/cli.js +1 -1
  15. package/dist/hooks/useCommandPanel.js +48 -46
  16. package/dist/hooks/useConversation.d.ts +2 -1
  17. package/dist/hooks/useConversation.js +116 -30
  18. package/dist/hooks/useGlobalExit.js +4 -2
  19. package/dist/hooks/useStreamingState.d.ts +9 -0
  20. package/dist/hooks/useStreamingState.js +3 -0
  21. package/dist/i18n/I18nContext.d.ts +14 -0
  22. package/dist/i18n/I18nContext.js +24 -0
  23. package/dist/i18n/index.d.ts +3 -0
  24. package/dist/i18n/index.js +2 -0
  25. package/dist/i18n/lang/en.d.ts +2 -0
  26. package/dist/i18n/lang/en.js +483 -0
  27. package/dist/i18n/lang/es.d.ts +2 -0
  28. package/dist/i18n/lang/es.js +483 -0
  29. package/dist/i18n/lang/ja.d.ts +2 -0
  30. package/dist/i18n/lang/ja.js +483 -0
  31. package/dist/i18n/lang/ko.d.ts +2 -0
  32. package/dist/i18n/lang/ko.js +483 -0
  33. package/dist/i18n/lang/zh-TW.d.ts +2 -0
  34. package/dist/i18n/lang/zh-TW.js +483 -0
  35. package/dist/i18n/lang/zh.d.ts +2 -0
  36. package/dist/i18n/lang/zh.js +483 -0
  37. package/dist/i18n/translations.d.ts +2 -0
  38. package/dist/i18n/translations.js +14 -0
  39. package/dist/i18n/types.d.ts +459 -0
  40. package/dist/i18n/types.js +1 -0
  41. package/dist/mcp/aceCodeSearch.d.ts +17 -48
  42. package/dist/mcp/aceCodeSearch.js +24 -56
  43. package/dist/mcp/bash.js +8 -1
  44. package/dist/mcp/codebaseSearch.d.ts +1 -1
  45. package/dist/mcp/codebaseSearch.js +159 -30
  46. package/dist/mcp/filesystem.d.ts +3 -80
  47. package/dist/mcp/filesystem.js +23 -103
  48. package/dist/mcp/subagent.d.ts +2 -1
  49. package/dist/mcp/subagent.js +54 -5
  50. package/dist/ui/components/ChatInput.js +22 -25
  51. package/dist/ui/components/CommandPanel.d.ts +1 -1
  52. package/dist/ui/components/CommandPanel.js +20 -13
  53. package/dist/ui/components/DiffViewer.d.ts +1 -1
  54. package/dist/ui/components/DiffViewer.js +101 -91
  55. package/dist/ui/components/FileList.js +22 -11
  56. package/dist/ui/components/HelpPanel.js +47 -21
  57. package/dist/ui/components/Menu.js +6 -2
  58. package/dist/ui/components/MessageList.d.ts +6 -0
  59. package/dist/ui/components/MessageList.js +1 -1
  60. package/dist/ui/components/ToolConfirmation.d.ts +4 -1
  61. package/dist/ui/components/ToolConfirmation.js +28 -2
  62. package/dist/ui/components/ToolResultPreview.d.ts +2 -1
  63. package/dist/ui/components/ToolResultPreview.js +41 -25
  64. package/dist/ui/pages/ChatScreen.js +177 -56
  65. package/dist/ui/pages/CodeBaseConfigScreen.js +54 -30
  66. package/dist/ui/pages/ConfigScreen.js +138 -98
  67. package/dist/ui/pages/CustomHeadersScreen.js +75 -69
  68. package/dist/ui/pages/LanguageSettingsScreen.d.ts +7 -0
  69. package/dist/ui/pages/LanguageSettingsScreen.js +89 -0
  70. package/dist/ui/pages/ProxyConfigScreen.js +27 -23
  71. package/dist/ui/pages/SensitiveCommandConfigScreen.js +32 -25
  72. package/dist/ui/pages/SubAgentConfigScreen.js +88 -75
  73. package/dist/ui/pages/SystemPromptConfigScreen.js +31 -26
  74. package/dist/ui/pages/WelcomeScreen.js +40 -26
  75. package/dist/utils/apiConfig.d.ts +2 -0
  76. package/dist/utils/codebaseConfig.d.ts +1 -5
  77. package/dist/utils/codebaseConfig.js +2 -10
  78. package/dist/utils/codebaseSearchEvents.d.ts +16 -0
  79. package/dist/utils/codebaseSearchEvents.js +13 -0
  80. package/dist/utils/commands/agent.js +2 -2
  81. package/dist/utils/commands/init.js +1 -1
  82. package/dist/utils/configManager.js +26 -5
  83. package/dist/utils/contextCompressor.js +1 -1
  84. package/dist/utils/languageConfig.d.ts +21 -0
  85. package/dist/utils/languageConfig.js +61 -0
  86. package/dist/utils/mcpToolsManager.js +0 -9
  87. package/dist/utils/notebookManager.js +11 -4
  88. package/dist/utils/sessionConverter.js +13 -3
  89. package/dist/utils/sessionManager.d.ts +1 -0
  90. package/dist/utils/subAgentConfig.d.ts +10 -5
  91. package/dist/utils/subAgentConfig.js +112 -19
  92. package/dist/utils/subAgentExecutor.d.ts +9 -1
  93. package/dist/utils/subAgentExecutor.js +122 -9
  94. package/dist/utils/toolExecutor.d.ts +2 -1
  95. package/dist/utils/toolExecutor.js +1 -2
  96. package/dist/utils/usageLogger.js +18 -3
  97. package/package.json +2 -1
@@ -19,21 +19,103 @@ import { sessionManager } from './sessionManager.js';
19
19
  */
20
20
  export async function executeSubAgent(agentId, prompt, onMessage, abortSignal, requestToolConfirmation, isToolAutoApproved, yoloMode, addToAlwaysApproved) {
21
21
  try {
22
- // Get sub-agent configuration
23
- const agent = getSubAgent(agentId);
24
- if (!agent) {
25
- return {
26
- success: false,
27
- result: '',
28
- error: `Sub-agent with ID "${agentId}" not found`,
22
+ // Handle built-in agents (hardcoded)
23
+ let agent;
24
+ if (agentId === 'agent_explore') {
25
+ agent = {
26
+ id: 'agent_explore',
27
+ name: 'Explore Agent',
28
+ description: 'Specialized for quickly exploring and understanding codebases. Excels at searching code, finding definitions, analyzing code structure and semantic understanding.',
29
+ role: 'You are a specialized code exploration agent. Your task is to help users understand codebase structure, locate specific code, and analyze dependencies. Use search and analysis tools to explore code, but do not modify any files or execute commands. Focus on code discovery and understanding.\n\nIMPORTANT: You have NO access to the main conversation history. The prompt provided to you contains ALL the context from the main session. Read it carefully - all file locations, business requirements, constraints, and discovered information are included in the prompt. Do not assume any additional context.',
30
+ tools: [
31
+ // Filesystem read-only tools
32
+ 'filesystem-read',
33
+ // ACE code search tools (core tools)
34
+ 'ace-find_definition',
35
+ 'ace-find_references',
36
+ 'ace-semantic_search',
37
+ 'ace-text_search',
38
+ 'ace-file_outline',
39
+ // Codebase search tools
40
+ 'codebase-search',
41
+ // Web search for documentation
42
+ 'websearch-search',
43
+ 'websearch-fetch',
44
+ ],
45
+ };
46
+ }
47
+ else if (agentId === 'agent_plan') {
48
+ agent = {
49
+ id: 'agent_plan',
50
+ name: 'Plan Agent',
51
+ description: 'Specialized for planning complex tasks. Excels at analyzing requirements, exploring existing code, and creating detailed implementation plans.',
52
+ role: 'You are a specialized task planning agent. Your task is to analyze user requirements, explore existing codebase, identify relevant files and dependencies, and then create detailed implementation plans. Use search and analysis tools to gather information, check diagnostics to understand current state, but do not execute actual modifications. Output clear step-by-step plans including files to modify, suggested implementation approaches, and important considerations.\n\nIMPORTANT: You have NO access to the main conversation history. The prompt provided to you contains ALL the context from the main session. Read it carefully - all requirements, architecture understanding, file locations, constraints, and user preferences are included in the prompt. Do not assume any additional context.',
53
+ tools: [
54
+ // Filesystem read-only tools
55
+ 'filesystem-read',
56
+ // ACE code search tools (planning requires code understanding)
57
+ 'ace-find_definition',
58
+ 'ace-find_references',
59
+ 'ace-semantic_search',
60
+ 'ace-text_search',
61
+ 'ace-file_outline',
62
+ // IDE diagnostics (understand current issues)
63
+ 'ide-get_diagnostics',
64
+ // Codebase search
65
+ 'codebase-search',
66
+ // Web search for reference
67
+ 'websearch-search',
68
+ 'websearch-fetch',
69
+ ],
29
70
  };
30
71
  }
72
+ else if (agentId === 'agent_general') {
73
+ agent = {
74
+ id: 'agent_general',
75
+ name: 'General Purpose Agent',
76
+ description: 'General-purpose multi-step task execution agent. Has complete tool access for code search, file modification, command execution, and various operations.',
77
+ role: 'You are a general-purpose task execution agent. You can perform various complex multi-step tasks, including searching code, modifying files, executing commands, etc. When given a task, systematically break it down and execute. You have access to all tools and should select appropriate tools as needed to complete tasks efficiently.\n\nIMPORTANT: You have NO access to the main conversation history. The prompt provided to you contains ALL the context from the main session. Read it carefully - all task requirements, file paths, code patterns, dependencies, business logic, constraints, and testing requirements are included in the prompt. Do not assume any additional context.',
78
+ tools: [
79
+ // Filesystem tools (complete access)
80
+ 'filesystem-read',
81
+ 'filesystem-create',
82
+ 'filesystem-edit',
83
+ 'filesystem-edit_search',
84
+ // Terminal tools
85
+ 'terminal-execute',
86
+ // ACE code search tools
87
+ 'ace-find_definition',
88
+ 'ace-find_references',
89
+ 'ace-semantic_search',
90
+ 'ace-text_search',
91
+ 'ace-file_outline',
92
+ // Web search tools
93
+ 'websearch-search',
94
+ 'websearch-fetch',
95
+ // IDE diagnostics tools
96
+ 'ide-get_diagnostics',
97
+ // Codebase search tools
98
+ 'codebase-search',
99
+ ],
100
+ };
101
+ }
102
+ else {
103
+ // Get user-configured sub-agent
104
+ agent = getSubAgent(agentId);
105
+ if (!agent) {
106
+ return {
107
+ success: false,
108
+ result: '',
109
+ error: `Sub-agent with ID "${agentId}" not found`,
110
+ };
111
+ }
112
+ }
31
113
  // Get all available tools
32
114
  const allTools = await collectAllMCPTools();
33
115
  // Filter tools based on sub-agent's allowed tools
34
116
  const allowedTools = allTools.filter((tool) => {
35
117
  const toolName = tool.function.name;
36
- return agent.tools.some(allowedTool => {
118
+ return agent.tools.some((allowedTool) => {
37
119
  // Normalize both tool names: replace underscores with hyphens for comparison
38
120
  const normalizedToolName = toolName.replace(/_/g, '-');
39
121
  const normalizedAllowedTool = allowedTool.replace(/_/g, '-');
@@ -65,6 +147,7 @@ export async function executeSubAgent(agentId, prompt, onMessage, abortSignal, r
65
147
  let finalResponse = '';
66
148
  let hasError = false;
67
149
  let errorMessage = '';
150
+ let totalUsage;
68
151
  // Local session-approved tools for this sub-agent execution
69
152
  // This ensures tools approved during execution are immediately recognized
70
153
  const sessionApprovedTools = new Set();
@@ -137,6 +220,33 @@ export async function executeSubAgent(agentId, prompt, onMessage, abortSignal, r
137
220
  message: event,
138
221
  });
139
222
  }
223
+ // Capture usage from stream events
224
+ if (event.type === 'usage' && event.usage) {
225
+ const eventUsage = event.usage;
226
+ if (!totalUsage) {
227
+ totalUsage = {
228
+ inputTokens: eventUsage.prompt_tokens || 0,
229
+ outputTokens: eventUsage.completion_tokens || 0,
230
+ cacheCreationInputTokens: eventUsage.cache_creation_input_tokens,
231
+ cacheReadInputTokens: eventUsage.cache_read_input_tokens,
232
+ };
233
+ }
234
+ else {
235
+ // Accumulate usage if there are multiple rounds
236
+ totalUsage.inputTokens += eventUsage.prompt_tokens || 0;
237
+ totalUsage.outputTokens += eventUsage.completion_tokens || 0;
238
+ if (eventUsage.cache_creation_input_tokens) {
239
+ totalUsage.cacheCreationInputTokens =
240
+ (totalUsage.cacheCreationInputTokens || 0) +
241
+ eventUsage.cache_creation_input_tokens;
242
+ }
243
+ if (eventUsage.cache_read_input_tokens) {
244
+ totalUsage.cacheReadInputTokens =
245
+ (totalUsage.cacheReadInputTokens || 0) +
246
+ eventUsage.cache_read_input_tokens;
247
+ }
248
+ }
249
+ }
140
250
  if (event.type === 'content' && event.content) {
141
251
  currentContent += event.content;
142
252
  }
@@ -193,7 +303,9 @@ export async function executeSubAgent(agentId, prompt, onMessage, abortSignal, r
193
303
  if (needsConfirmation && requestToolConfirmation) {
194
304
  // Request confirmation from user
195
305
  const confirmation = await requestToolConfirmation(toolName, args);
196
- if (confirmation === 'reject') {
306
+ if (confirmation === 'reject' ||
307
+ (typeof confirmation === 'object' &&
308
+ confirmation.type === 'reject_with_reply')) {
197
309
  rejectedToolCalls.push(toolCall);
198
310
  continue;
199
311
  }
@@ -309,6 +421,7 @@ export async function executeSubAgent(agentId, prompt, onMessage, abortSignal, r
309
421
  return {
310
422
  success: true,
311
423
  result: finalResponse,
424
+ usage: totalUsage,
312
425
  };
313
426
  }
314
427
  catch (error) {
@@ -1,4 +1,5 @@
1
1
  import type { SubAgentMessage } from './subAgentExecutor.js';
2
+ import type { ConfirmationResult } from '../ui/components/ToolConfirmation.js';
2
3
  export interface ToolCall {
3
4
  id: string;
4
5
  type: 'function';
@@ -14,7 +15,7 @@ export interface ToolResult {
14
15
  }
15
16
  export type SubAgentMessageCallback = (message: SubAgentMessage) => void;
16
17
  export interface ToolConfirmationCallback {
17
- (toolCall: ToolCall, batchToolNames?: string, allTools?: ToolCall[]): Promise<string>;
18
+ (toolCall: ToolCall, batchToolNames?: string, allTools?: ToolCall[]): Promise<ConfirmationResult>;
18
19
  }
19
20
  export interface ToolApprovalChecker {
20
21
  (toolName: string): boolean;
@@ -81,8 +81,7 @@ function getToolResourceType(toolName) {
81
81
  // Each file is a separate resource
82
82
  if (toolName === 'filesystem-edit' ||
83
83
  toolName === 'filesystem-edit_search' ||
84
- toolName === 'filesystem-create' ||
85
- toolName === 'filesystem-delete') {
84
+ toolName === 'filesystem-create') {
86
85
  return 'filesystem'; // Will be further refined by file path
87
86
  }
88
87
  // Other tools are independent
@@ -7,9 +7,24 @@ let writeQueue = Promise.resolve();
7
7
  async function getActiveProfile() {
8
8
  try {
9
9
  const homeDir = os.homedir();
10
- const profilePath = path.join(homeDir, '.snow', 'active-profile.txt');
11
- const profileName = await fs.readFile(profilePath, 'utf-8');
12
- return profileName.trim();
10
+ const jsonPath = path.join(homeDir, '.snow', 'active-profile.json');
11
+ const legacyPath = path.join(homeDir, '.snow', 'active-profile.txt');
12
+ // Try JSON format first
13
+ try {
14
+ const fileContent = await fs.readFile(jsonPath, 'utf-8');
15
+ const data = JSON.parse(fileContent.trim());
16
+ return data.activeProfile || 'default';
17
+ }
18
+ catch {
19
+ // Fallback to legacy .txt format if JSON doesn't exist
20
+ try {
21
+ const profileName = await fs.readFile(legacyPath, 'utf-8');
22
+ return profileName.trim() || 'default';
23
+ }
24
+ catch {
25
+ return 'default';
26
+ }
27
+ }
13
28
  }
14
29
  catch (error) {
15
30
  return 'default';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.3.36",
3
+ "version": "0.4.0",
4
4
  "description": "Intelligent Command Line Assistant powered by AI",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -65,6 +65,7 @@
65
65
  "devDependencies": {
66
66
  "@sindresorhus/tsconfig": "^3.0.1",
67
67
  "@types/diff": "^7.0.2",
68
+ "@types/prettier": "^2.7.3",
68
69
  "@types/react": "^18.0.32",
69
70
  "@types/ws": "^8.5.8",
70
71
  "@vdemedes/prettier-config": "^2.0.1",