snow-ai 0.4.16 → 0.4.17
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/bundle/cli.mjs +477445 -0
- package/bundle/sql-wasm.wasm +0 -0
- package/package.json +31 -26
- package/dist/agents/codebaseIndexAgent.d.ts +0 -102
- package/dist/agents/codebaseIndexAgent.js +0 -641
- package/dist/agents/codebaseReviewAgent.d.ts +0 -61
- package/dist/agents/codebaseReviewAgent.js +0 -301
- package/dist/agents/compactAgent.d.ts +0 -55
- package/dist/agents/compactAgent.js +0 -306
- package/dist/agents/promptOptimizeAgent.d.ts +0 -54
- package/dist/agents/promptOptimizeAgent.js +0 -268
- package/dist/agents/reviewAgent.d.ts +0 -50
- package/dist/agents/reviewAgent.js +0 -265
- package/dist/agents/summaryAgent.d.ts +0 -57
- package/dist/agents/summaryAgent.js +0 -260
- package/dist/api/anthropic.d.ts +0 -44
- package/dist/api/anthropic.js +0 -598
- package/dist/api/chat.d.ts +0 -73
- package/dist/api/chat.js +0 -386
- package/dist/api/embedding.d.ts +0 -34
- package/dist/api/embedding.js +0 -80
- package/dist/api/gemini.d.ts +0 -31
- package/dist/api/gemini.js +0 -445
- package/dist/api/models.d.ts +0 -15
- package/dist/api/models.js +0 -139
- package/dist/api/responses.d.ts +0 -38
- package/dist/api/responses.js +0 -515
- package/dist/api/systemPrompt.d.ts +0 -4
- package/dist/api/systemPrompt.js +0 -408
- package/dist/api/types.d.ts +0 -53
- package/dist/api/types.js +0 -4
- package/dist/app.d.ts +0 -8
- package/dist/app.js +0 -112
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -199
- package/dist/hooks/useAgentPicker.d.ts +0 -14
- package/dist/hooks/useAgentPicker.js +0 -119
- package/dist/hooks/useClipboard.d.ts +0 -4
- package/dist/hooks/useClipboard.js +0 -175
- package/dist/hooks/useCommandHandler.d.ts +0 -35
- package/dist/hooks/useCommandHandler.js +0 -346
- package/dist/hooks/useCommandPanel.d.ts +0 -17
- package/dist/hooks/useCommandPanel.js +0 -114
- package/dist/hooks/useConversation.d.ts +0 -49
- package/dist/hooks/useConversation.js +0 -1052
- package/dist/hooks/useFilePicker.d.ts +0 -18
- package/dist/hooks/useFilePicker.js +0 -224
- package/dist/hooks/useGlobalExit.d.ts +0 -5
- package/dist/hooks/useGlobalExit.js +0 -34
- package/dist/hooks/useGlobalNavigation.d.ts +0 -6
- package/dist/hooks/useGlobalNavigation.js +0 -17
- package/dist/hooks/useHistoryNavigation.d.ts +0 -35
- package/dist/hooks/useHistoryNavigation.js +0 -133
- package/dist/hooks/useInputBuffer.d.ts +0 -6
- package/dist/hooks/useInputBuffer.js +0 -45
- package/dist/hooks/useKeyboardInput.d.ts +0 -80
- package/dist/hooks/useKeyboardInput.js +0 -608
- package/dist/hooks/useSessionManagement.d.ts +0 -10
- package/dist/hooks/useSessionManagement.js +0 -43
- package/dist/hooks/useSessionSave.d.ts +0 -8
- package/dist/hooks/useSessionSave.js +0 -63
- package/dist/hooks/useSnapshotState.d.ts +0 -26
- package/dist/hooks/useSnapshotState.js +0 -28
- package/dist/hooks/useStreamingState.d.ts +0 -33
- package/dist/hooks/useStreamingState.js +0 -105
- package/dist/hooks/useTerminalFocus.d.ts +0 -28
- package/dist/hooks/useTerminalFocus.js +0 -87
- package/dist/hooks/useTerminalSize.d.ts +0 -4
- package/dist/hooks/useTerminalSize.js +0 -20
- package/dist/hooks/useTodoPicker.d.ts +0 -16
- package/dist/hooks/useTodoPicker.js +0 -94
- package/dist/hooks/useToolConfirmation.d.ts +0 -19
- package/dist/hooks/useToolConfirmation.js +0 -61
- package/dist/hooks/useVSCodeState.d.ts +0 -8
- package/dist/hooks/useVSCodeState.js +0 -81
- package/dist/i18n/I18nContext.d.ts +0 -14
- package/dist/i18n/I18nContext.js +0 -24
- package/dist/i18n/index.d.ts +0 -3
- package/dist/i18n/index.js +0 -2
- package/dist/i18n/lang/en.d.ts +0 -2
- package/dist/i18n/lang/en.js +0 -502
- package/dist/i18n/lang/es.d.ts +0 -2
- package/dist/i18n/lang/es.js +0 -502
- package/dist/i18n/lang/ja.d.ts +0 -2
- package/dist/i18n/lang/ja.js +0 -502
- package/dist/i18n/lang/ko.d.ts +0 -2
- package/dist/i18n/lang/ko.js +0 -502
- package/dist/i18n/lang/zh-TW.d.ts +0 -2
- package/dist/i18n/lang/zh-TW.js +0 -502
- package/dist/i18n/lang/zh.d.ts +0 -2
- package/dist/i18n/lang/zh.js +0 -502
- package/dist/i18n/translations.d.ts +0 -2
- package/dist/i18n/translations.js +0 -14
- package/dist/i18n/types.d.ts +0 -478
- package/dist/i18n/types.js +0 -1
- package/dist/mcp/aceCodeSearch.d.ts +0 -247
- package/dist/mcp/aceCodeSearch.js +0 -1058
- package/dist/mcp/bash.d.ts +0 -50
- package/dist/mcp/bash.js +0 -153
- package/dist/mcp/codebaseSearch.d.ts +0 -44
- package/dist/mcp/codebaseSearch.js +0 -275
- package/dist/mcp/filesystem.d.ts +0 -392
- package/dist/mcp/filesystem.js +0 -1445
- package/dist/mcp/ideDiagnostics.d.ts +0 -36
- package/dist/mcp/ideDiagnostics.js +0 -90
- package/dist/mcp/notebook.d.ts +0 -10
- package/dist/mcp/notebook.js +0 -367
- package/dist/mcp/subagent.d.ts +0 -37
- package/dist/mcp/subagent.js +0 -113
- package/dist/mcp/todo.d.ts +0 -46
- package/dist/mcp/todo.js +0 -511
- package/dist/mcp/types/aceCodeSearch.types.d.ts +0 -92
- package/dist/mcp/types/aceCodeSearch.types.js +0 -4
- package/dist/mcp/types/bash.types.d.ts +0 -13
- package/dist/mcp/types/bash.types.js +0 -4
- package/dist/mcp/types/filesystem.types.d.ts +0 -210
- package/dist/mcp/types/filesystem.types.js +0 -27
- package/dist/mcp/types/todo.types.d.ts +0 -27
- package/dist/mcp/types/todo.types.js +0 -4
- package/dist/mcp/types/websearch.types.d.ts +0 -30
- package/dist/mcp/types/websearch.types.js +0 -4
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.d.ts +0 -34
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.js +0 -146
- package/dist/mcp/utils/aceCodeSearch/language.utils.d.ts +0 -14
- package/dist/mcp/utils/aceCodeSearch/language.utils.js +0 -418
- package/dist/mcp/utils/aceCodeSearch/search.utils.d.ts +0 -31
- package/dist/mcp/utils/aceCodeSearch/search.utils.js +0 -136
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.d.ts +0 -20
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.js +0 -141
- package/dist/mcp/utils/bash/security.utils.d.ts +0 -20
- package/dist/mcp/utils/bash/security.utils.js +0 -34
- package/dist/mcp/utils/filesystem/batch-operations.utils.d.ts +0 -39
- package/dist/mcp/utils/filesystem/batch-operations.utils.js +0 -182
- package/dist/mcp/utils/filesystem/code-analysis.utils.d.ts +0 -18
- package/dist/mcp/utils/filesystem/code-analysis.utils.js +0 -165
- package/dist/mcp/utils/filesystem/match-finder.utils.d.ts +0 -16
- package/dist/mcp/utils/filesystem/match-finder.utils.js +0 -85
- package/dist/mcp/utils/filesystem/office-parser.utils.d.ts +0 -43
- package/dist/mcp/utils/filesystem/office-parser.utils.js +0 -163
- package/dist/mcp/utils/filesystem/path-fixer.utils.d.ts +0 -7
- package/dist/mcp/utils/filesystem/path-fixer.utils.js +0 -60
- package/dist/mcp/utils/filesystem/similarity.utils.d.ts +0 -22
- package/dist/mcp/utils/filesystem/similarity.utils.js +0 -75
- package/dist/mcp/utils/todo/date.utils.d.ts +0 -9
- package/dist/mcp/utils/todo/date.utils.js +0 -14
- package/dist/mcp/utils/websearch/browser.utils.d.ts +0 -8
- package/dist/mcp/utils/websearch/browser.utils.js +0 -58
- package/dist/mcp/utils/websearch/text.utils.d.ts +0 -16
- package/dist/mcp/utils/websearch/text.utils.js +0 -39
- package/dist/mcp/websearch.d.ts +0 -88
- package/dist/mcp/websearch.js +0 -375
- package/dist/test/logger-test.d.ts +0 -1
- package/dist/test/logger-test.js +0 -7
- package/dist/types/index.d.ts +0 -15
- package/dist/types/index.js +0 -1
- package/dist/ui/components/AgentPickerPanel.d.ts +0 -10
- package/dist/ui/components/AgentPickerPanel.js +0 -74
- package/dist/ui/components/ChatInput.d.ts +0 -46
- package/dist/ui/components/ChatInput.js +0 -384
- package/dist/ui/components/CommandPanel.d.ts +0 -15
- package/dist/ui/components/CommandPanel.js +0 -80
- package/dist/ui/components/DiffViewer.d.ts +0 -11
- package/dist/ui/components/DiffViewer.js +0 -178
- package/dist/ui/components/FileList.d.ts +0 -15
- package/dist/ui/components/FileList.js +0 -360
- package/dist/ui/components/FileRollbackConfirmation.d.ts +0 -8
- package/dist/ui/components/FileRollbackConfirmation.js +0 -108
- package/dist/ui/components/HelpPanel.d.ts +0 -2
- package/dist/ui/components/HelpPanel.js +0 -67
- package/dist/ui/components/MCPInfoPanel.d.ts +0 -2
- package/dist/ui/components/MCPInfoPanel.js +0 -108
- package/dist/ui/components/MCPInfoScreen.d.ts +0 -7
- package/dist/ui/components/MCPInfoScreen.js +0 -115
- package/dist/ui/components/MarkdownRenderer.d.ts +0 -6
- package/dist/ui/components/MarkdownRenderer.js +0 -70
- package/dist/ui/components/Menu.d.ts +0 -17
- package/dist/ui/components/Menu.js +0 -88
- package/dist/ui/components/MessageList.d.ts +0 -56
- package/dist/ui/components/MessageList.js +0 -97
- package/dist/ui/components/PendingMessages.d.ts +0 -13
- package/dist/ui/components/PendingMessages.js +0 -29
- package/dist/ui/components/PendingToolCalls.d.ts +0 -11
- package/dist/ui/components/PendingToolCalls.js +0 -35
- package/dist/ui/components/ScrollableSelectInput.d.ts +0 -29
- package/dist/ui/components/ScrollableSelectInput.js +0 -157
- package/dist/ui/components/SessionListPanel.d.ts +0 -7
- package/dist/ui/components/SessionListPanel.js +0 -175
- package/dist/ui/components/SessionListScreen.d.ts +0 -7
- package/dist/ui/components/SessionListScreen.js +0 -217
- package/dist/ui/components/SessionListScreenWrapper.d.ts +0 -7
- package/dist/ui/components/SessionListScreenWrapper.js +0 -14
- package/dist/ui/components/ShimmerText.d.ts +0 -9
- package/dist/ui/components/ShimmerText.js +0 -30
- package/dist/ui/components/TodoPickerPanel.d.ts +0 -14
- package/dist/ui/components/TodoPickerPanel.js +0 -119
- package/dist/ui/components/TodoTree.d.ts +0 -15
- package/dist/ui/components/TodoTree.js +0 -60
- package/dist/ui/components/ToolConfirmation.d.ts +0 -21
- package/dist/ui/components/ToolConfirmation.js +0 -204
- package/dist/ui/components/ToolResultPreview.d.ts +0 -13
- package/dist/ui/components/ToolResultPreview.js +0 -337
- package/dist/ui/components/UsagePanel.d.ts +0 -2
- package/dist/ui/components/UsagePanel.js +0 -394
- package/dist/ui/contexts/ThemeContext.d.ts +0 -13
- package/dist/ui/contexts/ThemeContext.js +0 -28
- package/dist/ui/pages/ChatScreen.d.ts +0 -6
- package/dist/ui/pages/ChatScreen.js +0 -1519
- package/dist/ui/pages/CodeBaseConfigScreen.d.ts +0 -8
- package/dist/ui/pages/CodeBaseConfigScreen.js +0 -350
- package/dist/ui/pages/ConfigScreen.d.ts +0 -8
- package/dist/ui/pages/ConfigScreen.js +0 -1101
- package/dist/ui/pages/CustomHeadersScreen.d.ts +0 -6
- package/dist/ui/pages/CustomHeadersScreen.js +0 -502
- package/dist/ui/pages/HeadlessModeScreen.d.ts +0 -7
- package/dist/ui/pages/HeadlessModeScreen.js +0 -381
- package/dist/ui/pages/LanguageSettingsScreen.d.ts +0 -7
- package/dist/ui/pages/LanguageSettingsScreen.js +0 -91
- package/dist/ui/pages/MCPConfigScreen.d.ts +0 -6
- package/dist/ui/pages/MCPConfigScreen.js +0 -55
- package/dist/ui/pages/ProxyConfigScreen.d.ts +0 -8
- package/dist/ui/pages/ProxyConfigScreen.js +0 -149
- package/dist/ui/pages/SensitiveCommandConfigScreen.d.ts +0 -7
- package/dist/ui/pages/SensitiveCommandConfigScreen.js +0 -271
- package/dist/ui/pages/SubAgentConfigScreen.d.ts +0 -9
- package/dist/ui/pages/SubAgentConfigScreen.js +0 -435
- package/dist/ui/pages/SubAgentListScreen.d.ts +0 -9
- package/dist/ui/pages/SubAgentListScreen.js +0 -131
- package/dist/ui/pages/SystemPromptConfigScreen.d.ts +0 -6
- package/dist/ui/pages/SystemPromptConfigScreen.js +0 -326
- package/dist/ui/pages/ThemeSettingsScreen.d.ts +0 -7
- package/dist/ui/pages/ThemeSettingsScreen.js +0 -106
- package/dist/ui/pages/WelcomeScreen.d.ts +0 -7
- package/dist/ui/pages/WelcomeScreen.js +0 -217
- package/dist/ui/themes/index.d.ts +0 -23
- package/dist/ui/themes/index.js +0 -140
- package/dist/utils/apiConfig.d.ts +0 -126
- package/dist/utils/apiConfig.js +0 -423
- package/dist/utils/autoCompress.d.ts +0 -15
- package/dist/utils/autoCompress.js +0 -24
- package/dist/utils/chatExporter.d.ts +0 -9
- package/dist/utils/chatExporter.js +0 -118
- package/dist/utils/checkpointManager.d.ts +0 -74
- package/dist/utils/checkpointManager.js +0 -181
- package/dist/utils/codebaseConfig.d.ts +0 -16
- package/dist/utils/codebaseConfig.js +0 -67
- package/dist/utils/codebaseDatabase.d.ts +0 -102
- package/dist/utils/codebaseDatabase.js +0 -333
- package/dist/utils/codebaseSearchEvents.d.ts +0 -16
- package/dist/utils/codebaseSearchEvents.js +0 -13
- package/dist/utils/commandExecutor.d.ts +0 -13
- package/dist/utils/commandExecutor.js +0 -26
- package/dist/utils/commands/agent.d.ts +0 -2
- package/dist/utils/commands/agent.js +0 -12
- package/dist/utils/commands/clear.d.ts +0 -2
- package/dist/utils/commands/clear.js +0 -12
- package/dist/utils/commands/compact.d.ts +0 -2
- package/dist/utils/commands/compact.js +0 -12
- package/dist/utils/commands/export.d.ts +0 -2
- package/dist/utils/commands/export.js +0 -12
- package/dist/utils/commands/help.d.ts +0 -2
- package/dist/utils/commands/help.js +0 -11
- package/dist/utils/commands/home.d.ts +0 -2
- package/dist/utils/commands/home.js +0 -34
- package/dist/utils/commands/ide.d.ts +0 -2
- package/dist/utils/commands/ide.js +0 -32
- package/dist/utils/commands/init.d.ts +0 -2
- package/dist/utils/commands/init.js +0 -93
- package/dist/utils/commands/mcp.d.ts +0 -2
- package/dist/utils/commands/mcp.js +0 -12
- package/dist/utils/commands/resume.d.ts +0 -2
- package/dist/utils/commands/resume.js +0 -12
- package/dist/utils/commands/review.d.ts +0 -2
- package/dist/utils/commands/review.js +0 -81
- package/dist/utils/commands/role.d.ts +0 -2
- package/dist/utils/commands/role.js +0 -37
- package/dist/utils/commands/todoPicker.d.ts +0 -2
- package/dist/utils/commands/todoPicker.js +0 -12
- package/dist/utils/commands/usage.d.ts +0 -2
- package/dist/utils/commands/usage.js +0 -12
- package/dist/utils/commands/yolo.d.ts +0 -2
- package/dist/utils/commands/yolo.js +0 -12
- package/dist/utils/configManager.d.ts +0 -45
- package/dist/utils/configManager.js +0 -303
- package/dist/utils/contextCompressor.d.ts +0 -16
- package/dist/utils/contextCompressor.js +0 -334
- package/dist/utils/devMode.d.ts +0 -13
- package/dist/utils/devMode.js +0 -54
- package/dist/utils/escapeHandler.d.ts +0 -79
- package/dist/utils/escapeHandler.js +0 -153
- package/dist/utils/fileDialog.d.ts +0 -9
- package/dist/utils/fileDialog.js +0 -74
- package/dist/utils/fileUtils.d.ts +0 -40
- package/dist/utils/fileUtils.js +0 -185
- package/dist/utils/historyManager.d.ts +0 -45
- package/dist/utils/historyManager.js +0 -159
- package/dist/utils/incrementalSnapshot.d.ts +0 -109
- package/dist/utils/incrementalSnapshot.js +0 -383
- package/dist/utils/index.d.ts +0 -11
- package/dist/utils/index.js +0 -18
- package/dist/utils/languageConfig.d.ts +0 -21
- package/dist/utils/languageConfig.js +0 -61
- package/dist/utils/logger.d.ts +0 -37
- package/dist/utils/logger.js +0 -122
- package/dist/utils/mcpToolsManager.d.ts +0 -52
- package/dist/utils/mcpToolsManager.js +0 -878
- package/dist/utils/messageFormatter.d.ts +0 -12
- package/dist/utils/messageFormatter.js +0 -115
- package/dist/utils/notebookManager.d.ts +0 -59
- package/dist/utils/notebookManager.js +0 -213
- package/dist/utils/patch-highlight.d.ts +0 -5
- package/dist/utils/patch-highlight.js +0 -23
- package/dist/utils/processManager.d.ts +0 -27
- package/dist/utils/processManager.js +0 -75
- package/dist/utils/proxyUtils.d.ts +0 -15
- package/dist/utils/proxyUtils.js +0 -50
- package/dist/utils/resourceMonitor.d.ts +0 -65
- package/dist/utils/resourceMonitor.js +0 -175
- package/dist/utils/retryUtils.d.ts +0 -49
- package/dist/utils/retryUtils.js +0 -303
- package/dist/utils/sensitiveCommandManager.d.ts +0 -53
- package/dist/utils/sensitiveCommandManager.js +0 -308
- package/dist/utils/sessionConverter.d.ts +0 -7
- package/dist/utils/sessionConverter.js +0 -306
- package/dist/utils/sessionManager.d.ts +0 -53
- package/dist/utils/sessionManager.js +0 -371
- package/dist/utils/subAgentConfig.d.ts +0 -50
- package/dist/utils/subAgentConfig.js +0 -221
- package/dist/utils/subAgentExecutor.d.ts +0 -40
- package/dist/utils/subAgentExecutor.js +0 -434
- package/dist/utils/terminal.d.ts +0 -5
- package/dist/utils/terminal.js +0 -13
- package/dist/utils/textBuffer.d.ts +0 -99
- package/dist/utils/textBuffer.js +0 -547
- package/dist/utils/textUtils.d.ts +0 -37
- package/dist/utils/textUtils.js +0 -102
- package/dist/utils/themeConfig.d.ts +0 -21
- package/dist/utils/themeConfig.js +0 -61
- package/dist/utils/todoPreprocessor.d.ts +0 -5
- package/dist/utils/todoPreprocessor.js +0 -18
- package/dist/utils/todoScanner.d.ts +0 -8
- package/dist/utils/todoScanner.js +0 -148
- package/dist/utils/toolDisplayConfig.d.ts +0 -16
- package/dist/utils/toolDisplayConfig.js +0 -47
- package/dist/utils/toolExecutor.d.ts +0 -37
- package/dist/utils/toolExecutor.js +0 -224
- package/dist/utils/usageLogger.d.ts +0 -11
- package/dist/utils/usageLogger.js +0 -114
- package/dist/utils/vscodeConnection.d.ts +0 -76
- package/dist/utils/vscodeConnection.js +0 -430
- package/dist/utils/workspaceSnapshot.d.ts +0 -63
- package/dist/utils/workspaceSnapshot.js +0 -300
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { useCallback, useRef } from 'react';
|
|
2
|
-
import { sessionManager } from '../utils/sessionManager.js';
|
|
3
|
-
export function useSessionSave() {
|
|
4
|
-
const savedMessagesRef = useRef(new Set());
|
|
5
|
-
// Generate a unique ID for a message (based on role + content + timestamp window + tool identifiers)
|
|
6
|
-
const generateMessageId = useCallback((message, timestamp) => {
|
|
7
|
-
// Base ID with role, content length, and time window
|
|
8
|
-
let id = `${message.role}-${message.content.length}-${Math.floor(timestamp / 5000)}`;
|
|
9
|
-
// For assistant messages with tool_calls, include tool call IDs to ensure uniqueness
|
|
10
|
-
if (message.role === 'assistant' && message.tool_calls && message.tool_calls.length > 0) {
|
|
11
|
-
const toolCallIds = message.tool_calls.map(tc => tc.id).sort().join(',');
|
|
12
|
-
id += `-tools:${toolCallIds}`;
|
|
13
|
-
}
|
|
14
|
-
// For tool result messages, include the tool_call_id to ensure uniqueness
|
|
15
|
-
if (message.role === 'tool' && message.tool_call_id) {
|
|
16
|
-
id += `-toolcall:${message.tool_call_id}`;
|
|
17
|
-
}
|
|
18
|
-
return id;
|
|
19
|
-
}, []);
|
|
20
|
-
// Save API message directly - 直接保存 API 格式的消息
|
|
21
|
-
const saveMessage = useCallback(async (message) => {
|
|
22
|
-
const timestamp = Date.now();
|
|
23
|
-
const messageId = generateMessageId(message, timestamp);
|
|
24
|
-
if (savedMessagesRef.current.has(messageId)) {
|
|
25
|
-
return; // Already saved
|
|
26
|
-
}
|
|
27
|
-
const sessionMessage = {
|
|
28
|
-
...message, // 直接展开 API 消息,包含所有字段
|
|
29
|
-
timestamp
|
|
30
|
-
};
|
|
31
|
-
try {
|
|
32
|
-
await sessionManager.addMessage(sessionMessage);
|
|
33
|
-
savedMessagesRef.current.add(messageId);
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error('Failed to save message:', error);
|
|
37
|
-
}
|
|
38
|
-
}, [generateMessageId]);
|
|
39
|
-
// Save multiple API messages at once
|
|
40
|
-
const saveMessages = useCallback(async (messages) => {
|
|
41
|
-
for (const message of messages) {
|
|
42
|
-
await saveMessage(message);
|
|
43
|
-
}
|
|
44
|
-
}, [saveMessage]);
|
|
45
|
-
// Clear saved messages tracking (for new sessions)
|
|
46
|
-
const clearSavedMessages = useCallback(() => {
|
|
47
|
-
savedMessagesRef.current.clear();
|
|
48
|
-
}, []);
|
|
49
|
-
// Initialize from existing session - 从已有会话初始化
|
|
50
|
-
const initializeFromSession = useCallback((messages) => {
|
|
51
|
-
savedMessagesRef.current.clear();
|
|
52
|
-
messages.forEach(message => {
|
|
53
|
-
const messageId = generateMessageId(message, message.timestamp);
|
|
54
|
-
savedMessagesRef.current.add(messageId);
|
|
55
|
-
});
|
|
56
|
-
}, [generateMessageId]);
|
|
57
|
-
return {
|
|
58
|
-
saveMessage,
|
|
59
|
-
saveMessages,
|
|
60
|
-
clearSavedMessages,
|
|
61
|
-
initializeFromSession
|
|
62
|
-
};
|
|
63
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export declare function useSnapshotState(messagesLength: number): {
|
|
2
|
-
snapshotFileCount: Map<number, number>;
|
|
3
|
-
setSnapshotFileCount: import("react").Dispatch<import("react").SetStateAction<Map<number, number>>>;
|
|
4
|
-
pendingRollback: {
|
|
5
|
-
messageIndex: number;
|
|
6
|
-
fileCount: number;
|
|
7
|
-
filePaths?: string[];
|
|
8
|
-
message?: string;
|
|
9
|
-
images?: Array<{
|
|
10
|
-
type: "image";
|
|
11
|
-
data: string;
|
|
12
|
-
mimeType: string;
|
|
13
|
-
}>;
|
|
14
|
-
} | null;
|
|
15
|
-
setPendingRollback: import("react").Dispatch<import("react").SetStateAction<{
|
|
16
|
-
messageIndex: number;
|
|
17
|
-
fileCount: number;
|
|
18
|
-
filePaths?: string[];
|
|
19
|
-
message?: string;
|
|
20
|
-
images?: Array<{
|
|
21
|
-
type: "image";
|
|
22
|
-
data: string;
|
|
23
|
-
mimeType: string;
|
|
24
|
-
}>;
|
|
25
|
-
} | null>>;
|
|
26
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import { sessionManager } from '../utils/sessionManager.js';
|
|
3
|
-
import { incrementalSnapshotManager } from '../utils/incrementalSnapshot.js';
|
|
4
|
-
export function useSnapshotState(messagesLength) {
|
|
5
|
-
const [snapshotFileCount, setSnapshotFileCount] = useState(new Map());
|
|
6
|
-
const [pendingRollback, setPendingRollback] = useState(null);
|
|
7
|
-
// Load snapshot file counts when session changes
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
const loadSnapshotFileCounts = async () => {
|
|
10
|
-
const currentSession = sessionManager.getCurrentSession();
|
|
11
|
-
if (!currentSession)
|
|
12
|
-
return;
|
|
13
|
-
const snapshots = await incrementalSnapshotManager.listSnapshots(currentSession.id);
|
|
14
|
-
const counts = new Map();
|
|
15
|
-
for (const snapshot of snapshots) {
|
|
16
|
-
counts.set(snapshot.messageIndex, snapshot.fileCount);
|
|
17
|
-
}
|
|
18
|
-
setSnapshotFileCount(counts);
|
|
19
|
-
};
|
|
20
|
-
loadSnapshotFileCounts();
|
|
21
|
-
}, [messagesLength]); // Reload when messages change
|
|
22
|
-
return {
|
|
23
|
-
snapshotFileCount,
|
|
24
|
-
setSnapshotFileCount,
|
|
25
|
-
pendingRollback,
|
|
26
|
-
setPendingRollback,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { UsageInfo } from '../api/chat.js';
|
|
2
|
-
export type RetryStatus = {
|
|
3
|
-
isRetrying: boolean;
|
|
4
|
-
attempt: number;
|
|
5
|
-
nextDelay: number;
|
|
6
|
-
remainingSeconds?: number;
|
|
7
|
-
errorMessage?: string;
|
|
8
|
-
};
|
|
9
|
-
export type CodebaseSearchStatus = {
|
|
10
|
-
isSearching: boolean;
|
|
11
|
-
attempt: number;
|
|
12
|
-
maxAttempts: number;
|
|
13
|
-
currentTopN: number;
|
|
14
|
-
message: string;
|
|
15
|
-
};
|
|
16
|
-
export declare function useStreamingState(): {
|
|
17
|
-
isStreaming: boolean;
|
|
18
|
-
setIsStreaming: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
19
|
-
streamTokenCount: number;
|
|
20
|
-
setStreamTokenCount: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
21
|
-
isReasoning: boolean;
|
|
22
|
-
setIsReasoning: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
23
|
-
abortController: AbortController | null;
|
|
24
|
-
setAbortController: import("react").Dispatch<import("react").SetStateAction<AbortController | null>>;
|
|
25
|
-
contextUsage: UsageInfo | null;
|
|
26
|
-
setContextUsage: import("react").Dispatch<import("react").SetStateAction<UsageInfo | null>>;
|
|
27
|
-
elapsedSeconds: number;
|
|
28
|
-
retryStatus: RetryStatus | null;
|
|
29
|
-
setRetryStatus: import("react").Dispatch<import("react").SetStateAction<RetryStatus | null>>;
|
|
30
|
-
animationFrame: number;
|
|
31
|
-
codebaseSearchStatus: CodebaseSearchStatus | null;
|
|
32
|
-
setCodebaseSearchStatus: import("react").Dispatch<import("react").SetStateAction<CodebaseSearchStatus | null>>;
|
|
33
|
-
};
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
export function useStreamingState() {
|
|
3
|
-
const [isStreaming, setIsStreaming] = useState(false);
|
|
4
|
-
const [streamTokenCount, setStreamTokenCount] = useState(0);
|
|
5
|
-
const [isReasoning, setIsReasoning] = useState(false);
|
|
6
|
-
const [abortController, setAbortController] = useState(null);
|
|
7
|
-
const [contextUsage, setContextUsage] = useState(null);
|
|
8
|
-
const [elapsedSeconds, setElapsedSeconds] = useState(0);
|
|
9
|
-
const [timerStartTime, setTimerStartTime] = useState(null);
|
|
10
|
-
const [retryStatus, setRetryStatus] = useState(null);
|
|
11
|
-
const [animationFrame, setAnimationFrame] = useState(0);
|
|
12
|
-
const [codebaseSearchStatus, setCodebaseSearchStatus] = useState(null);
|
|
13
|
-
// Animation for streaming/saving indicator
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (!isStreaming)
|
|
16
|
-
return;
|
|
17
|
-
const interval = setInterval(() => {
|
|
18
|
-
setAnimationFrame(prev => (prev + 1) % 5);
|
|
19
|
-
}, 300);
|
|
20
|
-
return () => {
|
|
21
|
-
clearInterval(interval);
|
|
22
|
-
setAnimationFrame(0);
|
|
23
|
-
};
|
|
24
|
-
}, [isStreaming]);
|
|
25
|
-
// Timer for tracking request duration
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
if (isStreaming && timerStartTime === null) {
|
|
28
|
-
// Start timer when streaming begins
|
|
29
|
-
setTimerStartTime(Date.now());
|
|
30
|
-
setElapsedSeconds(0);
|
|
31
|
-
}
|
|
32
|
-
else if (!isStreaming && timerStartTime !== null) {
|
|
33
|
-
// Stop timer when streaming ends
|
|
34
|
-
setTimerStartTime(null);
|
|
35
|
-
}
|
|
36
|
-
}, [isStreaming, timerStartTime]);
|
|
37
|
-
// Update elapsed time every second
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (timerStartTime === null)
|
|
40
|
-
return;
|
|
41
|
-
const interval = setInterval(() => {
|
|
42
|
-
const elapsed = Math.floor((Date.now() - timerStartTime) / 1000);
|
|
43
|
-
setElapsedSeconds(elapsed);
|
|
44
|
-
}, 1000);
|
|
45
|
-
return () => clearInterval(interval);
|
|
46
|
-
}, [timerStartTime]);
|
|
47
|
-
// Initialize remaining seconds when retry starts
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (!retryStatus?.isRetrying)
|
|
50
|
-
return;
|
|
51
|
-
if (retryStatus.remainingSeconds !== undefined)
|
|
52
|
-
return;
|
|
53
|
-
// Initialize remaining seconds from nextDelay (only once)
|
|
54
|
-
setRetryStatus(prev => prev
|
|
55
|
-
? {
|
|
56
|
-
...prev,
|
|
57
|
-
remainingSeconds: Math.ceil(prev.nextDelay / 1000),
|
|
58
|
-
}
|
|
59
|
-
: null);
|
|
60
|
-
}, [retryStatus?.isRetrying]); // Only depend on isRetrying flag
|
|
61
|
-
// Countdown timer for retry delays
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
if (!retryStatus || !retryStatus.isRetrying)
|
|
64
|
-
return;
|
|
65
|
-
if (retryStatus.remainingSeconds === undefined)
|
|
66
|
-
return;
|
|
67
|
-
// Countdown every second
|
|
68
|
-
const interval = setInterval(() => {
|
|
69
|
-
setRetryStatus(prev => {
|
|
70
|
-
if (!prev || prev.remainingSeconds === undefined)
|
|
71
|
-
return prev;
|
|
72
|
-
const newRemaining = prev.remainingSeconds - 1;
|
|
73
|
-
if (newRemaining <= 0) {
|
|
74
|
-
return {
|
|
75
|
-
...prev,
|
|
76
|
-
remainingSeconds: 0,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
...prev,
|
|
81
|
-
remainingSeconds: newRemaining,
|
|
82
|
-
};
|
|
83
|
-
});
|
|
84
|
-
}, 1000);
|
|
85
|
-
return () => clearInterval(interval);
|
|
86
|
-
}, [retryStatus?.isRetrying]); // ✅ 移除 remainingSeconds 避免循环
|
|
87
|
-
return {
|
|
88
|
-
isStreaming,
|
|
89
|
-
setIsStreaming,
|
|
90
|
-
streamTokenCount,
|
|
91
|
-
setStreamTokenCount,
|
|
92
|
-
isReasoning,
|
|
93
|
-
setIsReasoning,
|
|
94
|
-
abortController,
|
|
95
|
-
setAbortController,
|
|
96
|
-
contextUsage,
|
|
97
|
-
setContextUsage,
|
|
98
|
-
elapsedSeconds,
|
|
99
|
-
retryStatus,
|
|
100
|
-
setRetryStatus,
|
|
101
|
-
animationFrame,
|
|
102
|
-
codebaseSearchStatus,
|
|
103
|
-
setCodebaseSearchStatus,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook to detect terminal window focus state.
|
|
3
|
-
* Returns true when terminal has focus, false otherwise.
|
|
4
|
-
*
|
|
5
|
-
* Uses ANSI escape sequences to detect focus events:
|
|
6
|
-
* - ESC[I (\x1b[I) - Focus gained
|
|
7
|
-
* - ESC[O (\x1b[O) - Focus lost
|
|
8
|
-
*
|
|
9
|
-
* Cross-platform support:
|
|
10
|
-
* - ✅ Windows Terminal
|
|
11
|
-
* - ✅ macOS Terminal.app, iTerm2
|
|
12
|
-
* - ✅ Linux: GNOME Terminal, Konsole, Alacritty, kitty, etc.
|
|
13
|
-
*
|
|
14
|
-
* Note: Older or minimal terminals that don't support focus reporting
|
|
15
|
-
* will simply ignore the escape sequences and cursor will remain visible.
|
|
16
|
-
*
|
|
17
|
-
* Also provides a function to check if input contains focus events
|
|
18
|
-
* so they can be filtered from normal input processing.
|
|
19
|
-
*
|
|
20
|
-
* Auto-focus recovery: If user input is detected while in unfocused state,
|
|
21
|
-
* automatically restore focus state to ensure cursor visibility during
|
|
22
|
-
* operations like Shift+drag file drop where focus events may be delayed.
|
|
23
|
-
*/
|
|
24
|
-
export declare function useTerminalFocus(): {
|
|
25
|
-
hasFocus: boolean;
|
|
26
|
-
isFocusEvent: (input: string) => boolean;
|
|
27
|
-
ensureFocus: () => void;
|
|
28
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Hook to detect terminal window focus state.
|
|
4
|
-
* Returns true when terminal has focus, false otherwise.
|
|
5
|
-
*
|
|
6
|
-
* Uses ANSI escape sequences to detect focus events:
|
|
7
|
-
* - ESC[I (\x1b[I) - Focus gained
|
|
8
|
-
* - ESC[O (\x1b[O) - Focus lost
|
|
9
|
-
*
|
|
10
|
-
* Cross-platform support:
|
|
11
|
-
* - ✅ Windows Terminal
|
|
12
|
-
* - ✅ macOS Terminal.app, iTerm2
|
|
13
|
-
* - ✅ Linux: GNOME Terminal, Konsole, Alacritty, kitty, etc.
|
|
14
|
-
*
|
|
15
|
-
* Note: Older or minimal terminals that don't support focus reporting
|
|
16
|
-
* will simply ignore the escape sequences and cursor will remain visible.
|
|
17
|
-
*
|
|
18
|
-
* Also provides a function to check if input contains focus events
|
|
19
|
-
* so they can be filtered from normal input processing.
|
|
20
|
-
*
|
|
21
|
-
* Auto-focus recovery: If user input is detected while in unfocused state,
|
|
22
|
-
* automatically restore focus state to ensure cursor visibility during
|
|
23
|
-
* operations like Shift+drag file drop where focus events may be delayed.
|
|
24
|
-
*/
|
|
25
|
-
export function useTerminalFocus() {
|
|
26
|
-
const [hasFocus, setHasFocus] = useState(true); // Default to focused
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
let syncTimer = null;
|
|
29
|
-
// Set up listener first
|
|
30
|
-
const handleData = (data) => {
|
|
31
|
-
const str = data.toString();
|
|
32
|
-
// Focus gained: ESC[I
|
|
33
|
-
if (str === '\x1b[I') {
|
|
34
|
-
setHasFocus(true);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Focus lost: ESC[O
|
|
38
|
-
if (str === '\x1b[O') {
|
|
39
|
-
setHasFocus(false);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
// Auto-recovery: If we receive any input that's NOT a focus event
|
|
43
|
-
// while in unfocused state, treat it as an implicit focus gain.
|
|
44
|
-
// This handles cases where focus events are delayed (e.g., Shift+drag operations)
|
|
45
|
-
// Filter out escape sequences and other non-printable characters
|
|
46
|
-
const isPrintableInput = str.length > 0 &&
|
|
47
|
-
!str.startsWith('\x1b') && // Not an escape sequence
|
|
48
|
-
!/^[\x00-\x1f\x7f]+$/.test(str); // Not only control characters
|
|
49
|
-
if (!hasFocus && isPrintableInput) {
|
|
50
|
-
setHasFocus(true);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
// Listen to stdin data
|
|
54
|
-
process.stdin.on('data', handleData);
|
|
55
|
-
// Enable focus reporting AFTER listener is set up
|
|
56
|
-
// Add a small delay to ensure listener is fully registered
|
|
57
|
-
const enableTimer = setTimeout(() => {
|
|
58
|
-
// ESC[?1004h - Enable focus events
|
|
59
|
-
process.stdout.write('\x1b[?1004h');
|
|
60
|
-
// After enabling focus reporting, assume terminal has focus
|
|
61
|
-
// This ensures cursor is visible after component remount (e.g., after /clear)
|
|
62
|
-
// The terminal will send ESC[O if it doesn't have focus
|
|
63
|
-
syncTimer = setTimeout(() => {
|
|
64
|
-
setHasFocus(true);
|
|
65
|
-
}, 100);
|
|
66
|
-
}, 50);
|
|
67
|
-
return () => {
|
|
68
|
-
clearTimeout(enableTimer);
|
|
69
|
-
if (syncTimer) {
|
|
70
|
-
clearTimeout(syncTimer);
|
|
71
|
-
}
|
|
72
|
-
// Disable focus reporting on cleanup
|
|
73
|
-
// ESC[?1004l - Disable focus events
|
|
74
|
-
process.stdout.write('\x1b[?1004l');
|
|
75
|
-
process.stdin.off('data', handleData);
|
|
76
|
-
};
|
|
77
|
-
}, []); // Remove hasFocus from dependencies to avoid re-running effect
|
|
78
|
-
// Helper function to check if input is a focus event
|
|
79
|
-
const isFocusEvent = (input) => {
|
|
80
|
-
return input === '\x1b[I' || input === '\x1b[O';
|
|
81
|
-
};
|
|
82
|
-
// Manual focus restoration function (can be called externally if needed)
|
|
83
|
-
const ensureFocus = () => {
|
|
84
|
-
setHasFocus(true);
|
|
85
|
-
};
|
|
86
|
-
return { hasFocus, isFocusEvent, ensureFocus };
|
|
87
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
export function useTerminalSize() {
|
|
3
|
-
const [size, setSize] = useState({
|
|
4
|
-
columns: process.stdout.columns || 80,
|
|
5
|
-
rows: process.stdout.rows || 20,
|
|
6
|
-
});
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
function updateSize() {
|
|
9
|
-
setSize({
|
|
10
|
-
columns: process.stdout.columns || 80,
|
|
11
|
-
rows: process.stdout.rows || 20,
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
process.stdout.on('resize', updateSize);
|
|
15
|
-
return () => {
|
|
16
|
-
process.stdout.off('resize', updateSize);
|
|
17
|
-
};
|
|
18
|
-
}, []);
|
|
19
|
-
return size;
|
|
20
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TextBuffer } from '../utils/textBuffer.js';
|
|
2
|
-
import { type TodoItem } from '../utils/todoScanner.js';
|
|
3
|
-
export declare function useTodoPicker(buffer: TextBuffer, triggerUpdate: () => void, projectRoot: string): {
|
|
4
|
-
showTodoPicker: boolean;
|
|
5
|
-
setShowTodoPicker: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
6
|
-
todoSelectedIndex: number;
|
|
7
|
-
setTodoSelectedIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
8
|
-
todos: TodoItem[];
|
|
9
|
-
selectedTodos: Set<string>;
|
|
10
|
-
toggleTodoSelection: () => void;
|
|
11
|
-
confirmTodoSelection: () => void;
|
|
12
|
-
isLoading: boolean;
|
|
13
|
-
searchQuery: string;
|
|
14
|
-
setSearchQuery: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
15
|
-
totalTodoCount: number;
|
|
16
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
-
import { scanProjectTodos } from '../utils/todoScanner.js';
|
|
3
|
-
export function useTodoPicker(buffer, triggerUpdate, projectRoot) {
|
|
4
|
-
const [showTodoPicker, setShowTodoPicker] = useState(false);
|
|
5
|
-
const [todoSelectedIndex, setTodoSelectedIndex] = useState(0);
|
|
6
|
-
const [allTodos, setAllTodos] = useState([]);
|
|
7
|
-
const [selectedTodos, setSelectedTodos] = useState(new Set());
|
|
8
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
9
|
-
const [searchQuery, setSearchQuery] = useState('');
|
|
10
|
-
// Filter todos based on search query
|
|
11
|
-
const filteredTodos = useMemo(() => {
|
|
12
|
-
if (!searchQuery.trim()) {
|
|
13
|
-
return allTodos;
|
|
14
|
-
}
|
|
15
|
-
const query = searchQuery.toLowerCase();
|
|
16
|
-
return allTodos.filter(todo => todo.content.toLowerCase().includes(query) ||
|
|
17
|
-
todo.file.toLowerCase().includes(query));
|
|
18
|
-
}, [allTodos, searchQuery]);
|
|
19
|
-
// Load todos when picker is shown
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (showTodoPicker) {
|
|
22
|
-
setIsLoading(true);
|
|
23
|
-
setSearchQuery('');
|
|
24
|
-
setTodoSelectedIndex(0);
|
|
25
|
-
setSelectedTodos(new Set());
|
|
26
|
-
// Use setTimeout to allow UI to update with loading state
|
|
27
|
-
setTimeout(() => {
|
|
28
|
-
const foundTodos = scanProjectTodos(projectRoot);
|
|
29
|
-
setAllTodos(foundTodos);
|
|
30
|
-
setIsLoading(false);
|
|
31
|
-
}, 0);
|
|
32
|
-
}
|
|
33
|
-
}, [showTodoPicker, projectRoot]);
|
|
34
|
-
// Toggle selection of current todo
|
|
35
|
-
const toggleTodoSelection = useCallback(() => {
|
|
36
|
-
if (filteredTodos.length > 0 && todoSelectedIndex < filteredTodos.length) {
|
|
37
|
-
const todo = filteredTodos[todoSelectedIndex];
|
|
38
|
-
if (todo) {
|
|
39
|
-
setSelectedTodos(prev => {
|
|
40
|
-
const newSet = new Set(prev);
|
|
41
|
-
if (newSet.has(todo.id)) {
|
|
42
|
-
newSet.delete(todo.id);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
newSet.add(todo.id);
|
|
46
|
-
}
|
|
47
|
-
return newSet;
|
|
48
|
-
});
|
|
49
|
-
triggerUpdate();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}, [filteredTodos, todoSelectedIndex, triggerUpdate]);
|
|
53
|
-
// Confirm selection and insert into buffer
|
|
54
|
-
const confirmTodoSelection = useCallback(() => {
|
|
55
|
-
if (selectedTodos.size === 0) {
|
|
56
|
-
// If no todos selected, just close the picker
|
|
57
|
-
setShowTodoPicker(false);
|
|
58
|
-
setTodoSelectedIndex(0);
|
|
59
|
-
triggerUpdate();
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
// Build the text to insert
|
|
63
|
-
const selectedTodoItems = allTodos.filter(todo => selectedTodos.has(todo.id));
|
|
64
|
-
const todoTexts = selectedTodoItems.map(todo => `<${todo.file}:${todo.line}> ${todo.content}`);
|
|
65
|
-
// Clear buffer and insert selected todos
|
|
66
|
-
const currentText = buffer.getFullText().trim();
|
|
67
|
-
buffer.setText('');
|
|
68
|
-
if (currentText) {
|
|
69
|
-
buffer.insert(currentText + '\n' + todoTexts.join('\n'));
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
buffer.insert(todoTexts.join('\n'));
|
|
73
|
-
}
|
|
74
|
-
// Reset state
|
|
75
|
-
setShowTodoPicker(false);
|
|
76
|
-
setTodoSelectedIndex(0);
|
|
77
|
-
setSelectedTodos(new Set());
|
|
78
|
-
triggerUpdate();
|
|
79
|
-
}, [buffer, allTodos, selectedTodos, triggerUpdate]);
|
|
80
|
-
return {
|
|
81
|
-
showTodoPicker,
|
|
82
|
-
setShowTodoPicker,
|
|
83
|
-
todoSelectedIndex,
|
|
84
|
-
setTodoSelectedIndex,
|
|
85
|
-
todos: filteredTodos,
|
|
86
|
-
selectedTodos,
|
|
87
|
-
toggleTodoSelection,
|
|
88
|
-
confirmTodoSelection,
|
|
89
|
-
isLoading,
|
|
90
|
-
searchQuery,
|
|
91
|
-
setSearchQuery,
|
|
92
|
-
totalTodoCount: allTodos.length,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ToolCall } from '../utils/toolExecutor.js';
|
|
2
|
-
import type { ConfirmationResult } from '../ui/components/ToolConfirmation.js';
|
|
3
|
-
export type PendingConfirmation = {
|
|
4
|
-
tool: ToolCall;
|
|
5
|
-
batchToolNames?: string;
|
|
6
|
-
allTools?: ToolCall[];
|
|
7
|
-
resolve: (result: ConfirmationResult) => void;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Hook for managing tool confirmation state and logic
|
|
11
|
-
*/
|
|
12
|
-
export declare function useToolConfirmation(): {
|
|
13
|
-
pendingToolConfirmation: PendingConfirmation | null;
|
|
14
|
-
alwaysApprovedTools: Set<string>;
|
|
15
|
-
requestToolConfirmation: (toolCall: ToolCall, batchToolNames?: string, allTools?: ToolCall[]) => Promise<ConfirmationResult>;
|
|
16
|
-
isToolAutoApproved: (toolName: string) => boolean;
|
|
17
|
-
addToAlwaysApproved: (toolName: string) => void;
|
|
18
|
-
addMultipleToAlwaysApproved: (toolNames: string[]) => void;
|
|
19
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { useState, useRef, useCallback } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Hook for managing tool confirmation state and logic
|
|
4
|
-
*/
|
|
5
|
-
export function useToolConfirmation() {
|
|
6
|
-
const [pendingToolConfirmation, setPendingToolConfirmation] = useState(null);
|
|
7
|
-
// Use ref for always-approved tools to ensure closure functions always see latest state
|
|
8
|
-
const alwaysApprovedToolsRef = useRef(new Set());
|
|
9
|
-
const [alwaysApprovedTools, setAlwaysApprovedTools] = useState(new Set());
|
|
10
|
-
/**
|
|
11
|
-
* Request user confirmation for tool execution
|
|
12
|
-
*/
|
|
13
|
-
const requestToolConfirmation = async (toolCall, batchToolNames, allTools) => {
|
|
14
|
-
return new Promise(resolve => {
|
|
15
|
-
setPendingToolConfirmation({
|
|
16
|
-
tool: toolCall,
|
|
17
|
-
batchToolNames,
|
|
18
|
-
allTools,
|
|
19
|
-
resolve: (result) => {
|
|
20
|
-
setPendingToolConfirmation(null);
|
|
21
|
-
resolve(result);
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Check if a tool is auto-approved
|
|
28
|
-
* Uses ref to ensure it always sees the latest approved tools
|
|
29
|
-
*/
|
|
30
|
-
const isToolAutoApproved = useCallback((toolName) => {
|
|
31
|
-
return (alwaysApprovedToolsRef.current.has(toolName) ||
|
|
32
|
-
toolName.startsWith('todo-') ||
|
|
33
|
-
toolName.startsWith('subagent-'));
|
|
34
|
-
}, []);
|
|
35
|
-
/**
|
|
36
|
-
* Add a tool to the always-approved list
|
|
37
|
-
*/
|
|
38
|
-
const addToAlwaysApproved = useCallback((toolName) => {
|
|
39
|
-
// Update ref immediately (for closure functions)
|
|
40
|
-
alwaysApprovedToolsRef.current.add(toolName);
|
|
41
|
-
// Update state (for UI reactivity)
|
|
42
|
-
setAlwaysApprovedTools(prev => new Set([...prev, toolName]));
|
|
43
|
-
}, []);
|
|
44
|
-
/**
|
|
45
|
-
* Add multiple tools to the always-approved list
|
|
46
|
-
*/
|
|
47
|
-
const addMultipleToAlwaysApproved = useCallback((toolNames) => {
|
|
48
|
-
// Update ref immediately (for closure functions)
|
|
49
|
-
toolNames.forEach(name => alwaysApprovedToolsRef.current.add(name));
|
|
50
|
-
// Update state (for UI reactivity)
|
|
51
|
-
setAlwaysApprovedTools(prev => new Set([...prev, ...toolNames]));
|
|
52
|
-
}, []);
|
|
53
|
-
return {
|
|
54
|
-
pendingToolConfirmation,
|
|
55
|
-
alwaysApprovedTools,
|
|
56
|
-
requestToolConfirmation,
|
|
57
|
-
isToolAutoApproved,
|
|
58
|
-
addToAlwaysApproved,
|
|
59
|
-
addMultipleToAlwaysApproved,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type EditorContext } from '../utils/vscodeConnection.js';
|
|
2
|
-
export type VSCodeConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
3
|
-
export declare function useVSCodeState(): {
|
|
4
|
-
vscodeConnected: boolean;
|
|
5
|
-
vscodeConnectionStatus: VSCodeConnectionStatus;
|
|
6
|
-
setVscodeConnectionStatus: import("react").Dispatch<import("react").SetStateAction<VSCodeConnectionStatus>>;
|
|
7
|
-
editorContext: EditorContext;
|
|
8
|
-
};
|