@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.
Files changed (254) hide show
  1. package/dist/commands/agents/AgentsCommand.js +22 -24
  2. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  3. package/dist/commands/context.js +2 -1
  4. package/dist/commands/context.js.map +2 -2
  5. package/dist/commands/export.js +2 -1
  6. package/dist/commands/export.js.map +2 -2
  7. package/dist/commands/mcp-interactive.js +7 -6
  8. package/dist/commands/mcp-interactive.js.map +2 -2
  9. package/dist/commands/model.js +3 -2
  10. package/dist/commands/model.js.map +2 -2
  11. package/dist/commands/permissions.js +4 -3
  12. package/dist/commands/permissions.js.map +2 -2
  13. package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
  14. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  15. package/dist/commands/plugin/ConfirmDialog.js +2 -1
  16. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  17. package/dist/commands/plugin/ErrorView.js +2 -1
  18. package/dist/commands/plugin/ErrorView.js.map +2 -2
  19. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
  20. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  21. package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
  22. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  23. package/dist/commands/plugin/MainMenu.js +2 -1
  24. package/dist/commands/plugin/MainMenu.js.map +2 -2
  25. package/dist/commands/plugin/MarketplaceManager.js +5 -4
  26. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  27. package/dist/commands/plugin/MarketplaceSelector.js +4 -3
  28. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  29. package/dist/commands/plugin/PlaceholderScreen.js +3 -2
  30. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  31. package/dist/commands/plugin/PluginBrowser.js +6 -5
  32. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  33. package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
  34. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  35. package/dist/commands/plugin/PluginDetailsManage.js +4 -3
  36. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  37. package/dist/commands/plugin.js +16 -15
  38. package/dist/commands/plugin.js.map +2 -2
  39. package/dist/commands/sandbox.js +4 -3
  40. package/dist/commands/sandbox.js.map +2 -2
  41. package/dist/commands/setup.js +2 -1
  42. package/dist/commands/setup.js.map +2 -2
  43. package/dist/commands/status.js +2 -1
  44. package/dist/commands/status.js.map +2 -2
  45. package/dist/commands/undo.js +245 -0
  46. package/dist/commands/undo.js.map +7 -0
  47. package/dist/commands.js +2 -0
  48. package/dist/commands.js.map +2 -2
  49. package/dist/components/AgentThinkingBlock.js +1 -1
  50. package/dist/components/AgentThinkingBlock.js.map +2 -2
  51. package/dist/components/AsciiLogo.js +7 -8
  52. package/dist/components/AsciiLogo.js.map +2 -2
  53. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  54. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  55. package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
  56. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  57. package/dist/components/CollapsibleHint.js +2 -1
  58. package/dist/components/CollapsibleHint.js.map +2 -2
  59. package/dist/components/Config.js +3 -2
  60. package/dist/components/Config.js.map +2 -2
  61. package/dist/components/ConsoleOAuthFlow.js +2 -1
  62. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  63. package/dist/components/Cost.js +2 -1
  64. package/dist/components/Cost.js.map +2 -2
  65. package/dist/components/HeaderBar.js +13 -8
  66. package/dist/components/HeaderBar.js.map +2 -2
  67. package/dist/components/HistorySearchOverlay.js +4 -3
  68. package/dist/components/HistorySearchOverlay.js.map +2 -2
  69. package/dist/components/HotkeyHelpPanel.js +8 -11
  70. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  71. package/dist/components/InvalidConfigDialog.js +2 -1
  72. package/dist/components/InvalidConfigDialog.js.map +2 -2
  73. package/dist/components/Logo.js +23 -67
  74. package/dist/components/Logo.js.map +2 -2
  75. package/dist/components/MCPServerApprovalDialog.js +2 -1
  76. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  77. package/dist/components/MCPServerDialogCopy.js +2 -1
  78. package/dist/components/MCPServerDialogCopy.js.map +2 -2
  79. package/dist/components/MCPServerMultiselectDialog.js +2 -1
  80. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  81. package/dist/components/MessageSelector.js +4 -3
  82. package/dist/components/MessageSelector.js.map +2 -2
  83. package/dist/components/ModeIndicator.js +2 -1
  84. package/dist/components/ModeIndicator.js.map +2 -2
  85. package/dist/components/ModelConfig.js +4 -3
  86. package/dist/components/ModelConfig.js.map +2 -2
  87. package/dist/components/ModelListManager.js +4 -3
  88. package/dist/components/ModelListManager.js.map +2 -2
  89. package/dist/components/ModelSelector/ModelSelector.js +26 -13
  90. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  91. package/dist/components/Onboarding.js +3 -2
  92. package/dist/components/Onboarding.js.map +2 -2
  93. package/dist/components/OperationSummary.js +130 -0
  94. package/dist/components/OperationSummary.js.map +7 -0
  95. package/dist/components/PromptInput.js +88 -75
  96. package/dist/components/PromptInput.js.map +2 -2
  97. package/dist/components/SensitiveFileWarning.js +31 -0
  98. package/dist/components/SensitiveFileWarning.js.map +7 -0
  99. package/dist/components/Spinner.js +71 -22
  100. package/dist/components/Spinner.js.map +2 -2
  101. package/dist/components/StructuredDiff.js +6 -8
  102. package/dist/components/StructuredDiff.js.map +2 -2
  103. package/dist/components/SubagentBlock.js +4 -2
  104. package/dist/components/SubagentBlock.js.map +2 -2
  105. package/dist/components/SubagentProgress.js +7 -4
  106. package/dist/components/SubagentProgress.js.map +2 -2
  107. package/dist/components/TaskCard.js +14 -11
  108. package/dist/components/TaskCard.js.map +2 -2
  109. package/dist/components/TextInput.js +9 -1
  110. package/dist/components/TextInput.js.map +2 -2
  111. package/dist/components/TodoPanel.js +44 -26
  112. package/dist/components/TodoPanel.js.map +2 -2
  113. package/dist/components/ToolUseLoader.js +2 -2
  114. package/dist/components/ToolUseLoader.js.map +2 -2
  115. package/dist/components/TreeConnector.js +4 -3
  116. package/dist/components/TreeConnector.js.map +2 -2
  117. package/dist/components/TrustDialog.js +2 -1
  118. package/dist/components/TrustDialog.js.map +2 -2
  119. package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
  120. package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
  121. package/dist/components/messages/AssistantTextMessage.js +17 -9
  122. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  123. package/dist/components/messages/AssistantToolUseMessage.js +8 -4
  124. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  125. package/dist/components/messages/GroupRenderer.js +2 -1
  126. package/dist/components/messages/GroupRenderer.js.map +2 -2
  127. package/dist/components/messages/NestedTasksPreview.js +13 -1
  128. package/dist/components/messages/NestedTasksPreview.js.map +2 -2
  129. package/dist/components/messages/ParallelTasksGroupView.js +4 -3
  130. package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
  131. package/dist/components/messages/TaskInModuleView.js +35 -15
  132. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  133. package/dist/components/messages/TaskOutputContent.js +9 -6
  134. package/dist/components/messages/TaskOutputContent.js.map +2 -2
  135. package/dist/components/messages/UserPromptMessage.js +2 -2
  136. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  137. package/dist/constants/colors.js +90 -72
  138. package/dist/constants/colors.js.map +2 -2
  139. package/dist/constants/toolInputExamples.js +84 -0
  140. package/dist/constants/toolInputExamples.js.map +7 -0
  141. package/dist/core/backupManager.js +321 -0
  142. package/dist/core/backupManager.js.map +7 -0
  143. package/dist/core/costTracker.js +9 -18
  144. package/dist/core/costTracker.js.map +2 -2
  145. package/dist/core/gitAutoCommit.js +287 -0
  146. package/dist/core/gitAutoCommit.js.map +7 -0
  147. package/dist/core/index.js +3 -0
  148. package/dist/core/index.js.map +2 -2
  149. package/dist/core/operationTracker.js +212 -0
  150. package/dist/core/operationTracker.js.map +7 -0
  151. package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
  152. package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
  153. package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
  154. package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
  155. package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
  156. package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
  157. package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
  158. package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
  159. package/dist/core/tokenStats.js +9 -0
  160. package/dist/core/tokenStats.js.map +7 -0
  161. package/dist/core/tokenStatsManager.js +331 -0
  162. package/dist/core/tokenStatsManager.js.map +7 -0
  163. package/dist/entrypoints/cli.js +115 -87
  164. package/dist/entrypoints/cli.js.map +2 -2
  165. package/dist/hooks/useAgentTokenStats.js +72 -0
  166. package/dist/hooks/useAgentTokenStats.js.map +7 -0
  167. package/dist/hooks/useAgentTranscripts.js +30 -6
  168. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  169. package/dist/hooks/useLogMessages.js +12 -1
  170. package/dist/hooks/useLogMessages.js.map +2 -2
  171. package/dist/i18n/locales/en.js +6 -5
  172. package/dist/i18n/locales/en.js.map +2 -2
  173. package/dist/i18n/locales/zh-CN.js +6 -5
  174. package/dist/i18n/locales/zh-CN.js.map +2 -2
  175. package/dist/i18n/types.js.map +1 -1
  176. package/dist/permissions.js +28 -1
  177. package/dist/permissions.js.map +2 -2
  178. package/dist/query.js +78 -4
  179. package/dist/query.js.map +3 -3
  180. package/dist/screens/REPL.js +23 -3
  181. package/dist/screens/REPL.js.map +2 -2
  182. package/dist/services/claude.js +54 -3
  183. package/dist/services/claude.js.map +2 -2
  184. package/dist/services/intelligentCompactor.js +1 -1
  185. package/dist/services/intelligentCompactor.js.map +2 -2
  186. package/dist/services/mcpClient.js +81 -25
  187. package/dist/services/mcpClient.js.map +2 -2
  188. package/dist/services/sandbox/filesystemBoundary.js +58 -17
  189. package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
  190. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
  191. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  192. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
  193. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  194. package/dist/tools/BashTool/BashTool.js +22 -3
  195. package/dist/tools/BashTool/BashTool.js.map +2 -2
  196. package/dist/tools/BashTool/prompt.js +178 -34
  197. package/dist/tools/BashTool/prompt.js.map +2 -2
  198. package/dist/tools/FileEditTool/prompt.js +6 -3
  199. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  200. package/dist/tools/FileWriteTool/prompt.js +4 -2
  201. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  202. package/dist/tools/MultiEditTool/prompt.js +5 -3
  203. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  204. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -1
  205. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  206. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
  207. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  208. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
  209. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  210. package/dist/tools/PlanModeTool/prompt.js +1 -1
  211. package/dist/tools/PlanModeTool/prompt.js.map +1 -1
  212. package/dist/tools/SkillTool/SkillTool.js +4 -3
  213. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  214. package/dist/tools/SkillTool/prompt.js +1 -1
  215. package/dist/tools/SkillTool/prompt.js.map +1 -1
  216. package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
  217. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
  218. package/dist/tools/TaskTool/TaskTool.js +8 -0
  219. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  220. package/dist/utils/CircuitBreaker.js +242 -0
  221. package/dist/utils/CircuitBreaker.js.map +7 -0
  222. package/dist/utils/ask.js +2 -0
  223. package/dist/utils/ask.js.map +2 -2
  224. package/dist/utils/config.js +47 -5
  225. package/dist/utils/config.js.map +2 -2
  226. package/dist/utils/credentials/CredentialStore.js +1 -0
  227. package/dist/utils/credentials/CredentialStore.js.map +7 -0
  228. package/dist/utils/credentials/EncryptedFileStore.js +157 -0
  229. package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
  230. package/dist/utils/credentials/index.js +37 -0
  231. package/dist/utils/credentials/index.js.map +7 -0
  232. package/dist/utils/credentials/migration.js +82 -0
  233. package/dist/utils/credentials/migration.js.map +7 -0
  234. package/dist/utils/markdown.js +13 -1
  235. package/dist/utils/markdown.js.map +2 -2
  236. package/dist/utils/permissions/filesystem.js +5 -1
  237. package/dist/utils/permissions/filesystem.js.map +2 -2
  238. package/dist/utils/safePath.js +132 -0
  239. package/dist/utils/safePath.js.map +7 -0
  240. package/dist/utils/sensitiveFiles.js +125 -0
  241. package/dist/utils/sensitiveFiles.js.map +7 -0
  242. package/dist/utils/taskDisplayUtils.js +9 -9
  243. package/dist/utils/taskDisplayUtils.js.map +2 -2
  244. package/dist/utils/theme.js +6 -6
  245. package/dist/utils/theme.js.map +1 -1
  246. package/dist/utils/toolRiskClassification.js +207 -0
  247. package/dist/utils/toolRiskClassification.js.map +7 -0
  248. package/dist/utils/tooling/safeRender.js +5 -4
  249. package/dist/utils/tooling/safeRender.js.map +2 -2
  250. package/dist/version.js +2 -2
  251. package/dist/version.js.map +1 -1
  252. package/package.json +9 -7
  253. package/dist/hooks/useCancelRequest.js +0 -31
  254. 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, { dimColor: true }, "To change this later, run /config")), /* @__PURE__ */ React.createElement(
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: "gray",
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&apos;s get started.</Text>\n <Box flexDirection=\"column\">\n <Text bold>Choose the option that looks best when you select it:</Text>\n <Text dimColor>To change this later, run /config</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=\"gray\"\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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",
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&apos;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": "AAgBA,OAAO,SAAS,YAAY;AAC5B,SAAS,KAAK,YAAY;AAC1B,SAAS,uBAAuB;AAoChC,MAAM,UAAU,KAAK,SAASA,SAAQ;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,MAAI,UAAU,EAAG,QAAO;AAExB,SACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAO,gBAAgB,aAAY,MAAK,GAAC,GAC/C,oCAAC,QAAK,OAAO,gBAAgB,aAAY,KAAM,GAC/C,oCAAC,QAAK,OAAO,gBAAgB,SAAO,KAAE,KAAM,GAC3C,QAAQ,oCAAC,QAAK,OAAO,gBAAgB,SAAO,MAAG,MAAK,GAAC,CACxD,GACC,QACH;AAEJ,CAAC;AAUD,MAAM,WAAW,KAAK,SAASC,UAAS,EAAE,OAAO,UAAU,GAAkB;AAC3E,QAAM,eAAe,MAAM,MAAM,GAAG,SAAS;AAC7C,QAAM,YAAY,MAAM,SAAS;AAEjC,SACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACtC,aAAa,IAAI,CAAC,MAAM,QACvB,oCAAC,MAAM,UAAN,EAAe,KAAK,GAAG,IAAI,IAAI,GAAG,MACjC,oCAAC,QAAK,OAAO,gBAAgB,OAAM,eAAe,IAAI,CAAE,CAC1D,CACD,GACA,YAAY,KACX,oCAAC,QAAK,OAAO,gBAAgB,SAAO,WAAQ,WAAU,OAAK,CAE/D;AAEJ,CAAC;AAUD,MAAM,mBAAmB,KAAK,SAASC,kBAAiB;AAAA,EACtD;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,eAAe,MAAM,MAAM,GAAG,SAAS;AAC7C,QAAM,YAAY,MAAM,SAAS;AAEjC,SACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACtC,aAAa,IAAI,CAAC,MAAM,QACvB,oCAAC,OAAI,KAAK,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,eAAc,SAC7C,oCAAC,QAAK,OAAO,gBAAgB,OAAM,eAAe,KAAK,IAAI,GAAE,GAAC,IAC5D,KAAK,QAAQ,KAAK,KAAK,UAAU,MACjC,oCAAC,QAAK,OAAO,gBAAgB,SAAO,KAEjC,KAAK,QAAQ,KACZ,oCAAC,QAAK,OAAO,gBAAgB,WAAS,KAAE,KAAK,KAAM,GAEpD,KAAK,QAAQ,KAAK,KAAK,UAAU,KAAK,oCAAC,YAAK,GAAC,GAC7C,KAAK,UAAU,KACd,oCAAC,QAAK,OAAO,gBAAgB,SAAO,KAAE,KAAK,OAAQ,GACnD,GAEJ,CAEJ,CACD,GACA,YAAY,KACX,oCAAC,QAAK,OAAO,gBAAgB,SAAO,WAAQ,WAAU,OAAK,CAE/D;AAEJ,CAAC;AAUD,MAAM,cAAc,KAAK,SAASC,aAAY;AAAA,EAC5C;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,kBAAkB,SAAS,MAAM,GAAG,SAAS;AACnD,QAAM,YAAY,SAAS,SAAS;AAEpC,SACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACtC,gBAAgB,IAAI,CAAC,KAAK,QACzB,oCAAC,MAAM,UAAN,EAAe,KAAK,OAAO,GAAG,MAC7B,oCAAC,QAAK,OAAO,gBAAgB,OAAM,gBAAgB,KAAK,EAAE,CAAE,CAC9D,CACD,GACA,YAAY,KACX,oCAAC,QAAK,OAAO,gBAAgB,SAAO,WAAQ,WAAU,OAAK,CAE/D;AAEJ,CAAC;AAUD,SAAS,eAAe,UAA0B;AAChD,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,MAAI,MAAM,UAAU,EAAG,QAAO;AAC9B,SAAO,SAAS,MAAM,MAAM,EAAE,EAAE,KAAK,GAAG;AAC1C;AAKA,SAAS,gBAAgB,SAAiB,WAA2B;AAEnE,QAAM,aAAa,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACrD,MAAI,WAAW,UAAU,UAAW,QAAO;AAC3C,SAAO,WAAW,MAAM,GAAG,YAAY,CAAC,IAAI;AAC9C;AAKA,SAAS,kBAAkB,SAAwC;AACjE,SACE,QAAQ,UAAU,SAAS,KAC3B,QAAQ,cAAc,SAAS,KAC/B,QAAQ,aAAa,SAAS,KAC9B,QAAQ,YAAY,SAAS,KAC7B,QAAQ,iBAAiB,KACzB,QAAQ,cAAc;AAE1B;AAWO,MAAM,mBAAmB,KAAK,SAASC,kBAAiB;AAAA,EAC7D;AAAA,EACA,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,oBAAoB;AACtB,GAA0B;AAExB,MAAI,CAAC,kBAAkB,OAAO,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,QAAQ,cAAc;AAAA,IAC/C,CAAC,KAAK,UAAU;AAAA,MACd,OAAO,IAAI,QAAQ,KAAK;AAAA,MACxB,SAAS,IAAI,UAAU,KAAK;AAAA,IAC9B;AAAA,IACA,EAAE,OAAO,GAAG,SAAS,EAAE;AAAA,EACzB;AAEA,SACE,oCAAC,OAAI,eAAc,UAAS,WAAW,KAErC,oCAAC,QAAK,OAAO,gBAAgB,OAAO,MAAI,QAAC,iBAEzC,GAEA,oCAAC,OAAI,eAAc,UAAS,WAAW,KAEpC,QAAQ,UAAU,SAAS,KAC1B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ,UAAU;AAAA;AAAA,IAEzB,oCAAC,YAAS,OAAO,QAAQ,WAAW,WAAW,gBAAgB;AAAA,EACjE,GAID,QAAQ,cAAc,SAAS,KAC9B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ,cAAc;AAAA,MAC7B,MACE,WACI,kBAAkB,mBAAmB,QAAQ,KAAK,mBAAmB,UAAU,IAAI,OAAO,mBAAmB,KAAK,KAAK,mBAAmB,OAAO,KAAK,EAAE,KACxJ,mBAAmB,QAAQ,KAAK,mBAAmB,UAAU,IAC3D,IAAI,mBAAmB,KAAK,KAAK,mBAAmB,OAAO,KAC3D;AAAA;AAAA,IAGR;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,QAAQ;AAAA,QACf,WAAW;AAAA;AAAA,IACb;AAAA,EACF,GAID,QAAQ,aAAa,SAAS,KAC7B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ,aAAa;AAAA;AAAA,IAE5B,oCAAC,YAAS,OAAO,QAAQ,cAAc,WAAW,gBAAgB;AAAA,EACpE,GAID,QAAQ,YAAY,SAAS,KAC5B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ,YAAY;AAAA;AAAA,IAE3B;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,QAAQ;AAAA,QAClB,WAAW;AAAA;AAAA,IACb;AAAA,EACF,GAID,QAAQ,iBAAiB,KACxB;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ;AAAA;AAAA,EACjB,GAID,QAAQ,cAAc,KACrB;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,OAAO,QAAQ;AAAA;AAAA,EACjB,CAEJ,CACF;AAEJ,CAAC;AAED,IAAO,2BAAQ;",
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, { dimColor: true }, " ", "\u2191 ", visibleSuggestions[0].globalIndex, " more above...")), visibleSuggestions.map((suggestion) => {
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 ? theme.suggestion : isAgent && suggestion.metadata?.color ? suggestion.metadata.color : void 0;
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, { dimColor: true }, " ", "\u2193", " ", suggestions.length - visibleSuggestions[visibleSuggestions.length - 1].globalIndex - 1, " ", "more below...")));
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
- if (input.length > 0) {
713
- onInputChange("");
714
- setHotkeyMessage({ show: true, text: "Input cleared (Esc)" });
715
- setTimeout(() => setHotkeyMessage({ show: false }), 1e3);
716
- return true;
717
- } else if (isLoading && onInterrupt) {
718
- onInterrupt();
719
- setHotkeyMessage({
720
- show: true,
721
- text: "Interrupted by user (Esc)"
722
- });
723
- setTimeout(() => setHotkeyMessage({ show: false }), 2e3);
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: "yellow" }, "\u26A0\uFE0F Limited input mode"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " ", "(Advanced keyboard shortcuts unavailable - raw mode not supported)")), showHotkeyHelp && /* @__PURE__ */ React.createElement(
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, { dimColor: true }, "[", modelInfo.provider, "] ", modelInfo.name, ":", " ", 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, { dimColor: true }, "\u2500\u2500 Queued (", queuedPrompts.length, ") \xB7 will run after current task \xB7 \u2191 to edit last \u2500\u2500")), queuedPrompts.map((prompt, index) => /* @__PURE__ */ React.createElement(Box, { key: index, paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u276F "), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, prompt.length > 60 ? prompt.slice(0, 60) + "..." : prompt)))), /* @__PURE__ */ React.createElement(
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" ? theme.bashBorder : mode === "koding" ? theme.noting : theme.secondaryBorder,
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: theme.bashBorder }, "\xA0!\xA0") : mode === "koding" ? /* @__PURE__ */ React.createElement(Text, { color: theme.noting }, "\xA0#\xA0") : /* @__PURE__ */ React.createElement(Text, { color: isLoading ? theme.secondaryText : void 0, bold: true }, "\xA0\u276F\xA0")
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, { dimColor: true }, "Press ", exitMessage.key, " again to exit") : message.show ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, message.text) : hotkeyMessage.show ? /* @__PURE__ */ React.createElement(Text, { color: theme.success }, hotkeyMessage.text) : modelSwitchMessage.show ? /* @__PURE__ */ React.createElement(Text, { color: theme.success }, modelSwitchMessage.text) : verbose ? (
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" ? theme.bashBorder : void 0,
835
- dimColor: mode !== "bash"
835
+ color: mode === "bash" ? BRAND_GRADIENT.MIDDLE : SEMANTIC_COLORS.dim
836
836
  },
837
- "! for bash mode"
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" ? theme.noting : void 0,
842
- dimColor: mode !== "koding"
849
+ color: mode === "koding" ? SEMANTIC_COLORS.info : SEMANTIC_COLORS.dim
843
850
  },
844
- "\xB7 # for ",
845
- PROJECT_FILE
846
- ), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\xB7 / for commands \xB7 ctrl+? help"), backgroundShellCount > 0 && /* @__PURE__ */ React.createElement(
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 ? theme.primary : theme.success,
850
- backgroundColor: backgroundIndicatorFocused ? theme.success : void 0,
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: "yellow" }, "\xB7 \u{1F4CB} ", queuedPrompts.length, " queued"))
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 ? theme.primary : theme.success,
865
- backgroundColor: backgroundIndicatorFocused ? theme.success : void 0,
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: "yellow" }, "\u2502 \u{1F4CB} ", queuedPrompts.length, " queued"), isLoading && onQueuePrompt && queuedPrompts.length === 0 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2502 Type to queue next prompt"))
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, { dimColor: true }, terminalSetup.isEnabled && isShiftEnterKeyBindingInstalled() ? "shift + \u23CE for newline" : "\\\u23CE for newline"), /* @__PURE__ */ React.createElement(TokenWarning, { tokenUsage }))
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: "gray"
909
+ borderColor: BRAND_GRADIENT.START
896
910
  },
897
911
  /* @__PURE__ */ React.createElement(
898
912
  Text,
899
913
  {
900
- dimColor: !emptyDirMessage,
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];