snow-ai 0.4.15 → 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 -379
- 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 -1495
- 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,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
type Props = {
|
|
3
|
-
query: string;
|
|
4
|
-
selectedIndex: number;
|
|
5
|
-
visible: boolean;
|
|
6
|
-
maxItems?: number;
|
|
7
|
-
rootPath?: string;
|
|
8
|
-
onFilteredCountChange?: (count: number) => void;
|
|
9
|
-
searchMode?: 'file' | 'content';
|
|
10
|
-
};
|
|
11
|
-
export type FileListRef = {
|
|
12
|
-
getSelectedFile: () => string | null;
|
|
13
|
-
};
|
|
14
|
-
declare const FileList: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<FileListRef>>>;
|
|
15
|
-
export default FileList;
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useMemo, useCallback, forwardRef, useImperativeHandle, memo, } from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
|
|
6
|
-
import { useTheme } from '../contexts/ThemeContext.js';
|
|
7
|
-
const FileList = memo(forwardRef(({ query, selectedIndex, visible, maxItems = 10, rootPath = process.cwd(), onFilteredCountChange, searchMode = 'file', }, ref) => {
|
|
8
|
-
const { theme } = useTheme();
|
|
9
|
-
const [files, setFiles] = useState([]);
|
|
10
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
11
|
-
// Get terminal size for dynamic content display
|
|
12
|
-
const { columns: terminalWidth } = useTerminalSize();
|
|
13
|
-
// Fixed maximum display items to prevent rendering issues
|
|
14
|
-
const MAX_DISPLAY_ITEMS = 5;
|
|
15
|
-
const effectiveMaxItems = useMemo(() => {
|
|
16
|
-
return maxItems
|
|
17
|
-
? Math.min(maxItems, MAX_DISPLAY_ITEMS)
|
|
18
|
-
: MAX_DISPLAY_ITEMS;
|
|
19
|
-
}, [maxItems]);
|
|
20
|
-
// Get files from directory - optimized for performance with depth limit
|
|
21
|
-
const loadFiles = useCallback(async () => {
|
|
22
|
-
const MAX_DEPTH = 5; // Limit recursion depth to prevent performance issues
|
|
23
|
-
const MAX_FILES = 1000; // Reduced from 2000 for better performance
|
|
24
|
-
const getFilesRecursively = async (dir, depth = 0) => {
|
|
25
|
-
// Stop recursion if depth limit reached
|
|
26
|
-
if (depth > MAX_DEPTH) {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const entries = await fs.promises.readdir(dir, {
|
|
31
|
-
withFileTypes: true,
|
|
32
|
-
});
|
|
33
|
-
let result = [];
|
|
34
|
-
// Common ignore patterns for better performance
|
|
35
|
-
const ignorePatterns = [
|
|
36
|
-
'node_modules',
|
|
37
|
-
'dist',
|
|
38
|
-
'build',
|
|
39
|
-
'coverage',
|
|
40
|
-
'.git',
|
|
41
|
-
'.vscode',
|
|
42
|
-
'.idea',
|
|
43
|
-
'out',
|
|
44
|
-
'target',
|
|
45
|
-
'bin',
|
|
46
|
-
'obj',
|
|
47
|
-
'.next',
|
|
48
|
-
'.nuxt',
|
|
49
|
-
'vendor',
|
|
50
|
-
'__pycache__',
|
|
51
|
-
'.pytest_cache',
|
|
52
|
-
'.mypy_cache',
|
|
53
|
-
'venv',
|
|
54
|
-
'.venv',
|
|
55
|
-
'env',
|
|
56
|
-
'.env',
|
|
57
|
-
];
|
|
58
|
-
for (const entry of entries) {
|
|
59
|
-
// Early exit if we've collected enough files
|
|
60
|
-
if (result.length >= MAX_FILES) {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
// Skip hidden files and ignore patterns
|
|
64
|
-
if (entry.name.startsWith('.') ||
|
|
65
|
-
ignorePatterns.includes(entry.name)) {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
const fullPath = path.join(dir, entry.name);
|
|
69
|
-
// Skip if file is too large (> 10MB) for performance
|
|
70
|
-
try {
|
|
71
|
-
const stats = await fs.promises.stat(fullPath);
|
|
72
|
-
if (!entry.isDirectory() && stats.size > 10 * 1024 * 1024) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
let relativePath = path.relative(rootPath, fullPath);
|
|
80
|
-
// Ensure relative paths start with ./ for consistency
|
|
81
|
-
if (!relativePath.startsWith('.') &&
|
|
82
|
-
!path.isAbsolute(relativePath)) {
|
|
83
|
-
relativePath = './' + relativePath;
|
|
84
|
-
}
|
|
85
|
-
// Normalize to forward slashes for cross-platform consistency
|
|
86
|
-
relativePath = relativePath.replace(/\\/g, '/');
|
|
87
|
-
result.push({
|
|
88
|
-
name: entry.name,
|
|
89
|
-
path: relativePath,
|
|
90
|
-
isDirectory: entry.isDirectory(),
|
|
91
|
-
});
|
|
92
|
-
// Recursively get files from subdirectories with depth limit
|
|
93
|
-
if (entry.isDirectory() && depth < MAX_DEPTH) {
|
|
94
|
-
const subFiles = await getFilesRecursively(fullPath, depth + 1);
|
|
95
|
-
result = result.concat(subFiles);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return result;
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
// Batch all state updates together
|
|
105
|
-
setIsLoading(true);
|
|
106
|
-
const fileList = await getFilesRecursively(rootPath);
|
|
107
|
-
setFiles(fileList);
|
|
108
|
-
setIsLoading(false);
|
|
109
|
-
}, [rootPath]);
|
|
110
|
-
// Search file content for content search mode
|
|
111
|
-
const searchFileContent = useCallback(async (query) => {
|
|
112
|
-
if (!query.trim()) {
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
const results = [];
|
|
116
|
-
const queryLower = query.toLowerCase();
|
|
117
|
-
const maxResults = 100; // Limit results for performance
|
|
118
|
-
// Text file extensions to search
|
|
119
|
-
const textExtensions = new Set([
|
|
120
|
-
'.js',
|
|
121
|
-
'.jsx',
|
|
122
|
-
'.ts',
|
|
123
|
-
'.tsx',
|
|
124
|
-
'.py',
|
|
125
|
-
'.java',
|
|
126
|
-
'.c',
|
|
127
|
-
'.cpp',
|
|
128
|
-
'.h',
|
|
129
|
-
'.hpp',
|
|
130
|
-
'.cs',
|
|
131
|
-
'.go',
|
|
132
|
-
'.rs',
|
|
133
|
-
'.rb',
|
|
134
|
-
'.php',
|
|
135
|
-
'.swift',
|
|
136
|
-
'.kt',
|
|
137
|
-
'.scala',
|
|
138
|
-
'.sh',
|
|
139
|
-
'.bash',
|
|
140
|
-
'.zsh',
|
|
141
|
-
'.fish',
|
|
142
|
-
'.ps1',
|
|
143
|
-
'.html',
|
|
144
|
-
'.css',
|
|
145
|
-
'.scss',
|
|
146
|
-
'.sass',
|
|
147
|
-
'.less',
|
|
148
|
-
'.xml',
|
|
149
|
-
'.json',
|
|
150
|
-
'.yaml',
|
|
151
|
-
'.yml',
|
|
152
|
-
'.toml',
|
|
153
|
-
'.ini',
|
|
154
|
-
'.conf',
|
|
155
|
-
'.config',
|
|
156
|
-
'.txt',
|
|
157
|
-
'.md',
|
|
158
|
-
'.markdown',
|
|
159
|
-
'.rst',
|
|
160
|
-
'.tex',
|
|
161
|
-
'.sql',
|
|
162
|
-
'.graphql',
|
|
163
|
-
'.proto',
|
|
164
|
-
'.vue',
|
|
165
|
-
'.svelte',
|
|
166
|
-
]);
|
|
167
|
-
// Filter to only text files
|
|
168
|
-
const filesToSearch = files.filter(f => {
|
|
169
|
-
if (f.isDirectory)
|
|
170
|
-
return false;
|
|
171
|
-
const ext = path.extname(f.path).toLowerCase();
|
|
172
|
-
return textExtensions.has(ext);
|
|
173
|
-
});
|
|
174
|
-
// Process files in batches to avoid blocking
|
|
175
|
-
const batchSize = 10;
|
|
176
|
-
for (let batchStart = 0; batchStart < filesToSearch.length; batchStart += batchSize) {
|
|
177
|
-
if (results.length >= maxResults) {
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
const batch = filesToSearch.slice(batchStart, batchStart + batchSize);
|
|
181
|
-
// Process batch files concurrently but with limit
|
|
182
|
-
const batchPromises = batch.map(async (file) => {
|
|
183
|
-
const fileResults = [];
|
|
184
|
-
try {
|
|
185
|
-
const fullPath = path.join(rootPath, file.path);
|
|
186
|
-
const content = await fs.promises.readFile(fullPath, 'utf-8');
|
|
187
|
-
const lines = content.split('\n');
|
|
188
|
-
// Search each line for the query
|
|
189
|
-
for (let i = 0; i < lines.length; i++) {
|
|
190
|
-
if (fileResults.length >= 10) {
|
|
191
|
-
// Max 10 results per file
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
const line = lines[i];
|
|
195
|
-
if (line && line.toLowerCase().includes(queryLower)) {
|
|
196
|
-
const maxLineLength = Math.max(40, terminalWidth - 10);
|
|
197
|
-
fileResults.push({
|
|
198
|
-
name: file.name,
|
|
199
|
-
path: file.path,
|
|
200
|
-
isDirectory: false,
|
|
201
|
-
lineNumber: i + 1,
|
|
202
|
-
lineContent: line.trim().slice(0, maxLineLength),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
catch (error) {
|
|
208
|
-
// Skip files that can't be read (binary or encoding issues)
|
|
209
|
-
}
|
|
210
|
-
return fileResults;
|
|
211
|
-
});
|
|
212
|
-
// Wait for batch to complete
|
|
213
|
-
const batchResults = await Promise.all(batchPromises);
|
|
214
|
-
// Flatten and add to results
|
|
215
|
-
for (const fileResults of batchResults) {
|
|
216
|
-
if (results.length >= maxResults) {
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
results.push(...fileResults.slice(0, maxResults - results.length));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return results;
|
|
223
|
-
}, [files, rootPath, terminalWidth]);
|
|
224
|
-
// Load files when component becomes visible
|
|
225
|
-
// This ensures the file list is always fresh without complex file watching
|
|
226
|
-
useEffect(() => {
|
|
227
|
-
if (!visible) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
// Always reload when becoming visible to ensure fresh data
|
|
231
|
-
loadFiles();
|
|
232
|
-
}, [visible, rootPath, loadFiles]);
|
|
233
|
-
// State for filtered files (needed for async content search)
|
|
234
|
-
const [allFilteredFiles, setAllFilteredFiles] = useState([]);
|
|
235
|
-
// Filter files based on query and search mode with debounce
|
|
236
|
-
useEffect(() => {
|
|
237
|
-
const performSearch = async () => {
|
|
238
|
-
if (!query.trim()) {
|
|
239
|
-
setAllFilteredFiles(files);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
if (searchMode === 'content') {
|
|
243
|
-
// Content search mode (@@)
|
|
244
|
-
const results = await searchFileContent(query);
|
|
245
|
-
setAllFilteredFiles(results);
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
// File name search mode (@)
|
|
249
|
-
const queryLower = query.toLowerCase();
|
|
250
|
-
const filtered = files.filter(file => {
|
|
251
|
-
const fileName = file.name.toLowerCase();
|
|
252
|
-
const filePath = file.path.toLowerCase();
|
|
253
|
-
return (fileName.includes(queryLower) || filePath.includes(queryLower));
|
|
254
|
-
});
|
|
255
|
-
// Sort by relevance (exact name matches first, then path matches)
|
|
256
|
-
filtered.sort((a, b) => {
|
|
257
|
-
const aNameMatch = a.name.toLowerCase().startsWith(queryLower);
|
|
258
|
-
const bNameMatch = b.name.toLowerCase().startsWith(queryLower);
|
|
259
|
-
if (aNameMatch && !bNameMatch)
|
|
260
|
-
return -1;
|
|
261
|
-
if (!aNameMatch && bNameMatch)
|
|
262
|
-
return 1;
|
|
263
|
-
return a.name.localeCompare(b.name);
|
|
264
|
-
});
|
|
265
|
-
setAllFilteredFiles(filtered);
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
// Debounce search to avoid excessive updates during fast typing
|
|
269
|
-
// Use shorter delay for file search (150ms) and longer for content search (500ms)
|
|
270
|
-
const debounceDelay = searchMode === 'content' ? 500 : 150;
|
|
271
|
-
const timer = setTimeout(() => {
|
|
272
|
-
performSearch();
|
|
273
|
-
}, debounceDelay);
|
|
274
|
-
return () => clearTimeout(timer);
|
|
275
|
-
}, [files, query, searchMode, searchFileContent]);
|
|
276
|
-
// Display with scrolling window
|
|
277
|
-
const filteredFiles = useMemo(() => {
|
|
278
|
-
if (allFilteredFiles.length <= effectiveMaxItems) {
|
|
279
|
-
return allFilteredFiles;
|
|
280
|
-
}
|
|
281
|
-
// Show files around the selected index
|
|
282
|
-
const halfWindow = Math.floor(effectiveMaxItems / 2);
|
|
283
|
-
let startIndex = Math.max(0, selectedIndex - halfWindow);
|
|
284
|
-
let endIndex = Math.min(allFilteredFiles.length, startIndex + effectiveMaxItems);
|
|
285
|
-
// Adjust if we're near the end
|
|
286
|
-
if (endIndex - startIndex < effectiveMaxItems) {
|
|
287
|
-
startIndex = Math.max(0, endIndex - effectiveMaxItems);
|
|
288
|
-
}
|
|
289
|
-
return allFilteredFiles.slice(startIndex, endIndex);
|
|
290
|
-
}, [allFilteredFiles, selectedIndex, effectiveMaxItems]);
|
|
291
|
-
// Notify parent of filtered count changes
|
|
292
|
-
useEffect(() => {
|
|
293
|
-
if (onFilteredCountChange) {
|
|
294
|
-
onFilteredCountChange(allFilteredFiles.length);
|
|
295
|
-
}
|
|
296
|
-
}, [allFilteredFiles.length, onFilteredCountChange]);
|
|
297
|
-
// Expose methods to parent
|
|
298
|
-
useImperativeHandle(ref, () => ({
|
|
299
|
-
getSelectedFile: () => {
|
|
300
|
-
if (allFilteredFiles.length > 0 &&
|
|
301
|
-
selectedIndex < allFilteredFiles.length &&
|
|
302
|
-
allFilteredFiles[selectedIndex]) {
|
|
303
|
-
const selectedFile = allFilteredFiles[selectedIndex];
|
|
304
|
-
// For content search mode, include line number
|
|
305
|
-
if (selectedFile.lineNumber !== undefined) {
|
|
306
|
-
return `${selectedFile.path}:${selectedFile.lineNumber}`;
|
|
307
|
-
}
|
|
308
|
-
return selectedFile.path;
|
|
309
|
-
}
|
|
310
|
-
return null;
|
|
311
|
-
},
|
|
312
|
-
}), [allFilteredFiles, selectedIndex]);
|
|
313
|
-
// Calculate display index for the scrolling window
|
|
314
|
-
// MUST be before early returns to avoid hook order issues
|
|
315
|
-
const displaySelectedIndex = useMemo(() => {
|
|
316
|
-
return filteredFiles.findIndex(file => {
|
|
317
|
-
const originalIndex = allFilteredFiles.indexOf(file);
|
|
318
|
-
return originalIndex === selectedIndex;
|
|
319
|
-
});
|
|
320
|
-
}, [filteredFiles, allFilteredFiles, selectedIndex]);
|
|
321
|
-
if (!visible) {
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
if (isLoading) {
|
|
325
|
-
return (React.createElement(Box, { paddingX: 1, marginTop: 1 },
|
|
326
|
-
React.createElement(Text, { color: "blue", dimColor: true }, "Loading files...")));
|
|
327
|
-
}
|
|
328
|
-
if (filteredFiles.length === 0) {
|
|
329
|
-
return (React.createElement(Box, { paddingX: 1, marginTop: 1 },
|
|
330
|
-
React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, "No files found")));
|
|
331
|
-
}
|
|
332
|
-
return (React.createElement(Box, { paddingX: 1, marginTop: 1, flexDirection: "column" },
|
|
333
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
334
|
-
React.createElement(Text, { color: "blue", bold: true },
|
|
335
|
-
searchMode === 'content' ? '≡ Content Search' : '≡ Files',
|
|
336
|
-
' ',
|
|
337
|
-
allFilteredFiles.length > effectiveMaxItems &&
|
|
338
|
-
`(${selectedIndex + 1}/${allFilteredFiles.length})`)),
|
|
339
|
-
filteredFiles.map((file, index) => (React.createElement(Box, { key: `${file.path}-${file.lineNumber || 0}`, flexDirection: "column" },
|
|
340
|
-
React.createElement(Text, { backgroundColor: index === displaySelectedIndex ? theme.colors.menuSelected : undefined, color: index === displaySelectedIndex
|
|
341
|
-
? theme.colors.menuNormal
|
|
342
|
-
: file.isDirectory
|
|
343
|
-
? theme.colors.warning
|
|
344
|
-
: 'white' }, searchMode === 'content' && file.lineNumber !== undefined
|
|
345
|
-
? `${file.path}:${file.lineNumber}`
|
|
346
|
-
: file.isDirectory
|
|
347
|
-
? '◇ ' + file.path
|
|
348
|
-
: '◆ ' + file.path),
|
|
349
|
-
searchMode === 'content' && file.lineContent && (React.createElement(Text, { backgroundColor: index === displaySelectedIndex ? theme.colors.menuSelected : undefined, color: index === displaySelectedIndex ? theme.colors.menuSecondary : theme.colors.menuSecondary, dimColor: true },
|
|
350
|
-
' ',
|
|
351
|
-
file.lineContent))))),
|
|
352
|
-
allFilteredFiles.length > effectiveMaxItems && (React.createElement(Box, { marginTop: 1 },
|
|
353
|
-
React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true },
|
|
354
|
-
"\u2191\u2193 to scroll \u00B7 ",
|
|
355
|
-
allFilteredFiles.length - effectiveMaxItems,
|
|
356
|
-
' ',
|
|
357
|
-
"more hidden")))));
|
|
358
|
-
}));
|
|
359
|
-
FileList.displayName = 'FileList';
|
|
360
|
-
export default FileList;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
type Props = {
|
|
3
|
-
fileCount: number;
|
|
4
|
-
filePaths: string[];
|
|
5
|
-
onConfirm: (rollbackFiles: boolean | null) => void;
|
|
6
|
-
};
|
|
7
|
-
export default function FileRollbackConfirmation({ fileCount, filePaths, onConfirm }: Props): React.JSX.Element;
|
|
8
|
-
export {};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Box, Text, useInput } from 'ink';
|
|
3
|
-
export default function FileRollbackConfirmation({ fileCount, filePaths, onConfirm }) {
|
|
4
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
5
|
-
const [showFullList, setShowFullList] = useState(false);
|
|
6
|
-
const [fileScrollIndex, setFileScrollIndex] = useState(0);
|
|
7
|
-
const options = [
|
|
8
|
-
{ label: 'Yes, rollback files and conversation', value: true },
|
|
9
|
-
{ label: 'No, rollback conversation only', value: false }
|
|
10
|
-
];
|
|
11
|
-
useInput((_, key) => {
|
|
12
|
-
// Tab - toggle full file list view
|
|
13
|
-
if (key.tab) {
|
|
14
|
-
setShowFullList(prev => !prev);
|
|
15
|
-
setFileScrollIndex(0); // Reset scroll when toggling
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
// In full list mode, use up/down to scroll files
|
|
19
|
-
if (showFullList) {
|
|
20
|
-
const maxVisibleFiles = 10;
|
|
21
|
-
const maxScroll = Math.max(0, filePaths.length - maxVisibleFiles);
|
|
22
|
-
if (key.upArrow) {
|
|
23
|
-
setFileScrollIndex(prev => Math.max(0, prev - 1));
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
if (key.downArrow) {
|
|
27
|
-
setFileScrollIndex(prev => Math.min(maxScroll, prev + 1));
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// In compact mode, up/down navigate options
|
|
33
|
-
if (key.upArrow) {
|
|
34
|
-
setSelectedIndex(prev => Math.max(0, prev - 1));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (key.downArrow) {
|
|
38
|
-
setSelectedIndex(prev => Math.min(options.length - 1, prev + 1));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// Enter - confirm selection (only when not in full list mode)
|
|
43
|
-
if (key.return && !showFullList) {
|
|
44
|
-
onConfirm(options[selectedIndex]?.value ?? false);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// ESC - exit full list mode or cancel rollback
|
|
48
|
-
if (key.escape) {
|
|
49
|
-
if (showFullList) {
|
|
50
|
-
setShowFullList(false);
|
|
51
|
-
setFileScrollIndex(0);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
onConfirm(null); // null means cancel everything
|
|
55
|
-
}
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
// Display logic for file list
|
|
60
|
-
const maxFilesToShowCompact = 5;
|
|
61
|
-
const maxFilesToShowFull = 10;
|
|
62
|
-
const displayFiles = showFullList
|
|
63
|
-
? filePaths.slice(fileScrollIndex, fileScrollIndex + maxFilesToShowFull)
|
|
64
|
-
: filePaths.slice(0, maxFilesToShowCompact);
|
|
65
|
-
const remainingCountCompact = fileCount - maxFilesToShowCompact;
|
|
66
|
-
const hasMoreAbove = showFullList && fileScrollIndex > 0;
|
|
67
|
-
const hasMoreBelow = showFullList && (fileScrollIndex + maxFilesToShowFull) < filePaths.length;
|
|
68
|
-
return (React.createElement(Box, { flexDirection: "column", marginX: 1, marginBottom: 1, padding: 1 },
|
|
69
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
70
|
-
React.createElement(Text, { color: "yellow", bold: true }, "\u26A0 File Rollback Confirmation")),
|
|
71
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
72
|
-
React.createElement(Text, { color: "white" },
|
|
73
|
-
"This checkpoint has ",
|
|
74
|
-
fileCount,
|
|
75
|
-
" file",
|
|
76
|
-
fileCount > 1 ? 's' : '',
|
|
77
|
-
" that will be rolled back:")),
|
|
78
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2 },
|
|
79
|
-
hasMoreAbove && (React.createElement(Text, { color: "gray", dimColor: true },
|
|
80
|
-
"\u2191 ",
|
|
81
|
-
fileScrollIndex,
|
|
82
|
-
" more above...")),
|
|
83
|
-
displayFiles.map((file, index) => (React.createElement(Text, { key: index, color: "cyan", dimColor: true },
|
|
84
|
-
"\u2022 ",
|
|
85
|
-
file))),
|
|
86
|
-
hasMoreBelow && (React.createElement(Text, { color: "gray", dimColor: true },
|
|
87
|
-
"\u2193 ",
|
|
88
|
-
filePaths.length - (fileScrollIndex + maxFilesToShowFull),
|
|
89
|
-
" more below...")),
|
|
90
|
-
!showFullList && remainingCountCompact > 0 && (React.createElement(Text, { color: "gray", dimColor: true },
|
|
91
|
-
"... and ",
|
|
92
|
-
remainingCountCompact,
|
|
93
|
-
" more file",
|
|
94
|
-
remainingCountCompact > 1 ? 's' : ''))),
|
|
95
|
-
!showFullList && (React.createElement(React.Fragment, null,
|
|
96
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
97
|
-
React.createElement(Text, { color: "gray", dimColor: true }, "Do you want to rollback the files as well?")),
|
|
98
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, options.map((option, index) => (React.createElement(Box, { key: index },
|
|
99
|
-
React.createElement(Text, { color: index === selectedIndex ? 'green' : 'white', bold: index === selectedIndex },
|
|
100
|
-
index === selectedIndex ? '❯ ' : ' ',
|
|
101
|
-
option.label))))))),
|
|
102
|
-
React.createElement(Box, null,
|
|
103
|
-
React.createElement(Text, { color: "gray", dimColor: true }, showFullList
|
|
104
|
-
? '↑↓ scroll · Tab back · ESC close'
|
|
105
|
-
: fileCount > maxFilesToShowCompact
|
|
106
|
-
? `↑↓ select · Tab view all (${fileCount} files) · Enter confirm · ESC cancel`
|
|
107
|
-
: '↑↓ select · Enter confirm · ESC cancel'))));
|
|
108
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
import { useI18n } from '../../i18n/index.js';
|
|
4
|
-
// Get platform-specific paste key
|
|
5
|
-
const getPasteKey = () => {
|
|
6
|
-
return process.platform === 'darwin' ? 'Ctrl+V' : 'Alt+V';
|
|
7
|
-
};
|
|
8
|
-
export default function HelpPanel() {
|
|
9
|
-
const pasteKey = getPasteKey();
|
|
10
|
-
const { t } = useI18n();
|
|
11
|
-
return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 },
|
|
12
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
13
|
-
React.createElement(Text, { bold: true, color: "cyan" }, t.helpPanel.title)),
|
|
14
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
15
|
-
React.createElement(Text, { bold: true, color: "yellow" }, t.helpPanel.textEditingTitle),
|
|
16
|
-
React.createElement(Text, null,
|
|
17
|
-
" \u2022 ",
|
|
18
|
-
t.helpPanel.deleteToStart),
|
|
19
|
-
React.createElement(Text, null,
|
|
20
|
-
" \u2022 ",
|
|
21
|
-
t.helpPanel.deleteToEnd),
|
|
22
|
-
React.createElement(Text, null,
|
|
23
|
-
' ',
|
|
24
|
-
"\u2022 ",
|
|
25
|
-
t.helpPanel.pasteImages.replace('{pasteKey}', pasteKey))),
|
|
26
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
27
|
-
React.createElement(Text, { bold: true, color: "green" }, t.helpPanel.quickAccessTitle),
|
|
28
|
-
React.createElement(Text, null,
|
|
29
|
-
" \u2022 ",
|
|
30
|
-
t.helpPanel.insertFiles),
|
|
31
|
-
React.createElement(Text, null,
|
|
32
|
-
" \u2022 ",
|
|
33
|
-
t.helpPanel.searchContent),
|
|
34
|
-
React.createElement(Text, null,
|
|
35
|
-
" \u2022 ",
|
|
36
|
-
t.helpPanel.selectAgent),
|
|
37
|
-
React.createElement(Text, null,
|
|
38
|
-
" \u2022 ",
|
|
39
|
-
t.helpPanel.showCommands)),
|
|
40
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
41
|
-
React.createElement(Text, { bold: true, color: "blue" }, t.helpPanel.navigationTitle),
|
|
42
|
-
React.createElement(Text, null,
|
|
43
|
-
" \u2022 ",
|
|
44
|
-
t.helpPanel.navigateHistory),
|
|
45
|
-
React.createElement(Text, null,
|
|
46
|
-
" \u2022 ",
|
|
47
|
-
t.helpPanel.selectItem),
|
|
48
|
-
React.createElement(Text, null,
|
|
49
|
-
" \u2022 ",
|
|
50
|
-
t.helpPanel.cancelClose),
|
|
51
|
-
React.createElement(Text, null,
|
|
52
|
-
" \u2022 ",
|
|
53
|
-
t.helpPanel.toggleYolo)),
|
|
54
|
-
React.createElement(Box, { flexDirection: "column" },
|
|
55
|
-
React.createElement(Text, { bold: true, color: "magenta" }, t.helpPanel.tipsTitle),
|
|
56
|
-
React.createElement(Text, null,
|
|
57
|
-
" \u2022 ",
|
|
58
|
-
t.helpPanel.tipUseHelp),
|
|
59
|
-
React.createElement(Text, null,
|
|
60
|
-
" \u2022 ",
|
|
61
|
-
t.helpPanel.tipShowCommands),
|
|
62
|
-
React.createElement(Text, null,
|
|
63
|
-
" \u2022 ",
|
|
64
|
-
t.helpPanel.tipInterrupt)),
|
|
65
|
-
React.createElement(Box, { marginTop: 1 },
|
|
66
|
-
React.createElement(Text, { dimColor: true, color: "gray" }, t.helpPanel.closeHint))));
|
|
67
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
import SelectInput from 'ink-select-input';
|
|
4
|
-
import { getMCPServicesInfo, refreshMCPToolsCache, reconnectMCPService } from '../../utils/mcpToolsManager.js';
|
|
5
|
-
export default function MCPInfoPanel() {
|
|
6
|
-
const [mcpStatus, setMcpStatus] = useState([]);
|
|
7
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
8
|
-
const [errorMessage, setErrorMessage] = useState(null);
|
|
9
|
-
const [isReconnecting, setIsReconnecting] = useState(false);
|
|
10
|
-
const loadMCPStatus = async () => {
|
|
11
|
-
try {
|
|
12
|
-
const servicesInfo = await getMCPServicesInfo();
|
|
13
|
-
const statusList = servicesInfo.map(service => ({
|
|
14
|
-
name: service.serviceName,
|
|
15
|
-
connected: service.connected,
|
|
16
|
-
tools: service.tools.map(tool => tool.name),
|
|
17
|
-
connectionMethod: service.isBuiltIn ? 'Built-in' : 'External',
|
|
18
|
-
isBuiltIn: service.isBuiltIn,
|
|
19
|
-
error: service.error
|
|
20
|
-
}));
|
|
21
|
-
setMcpStatus(statusList);
|
|
22
|
-
setErrorMessage(null);
|
|
23
|
-
setIsLoading(false);
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
setErrorMessage(error instanceof Error ? error.message : 'Failed to load MCP services');
|
|
27
|
-
setIsLoading(false);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
let isMounted = true;
|
|
32
|
-
const load = async () => {
|
|
33
|
-
await loadMCPStatus();
|
|
34
|
-
};
|
|
35
|
-
if (isMounted) {
|
|
36
|
-
load();
|
|
37
|
-
}
|
|
38
|
-
return () => {
|
|
39
|
-
isMounted = false;
|
|
40
|
-
};
|
|
41
|
-
}, []);
|
|
42
|
-
const handleServiceSelect = async (item) => {
|
|
43
|
-
setIsReconnecting(true);
|
|
44
|
-
try {
|
|
45
|
-
if (item.value === 'refresh-all') {
|
|
46
|
-
// Refresh all services
|
|
47
|
-
await refreshMCPToolsCache();
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
// Reconnect specific service
|
|
51
|
-
await reconnectMCPService(item.value);
|
|
52
|
-
}
|
|
53
|
-
await loadMCPStatus();
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
setErrorMessage(error instanceof Error ? error.message : 'Failed to reconnect');
|
|
57
|
-
}
|
|
58
|
-
finally {
|
|
59
|
-
setIsReconnecting(false);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
// Build select items from all services
|
|
63
|
-
const selectItems = [
|
|
64
|
-
{ label: 'Refresh all services', value: 'refresh-all', isRefreshAll: true },
|
|
65
|
-
...mcpStatus.map(s => ({
|
|
66
|
-
label: s.name,
|
|
67
|
-
value: s.name,
|
|
68
|
-
connected: s.connected,
|
|
69
|
-
isBuiltIn: s.isBuiltIn,
|
|
70
|
-
error: s.error
|
|
71
|
-
}))
|
|
72
|
-
];
|
|
73
|
-
// Custom item component to render with colors
|
|
74
|
-
const ItemComponent = ({ isSelected, label }) => {
|
|
75
|
-
const item = selectItems.find(i => i.label === label);
|
|
76
|
-
if (!item)
|
|
77
|
-
return React.createElement(Text, null, label);
|
|
78
|
-
if (item.isRefreshAll) {
|
|
79
|
-
return (React.createElement(Text, { color: isSelected ? 'cyan' : 'blue' },
|
|
80
|
-
"\u21BB ",
|
|
81
|
-
label));
|
|
82
|
-
}
|
|
83
|
-
const statusColor = item.connected ? 'green' : 'red';
|
|
84
|
-
const suffix = item.isBuiltIn ? ' (System)' : item.connected ? ' (External)' : ` - ${item.error || 'Failed'}`;
|
|
85
|
-
return (React.createElement(Box, null,
|
|
86
|
-
React.createElement(Text, { color: statusColor }, "\u25CF "),
|
|
87
|
-
React.createElement(Text, { color: isSelected ? 'cyan' : 'white' }, label),
|
|
88
|
-
React.createElement(Text, { color: "gray", dimColor: true }, suffix)));
|
|
89
|
-
};
|
|
90
|
-
if (isLoading) {
|
|
91
|
-
return (React.createElement(Text, { color: "gray" }, "Loading MCP services..."));
|
|
92
|
-
}
|
|
93
|
-
if (errorMessage) {
|
|
94
|
-
return (React.createElement(Box, { borderColor: "red", borderStyle: "round", paddingX: 2, paddingY: 0 },
|
|
95
|
-
React.createElement(Text, { color: "red", dimColor: true },
|
|
96
|
-
"Error: ",
|
|
97
|
-
errorMessage)));
|
|
98
|
-
}
|
|
99
|
-
if (mcpStatus.length === 0) {
|
|
100
|
-
return (React.createElement(Box, { borderColor: "cyan", borderStyle: "round", paddingX: 2, paddingY: 0 },
|
|
101
|
-
React.createElement(Text, { color: "gray", dimColor: true }, "No available MCP services detected")));
|
|
102
|
-
}
|
|
103
|
-
return (React.createElement(Box, { borderColor: "cyan", borderStyle: "round", paddingX: 2, paddingY: 0 },
|
|
104
|
-
React.createElement(Box, { flexDirection: "column" },
|
|
105
|
-
React.createElement(Text, { color: "cyan", bold: true }, isReconnecting ? 'Refreshing services...' : 'MCP Services'),
|
|
106
|
-
!isReconnecting && (React.createElement(SelectInput, { items: selectItems, onSelect: handleServiceSelect, itemComponent: ItemComponent })),
|
|
107
|
-
isReconnecting && (React.createElement(Text, { color: "yellow", dimColor: true }, "Please wait...")))));
|
|
108
|
-
}
|