@within-7/minto 0.2.0 → 0.3.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.
- package/dist/commands/agents/AgentsCommand.js +22 -24
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/context.js +2 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +2 -1
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/mcp-interactive.js +7 -6
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +3 -2
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +4 -3
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/sandbox.js +4 -3
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/CollapsibleHint.js +2 -1
- package/dist/components/CollapsibleHint.js.map +2 -2
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +8 -11
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +23 -67
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +4 -3
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +26 -13
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +3 -2
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/PromptInput.js +88 -75
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +71 -22
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +4 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +7 -4
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +14 -11
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoPanel.js +44 -26
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +4 -3
- package/dist/components/TreeConnector.js.map +2 -2
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +17 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +8 -4
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +2 -1
- package/dist/components/messages/GroupRenderer.js.map +2 -2
- package/dist/components/messages/NestedTasksPreview.js +13 -1
- package/dist/components/messages/NestedTasksPreview.js.map +2 -2
- package/dist/components/messages/ParallelTasksGroupView.js +4 -3
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +35 -15
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskOutputContent.js +9 -6
- package/dist/components/messages/TaskOutputContent.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/colors.js +90 -72
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/costTracker.js +9 -18
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +2 -2
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
- package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
- package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
- package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
- package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/entrypoints/cli.js +115 -87
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +30 -6
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useLogMessages.js +12 -1
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/i18n/locales/en.js +6 -5
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +6 -5
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/permissions.js +28 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +78 -4
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +23 -3
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/claude.js +54 -3
- package/dist/services/claude.js.map +2 -2
- package/dist/services/intelligentCompactor.js +1 -1
- package/dist/services/intelligentCompactor.js.map +2 -2
- package/dist/services/mcpClient.js +81 -25
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +58 -17
- package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +22 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +178 -34
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +6 -3
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +4 -2
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +1 -1
- package/dist/tools/PlanModeTool/prompt.js.map +1 -1
- package/dist/tools/SkillTool/SkillTool.js +4 -3
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +8 -0
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/config.js +47 -5
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/permissions/filesystem.js +5 -1
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +9 -9
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +5 -4
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +9 -7
- package/dist/hooks/useCancelRequest.js +0 -31
- package/dist/hooks/useCancelRequest.js.map +0 -7
|
@@ -15,6 +15,7 @@ import { getTheme } from "../utils/theme.js";
|
|
|
15
15
|
import { clearTerminal } from "../utils/terminal.js";
|
|
16
16
|
import { PressEnterToContinue } from "./PressEnterToContinue.js";
|
|
17
17
|
import { ModelSelector } from "./ModelSelector/index.js";
|
|
18
|
+
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
18
19
|
function Onboarding({ onDone }) {
|
|
19
20
|
const [currentStepIndex, setCurrentStepIndex] = useState(0);
|
|
20
21
|
const [showModelSelector, setShowModelSelector] = useState(false);
|
|
@@ -64,7 +65,7 @@ function Onboarding({ onDone }) {
|
|
|
64
65
|
},
|
|
65
66
|
{ isActive: !showModelSelector }
|
|
66
67
|
);
|
|
67
|
-
const themeStep = /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1, paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Let's get started."), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Choose the option that looks best when you select it:"), /* @__PURE__ */ React.createElement(Text, {
|
|
68
|
+
const themeStep = /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1, paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Let's get started."), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Choose the option that looks best when you select it:"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "To change this later, run /config")), /* @__PURE__ */ React.createElement(
|
|
68
69
|
Select,
|
|
69
70
|
{
|
|
70
71
|
options: [
|
|
@@ -88,7 +89,7 @@ function Onboarding({ onDone }) {
|
|
|
88
89
|
paddingLeft: 1,
|
|
89
90
|
marginRight: 1,
|
|
90
91
|
borderStyle: "round",
|
|
91
|
-
borderColor:
|
|
92
|
+
borderColor: SEMANTIC_COLORS.dim,
|
|
92
93
|
flexDirection: "column"
|
|
93
94
|
},
|
|
94
95
|
/* @__PURE__ */ React.createElement(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/Onboarding.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useState } from 'react'\nimport { PRODUCT_NAME } from '@constants/product'\nimport { Box, Newline, Text, useInput } from 'ink'\nimport {\n getGlobalConfig,\n saveGlobalConfig,\n DEFAULT_GLOBAL_CONFIG,\n ProviderType,\n} from '@utils/config'\nimport { OrderedList } from '@inkjs/ui'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { MIN_LOGO_WIDTH } from './Logo'\nimport { Select } from './CustomSelect/select'\nimport { StructuredDiff } from './StructuredDiff'\nimport { getTheme, type ThemeNames } from '@utils/theme'\nimport { clearTerminal } from '@utils/terminal'\nimport { PressEnterToContinue } from './PressEnterToContinue'\nimport { ModelSelector } from './ModelSelector'\ntype StepId = 'theme' | 'usage' | 'providers' | 'model'\n\ninterface OnboardingStep {\n id: StepId\n component: React.ReactNode\n}\n\ntype Props = {\n onDone(): void\n}\n\nexport function Onboarding({ onDone }: Props): React.ReactNode {\n const [currentStepIndex, setCurrentStepIndex] = useState(0)\n const [showModelSelector, setShowModelSelector] = useState(false)\n const config = getGlobalConfig()\n\n const [selectedTheme, setSelectedTheme] = useState(\n DEFAULT_GLOBAL_CONFIG.theme,\n )\n const theme = getTheme()\n function goToNextStep() {\n if (currentStepIndex < steps.length - 1) {\n const nextIndex = currentStepIndex + 1\n setCurrentStepIndex(nextIndex)\n }\n }\n\n function handleThemeSelection(newTheme: string) {\n saveGlobalConfig({\n ...config,\n theme: newTheme as ThemeNames,\n })\n goToNextStep()\n }\n\n function handleThemePreview(newTheme: string) {\n setSelectedTheme(newTheme as ThemeNames)\n }\n\n function handleProviderSelectionDone() {\n // After model selection is done, go to the next step\n goToNextStep()\n }\n\n function handleModelSelectionDone() {\n // After final model selection is done, complete onboarding\n onDone()\n }\n\n // Disable exit handler when showing ModelSelector to prevent listener accumulation\n const exitState = useExitOnCtrlCD(() => process.exit(0), {\n isActive: !showModelSelector,\n })\n\n // Only listen when not showing ModelSelector\n useInput(\n async (_, key) => {\n const currentStep = steps[currentStepIndex]\n if (\n key.return &&\n currentStep &&\n ['usage', 'providers', 'model'].includes(currentStep.id)\n ) {\n if (currentStep.id === 'model') {\n // Navigate to ModelSelector component\n setShowModelSelector(true)\n } else if (currentStepIndex === steps.length - 1) {\n onDone()\n } else {\n // HACK: for some reason there's now a jump here otherwise :(\n await clearTerminal()\n goToNextStep()\n }\n }\n },\n { isActive: !showModelSelector },\n )\n\n // Define all onboarding steps\n const themeStep = (\n <Box flexDirection=\"column\" gap={1} paddingLeft={1}>\n <Text>Let's get started.</Text>\n <Box flexDirection=\"column\">\n <Text bold>Choose the option that looks best when you select it:</Text>\n <Text
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,gBAAgB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,KAAK,SAAS,MAAM,gBAAgB;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,gBAAiC;AAC1C,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;
|
|
4
|
+
"sourcesContent": ["import React, { useState } from 'react'\nimport { PRODUCT_NAME } from '@constants/product'\nimport { Box, Newline, Text, useInput } from 'ink'\nimport {\n getGlobalConfig,\n saveGlobalConfig,\n DEFAULT_GLOBAL_CONFIG,\n ProviderType,\n} from '@utils/config'\nimport { OrderedList } from '@inkjs/ui'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { MIN_LOGO_WIDTH } from './Logo'\nimport { Select } from './CustomSelect/select'\nimport { StructuredDiff } from './StructuredDiff'\nimport { getTheme, type ThemeNames } from '@utils/theme'\nimport { clearTerminal } from '@utils/terminal'\nimport { PressEnterToContinue } from './PressEnterToContinue'\nimport { ModelSelector } from './ModelSelector'\nimport { SEMANTIC_COLORS } from '@constants/colors'\ntype StepId = 'theme' | 'usage' | 'providers' | 'model'\n\ninterface OnboardingStep {\n id: StepId\n component: React.ReactNode\n}\n\ntype Props = {\n onDone(): void\n}\n\nexport function Onboarding({ onDone }: Props): React.ReactNode {\n const [currentStepIndex, setCurrentStepIndex] = useState(0)\n const [showModelSelector, setShowModelSelector] = useState(false)\n const config = getGlobalConfig()\n\n const [selectedTheme, setSelectedTheme] = useState(\n DEFAULT_GLOBAL_CONFIG.theme,\n )\n const theme = getTheme()\n function goToNextStep() {\n if (currentStepIndex < steps.length - 1) {\n const nextIndex = currentStepIndex + 1\n setCurrentStepIndex(nextIndex)\n }\n }\n\n function handleThemeSelection(newTheme: string) {\n saveGlobalConfig({\n ...config,\n theme: newTheme as ThemeNames,\n })\n goToNextStep()\n }\n\n function handleThemePreview(newTheme: string) {\n setSelectedTheme(newTheme as ThemeNames)\n }\n\n function handleProviderSelectionDone() {\n // After model selection is done, go to the next step\n goToNextStep()\n }\n\n function handleModelSelectionDone() {\n // After final model selection is done, complete onboarding\n onDone()\n }\n\n // Disable exit handler when showing ModelSelector to prevent listener accumulation\n const exitState = useExitOnCtrlCD(() => process.exit(0), {\n isActive: !showModelSelector,\n })\n\n // Only listen when not showing ModelSelector\n useInput(\n async (_, key) => {\n const currentStep = steps[currentStepIndex]\n if (\n key.return &&\n currentStep &&\n ['usage', 'providers', 'model'].includes(currentStep.id)\n ) {\n if (currentStep.id === 'model') {\n // Navigate to ModelSelector component\n setShowModelSelector(true)\n } else if (currentStepIndex === steps.length - 1) {\n onDone()\n } else {\n // HACK: for some reason there's now a jump here otherwise :(\n await clearTerminal()\n goToNextStep()\n }\n }\n },\n { isActive: !showModelSelector },\n )\n\n // Define all onboarding steps\n const themeStep = (\n <Box flexDirection=\"column\" gap={1} paddingLeft={1}>\n <Text>Let's get started.</Text>\n <Box flexDirection=\"column\">\n <Text bold>Choose the option that looks best when you select it:</Text>\n <Text color={SEMANTIC_COLORS.dim}>\n To change this later, run /config\n </Text>\n </Box>\n <Select\n options={[\n { label: 'Light text', value: 'dark' },\n { label: 'Dark text', value: 'light' },\n {\n label: 'Light text (colorblind-friendly)',\n value: 'dark-daltonized',\n },\n {\n label: 'Dark text (colorblind-friendly)',\n value: 'light-daltonized',\n },\n ]}\n onFocus={handleThemePreview}\n onChange={handleThemeSelection}\n />\n <Box flexDirection=\"column\">\n <Box\n paddingLeft={1}\n marginRight={1}\n borderStyle=\"round\"\n borderColor={SEMANTIC_COLORS.dim}\n flexDirection=\"column\"\n >\n <StructuredDiff\n patch={{\n oldStart: 1,\n newStart: 1,\n oldLines: 3,\n newLines: 3,\n lines: [\n 'function greet() {',\n '- console.log(\"Hello, World!\");',\n '+ console.log(\"Hello, anon!\");',\n '}',\n ],\n }}\n dim={false}\n width={40}\n overrideTheme={selectedTheme}\n />\n </Box>\n </Box>\n </Box>\n )\n\n const providersStep = (\n <Box flexDirection=\"column\" gap={1} paddingLeft={1}>\n <Box flexDirection=\"column\" width={70}>\n <Text color={theme.secondaryText}>\n Next, let's select your preferred AI provider and model.\n </Text>\n </Box>\n <ModelSelector\n onDone={handleProviderSelectionDone}\n skipModelType={true}\n isOnboarding={true}\n />\n </Box>\n )\n\n const usageStep = (\n <Box flexDirection=\"column\" gap={1} paddingLeft={1}>\n <Text bold>Using {PRODUCT_NAME} effectively:</Text>\n <Box flexDirection=\"column\" width={70}>\n <OrderedList children={[]}>\n <OrderedList.Item children={[]}>\n <Text>\n Start in your project directory\n <Newline />\n <Text color={theme.secondaryText}>\n Files are automatically added to context when needed.\n </Text>\n <Newline />\n </Text>\n </OrderedList.Item>\n <OrderedList.Item children={[]}>\n <Text>\n Use {PRODUCT_NAME} as a development partner\n <Newline />\n <Text color={theme.secondaryText}>\n Get help with file analysis, editing, bash commands,\n <Newline />\n and git history.\n <Newline />\n </Text>\n </Text>\n </OrderedList.Item>\n <OrderedList.Item children={[]}>\n <Text>\n Provide clear context\n <Newline />\n <Text color={theme.secondaryText}>\n Be as specific as you would with another engineer. <Newline />\n The better the context, the better the results. <Newline />\n </Text>\n </Text>\n </OrderedList.Item>\n </OrderedList>\n </Box>\n <PressEnterToContinue />\n </Box>\n )\n\n const modelStep = (\n <Box flexDirection=\"column\" gap={1} paddingLeft={1}>\n <Text bold>Configure your models:</Text>\n <Box flexDirection=\"column\" width={70}>\n <Text>\n You can customize which models {PRODUCT_NAME} uses for different\n tasks.\n <Newline />\n <Text color={theme.secondaryText}>\n Let's set up your preferred models for large and small tasks.\n </Text>\n </Text>\n <Box marginTop={1}>\n <Text>\n Press <Text color={theme.suggestion}>Enter</Text> to continue to the\n model selection screen.\n </Text>\n </Box>\n </Box>\n <PressEnterToContinue />\n </Box>\n )\n\n const steps: OnboardingStep[] = []\n steps.push({ id: 'theme', component: themeStep })\n steps.push({ id: 'usage', component: usageStep })\n\n steps.push({ id: 'model', component: modelStep })\n\n // If we're showing the model selector screen, render it directly\n if (showModelSelector) {\n return (\n <ModelSelector\n onDone={handleModelSelectionDone}\n skipModelType={true}\n isOnboarding={true}\n />\n )\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <>\n <Box flexDirection=\"column\" gap={1}>\n <Text bold>\n {PRODUCT_NAME}{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n {steps[currentStepIndex]?.component}\n </Box>\n </>\n </Box>\n )\n}\n\nexport function WelcomeBox(): React.ReactNode {\n const theme = getTheme()\n return (\n <Box\n borderColor={theme.minto}\n borderStyle=\"round\"\n paddingX={1}\n width={MIN_LOGO_WIDTH}\n >\n <Text>\n <Text color={theme.minto}>\u273B</Text> Welcome to{' '}\n <Text bold>{PRODUCT_NAME}</Text> research preview!\n </Text>\n </Box>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { memo } from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
4
|
+
const Section = memo(function Section2({
|
|
5
|
+
icon,
|
|
6
|
+
title,
|
|
7
|
+
count,
|
|
8
|
+
hint,
|
|
9
|
+
children
|
|
10
|
+
}) {
|
|
11
|
+
if (count === 0) return null;
|
|
12
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, icon, " "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, title), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.brand }, " ", count), hint && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, " (", hint, ")")), children);
|
|
13
|
+
});
|
|
14
|
+
const FileList = memo(function FileList2({ files, maxToShow }) {
|
|
15
|
+
const displayFiles = files.slice(0, maxToShow);
|
|
16
|
+
const remaining = files.length - maxToShow;
|
|
17
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, displayFiles.map((file, idx) => /* @__PURE__ */ React.createElement(React.Fragment, { key: `${file}-${idx}` }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, formatFilePath(file)))), remaining > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "...and ", remaining, " more"));
|
|
18
|
+
});
|
|
19
|
+
const ModifiedFileList = memo(function ModifiedFileList2({
|
|
20
|
+
files,
|
|
21
|
+
maxToShow
|
|
22
|
+
}) {
|
|
23
|
+
const displayFiles = files.slice(0, maxToShow);
|
|
24
|
+
const remaining = files.length - maxToShow;
|
|
25
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, displayFiles.map((file, idx) => /* @__PURE__ */ React.createElement(Box, { key: `${file.path}-${idx}`, flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, formatFilePath(file.path), " "), (file.added > 0 || file.removed > 0) && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "(", file.added > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.success }, "+", file.added), file.added > 0 && file.removed > 0 && /* @__PURE__ */ React.createElement(Text, null, "/"), file.removed > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "-", file.removed), ")"))), remaining > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "...and ", remaining, " more"));
|
|
26
|
+
});
|
|
27
|
+
const CommandList = memo(function CommandList2({
|
|
28
|
+
commands,
|
|
29
|
+
maxToShow
|
|
30
|
+
}) {
|
|
31
|
+
const displayCommands = commands.slice(0, maxToShow);
|
|
32
|
+
const remaining = commands.length - maxToShow;
|
|
33
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, displayCommands.map((cmd, idx) => /* @__PURE__ */ React.createElement(React.Fragment, { key: `cmd-${idx}` }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, truncateCommand(cmd, 60)))), remaining > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "...and ", remaining, " more"));
|
|
34
|
+
});
|
|
35
|
+
function formatFilePath(filePath) {
|
|
36
|
+
const parts = filePath.split("/");
|
|
37
|
+
if (parts.length <= 2) return filePath;
|
|
38
|
+
return ".../" + parts.slice(-2).join("/");
|
|
39
|
+
}
|
|
40
|
+
function truncateCommand(command, maxLength) {
|
|
41
|
+
const normalized = command.replace(/\s+/g, " ").trim();
|
|
42
|
+
if (normalized.length <= maxLength) return normalized;
|
|
43
|
+
return normalized.slice(0, maxLength - 1) + "...";
|
|
44
|
+
}
|
|
45
|
+
function hasSummaryContent(summary) {
|
|
46
|
+
return summary.filesRead.length > 0 || summary.filesModified.length > 0 || summary.filesCreated.length > 0 || summary.commandsRun.length > 0 || summary.tasksCompleted > 0 || summary.webSearches > 0;
|
|
47
|
+
}
|
|
48
|
+
const OperationSummary = memo(function OperationSummary2({
|
|
49
|
+
summary,
|
|
50
|
+
showUndo = false,
|
|
51
|
+
maxFilesToShow = 3,
|
|
52
|
+
maxCommandsToShow = 5
|
|
53
|
+
}) {
|
|
54
|
+
if (!hasSummaryContent(summary)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const totalModifiedStats = summary.filesModified.reduce(
|
|
58
|
+
(acc, file) => ({
|
|
59
|
+
added: acc.added + file.added,
|
|
60
|
+
removed: acc.removed + file.removed
|
|
61
|
+
}),
|
|
62
|
+
{ added: 0, removed: 0 }
|
|
63
|
+
);
|
|
64
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.brand, bold: true }, "Session Summary"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, summary.filesRead.length > 0 && /* @__PURE__ */ React.createElement(
|
|
65
|
+
Section,
|
|
66
|
+
{
|
|
67
|
+
icon: "[read]",
|
|
68
|
+
title: "Files read:",
|
|
69
|
+
count: summary.filesRead.length
|
|
70
|
+
},
|
|
71
|
+
/* @__PURE__ */ React.createElement(FileList, { files: summary.filesRead, maxToShow: maxFilesToShow })
|
|
72
|
+
), summary.filesModified.length > 0 && /* @__PURE__ */ React.createElement(
|
|
73
|
+
Section,
|
|
74
|
+
{
|
|
75
|
+
icon: "[edit]",
|
|
76
|
+
title: "Files modified:",
|
|
77
|
+
count: summary.filesModified.length,
|
|
78
|
+
hint: showUndo ? `/undo to revert${totalModifiedStats.added > 0 || totalModifiedStats.removed > 0 ? ` | +${totalModifiedStats.added}/-${totalModifiedStats.removed}` : ""}` : totalModifiedStats.added > 0 || totalModifiedStats.removed > 0 ? `+${totalModifiedStats.added}/-${totalModifiedStats.removed}` : void 0
|
|
79
|
+
},
|
|
80
|
+
/* @__PURE__ */ React.createElement(
|
|
81
|
+
ModifiedFileList,
|
|
82
|
+
{
|
|
83
|
+
files: summary.filesModified,
|
|
84
|
+
maxToShow: maxFilesToShow
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
), summary.filesCreated.length > 0 && /* @__PURE__ */ React.createElement(
|
|
88
|
+
Section,
|
|
89
|
+
{
|
|
90
|
+
icon: "[new]",
|
|
91
|
+
title: "Files created:",
|
|
92
|
+
count: summary.filesCreated.length
|
|
93
|
+
},
|
|
94
|
+
/* @__PURE__ */ React.createElement(FileList, { files: summary.filesCreated, maxToShow: maxFilesToShow })
|
|
95
|
+
), summary.commandsRun.length > 0 && /* @__PURE__ */ React.createElement(
|
|
96
|
+
Section,
|
|
97
|
+
{
|
|
98
|
+
icon: "[cmd]",
|
|
99
|
+
title: "Commands run:",
|
|
100
|
+
count: summary.commandsRun.length
|
|
101
|
+
},
|
|
102
|
+
/* @__PURE__ */ React.createElement(
|
|
103
|
+
CommandList,
|
|
104
|
+
{
|
|
105
|
+
commands: summary.commandsRun,
|
|
106
|
+
maxToShow: maxCommandsToShow
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
), summary.tasksCompleted > 0 && /* @__PURE__ */ React.createElement(
|
|
110
|
+
Section,
|
|
111
|
+
{
|
|
112
|
+
icon: "[task]",
|
|
113
|
+
title: "Tasks completed:",
|
|
114
|
+
count: summary.tasksCompleted
|
|
115
|
+
}
|
|
116
|
+
), summary.webSearches > 0 && /* @__PURE__ */ React.createElement(
|
|
117
|
+
Section,
|
|
118
|
+
{
|
|
119
|
+
icon: "[web]",
|
|
120
|
+
title: "Web searches:",
|
|
121
|
+
count: summary.webSearches
|
|
122
|
+
}
|
|
123
|
+
)));
|
|
124
|
+
});
|
|
125
|
+
var OperationSummary_default = OperationSummary;
|
|
126
|
+
export {
|
|
127
|
+
OperationSummary,
|
|
128
|
+
OperationSummary_default as default
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=OperationSummary.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/components/OperationSummary.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * Operation Summary Component\n *\n * Displays a summary of operations performed during a session.\n * Shows files read, modified, created, and commands run in a compact format.\n *\n * Usage:\n * ```tsx\n * import { OperationSummary } from '@components/OperationSummary'\n * import { getOperationSummary } from '@core/operationTracker'\n *\n * const summary = getOperationSummary()\n * <OperationSummary summary={summary} showUndo={true} />\n * ```\n */\n\nimport React, { memo } from 'react'\nimport { Box, Text } from 'ink'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport type { OperationSummary as OperationSummaryType } from '@core/operationTracker'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface OperationSummaryProps {\n /** Aggregated summary of operations */\n summary: OperationSummaryType\n\n /** Show /undo hint when true (for file modifications) */\n showUndo?: boolean\n\n /** Maximum number of files to show in each category */\n maxFilesToShow?: number\n\n /** Maximum number of commands to show */\n maxCommandsToShow?: number\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\ninterface SectionProps {\n icon: string\n title: string\n count: number\n hint?: string\n children?: React.ReactNode\n}\n\n/**\n * Section header with icon, title, count, and optional hint\n */\nconst Section = memo(function Section({\n icon,\n title,\n count,\n hint,\n children,\n}: SectionProps) {\n if (count === 0) return null\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text color={SEMANTIC_COLORS.secondary}>{icon} </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{title}</Text>\n <Text color={SEMANTIC_COLORS.brand}> {count}</Text>\n {hint && <Text color={SEMANTIC_COLORS.muted}> ({hint})</Text>}\n </Box>\n {children}\n </Box>\n )\n})\n\ninterface FileListProps {\n files: string[]\n maxToShow: number\n}\n\n/**\n * List of file paths with truncation\n */\nconst FileList = memo(function FileList({ files, maxToShow }: FileListProps) {\n const displayFiles = files.slice(0, maxToShow)\n const remaining = files.length - maxToShow\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n {displayFiles.map((file, idx) => (\n <React.Fragment key={`${file}-${idx}`}>\n <Text color={SEMANTIC_COLORS.dim}>{formatFilePath(file)}</Text>\n </React.Fragment>\n ))}\n {remaining > 0 && (\n <Text color={SEMANTIC_COLORS.muted}>...and {remaining} more</Text>\n )}\n </Box>\n )\n})\n\ninterface ModifiedFileListProps {\n files: { path: string; added: number; removed: number }[]\n maxToShow: number\n}\n\n/**\n * List of modified files with +added/-removed stats\n */\nconst ModifiedFileList = memo(function ModifiedFileList({\n files,\n maxToShow,\n}: ModifiedFileListProps) {\n const displayFiles = files.slice(0, maxToShow)\n const remaining = files.length - maxToShow\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n {displayFiles.map((file, idx) => (\n <Box key={`${file.path}-${idx}`} flexDirection=\"row\">\n <Text color={SEMANTIC_COLORS.dim}>{formatFilePath(file.path)} </Text>\n {(file.added > 0 || file.removed > 0) && (\n <Text color={SEMANTIC_COLORS.muted}>\n (\n {file.added > 0 && (\n <Text color={SEMANTIC_COLORS.success}>+{file.added}</Text>\n )}\n {file.added > 0 && file.removed > 0 && <Text>/</Text>}\n {file.removed > 0 && (\n <Text color={SEMANTIC_COLORS.error}>-{file.removed}</Text>\n )}\n )\n </Text>\n )}\n </Box>\n ))}\n {remaining > 0 && (\n <Text color={SEMANTIC_COLORS.muted}>...and {remaining} more</Text>\n )}\n </Box>\n )\n})\n\ninterface CommandListProps {\n commands: string[]\n maxToShow: number\n}\n\n/**\n * List of commands with truncation\n */\nconst CommandList = memo(function CommandList({\n commands,\n maxToShow,\n}: CommandListProps) {\n const displayCommands = commands.slice(0, maxToShow)\n const remaining = commands.length - maxToShow\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n {displayCommands.map((cmd, idx) => (\n <React.Fragment key={`cmd-${idx}`}>\n <Text color={SEMANTIC_COLORS.dim}>{truncateCommand(cmd, 60)}</Text>\n </React.Fragment>\n ))}\n {remaining > 0 && (\n <Text color={SEMANTIC_COLORS.muted}>...and {remaining} more</Text>\n )}\n </Box>\n )\n})\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Format a file path for display\n * Shows only the last 2 path components for brevity\n */\nfunction formatFilePath(filePath: string): string {\n const parts = filePath.split('/')\n if (parts.length <= 2) return filePath\n return '.../' + parts.slice(-2).join('/')\n}\n\n/**\n * Truncate a command string for display\n */\nfunction truncateCommand(command: string, maxLength: number): string {\n // Remove newlines and normalize whitespace\n const normalized = command.replace(/\\s+/g, ' ').trim()\n if (normalized.length <= maxLength) return normalized\n return normalized.slice(0, maxLength - 1) + '...'\n}\n\n/**\n * Check if summary has any operations\n */\nfunction hasSummaryContent(summary: OperationSummaryType): boolean {\n return (\n summary.filesRead.length > 0 ||\n summary.filesModified.length > 0 ||\n summary.filesCreated.length > 0 ||\n summary.commandsRun.length > 0 ||\n summary.tasksCompleted > 0 ||\n summary.webSearches > 0\n )\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Operation Summary Component\n *\n * Displays a compact summary of all operations performed during a session.\n */\nexport const OperationSummary = memo(function OperationSummary({\n summary,\n showUndo = false,\n maxFilesToShow = 3,\n maxCommandsToShow = 5,\n}: OperationSummaryProps) {\n // Don't render if no operations\n if (!hasSummaryContent(summary)) {\n return null\n }\n\n const totalModifiedStats = summary.filesModified.reduce(\n (acc, file) => ({\n added: acc.added + file.added,\n removed: acc.removed + file.removed,\n }),\n { added: 0, removed: 0 },\n )\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {/* Header */}\n <Text color={SEMANTIC_COLORS.brand} bold>\n Session Summary\n </Text>\n\n <Box flexDirection=\"column\" marginTop={1}>\n {/* Files Read */}\n {summary.filesRead.length > 0 && (\n <Section\n icon=\"[read]\"\n title=\"Files read:\"\n count={summary.filesRead.length}\n >\n <FileList files={summary.filesRead} maxToShow={maxFilesToShow} />\n </Section>\n )}\n\n {/* Files Modified */}\n {summary.filesModified.length > 0 && (\n <Section\n icon=\"[edit]\"\n title=\"Files modified:\"\n count={summary.filesModified.length}\n hint={\n showUndo\n ? `/undo to revert${totalModifiedStats.added > 0 || totalModifiedStats.removed > 0 ? ` | +${totalModifiedStats.added}/-${totalModifiedStats.removed}` : ''}`\n : totalModifiedStats.added > 0 || totalModifiedStats.removed > 0\n ? `+${totalModifiedStats.added}/-${totalModifiedStats.removed}`\n : undefined\n }\n >\n <ModifiedFileList\n files={summary.filesModified}\n maxToShow={maxFilesToShow}\n />\n </Section>\n )}\n\n {/* Files Created */}\n {summary.filesCreated.length > 0 && (\n <Section\n icon=\"[new]\"\n title=\"Files created:\"\n count={summary.filesCreated.length}\n >\n <FileList files={summary.filesCreated} maxToShow={maxFilesToShow} />\n </Section>\n )}\n\n {/* Commands Run */}\n {summary.commandsRun.length > 0 && (\n <Section\n icon=\"[cmd]\"\n title=\"Commands run:\"\n count={summary.commandsRun.length}\n >\n <CommandList\n commands={summary.commandsRun}\n maxToShow={maxCommandsToShow}\n />\n </Section>\n )}\n\n {/* Tasks Completed */}\n {summary.tasksCompleted > 0 && (\n <Section\n icon=\"[task]\"\n title=\"Tasks completed:\"\n count={summary.tasksCompleted}\n />\n )}\n\n {/* Web Searches */}\n {summary.webSearches > 0 && (\n <Section\n icon=\"[web]\"\n title=\"Web searches:\"\n count={summary.webSearches}\n />\n )}\n </Box>\n </Box>\n )\n})\n\nexport default OperationSummary\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Section", "FileList", "ModifiedFileList", "CommandList", "OperationSummary"]
|
|
7
|
+
}
|
|
@@ -17,6 +17,7 @@ import { SentryErrorBoundary } from "./SentryErrorBoundary.js";
|
|
|
17
17
|
import { TokenWarning, WARNING_THRESHOLD } from "./TokenWarning.js";
|
|
18
18
|
import { useTerminalSize } from "../hooks/useTerminalSize.js";
|
|
19
19
|
import { getTheme } from "../utils/theme.js";
|
|
20
|
+
import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../constants/colors.js";
|
|
20
21
|
import { getModelManager } from "../utils/model.js";
|
|
21
22
|
import {
|
|
22
23
|
getGlobalConfig,
|
|
@@ -117,6 +118,7 @@ function PromptInput({
|
|
|
117
118
|
const [ctrlDTimer, setCtrlDTimer] = useState(null);
|
|
118
119
|
const [escCount, setEscCount] = useState(0);
|
|
119
120
|
const [escTimer, setEscTimer] = useState(null);
|
|
121
|
+
const ESC_DOUBLE_TAP_WINDOW = 500;
|
|
120
122
|
const [hotkeyMessage, setHotkeyMessage] = useState({ show: false });
|
|
121
123
|
useEffect(() => {
|
|
122
124
|
if (verboseToggleMessage) {
|
|
@@ -176,10 +178,10 @@ function PromptInput({
|
|
|
176
178
|
if (suggestions.length === 0) return null;
|
|
177
179
|
const hasMoreAbove = visibleSuggestions.length > 0 && visibleSuggestions[0].globalIndex > 0;
|
|
178
180
|
const hasMoreBelow = visibleSuggestions.length > 0 && visibleSuggestions[visibleSuggestions.length - 1].globalIndex < suggestions.length - 1;
|
|
179
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, hasMoreAbove && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, {
|
|
181
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, hasMoreAbove && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "\u2191 ", visibleSuggestions[0].globalIndex, " more above...")), visibleSuggestions.map((suggestion) => {
|
|
180
182
|
const isSelected = suggestion.globalIndex === selectedIndex;
|
|
181
183
|
const isAgent = suggestion.type === "agent";
|
|
182
|
-
const displayColor = isSelected ?
|
|
184
|
+
const displayColor = isSelected ? BRAND_GRADIENT.START : isAgent && suggestion.metadata?.color ? suggestion.metadata.color : void 0;
|
|
183
185
|
return /* @__PURE__ */ React.createElement(
|
|
184
186
|
Box,
|
|
185
187
|
{
|
|
@@ -189,14 +191,13 @@ function PromptInput({
|
|
|
189
191
|
/* @__PURE__ */ React.createElement(
|
|
190
192
|
Text,
|
|
191
193
|
{
|
|
192
|
-
color: displayColor
|
|
193
|
-
dimColor: !isSelected && !displayColor
|
|
194
|
+
color: displayColor || (!isSelected ? SEMANTIC_COLORS.dim : void 0)
|
|
194
195
|
},
|
|
195
196
|
isSelected ? "\u25C6 " : " ",
|
|
196
197
|
suggestion.displayValue
|
|
197
198
|
)
|
|
198
199
|
);
|
|
199
|
-
}), hasMoreBelow && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, {
|
|
200
|
+
}), hasMoreBelow && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "\u2193", " ", suggestions.length - visibleSuggestions[visibleSuggestions.length - 1].globalIndex - 1, " ", "more below...")));
|
|
200
201
|
}, [suggestions, selectedIndex, visibleSuggestions, theme.suggestion]);
|
|
201
202
|
const onChange = useCallback(
|
|
202
203
|
(value) => {
|
|
@@ -649,37 +650,6 @@ function PromptInput({
|
|
|
649
650
|
if (inputChar === "" && (key.escape || key.backspace || key.delete)) {
|
|
650
651
|
onModeChange("prompt");
|
|
651
652
|
}
|
|
652
|
-
if (key.escape && !input && !isLoading && messages.length > 0 && onRollbackConversation) {
|
|
653
|
-
setEscCount((prev) => prev + 1);
|
|
654
|
-
if (escTimer) clearTimeout(escTimer);
|
|
655
|
-
const timer = setTimeout(() => setEscCount(0), 1e3);
|
|
656
|
-
setEscTimer(timer);
|
|
657
|
-
if (escCount >= 1) {
|
|
658
|
-
const success = onRollbackConversation();
|
|
659
|
-
if (success) {
|
|
660
|
-
setMessage({
|
|
661
|
-
show: true,
|
|
662
|
-
text: "Conversation rolled back (Esc Esc)"
|
|
663
|
-
});
|
|
664
|
-
setTimeout(() => setMessage({ show: false }), 2e3);
|
|
665
|
-
} else {
|
|
666
|
-
setMessage({ show: true, text: "No history to rollback" });
|
|
667
|
-
setTimeout(() => setMessage({ show: false }), 2e3);
|
|
668
|
-
}
|
|
669
|
-
setEscCount(0);
|
|
670
|
-
return true;
|
|
671
|
-
} else {
|
|
672
|
-
setMessage({
|
|
673
|
-
show: true,
|
|
674
|
-
text: "Press Esc again to rollback conversation"
|
|
675
|
-
});
|
|
676
|
-
setTimeout(() => setMessage({ show: false }), 2e3);
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
if (key.escape && messages.length > 0 && !input && !isLoading) {
|
|
681
|
-
onShowMessageSelector();
|
|
682
|
-
}
|
|
683
653
|
if (key.tab && !key.shift && !completionActive) {
|
|
684
654
|
const config = getGlobalConfig();
|
|
685
655
|
const newThinking = !config.thinking;
|
|
@@ -709,18 +679,40 @@ function PromptInput({
|
|
|
709
679
|
return true;
|
|
710
680
|
}
|
|
711
681
|
if (key.escape) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
text: "
|
|
722
|
-
|
|
723
|
-
|
|
682
|
+
const newEscCount = escCount + 1;
|
|
683
|
+
setEscCount(newEscCount);
|
|
684
|
+
if (escTimer) clearTimeout(escTimer);
|
|
685
|
+
const timer = setTimeout(() => setEscCount(0), ESC_DOUBLE_TAP_WINDOW);
|
|
686
|
+
setEscTimer(timer);
|
|
687
|
+
if (newEscCount >= 2) {
|
|
688
|
+
setEscCount(0);
|
|
689
|
+
if (input.length > 0) {
|
|
690
|
+
onInputChange("");
|
|
691
|
+
setHotkeyMessage({ show: true, text: "Input cleared (Esc Esc)" });
|
|
692
|
+
setTimeout(() => setHotkeyMessage({ show: false }), 1e3);
|
|
693
|
+
return true;
|
|
694
|
+
} else if (isLoading && onInterrupt) {
|
|
695
|
+
onInterrupt();
|
|
696
|
+
setHotkeyMessage({
|
|
697
|
+
show: true,
|
|
698
|
+
text: "Interrupted by user (Esc Esc)"
|
|
699
|
+
});
|
|
700
|
+
setTimeout(() => setHotkeyMessage({ show: false }), 2e3);
|
|
701
|
+
return true;
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
if (input.length > 0) {
|
|
705
|
+
setHotkeyMessage({
|
|
706
|
+
show: true,
|
|
707
|
+
text: "Press Esc again to clear input"
|
|
708
|
+
});
|
|
709
|
+
} else if (isLoading) {
|
|
710
|
+
setHotkeyMessage({
|
|
711
|
+
show: true,
|
|
712
|
+
text: "Press Esc again to interrupt"
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
setTimeout(() => setHotkeyMessage({ show: false }), 1500);
|
|
724
716
|
return true;
|
|
725
717
|
}
|
|
726
718
|
}
|
|
@@ -731,7 +723,9 @@ function PromptInput({
|
|
|
731
723
|
isLoading,
|
|
732
724
|
input.length,
|
|
733
725
|
onInputChange,
|
|
734
|
-
onInterrupt
|
|
726
|
+
onInterrupt,
|
|
727
|
+
escCount,
|
|
728
|
+
escTimer
|
|
735
729
|
]
|
|
736
730
|
);
|
|
737
731
|
const tokenUsage = useMemo(() => countTokens(messages), [messages]);
|
|
@@ -754,7 +748,7 @@ function PromptInput({
|
|
|
754
748
|
currentTokens: tokenUsage
|
|
755
749
|
};
|
|
756
750
|
}, [tokenUsage, modelSwitchMessage.show, submitCount, currentModelId]);
|
|
757
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, fallbackMode && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color:
|
|
751
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, fallbackMode && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "\u26A0\uFE0F Limited input mode"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "(Advanced keyboard shortcuts unavailable - raw mode not supported)")), showHotkeyHelp && /* @__PURE__ */ React.createElement(
|
|
758
752
|
HotkeyHelpPanel,
|
|
759
753
|
{
|
|
760
754
|
isVisible: showHotkeyHelp,
|
|
@@ -767,7 +761,7 @@ function PromptInput({
|
|
|
767
761
|
results: historySearch.filteredResults,
|
|
768
762
|
selectedIndex: historySearch.selectedIndex
|
|
769
763
|
}
|
|
770
|
-
), modelInfo && /* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-end", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, {
|
|
764
|
+
), modelInfo && /* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-end", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "\u25C6"), " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, modelInfo.name), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "\xB7 ", Math.round(modelInfo.currentTokens / 1e3), "k /", " ", Math.round(modelInfo.contextLength / 1e3), "k"))), queuedPrompts.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.MIDDLE }, "\u2500\u2500 Queued (", queuedPrompts.length, ")"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "\xB7 will run after current task \xB7", " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, "\u2191"), " to edit \u2500\u2500")), queuedPrompts.map((prompt, index) => /* @__PURE__ */ React.createElement(Box, { key: index, paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "\u25C7 "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, prompt.length > 60 ? prompt.slice(0, 60) + "..." : prompt)))), /* @__PURE__ */ React.createElement(
|
|
771
765
|
Box,
|
|
772
766
|
{
|
|
773
767
|
alignItems: "flex-start",
|
|
@@ -776,7 +770,7 @@ function PromptInput({
|
|
|
776
770
|
borderBottom: true,
|
|
777
771
|
borderLeft: false,
|
|
778
772
|
borderRight: false,
|
|
779
|
-
borderColor: mode === "bash" ?
|
|
773
|
+
borderColor: mode === "bash" ? SEMANTIC_COLORS.running : mode === "koding" ? SEMANTIC_COLORS.info : BRAND_GRADIENT.START,
|
|
780
774
|
borderDimColor: false,
|
|
781
775
|
borderStyle: "single",
|
|
782
776
|
marginTop: queuedPrompts.length > 0 ? 0 : 1,
|
|
@@ -791,7 +785,14 @@ function PromptInput({
|
|
|
791
785
|
justifyContent: "flex-start",
|
|
792
786
|
width: 3
|
|
793
787
|
},
|
|
794
|
-
mode === "bash" ? /* @__PURE__ */ React.createElement(Text, { color:
|
|
788
|
+
mode === "bash" ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "\xA0!\xA0") : mode === "koding" ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.info }, "\xA0#\xA0") : /* @__PURE__ */ React.createElement(
|
|
789
|
+
Text,
|
|
790
|
+
{
|
|
791
|
+
color: isLoading ? SEMANTIC_COLORS.dim : BRAND_GRADIENT.START,
|
|
792
|
+
bold: true
|
|
793
|
+
},
|
|
794
|
+
"\xA0\u276F\xA0"
|
|
795
|
+
)
|
|
795
796
|
),
|
|
796
797
|
/* @__PURE__ */ React.createElement(Box, { paddingRight: 1 }, /* @__PURE__ */ React.createElement(
|
|
797
798
|
TextInput,
|
|
@@ -826,56 +827,69 @@ function PromptInput({
|
|
|
826
827
|
paddingX: 2,
|
|
827
828
|
paddingY: 0
|
|
828
829
|
},
|
|
829
|
-
/* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-start", gap: 1 }, exitMessage.show ? /* @__PURE__ */ React.createElement(Text, {
|
|
830
|
-
// Verbose mode: full static hints
|
|
830
|
+
/* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-start", gap: 1 }, exitMessage.show ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press", " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, exitMessage.key), " ", "again to exit") : message.show ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, message.text) : hotkeyMessage.show ? /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, hotkeyMessage.text) : modelSwitchMessage.show ? /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, modelSwitchMessage.text) : verbose ? (
|
|
831
|
+
// Verbose mode: full static hints (商务用户友好) - 使用品牌配色
|
|
831
832
|
/* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
832
833
|
Text,
|
|
833
834
|
{
|
|
834
|
-
color: mode === "bash" ?
|
|
835
|
-
dimColor: mode !== "bash"
|
|
835
|
+
color: mode === "bash" ? BRAND_GRADIENT.MIDDLE : SEMANTIC_COLORS.dim
|
|
836
836
|
},
|
|
837
|
-
|
|
837
|
+
/* @__PURE__ */ React.createElement(
|
|
838
|
+
Text,
|
|
839
|
+
{
|
|
840
|
+
color: mode === "bash" ? BRAND_GRADIENT.MIDDLE : SEMANTIC_COLORS.secondary
|
|
841
|
+
},
|
|
842
|
+
"!"
|
|
843
|
+
),
|
|
844
|
+
" ",
|
|
845
|
+
"\u6267\u884C\u547D\u4EE4"
|
|
838
846
|
), /* @__PURE__ */ React.createElement(
|
|
839
847
|
Text,
|
|
840
848
|
{
|
|
841
|
-
color: mode === "koding" ?
|
|
842
|
-
dimColor: mode !== "koding"
|
|
849
|
+
color: mode === "koding" ? SEMANTIC_COLORS.info : SEMANTIC_COLORS.dim
|
|
843
850
|
},
|
|
844
|
-
"\xB7
|
|
845
|
-
|
|
846
|
-
|
|
851
|
+
"\xB7",
|
|
852
|
+
" ",
|
|
853
|
+
/* @__PURE__ */ React.createElement(
|
|
854
|
+
Text,
|
|
855
|
+
{
|
|
856
|
+
color: mode === "koding" ? SEMANTIC_COLORS.info : SEMANTIC_COLORS.secondary
|
|
857
|
+
},
|
|
858
|
+
"#"
|
|
859
|
+
),
|
|
860
|
+
" ",
|
|
861
|
+
"\u8BB0\u5F55\u7B14\u8BB0"
|
|
862
|
+
), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\xB7 ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, "/"), " \u529F\u80FD\u83DC\u5355 \xB7", " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, "ctrl+?"), " \u5E2E\u52A9"), backgroundShellCount > 0 && /* @__PURE__ */ React.createElement(
|
|
847
863
|
Text,
|
|
848
864
|
{
|
|
849
|
-
color: backgroundIndicatorFocused ?
|
|
850
|
-
backgroundColor: backgroundIndicatorFocused ?
|
|
851
|
-
dimColor: !backgroundIndicatorFocused
|
|
865
|
+
color: backgroundIndicatorFocused ? BRAND_GRADIENT.START : BRAND_GRADIENT.MIDDLE,
|
|
866
|
+
backgroundColor: backgroundIndicatorFocused ? BRAND_GRADIENT.START : void 0
|
|
852
867
|
},
|
|
853
868
|
"\xB7 ",
|
|
854
869
|
backgroundIndicatorFocused ? "\u25BA " : "",
|
|
855
870
|
backgroundShellCount,
|
|
856
871
|
" background task",
|
|
857
872
|
backgroundShellCount > 1 ? "s" : ""
|
|
858
|
-
), queuedPrompts.length > 0 && /* @__PURE__ */ React.createElement(Text, { color:
|
|
873
|
+
), queuedPrompts.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.MIDDLE }, "\xB7 \u{1F4CB} ", queuedPrompts.length, " queued"))
|
|
859
874
|
) : (
|
|
860
875
|
// Normal mode: context-aware hints with 0.1.7 style
|
|
861
876
|
/* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ContextAwareHints, { context: inputContext, compact: true }), backgroundShellCount > 0 && /* @__PURE__ */ React.createElement(
|
|
862
877
|
Text,
|
|
863
878
|
{
|
|
864
|
-
color: backgroundIndicatorFocused ?
|
|
865
|
-
backgroundColor: backgroundIndicatorFocused ?
|
|
866
|
-
dimColor: !backgroundIndicatorFocused
|
|
879
|
+
color: backgroundIndicatorFocused ? BRAND_GRADIENT.START : BRAND_GRADIENT.MIDDLE,
|
|
880
|
+
backgroundColor: backgroundIndicatorFocused ? BRAND_GRADIENT.START : void 0
|
|
867
881
|
},
|
|
868
882
|
"\u2502 ",
|
|
869
883
|
backgroundIndicatorFocused ? "\u25BA " : "",
|
|
870
884
|
backgroundShellCount,
|
|
871
885
|
" task",
|
|
872
886
|
backgroundShellCount > 1 ? "s" : ""
|
|
873
|
-
), queuedPrompts.length > 0 && /* @__PURE__ */ React.createElement(Text, { color:
|
|
887
|
+
), queuedPrompts.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.MIDDLE }, "\u2502 \u{1F4CB} ", queuedPrompts.length, " queued"), isLoading && onQueuePrompt && queuedPrompts.length === 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u2502 Type to queue next prompt"))
|
|
874
888
|
)),
|
|
875
889
|
/* @__PURE__ */ React.createElement(
|
|
876
890
|
SentryErrorBoundary,
|
|
877
891
|
{
|
|
878
|
-
children: /* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-end", gap: 1 }, !debug && tokenUsage < WARNING_THRESHOLD && /* @__PURE__ */ React.createElement(Text, {
|
|
892
|
+
children: /* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-end", gap: 1 }, !debug && tokenUsage < WARNING_THRESHOLD && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, terminalSetup.isEnabled && isShiftEnterKeyBindingInstalled() ? "shift + \u23CE" : "\\\u23CE"), " ", "for newline"), /* @__PURE__ */ React.createElement(TokenWarning, { tokenUsage }))
|
|
879
893
|
}
|
|
880
894
|
)
|
|
881
895
|
), suggestions.length > 0 && /* @__PURE__ */ React.createElement(
|
|
@@ -892,13 +906,12 @@ function PromptInput({
|
|
|
892
906
|
marginTop: 1,
|
|
893
907
|
paddingX: 3,
|
|
894
908
|
borderStyle: "round",
|
|
895
|
-
borderColor:
|
|
909
|
+
borderColor: BRAND_GRADIENT.START
|
|
896
910
|
},
|
|
897
911
|
/* @__PURE__ */ React.createElement(
|
|
898
912
|
Text,
|
|
899
913
|
{
|
|
900
|
-
|
|
901
|
-
color: emptyDirMessage ? "yellow" : void 0
|
|
914
|
+
color: emptyDirMessage ? BRAND_GRADIENT.END : SEMANTIC_COLORS.dim
|
|
902
915
|
},
|
|
903
916
|
emptyDirMessage || (() => {
|
|
904
917
|
const selected = suggestions[selectedIndex];
|