@within-7/minto 0.3.5 → 0.3.9

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 (153) hide show
  1. package/{cli.js → cli.cjs} +25 -23
  2. package/dist/commands/language.js +137 -0
  3. package/dist/commands/language.js.map +7 -0
  4. package/dist/commands/new.js +56 -0
  5. package/dist/commands/new.js.map +7 -0
  6. package/dist/commands/resume.js +251 -16
  7. package/dist/commands/resume.js.map +2 -2
  8. package/dist/commands/sessions.js +224 -0
  9. package/dist/commands/sessions.js.map +7 -0
  10. package/dist/commands/setup.js +3 -2
  11. package/dist/commands/setup.js.map +2 -2
  12. package/dist/commands/stats.js +235 -0
  13. package/dist/commands/stats.js.map +7 -0
  14. package/dist/commands/status.js +11 -5
  15. package/dist/commands/status.js.map +2 -2
  16. package/dist/commands/undo.js +26 -16
  17. package/dist/commands/undo.js.map +2 -2
  18. package/dist/commands.js +6 -0
  19. package/dist/commands.js.map +2 -2
  20. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  21. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  22. package/dist/components/Config.js +9 -8
  23. package/dist/components/Config.js.map +2 -2
  24. package/dist/components/HeaderBar.js +2 -1
  25. package/dist/components/HeaderBar.js.map +2 -2
  26. package/dist/components/Help.js +2 -1
  27. package/dist/components/Help.js.map +2 -2
  28. package/dist/components/HotkeyHelpPanel.js +46 -44
  29. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  30. package/dist/components/Logo.js +5 -2
  31. package/dist/components/Logo.js.map +2 -2
  32. package/dist/components/MCPServerApprovalDialog.js +6 -5
  33. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  34. package/dist/components/MCPServerMultiselectDialog.js +5 -4
  35. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  36. package/dist/components/MessageSelector.js +4 -3
  37. package/dist/components/MessageSelector.js.map +2 -2
  38. package/dist/components/ModelConfig.js +13 -12
  39. package/dist/components/ModelConfig.js.map +2 -2
  40. package/dist/components/ModelListManager.js +4 -3
  41. package/dist/components/ModelListManager.js.map +2 -2
  42. package/dist/components/PromptInput.js +72 -39
  43. package/dist/components/PromptInput.js.map +2 -2
  44. package/dist/components/SensitiveFileWarning.js +12 -8
  45. package/dist/components/SensitiveFileWarning.js.map +2 -2
  46. package/dist/components/TabbedListView/ScrollableList.js +91 -0
  47. package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
  48. package/dist/components/TabbedListView/SearchInput.js +23 -0
  49. package/dist/components/TabbedListView/SearchInput.js.map +7 -0
  50. package/dist/components/TabbedListView/TabBar.js +20 -0
  51. package/dist/components/TabbedListView/TabBar.js.map +7 -0
  52. package/dist/components/TabbedListView/TabbedListView.js +171 -0
  53. package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
  54. package/dist/components/TabbedListView/index.js +11 -0
  55. package/dist/components/TabbedListView/index.js.map +7 -0
  56. package/dist/components/TabbedListView/types.js +1 -0
  57. package/dist/components/TabbedListView/types.js.map +7 -0
  58. package/dist/components/TodoChangeBlock.js +6 -5
  59. package/dist/components/TodoChangeBlock.js.map +3 -3
  60. package/dist/components/TodoPanel.js +6 -3
  61. package/dist/components/TodoPanel.js.map +3 -3
  62. package/dist/components/TrustDialog.js +6 -5
  63. package/dist/components/TrustDialog.js.map +2 -2
  64. package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
  65. package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
  66. package/dist/constants/macros.js +1 -1
  67. package/dist/constants/macros.js.map +1 -1
  68. package/dist/constants/product.js +2 -2
  69. package/dist/constants/product.js.map +1 -1
  70. package/dist/constants/prompts.js +17 -0
  71. package/dist/constants/prompts.js.map +2 -2
  72. package/dist/constants/toolInputExamples.js +5 -1
  73. package/dist/constants/toolInputExamples.js.map +2 -2
  74. package/dist/core/tokenStatsManager.js +5 -0
  75. package/dist/core/tokenStatsManager.js.map +2 -2
  76. package/dist/entrypoints/bootstrap.js +54 -0
  77. package/dist/entrypoints/bootstrap.js.map +7 -0
  78. package/dist/entrypoints/cli.js +132 -23
  79. package/dist/entrypoints/cli.js.map +3 -3
  80. package/dist/history.js +75 -15
  81. package/dist/history.js.map +2 -2
  82. package/dist/i18n/index.js +2 -2
  83. package/dist/i18n/index.js.map +2 -2
  84. package/dist/i18n/locales/en.js +283 -1
  85. package/dist/i18n/locales/en.js.map +2 -2
  86. package/dist/i18n/locales/zh-CN.js +283 -1
  87. package/dist/i18n/locales/zh-CN.js.map +2 -2
  88. package/dist/i18n/types.js.map +1 -1
  89. package/dist/index.js +1 -1
  90. package/dist/index.js.map +2 -2
  91. package/dist/messages.js +11 -0
  92. package/dist/messages.js.map +2 -2
  93. package/dist/permissions.js.map +2 -2
  94. package/dist/query.js +9 -0
  95. package/dist/query.js.map +2 -2
  96. package/dist/screens/REPL.js +45 -7
  97. package/dist/screens/REPL.js.map +2 -2
  98. package/dist/services/customCommands.js +14 -8
  99. package/dist/services/customCommands.js.map +2 -2
  100. package/dist/tools/TaskTool/TaskTool.js +176 -1
  101. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  102. package/dist/tools/TodoWriteTool/prompt.js +21 -0
  103. package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
  104. package/dist/tools/URLFetcherTool/prompt.js +14 -9
  105. package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
  106. package/dist/tools/WebSearchTool/prompt.js +12 -6
  107. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  108. package/dist/types/PermissionMode.js +30 -1
  109. package/dist/types/PermissionMode.js.map +2 -2
  110. package/dist/types/plugin.js.map +2 -2
  111. package/dist/utils/agentHookExecutor.js +106 -0
  112. package/dist/utils/agentHookExecutor.js.map +7 -0
  113. package/dist/utils/agentLoader.js +212 -26
  114. package/dist/utils/agentLoader.js.map +2 -2
  115. package/dist/utils/agentMemory.js +134 -0
  116. package/dist/utils/agentMemory.js.map +7 -0
  117. package/dist/utils/config.js +51 -1
  118. package/dist/utils/config.js.map +2 -2
  119. package/dist/utils/configPaths.js +199 -0
  120. package/dist/utils/configPaths.js.map +7 -0
  121. package/dist/utils/historyManager.js +234 -0
  122. package/dist/utils/historyManager.js.map +7 -0
  123. package/dist/utils/messages.js +13 -8
  124. package/dist/utils/messages.js.map +2 -2
  125. package/dist/utils/migration/index.js +37 -0
  126. package/dist/utils/migration/index.js.map +7 -0
  127. package/dist/utils/migration/migrateHistory.js +273 -0
  128. package/dist/utils/migration/migrateHistory.js.map +7 -0
  129. package/dist/utils/migration/migrateTodos.js +323 -0
  130. package/dist/utils/migration/migrateTodos.js.map +7 -0
  131. package/dist/utils/pasteCache.js +309 -0
  132. package/dist/utils/pasteCache.js.map +7 -0
  133. package/dist/utils/pluginLoader.js +6 -3
  134. package/dist/utils/pluginLoader.js.map +2 -2
  135. package/dist/utils/sessionIndex.js +192 -0
  136. package/dist/utils/sessionIndex.js.map +7 -0
  137. package/dist/utils/sessionTracker.js +170 -0
  138. package/dist/utils/sessionTracker.js.map +7 -0
  139. package/dist/utils/skillLoader.js +91 -5
  140. package/dist/utils/skillLoader.js.map +2 -2
  141. package/dist/utils/stats.js +417 -0
  142. package/dist/utils/stats.js.map +7 -0
  143. package/dist/utils/stringSubstitution.js +107 -0
  144. package/dist/utils/stringSubstitution.js.map +7 -0
  145. package/dist/utils/teamConfig.js +3 -1
  146. package/dist/utils/teamConfig.js.map +2 -2
  147. package/dist/utils/todoStorage.js +51 -19
  148. package/dist/utils/todoStorage.js.map +2 -2
  149. package/dist/utils/tooling/safeRender.js.map +2 -2
  150. package/dist/version.js +2 -2
  151. package/dist/version.js.map +1 -1
  152. package/package.json +71 -28
  153. package/scripts/{postinstall.js → postinstall.cjs} +1 -1
@@ -8,6 +8,7 @@ import { useExitOnCtrlCD } from "../hooks/useExitOnCtrlCD.js";
8
8
  import { getModelManager } from "../utils/model.js";
9
9
  import { getCompressionMode, setCompressionMode } from "../utils/compressionMode.js";
10
10
  import { SEMANTIC_COLORS } from "../constants/colors.js";
11
+ import { t } from "../i18n/index.js";
11
12
  function Config({ onClose }) {
12
13
  const [globalConfig, setGlobalConfig] = useState(getGlobalConfig());
13
14
  const initialConfig = React.useRef(getGlobalConfig());
@@ -22,7 +23,7 @@ function Config({ onClose }) {
22
23
  // Global settings
23
24
  {
24
25
  id: "theme",
25
- label: "Theme",
26
+ label: t("config.theme"),
26
27
  value: globalConfig.theme ?? "dark",
27
28
  options: ["dark", "light"],
28
29
  onChange(theme2) {
@@ -34,7 +35,7 @@ function Config({ onClose }) {
34
35
  },
35
36
  {
36
37
  id: "verbose",
37
- label: "Verbose mode",
38
+ label: t("config.verboseMode"),
38
39
  value: globalConfig.verbose ?? false,
39
40
  onChange(verbose) {
40
41
  const config = { ...getGlobalConfig(), verbose };
@@ -45,7 +46,7 @@ function Config({ onClose }) {
45
46
  },
46
47
  {
47
48
  id: "stream",
48
- label: "Stream responses",
49
+ label: t("config.streamResponses"),
49
50
  value: globalConfig.stream ?? true,
50
51
  onChange(stream) {
51
52
  const config = { ...getGlobalConfig(), stream };
@@ -56,7 +57,7 @@ function Config({ onClose }) {
56
57
  },
57
58
  {
58
59
  id: "compressionMode",
59
- label: "Compression mode (/compact)",
60
+ label: t("config.compressionMode"),
60
61
  value: getCompressionMode(),
61
62
  options: ["business", "code"],
62
63
  onChange(mode) {
@@ -154,8 +155,8 @@ function Config({ onClose }) {
154
155
  paddingY: 1,
155
156
  gap: 1
156
157
  },
157
- /* @__PURE__ */ React.createElement(Text, { bold: true }, "Configuration", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
158
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, "Model Configuration:"), activeProfiles.length === 0 ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "No models configured. Use /model to add models.") : /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, activeProfiles.map((profile) => /* @__PURE__ */ React.createElement(React.Fragment, { key: profile.modelName }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "\u2022 ", profile.name, " (", profile.provider, ")"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Use /model to manage model configurations")))),
158
+ /* @__PURE__ */ React.createElement(Text, { bold: true }, t("config.title"), " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
159
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, t("config.modelConfiguration")), activeProfiles.length === 0 ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("config.noModelsConfigured")) : /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, activeProfiles.map((profile) => /* @__PURE__ */ React.createElement(React.Fragment, { key: profile.modelName }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "\u2022 ", profile.name, " (", profile.provider, ")"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, t("config.useModelCommand"))))),
159
160
  /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, settings.map((setting, index) => /* @__PURE__ */ React.createElement(Box, { key: setting.id, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(
160
161
  Text,
161
162
  {
@@ -170,8 +171,8 @@ function Config({ onClose }) {
170
171
  color: setting.disabled ? theme.secondaryText : theme.suggestion
171
172
  },
172
173
  setting.type === "boolean" ? setting.value ? "enabled" : "disabled" : setting.type === "enum" ? setting.value : String(setting.value)
173
- )), index === selectedIndex && editingString && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter new value: ", currentInput), inputError && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, inputError))))),
174
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, editingString ? "Enter to save \xB7 Esc to cancel" : /* @__PURE__ */ React.createElement(React.Fragment, null, "\u2191/\u2193 to navigate \xB7 Enter to change \xB7 Esc to close", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, " ", "\xB7 Use /model for model config"))))
174
+ )), index === selectedIndex && editingString && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, t("config.enterNewValue"), " ", currentInput), inputError && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, inputError))))),
175
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, editingString ? t("config.enterToSaveEscToCancel") : /* @__PURE__ */ React.createElement(React.Fragment, null, t("config.navigateChangeClose"), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, " ", "\xB7 ", t("config.useModelCommand")))))
175
176
  ));
176
177
  }
177
178
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/Config.tsx"],
4
- "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState } from 'react'\nimport figures from 'figures'\nimport { getTheme } from '@utils/theme'\nimport { GlobalConfig, saveGlobalConfig, getGlobalConfig } from '@utils/config'\nimport chalk from 'chalk'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { getModelManager } from '@utils/model'\nimport { getCompressionMode, setCompressionMode } from '@utils/compressionMode'\nimport type { CompressionMode } from '@constants/compressionPrompts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\ntype Props = {\n onClose: () => void\n}\n\ntype Setting =\n | {\n id: string\n label: string\n value: boolean\n onChange(value: boolean): void\n type: 'boolean'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n options: string[]\n onChange(value: string): void\n type: 'enum'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n onChange(value: string): void\n type: 'string'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: number\n onChange(value: number): void\n type: 'number'\n disabled?: boolean\n }\n\nexport function Config({ onClose }: Props): React.ReactNode {\n const [globalConfig, setGlobalConfig] = useState(getGlobalConfig())\n const initialConfig = React.useRef(getGlobalConfig())\n const [selectedIndex, setSelectedIndex] = useState(0)\n const exitState = useExitOnCtrlCD(() => process.exit(0))\n const [editingString, setEditingString] = useState(false)\n const [currentInput, setCurrentInput] = useState('')\n const [inputError, setInputError] = useState<string | null>(null)\n\n const modelManager = getModelManager()\n const activeProfiles = modelManager.getAvailableModels()\n\n const settings: Setting[] = [\n // Global settings\n {\n id: 'theme',\n label: 'Theme',\n value: globalConfig.theme ?? 'dark',\n options: ['dark', 'light'],\n onChange(theme: string) {\n const config = { ...getGlobalConfig(), theme: theme as any }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n {\n id: 'verbose',\n label: 'Verbose mode',\n value: globalConfig.verbose ?? false,\n onChange(verbose: boolean) {\n const config = { ...getGlobalConfig(), verbose }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'stream',\n label: 'Stream responses',\n value: globalConfig.stream ?? true,\n onChange(stream: boolean) {\n const config = { ...getGlobalConfig(), stream }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'compressionMode',\n label: 'Compression mode (/compact)',\n value: getCompressionMode(),\n options: ['business', 'code'],\n onChange(mode: string) {\n setCompressionMode(mode as CompressionMode)\n const config = {\n ...getGlobalConfig(),\n compressionMode: mode as CompressionMode,\n }\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n ]\n\n const theme = getTheme()\n\n useInput((input, key) => {\n if (editingString) {\n if (key.return) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.type === 'string') {\n try {\n currentSetting.onChange(currentInput)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n } else if (currentSetting?.type === 'number') {\n const numValue = parseFloat(currentInput)\n if (isNaN(numValue)) {\n setInputError('Please enter a valid number')\n } else {\n try {\n ;(currentSetting as any).onChange(numValue)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n }\n }\n } else if (key.escape) {\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } else if (key.delete || key.backspace) {\n setCurrentInput(prev => prev.slice(0, -1))\n } else if (input) {\n setCurrentInput(prev => prev + input)\n }\n return\n }\n\n if (key.upArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.min(settings.length - 1, prev + 1))\n } else if (key.return && !exitState.pending) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.disabled) return\n\n if (currentSetting?.type === 'boolean') {\n currentSetting.onChange(!currentSetting.value)\n } else if (currentSetting?.type === 'enum') {\n const currentIndex = currentSetting.options.indexOf(\n currentSetting.value,\n )\n const nextIndex = (currentIndex + 1) % currentSetting.options.length\n currentSetting.onChange(currentSetting.options[nextIndex])\n } else if (\n currentSetting?.type === 'string' ||\n currentSetting?.type === 'number'\n ) {\n setCurrentInput(String(currentSetting.value))\n setEditingString(true)\n setInputError(null)\n }\n } else if (key.escape && !exitState.pending) {\n // Check if config has changed\n const currentConfigString = JSON.stringify(getGlobalConfig())\n const initialConfigString = JSON.stringify(initialConfig.current)\n\n if (currentConfigString !== initialConfigString) {\n // Config has changed, save it\n saveGlobalConfig(getGlobalConfig())\n }\n\n onClose()\n }\n })\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.secondaryBorder}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text bold>\n Configuration{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n\n {/* Model Configuration Summary */}\n <Box flexDirection=\"column\" marginY={1}>\n <Text bold color={theme.success}>\n Model Configuration:\n </Text>\n {activeProfiles.length === 0 ? (\n <Text color={theme.secondaryText}>\n No models configured. Use /model to add models.\n </Text>\n ) : (\n <Box flexDirection=\"column\" marginLeft={2}>\n {activeProfiles.map(profile => (\n <React.Fragment key={profile.modelName}>\n <Text color={theme.secondaryText}>\n \u2022 {profile.name} ({profile.provider})\n </Text>\n </React.Fragment>\n ))}\n <Box marginTop={1}>\n <Text color={theme.suggestion}>\n Use /model to manage model configurations\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n\n {/* Settings List */}\n <Box flexDirection=\"column\">\n {settings.map((setting, index) => (\n <Box key={setting.id} flexDirection=\"column\">\n <Box flexDirection=\"row\" gap={1}>\n <Text\n color={\n index === selectedIndex\n ? theme.success\n : setting.disabled\n ? theme.secondaryText\n : theme.text\n }\n >\n {index === selectedIndex ? figures.pointer : ' '}{' '}\n {setting.label}\n </Text>\n <Text\n color={\n setting.disabled ? theme.secondaryText : theme.suggestion\n }\n >\n {setting.type === 'boolean'\n ? setting.value\n ? 'enabled'\n : 'disabled'\n : setting.type === 'enum'\n ? setting.value\n : String(setting.value)}\n </Text>\n </Box>\n {index === selectedIndex && editingString && (\n <Box flexDirection=\"column\" marginLeft={2}>\n <Text color={theme.suggestion}>\n Enter new value: {currentInput}\n </Text>\n {inputError && (\n <Text color={SEMANTIC_COLORS.error}>{inputError}</Text>\n )}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n {editingString ? (\n 'Enter to save \u00B7 Esc to cancel'\n ) : (\n <>\n \u2191/\u2193 to navigate \u00B7 Enter to change \u00B7 Esc to close\n <Text color={theme.suggestion}>\n {' '}\n \u00B7 Use /model for model config\n </Text>\n </>\n )}\n </Text>\n </Box>\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState } from 'react'\nimport figures from 'figures'\nimport { getTheme } from '@utils/theme'\nimport { GlobalConfig, saveGlobalConfig, getGlobalConfig } from '@utils/config'\nimport chalk from 'chalk'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { getModelManager } from '@utils/model'\nimport { getCompressionMode, setCompressionMode } from '@utils/compressionMode'\nimport type { CompressionMode } from '@constants/compressionPrompts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { t } from '@i18n'\n\ntype Props = {\n onClose: () => void\n}\n\ntype Setting =\n | {\n id: string\n label: string\n value: boolean\n onChange(value: boolean): void\n type: 'boolean'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n options: string[]\n onChange(value: string): void\n type: 'enum'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n onChange(value: string): void\n type: 'string'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: number\n onChange(value: number): void\n type: 'number'\n disabled?: boolean\n }\n\nexport function Config({ onClose }: Props): React.ReactNode {\n const [globalConfig, setGlobalConfig] = useState(getGlobalConfig())\n const initialConfig = React.useRef(getGlobalConfig())\n const [selectedIndex, setSelectedIndex] = useState(0)\n const exitState = useExitOnCtrlCD(() => process.exit(0))\n const [editingString, setEditingString] = useState(false)\n const [currentInput, setCurrentInput] = useState('')\n const [inputError, setInputError] = useState<string | null>(null)\n\n const modelManager = getModelManager()\n const activeProfiles = modelManager.getAvailableModels()\n\n const settings: Setting[] = [\n // Global settings\n {\n id: 'theme',\n label: t('config.theme'),\n value: globalConfig.theme ?? 'dark',\n options: ['dark', 'light'],\n onChange(theme: string) {\n const config = { ...getGlobalConfig(), theme: theme as any }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n {\n id: 'verbose',\n label: t('config.verboseMode'),\n value: globalConfig.verbose ?? false,\n onChange(verbose: boolean) {\n const config = { ...getGlobalConfig(), verbose }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'stream',\n label: t('config.streamResponses'),\n value: globalConfig.stream ?? true,\n onChange(stream: boolean) {\n const config = { ...getGlobalConfig(), stream }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'compressionMode',\n label: t('config.compressionMode'),\n value: getCompressionMode(),\n options: ['business', 'code'],\n onChange(mode: string) {\n setCompressionMode(mode as CompressionMode)\n const config = {\n ...getGlobalConfig(),\n compressionMode: mode as CompressionMode,\n }\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n ]\n\n const theme = getTheme()\n\n useInput((input, key) => {\n if (editingString) {\n if (key.return) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.type === 'string') {\n try {\n currentSetting.onChange(currentInput)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n } else if (currentSetting?.type === 'number') {\n const numValue = parseFloat(currentInput)\n if (isNaN(numValue)) {\n setInputError('Please enter a valid number')\n } else {\n try {\n ;(currentSetting as any).onChange(numValue)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n }\n }\n } else if (key.escape) {\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } else if (key.delete || key.backspace) {\n setCurrentInput(prev => prev.slice(0, -1))\n } else if (input) {\n setCurrentInput(prev => prev + input)\n }\n return\n }\n\n if (key.upArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.min(settings.length - 1, prev + 1))\n } else if (key.return && !exitState.pending) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.disabled) return\n\n if (currentSetting?.type === 'boolean') {\n currentSetting.onChange(!currentSetting.value)\n } else if (currentSetting?.type === 'enum') {\n const currentIndex = currentSetting.options.indexOf(\n currentSetting.value,\n )\n const nextIndex = (currentIndex + 1) % currentSetting.options.length\n currentSetting.onChange(currentSetting.options[nextIndex])\n } else if (\n currentSetting?.type === 'string' ||\n currentSetting?.type === 'number'\n ) {\n setCurrentInput(String(currentSetting.value))\n setEditingString(true)\n setInputError(null)\n }\n } else if (key.escape && !exitState.pending) {\n // Check if config has changed\n const currentConfigString = JSON.stringify(getGlobalConfig())\n const initialConfigString = JSON.stringify(initialConfig.current)\n\n if (currentConfigString !== initialConfigString) {\n // Config has changed, save it\n saveGlobalConfig(getGlobalConfig())\n }\n\n onClose()\n }\n })\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.secondaryBorder}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text bold>\n {t('config.title')}{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n\n {/* Model Configuration Summary */}\n <Box flexDirection=\"column\" marginY={1}>\n <Text bold color={theme.success}>\n {t('config.modelConfiguration')}\n </Text>\n {activeProfiles.length === 0 ? (\n <Text color={theme.secondaryText}>\n {t('config.noModelsConfigured')}\n </Text>\n ) : (\n <Box flexDirection=\"column\" marginLeft={2}>\n {activeProfiles.map(profile => (\n <React.Fragment key={profile.modelName}>\n <Text color={theme.secondaryText}>\n \u2022 {profile.name} ({profile.provider})\n </Text>\n </React.Fragment>\n ))}\n <Box marginTop={1}>\n <Text color={theme.suggestion}>\n {t('config.useModelCommand')}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n\n {/* Settings List */}\n <Box flexDirection=\"column\">\n {settings.map((setting, index) => (\n <Box key={setting.id} flexDirection=\"column\">\n <Box flexDirection=\"row\" gap={1}>\n <Text\n color={\n index === selectedIndex\n ? theme.success\n : setting.disabled\n ? theme.secondaryText\n : theme.text\n }\n >\n {index === selectedIndex ? figures.pointer : ' '}{' '}\n {setting.label}\n </Text>\n <Text\n color={\n setting.disabled ? theme.secondaryText : theme.suggestion\n }\n >\n {setting.type === 'boolean'\n ? setting.value\n ? 'enabled'\n : 'disabled'\n : setting.type === 'enum'\n ? setting.value\n : String(setting.value)}\n </Text>\n </Box>\n {index === selectedIndex && editingString && (\n <Box flexDirection=\"column\" marginLeft={2}>\n <Text color={theme.suggestion}>\n {t('config.enterNewValue')} {currentInput}\n </Text>\n {inputError && (\n <Text color={SEMANTIC_COLORS.error}>{inputError}</Text>\n )}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n {editingString ? (\n t('config.enterToSaveEscToCancel')\n ) : (\n <>\n {t('config.navigateChangeClose')}\n <Text color={theme.suggestion}>\n {' '}\n \u00B7 {t('config.useModelCommand')}\n </Text>\n </>\n )}\n </Text>\n </Box>\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["theme"]
7
7
  }
@@ -4,6 +4,7 @@ import { getTheme } from "../utils/theme.js";
4
4
  import { getCwd } from "../utils/state.js";
5
5
  import { getModelManager } from "../utils/model.js";
6
6
  import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../constants/colors.js";
7
+ import { t } from "../i18n/index.js";
7
8
  function HeaderBar({
8
9
  tokenUsage = 0,
9
10
  mcpClients = [],
@@ -16,7 +17,7 @@ function HeaderBar({
16
17
  const contextPercentage = currentModel ? Math.round(tokenUsage / currentModel.contextLength * 100) : 0;
17
18
  const formatTokens = (tokens) => `${Math.round(tokens / 1e3)}k`;
18
19
  const getDisplayModelName = (modelName) => {
19
- if (!modelName) return "AI \u52A9\u624B";
20
+ if (!modelName) return t("ui.model.fallbackName");
20
21
  const simplified = modelName.replace(/^(claude-|gpt-|glm-)/, "").replace(/-\d+.*$/, "").replace(/-latest$/, "");
21
22
  return simplified.charAt(0).toUpperCase() + simplified.slice(1);
22
23
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/HeaderBar.tsx"],
4
- "sourcesContent": ["/**\n * HeaderBar - Minto \u54C1\u724C\u9875\u7709\u7EC4\u4EF6\n *\n * \u8BBE\u8BA1\u539F\u5219\uFF1A\n * 1. **\u54C1\u724C\u8BC6\u522B** - \u7D2B\u84DD\u2192\u73CA\u745A\u6E10\u53D8\uFF0C\u4F20\u9012\u4E13\u4E1A\u4E0E\u70ED\u60C5\n * 2. **\u4FE1\u606F\u6E05\u6670** - \u663E\u793A\u5173\u952E\u4FE1\u606F\uFF08\u9879\u76EE\u4F4D\u7F6E\u3001AI \u6A21\u578B\u3001\u4F7F\u7528\u91CF\uFF09\n * 3. **\u5546\u52A1\u53CB\u597D** - \u6E29\u6696\u3001\u4E13\u4E1A\u3001\u6613\u4E8E\u7406\u89E3\n * 4. **\u89C6\u89C9\u7CBE\u7B80** - \u4E0D\u5360\u7528\u8FC7\u591A\u5782\u76F4\u7A7A\u95F4\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { getCwd } from '@utils/state'\nimport { getModelManager } from '@utils/model'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport type { WrappedClient } from '@services/mcpClient'\n\ninterface Props {\n /** \u5F53\u524D Token \u4F7F\u7528\u91CF */\n tokenUsage?: number\n\n /** MCP \u5BA2\u6237\u7AEF (\u53EF\u9009) */\n mcpClients?: WrappedClient[]\n\n /** \u662F\u5426\u662F\u9ED8\u8BA4\u6A21\u578B */\n isDefaultModel?: boolean\n}\n\n/**\n * HeaderBar - \u54C1\u724C\u9875\u7709\u72B6\u6001\u680F\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\n * \u2502 \u25C6 Minto \u00B7 /path/to/project AI Model \u00B7 50k/200k\u2502\n * \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n * ```\n */\nexport function HeaderBar({\n tokenUsage = 0,\n mcpClients = [],\n isDefaultModel = true,\n}: Props): React.ReactNode {\n const theme = getTheme()\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n // \u8BA1\u7B97\u4E0A\u4E0B\u6587\u4F7F\u7528\u767E\u5206\u6BD4\n const contextPercentage = currentModel\n ? Math.round((tokenUsage / currentModel.contextLength) * 100)\n : 0\n\n // \u683C\u5F0F\u5316 Token \u6570\u91CF (k \u4E3A\u5355\u4F4D)\n const formatTokens = (tokens: number) => `${Math.round(tokens / 1000)}k`\n\n // \u83B7\u53D6\u7B80\u5316\u7684\u6A21\u578B\u663E\u793A\u540D\u79F0\uFF08\u5BF9\u975E\u6280\u672F\u7528\u6237\u66F4\u53CB\u597D\uFF09\n const getDisplayModelName = (modelName: string | undefined) => {\n if (!modelName) return 'AI \u52A9\u624B'\n // \u63D0\u53D6\u6A21\u578B\u7B80\u79F0\uFF0C\u79FB\u9664\u7248\u672C\u53F7\u7B49\u6280\u672F\u7EC6\u8282\n const simplified = modelName\n .replace(/^(claude-|gpt-|glm-)/, '')\n .replace(/-\\d+.*$/, '')\n .replace(/-latest$/, '')\n return simplified.charAt(0).toUpperCase() + simplified.slice(1)\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderColor={BRAND_GRADIENT.START}\n borderStyle=\"round\"\n paddingX={1}\n marginBottom={1}\n >\n {/* \u4E3B\u4FE1\u606F\u884C */}\n <Box flexDirection=\"row\" justifyContent=\"space-between\">\n {/* \u5DE6\u4FA7\uFF1A\u54C1\u724C\u6807\u8BC6 + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* \u53F3\u4FA7\uFF1AAI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n <Box flexDirection=\"row\">\n <Text color={SEMANTIC_COLORS.dim}>\n {getDisplayModelName(currentModel?.modelName)}\n </Text>\n {currentModel && (\n <>\n <Text color={SEMANTIC_COLORS.muted}> \u00B7 </Text>\n <Text\n color={\n contextPercentage > 80\n ? SEMANTIC_COLORS.error\n : contextPercentage > 60\n ? SEMANTIC_COLORS.running\n : SEMANTIC_COLORS.muted\n }\n >\n {formatTokens(tokenUsage)}/\n {formatTokens(currentModel.contextLength)}\n </Text>\n </>\n )}\n </Box>\n </Box>\n\n {/* \u6269\u5C55\u670D\u52A1\u72B6\u6001 (\u5982\u679C\u6709) */}\n {mcpClients.length > 0 && (\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={SEMANTIC_COLORS.muted}>MCP: </Text>\n {mcpClients.map((client, idx) => (\n <React.Fragment key={idx}>\n <Text\n color={\n client.type === 'connected'\n ? SEMANTIC_COLORS.success\n : SEMANTIC_COLORS.error\n }\n >\n {client.name}\n </Text>\n {idx < mcpClients.length - 1 && (\n <Text color={SEMANTIC_COLORS.muted}>, </Text>\n )}\n </React.Fragment>\n ))}\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * \u6781\u7B80\u7248\u9875\u7709 (\u53EA\u663E\u793A\u57FA\u672C\u4FE1\u606F)\n */\nexport function MinimalHeaderBar({\n tokenUsage = 0,\n}: {\n tokenUsage?: number\n}): React.ReactNode {\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n return (\n <Box flexDirection=\"row\" justifyContent=\"space-between\" paddingX={2}>\n {/* \u54C1\u724C + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* AI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n {currentModel && (\n <Text color={SEMANTIC_COLORS.dim}>\n {Math.round(tokenUsage / 1000)}k/\n {Math.round(currentModel.contextLength / 1000)}k\n </Text>\n )}\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * HeaderBar - Minto \u54C1\u724C\u9875\u7709\u7EC4\u4EF6\n *\n * \u8BBE\u8BA1\u539F\u5219\uFF1A\n * 1. **\u54C1\u724C\u8BC6\u522B** - \u7D2B\u84DD\u2192\u73CA\u745A\u6E10\u53D8\uFF0C\u4F20\u9012\u4E13\u4E1A\u4E0E\u70ED\u60C5\n * 2. **\u4FE1\u606F\u6E05\u6670** - \u663E\u793A\u5173\u952E\u4FE1\u606F\uFF08\u9879\u76EE\u4F4D\u7F6E\u3001AI \u6A21\u578B\u3001\u4F7F\u7528\u91CF\uFF09\n * 3. **\u5546\u52A1\u53CB\u597D** - \u6E29\u6696\u3001\u4E13\u4E1A\u3001\u6613\u4E8E\u7406\u89E3\n * 4. **\u89C6\u89C9\u7CBE\u7B80** - \u4E0D\u5360\u7528\u8FC7\u591A\u5782\u76F4\u7A7A\u95F4\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { getCwd } from '@utils/state'\nimport { getModelManager } from '@utils/model'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport type { WrappedClient } from '@services/mcpClient'\nimport { t } from '@i18n'\n\ninterface Props {\n /** \u5F53\u524D Token \u4F7F\u7528\u91CF */\n tokenUsage?: number\n\n /** MCP \u5BA2\u6237\u7AEF (\u53EF\u9009) */\n mcpClients?: WrappedClient[]\n\n /** \u662F\u5426\u662F\u9ED8\u8BA4\u6A21\u578B */\n isDefaultModel?: boolean\n}\n\n/**\n * HeaderBar - \u54C1\u724C\u9875\u7709\u72B6\u6001\u680F\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\n * \u2502 \u25C6 Minto \u00B7 /path/to/project AI Model \u00B7 50k/200k\u2502\n * \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n * ```\n */\nexport function HeaderBar({\n tokenUsage = 0,\n mcpClients = [],\n isDefaultModel = true,\n}: Props): React.ReactNode {\n const theme = getTheme()\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n // \u8BA1\u7B97\u4E0A\u4E0B\u6587\u4F7F\u7528\u767E\u5206\u6BD4\n const contextPercentage = currentModel\n ? Math.round((tokenUsage / currentModel.contextLength) * 100)\n : 0\n\n // \u683C\u5F0F\u5316 Token \u6570\u91CF (k \u4E3A\u5355\u4F4D)\n const formatTokens = (tokens: number) => `${Math.round(tokens / 1000)}k`\n\n // Get simplified model display name (more friendly for non-technical users)\n const getDisplayModelName = (modelName: string | undefined) => {\n if (!modelName) return t('ui.model.fallbackName')\n // Extract model short name, remove version numbers and technical details\n const simplified = modelName\n .replace(/^(claude-|gpt-|glm-)/, '')\n .replace(/-\\d+.*$/, '')\n .replace(/-latest$/, '')\n return simplified.charAt(0).toUpperCase() + simplified.slice(1)\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderColor={BRAND_GRADIENT.START}\n borderStyle=\"round\"\n paddingX={1}\n marginBottom={1}\n >\n {/* \u4E3B\u4FE1\u606F\u884C */}\n <Box flexDirection=\"row\" justifyContent=\"space-between\">\n {/* \u5DE6\u4FA7\uFF1A\u54C1\u724C\u6807\u8BC6 + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* \u53F3\u4FA7\uFF1AAI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n <Box flexDirection=\"row\">\n <Text color={SEMANTIC_COLORS.dim}>\n {getDisplayModelName(currentModel?.modelName)}\n </Text>\n {currentModel && (\n <>\n <Text color={SEMANTIC_COLORS.muted}> \u00B7 </Text>\n <Text\n color={\n contextPercentage > 80\n ? SEMANTIC_COLORS.error\n : contextPercentage > 60\n ? SEMANTIC_COLORS.running\n : SEMANTIC_COLORS.muted\n }\n >\n {formatTokens(tokenUsage)}/\n {formatTokens(currentModel.contextLength)}\n </Text>\n </>\n )}\n </Box>\n </Box>\n\n {/* \u6269\u5C55\u670D\u52A1\u72B6\u6001 (\u5982\u679C\u6709) */}\n {mcpClients.length > 0 && (\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={SEMANTIC_COLORS.muted}>MCP: </Text>\n {mcpClients.map((client, idx) => (\n <React.Fragment key={idx}>\n <Text\n color={\n client.type === 'connected'\n ? SEMANTIC_COLORS.success\n : SEMANTIC_COLORS.error\n }\n >\n {client.name}\n </Text>\n {idx < mcpClients.length - 1 && (\n <Text color={SEMANTIC_COLORS.muted}>, </Text>\n )}\n </React.Fragment>\n ))}\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * \u6781\u7B80\u7248\u9875\u7709 (\u53EA\u663E\u793A\u57FA\u672C\u4FE1\u606F)\n */\nexport function MinimalHeaderBar({\n tokenUsage = 0,\n}: {\n tokenUsage?: number\n}): React.ReactNode {\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n return (\n <Box flexDirection=\"row\" justifyContent=\"space-between\" paddingX={2}>\n {/* \u54C1\u724C + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* AI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n {currentModel && (\n <Text color={SEMANTIC_COLORS.dim}>\n {Math.round(tokenUsage / 1000)}k/\n {Math.round(currentModel.contextLength / 1000)}k\n </Text>\n )}\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,7 @@ import { Box, Text, useInput } from "ink";
7
7
  import { getTheme } from "../utils/theme.js";
8
8
  import { PressEnterToContinue } from "./PressEnterToContinue.js";
9
9
  import { MACRO } from "../constants/macros.js";
10
+ import { t } from "../i18n/index.js";
10
11
  function Help({
11
12
  commands,
12
13
  onClose
@@ -36,7 +37,7 @@ function Help({
36
37
  useInput((_, key) => {
37
38
  if (key.return || key.escape) onClose();
38
39
  });
39
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `${PRODUCT_NAME} v${MACRO.VERSION}`), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, PRODUCT_NAME, " is a beta research preview. Always review", " ", PRODUCT_NAME, "'s responses, especially when running code.", " ", PRODUCT_NAME, " has read access to files in the current directory and can run commands and edit files with your permission.")), count >= 1 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Usage Modes:"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 REPL: ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND), " (interactive session)"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Non-interactive:", " ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND, ' -p "question"')), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Run ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND, " -h"), " for all command line options"))), count >= 2 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Common Tasks:"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Ask questions about your codebase", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> How does foo.py work?")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Edit files", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> Update bar.ts to...")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Fix errors", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> cargo build")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Run commands", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> /help")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Run bash commands", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> !ls"))), count >= 3 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Built-in Commands:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, builtInCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description)))), customCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Custom Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, customCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"), cmd.scope && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " [", cmd.scope, "]"))))), pluginCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Plugin Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, pluginCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), mcpCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "MCP Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, mcpCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), (hasCustomCommands() || customCommands.length > 0 || pluginCommands.length > 0 || mcpCommands.length > 0) && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Commands are loaded in priority order:"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "1. Built-in commands (highest priority, alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "2. Custom commands (user/project, alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "3. Plugin commands (alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "4. MCP commands (alphabetically sorted)"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Use /refresh-commands to reload after changes")))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, moreHelp)), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(PressEnterToContinue, null)));
40
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `${PRODUCT_NAME} v${MACRO.VERSION}`), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, t("help.productDescription", { product: PRODUCT_NAME }))), count >= 1 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.usageModes")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 REPL: ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND), " (interactive session)"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.nonInteractive"), " ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND, ' -p "question"')), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, t("help.runForOptions", { command: PRODUCT_COMMAND })))), count >= 2 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.commonTasks")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.taskAskQuestions"), " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> How does foo.py work?")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.taskEditFiles"), " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> Update bar.ts to...")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.taskFixErrors"), " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> cargo build")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.taskRunCommands"), " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> /help")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("help.taskRunBash"), " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> !ls")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.modeSystems")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.safetyModes")), /* @__PURE__ */ React.createElement(Box, { marginLeft: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.safetyModeYolo")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.safetyModeSmart")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.safetyModeStrict")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.safetyModeFree"))), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.permissionModes")), /* @__PURE__ */ React.createElement(Box, { marginLeft: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.permissionModeDefault")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.permissionModeAcceptEdits")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.permissionModePlan")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.permissionModeBypass"))), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText, italic: true }, t("help.modeInteraction")))), count >= 3 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.builtInCommands")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, builtInCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description)))), customCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.customCommands"))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, customCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"), cmd.scope && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " [", cmd.scope, "]"))))), pluginCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.pluginCommands"))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, pluginCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), mcpCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("help.mcpCommands"))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, mcpCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), (hasCustomCommands() || customCommands.length > 0 || pluginCommands.length > 0 || mcpCommands.length > 0) && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.commandPriority")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.priorityBuiltIn")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.priorityCustom")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.priorityPlugin")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.priorityMcp")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("help.refreshCommandsHint"))))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, moreHelp)), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(PressEnterToContinue, null)));
40
41
  }
41
42
  export {
42
43
  Help
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/Help.tsx"],
4
- "sourcesContent": ["import { Command } from '@commands'\nimport { PRODUCT_COMMAND, PRODUCT_NAME } from '@constants/product'\nimport {\n getCustomCommandDirectories,\n hasCustomCommands,\n type CustomCommandWithScope,\n} from '@services/customCommands'\nimport * as React from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { PressEnterToContinue } from './PressEnterToContinue'\nimport { MACRO } from '@constants/macros'\n\n/**\n * Help Component - Interactive help system with progressive disclosure\n *\n * This component provides a comprehensive help interface that progressively\n * reveals information to avoid overwhelming users. It categorizes commands\n * into built-in and custom types, providing clear guidance on usage.\n *\n * The progressive disclosure pattern (count-based) ensures users can absorb\n * information at their own pace while maintaining a responsive interface.\n */\nexport function Help({\n commands,\n onClose,\n}: {\n commands: Command[]\n onClose: () => void\n}): React.ReactNode {\n const theme = getTheme()\n const moreHelp = `Learn more at: ${MACRO.README_URL}`\n\n // Filter out hidden commands from the help display\n const filteredCommands = commands.filter(cmd => !cmd.isHidden)\n\n // Categorize commands by their source/type\n const builtInCommands = filteredCommands\n .filter(\n cmd =>\n !cmd.name.startsWith('project:') &&\n !cmd.name.startsWith('user:') &&\n !cmd.name.startsWith('plugin:') &&\n !cmd.name.startsWith('mcp:'),\n )\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // Custom commands (user: and project: prefixes)\n const customCommands = filteredCommands\n .filter(\n cmd => cmd.name.startsWith('project:') || cmd.name.startsWith('user:'),\n )\n .sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n ) as CustomCommandWithScope[]\n\n // Plugin commands\n const pluginCommands = filteredCommands\n .filter(cmd => cmd.name.startsWith('plugin:'))\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // MCP commands\n const mcpCommands = filteredCommands\n .filter(cmd => cmd.name.startsWith('mcp:'))\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // Progressive disclosure state for managing information flow\n const [count, setCount] = React.useState(0)\n\n // Timer-based progressive disclosure to prevent information overload\n React.useEffect(() => {\n const timer = setTimeout(() => {\n if (count < 3) {\n setCount(count + 1)\n }\n }, 250)\n\n return () => clearTimeout(timer)\n }, [count])\n\n // Handle Enter or Esc key to close help\n useInput((_, key) => {\n if (key.return || key.escape) onClose()\n })\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text bold color={theme.minto}>\n {`${PRODUCT_NAME} v${MACRO.VERSION}`}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n {PRODUCT_NAME} is a beta research preview. Always review{' '}\n {PRODUCT_NAME}&apos;s responses, especially when running code.{' '}\n {PRODUCT_NAME} has read access to files in the current directory and\n can run commands and edit files with your permission.\n </Text>\n </Box>\n\n {count >= 1 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>Usage Modes:</Text>\n <Text>\n \u2022 REPL: <Text bold>{PRODUCT_COMMAND}</Text> (interactive session)\n </Text>\n <Text>\n \u2022 Non-interactive:{' '}\n <Text bold>{PRODUCT_COMMAND} -p &quot;question&quot;</Text>\n </Text>\n <Box marginTop={1}>\n <Text>\n Run <Text bold>{PRODUCT_COMMAND} -h</Text> for all command line\n options\n </Text>\n </Box>\n </Box>\n )}\n\n {count >= 2 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Common Tasks:</Text>\n <Text>\n \u2022 Ask questions about your codebase{' '}\n <Text color={getTheme().secondaryText}>\n &gt; How does foo.py work?\n </Text>\n </Text>\n <Text>\n \u2022 Edit files{' '}\n <Text color={getTheme().secondaryText}>\n &gt; Update bar.ts to...\n </Text>\n </Text>\n <Text>\n \u2022 Fix errors{' '}\n <Text color={getTheme().secondaryText}>&gt; cargo build</Text>\n </Text>\n <Text>\n \u2022 Run commands{' '}\n <Text color={getTheme().secondaryText}>&gt; /help</Text>\n </Text>\n <Text>\n \u2022 Run bash commands{' '}\n <Text color={getTheme().secondaryText}>&gt; !ls</Text>\n </Text>\n </Box>\n )}\n\n {count >= 3 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Built-in Commands:</Text>\n\n <Box flexDirection=\"column\">\n {builtInCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n </Box>\n ))}\n </Box>\n\n {customCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>Custom Commands:</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {customCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n {/* Show scope indicator for debugging */}\n {cmd.scope && (\n <Text color={theme.secondaryText}> [{cmd.scope}]</Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {pluginCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>Plugin Commands:</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {pluginCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {mcpCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>MCP Commands:</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {mcpCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {/* Show command loading information */}\n {(hasCustomCommands() ||\n customCommands.length > 0 ||\n pluginCommands.length > 0 ||\n mcpCommands.length > 0) && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={theme.secondaryText}>\n Commands are loaded in priority order:\n </Text>\n <Text color={theme.secondaryText}>\n 1. Built-in commands (highest priority, alphabetically sorted)\n </Text>\n <Text color={theme.secondaryText}>\n 2. Custom commands (user/project, alphabetically sorted)\n </Text>\n <Text color={theme.secondaryText}>\n 3. Plugin commands (alphabetically sorted)\n </Text>\n <Text color={theme.secondaryText}>\n 4. MCP commands (alphabetically sorted)\n </Text>\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>\n Use /refresh-commands to reload after changes\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>{moreHelp}</Text>\n </Box>\n\n <Box marginTop={2}>\n <PressEnterToContinue />\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Command } from '@commands'\nimport { PRODUCT_COMMAND, PRODUCT_NAME } from '@constants/product'\nimport {\n getCustomCommandDirectories,\n hasCustomCommands,\n type CustomCommandWithScope,\n} from '@services/customCommands'\nimport * as React from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { PressEnterToContinue } from './PressEnterToContinue'\nimport { MACRO } from '@constants/macros'\nimport { t } from '@i18n'\n\n/**\n * Help Component - Interactive help system with progressive disclosure\n *\n * This component provides a comprehensive help interface that progressively\n * reveals information to avoid overwhelming users. It categorizes commands\n * into built-in and custom types, providing clear guidance on usage.\n *\n * The progressive disclosure pattern (count-based) ensures users can absorb\n * information at their own pace while maintaining a responsive interface.\n */\nexport function Help({\n commands,\n onClose,\n}: {\n commands: Command[]\n onClose: () => void\n}): React.ReactNode {\n const theme = getTheme()\n const moreHelp = `Learn more at: ${MACRO.README_URL}`\n\n // Filter out hidden commands from the help display\n const filteredCommands = commands.filter(cmd => !cmd.isHidden)\n\n // Categorize commands by their source/type\n const builtInCommands = filteredCommands\n .filter(\n cmd =>\n !cmd.name.startsWith('project:') &&\n !cmd.name.startsWith('user:') &&\n !cmd.name.startsWith('plugin:') &&\n !cmd.name.startsWith('mcp:'),\n )\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // Custom commands (user: and project: prefixes)\n const customCommands = filteredCommands\n .filter(\n cmd => cmd.name.startsWith('project:') || cmd.name.startsWith('user:'),\n )\n .sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n ) as CustomCommandWithScope[]\n\n // Plugin commands\n const pluginCommands = filteredCommands\n .filter(cmd => cmd.name.startsWith('plugin:'))\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // MCP commands\n const mcpCommands = filteredCommands\n .filter(cmd => cmd.name.startsWith('mcp:'))\n .sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()))\n\n // Progressive disclosure state for managing information flow\n const [count, setCount] = React.useState(0)\n\n // Timer-based progressive disclosure to prevent information overload\n React.useEffect(() => {\n const timer = setTimeout(() => {\n if (count < 3) {\n setCount(count + 1)\n }\n }, 250)\n\n return () => clearTimeout(timer)\n }, [count])\n\n // Handle Enter or Esc key to close help\n useInput((_, key) => {\n if (key.return || key.escape) onClose()\n })\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text bold color={theme.minto}>\n {`${PRODUCT_NAME} v${MACRO.VERSION}`}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>{t('help.productDescription', { product: PRODUCT_NAME })}</Text>\n </Box>\n\n {count >= 1 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>{t('help.usageModes')}</Text>\n <Text>\n \u2022 REPL: <Text bold>{PRODUCT_COMMAND}</Text> (interactive session)\n </Text>\n <Text>\n \u2022 {t('help.nonInteractive')}{' '}\n <Text bold>{PRODUCT_COMMAND} -p &quot;question&quot;</Text>\n </Text>\n <Box marginTop={1}>\n <Text>{t('help.runForOptions', { command: PRODUCT_COMMAND })}</Text>\n </Box>\n </Box>\n )}\n\n {count >= 2 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>{t('help.commonTasks')}</Text>\n <Text>\n \u2022 {t('help.taskAskQuestions')}{' '}\n <Text color={getTheme().secondaryText}>\n &gt; How does foo.py work?\n </Text>\n </Text>\n <Text>\n \u2022 {t('help.taskEditFiles')}{' '}\n <Text color={getTheme().secondaryText}>\n &gt; Update bar.ts to...\n </Text>\n </Text>\n <Text>\n \u2022 {t('help.taskFixErrors')}{' '}\n <Text color={getTheme().secondaryText}>&gt; cargo build</Text>\n </Text>\n <Text>\n \u2022 {t('help.taskRunCommands')}{' '}\n <Text color={getTheme().secondaryText}>&gt; /help</Text>\n </Text>\n <Text>\n \u2022 {t('help.taskRunBash')}{' '}\n <Text color={getTheme().secondaryText}>&gt; !ls</Text>\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>{t('help.modeSystems')}</Text>\n <Text color={theme.secondaryText}>{t('help.safetyModes')}</Text>\n <Box marginLeft={1} flexDirection=\"column\">\n <Text color={theme.secondaryText}>\n {t('help.safetyModeYolo')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.safetyModeSmart')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.safetyModeStrict')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.safetyModeFree')}\n </Text>\n </Box>\n <Text color={theme.secondaryText}>{t('help.permissionModes')}</Text>\n <Box marginLeft={1} flexDirection=\"column\">\n <Text color={theme.secondaryText}>\n {t('help.permissionModeDefault')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.permissionModeAcceptEdits')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.permissionModePlan')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.permissionModeBypass')}\n </Text>\n </Box>\n <Text color={theme.secondaryText} italic>\n {t('help.modeInteraction')}\n </Text>\n </Box>\n </Box>\n )}\n\n {count >= 3 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>{t('help.builtInCommands')}</Text>\n\n <Box flexDirection=\"column\">\n {builtInCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n </Box>\n ))}\n </Box>\n\n {customCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>{t('help.customCommands')}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {customCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n {/* Show scope indicator for debugging */}\n {cmd.scope && (\n <Text color={theme.secondaryText}> [{cmd.scope}]</Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {pluginCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>{t('help.pluginCommands')}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {pluginCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {mcpCommands.length > 0 && (\n <>\n <Box marginTop={1}>\n <Text bold>{t('help.mcpCommands')}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {mcpCommands.map((cmd, i) => (\n <Box key={i} marginLeft={1}>\n <Text bold color={theme.minto}>{`/${cmd.name}`}</Text>\n <Text> - {cmd.description}</Text>\n {cmd.aliases && cmd.aliases.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n (aliases: {cmd.aliases.join(', ')})\n </Text>\n )}\n </Box>\n ))}\n </Box>\n </>\n )}\n\n {/* Show command loading information */}\n {(hasCustomCommands() ||\n customCommands.length > 0 ||\n pluginCommands.length > 0 ||\n mcpCommands.length > 0) && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={theme.secondaryText}>\n {t('help.commandPriority')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.priorityBuiltIn')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.priorityCustom')}\n </Text>\n <Text color={theme.secondaryText}>\n {t('help.priorityPlugin')}\n </Text>\n <Text color={theme.secondaryText}>{t('help.priorityMcp')}</Text>\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>\n {t('help.refreshCommandsHint')}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>{moreHelp}</Text>\n </Box>\n\n <Box marginTop={2}>\n <PressEnterToContinue />\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,43 +2,45 @@ import { Box, Text, useInput } from "ink";
2
2
  import * as React from "react";
3
3
  import { t } from "../i18n/index.js";
4
4
  import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../constants/colors.js";
5
- const HOTKEY_GROUPS = [
6
- {
7
- title: "Navigation",
8
- hotkeys: [
9
- { keys: "\u2191/\u2193", description: "Browse command history" },
10
- { keys: "Ctrl+R", description: "Search command history" },
11
- { keys: "Tab", description: "Autocomplete commands/paths" },
12
- { keys: "Esc Esc", description: "Rollback last response" }
13
- ]
14
- },
15
- {
16
- title: "Control",
17
- hotkeys: [
18
- { keys: "Ctrl+C", description: "Cancel current operation" },
19
- { keys: "Ctrl+D", description: "Exit (press twice)" },
20
- { keys: "Ctrl+L", description: "Clear screen" },
21
- { keys: "Enter", description: "Submit prompt" }
22
- ]
23
- },
24
- {
25
- title: "Features",
26
- hotkeys: [
27
- { keys: "Ctrl+T", description: "Toggle todo panel" },
28
- { keys: "Ctrl+O", description: "Cycle display mode" },
29
- { keys: "Ctrl+B", description: "Execute as bash command" },
30
- { keys: "Ctrl+?", description: "Show/hide this help" }
31
- ]
32
- },
33
- {
34
- title: "Input Modes",
35
- hotkeys: [
36
- { keys: "/", description: "Start a slash command" },
37
- { keys: "!", description: "Execute bash command" },
38
- { keys: "#", description: "Add note to KODING.md" }
39
- ]
40
- }
41
- ];
5
+ function getHotkeyGroups() {
6
+ return [
7
+ {
8
+ title: t("hotkey.navigation"),
9
+ hotkeys: [
10
+ { keys: "\u2191/\u2193", description: t("hotkey.browseHistory") },
11
+ { keys: "Ctrl+R", description: t("hotkey.searchHistory") },
12
+ { keys: "Tab", description: t("hotkey.autocomplete") },
13
+ { keys: "Esc Esc", description: t("hotkey.rollbackResponse") }
14
+ ]
15
+ },
16
+ {
17
+ title: t("hotkey.control"),
18
+ hotkeys: [
19
+ { keys: "Ctrl+C", description: t("hotkey.cancelOperation") },
20
+ { keys: "Ctrl+D", description: t("hotkey.exitPressTwice") },
21
+ { keys: "Ctrl+L", description: t("hotkey.clearScreen") },
22
+ { keys: "Enter", description: t("hotkey.submitPrompt") }
23
+ ]
24
+ },
25
+ {
26
+ title: t("hotkey.features"),
27
+ hotkeys: [
28
+ { keys: "Ctrl+T", description: t("hotkey.toggleTodoPanel") },
29
+ { keys: "Ctrl+O", description: t("hotkey.cycleDisplayMode") },
30
+ { keys: "Ctrl+B", description: t("hotkey.executeAsBash") },
31
+ { keys: "Ctrl+?", description: t("hotkey.showHideHelp") }
32
+ ]
33
+ },
34
+ {
35
+ title: t("hotkey.inputModes"),
36
+ hotkeys: [
37
+ { keys: "/", description: t("hotkey.startSlashCommand") },
38
+ { keys: "!", description: t("hotkey.executeBashCommand") },
39
+ { keys: "#", description: t("hotkey.addNoteToKoding") }
40
+ ]
41
+ }
42
+ ];
43
+ }
42
44
  function HotkeyHelpPanel({
43
45
  onClose,
44
46
  isVisible
@@ -65,22 +67,22 @@ function HotkeyHelpPanel({
65
67
  marginBottom: 1
66
68
  },
67
69
  /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: BRAND_GRADIENT.START }, "\u2328\uFE0F ", t("ui.hints.shortcuts")), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, " ", "(", t("ui.hints.pressEsc"), ")")),
68
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 4 }, HOTKEY_GROUPS.map((group, groupIndex) => /* @__PURE__ */ React.createElement(Box, { key: groupIndex, flexDirection: "column", minWidth: 28 }, /* @__PURE__ */ React.createElement(Text, { bold: true, underline: true, color: SEMANTIC_COLORS.secondary }, group.title), group.hotkeys.map((hotkey, hotkeyIndex) => /* @__PURE__ */ React.createElement(Box, { key: hotkeyIndex }, /* @__PURE__ */ React.createElement(Box, { width: 12 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: BRAND_GRADIENT.MIDDLE }, hotkey.keys)), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.primary }, hotkey.description)))))),
70
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 4 }, getHotkeyGroups().map((group, groupIndex) => /* @__PURE__ */ React.createElement(Box, { key: groupIndex, flexDirection: "column", minWidth: 28 }, /* @__PURE__ */ React.createElement(Text, { bold: true, underline: true, color: SEMANTIC_COLORS.secondary }, group.title), group.hotkeys.map((hotkey, hotkeyIndex) => /* @__PURE__ */ React.createElement(Box, { key: hotkeyIndex }, /* @__PURE__ */ React.createElement(Box, { width: 12 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: BRAND_GRADIENT.MIDDLE }, hotkey.keys)), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.primary }, hotkey.description)))))),
69
71
  /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, t("ui.hints.tip")))
70
72
  );
71
73
  }
72
74
  function HotkeyHint() {
73
- return /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Ctrl+? for shortcuts");
75
+ return /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, t("hotkey.ctrlQuestionForShortcuts"));
74
76
  }
75
77
  function getContextHints(context) {
76
78
  switch (context) {
77
79
  case "idle":
78
80
  return [
79
- { keys: "!", description: "for bash mode" },
80
- { keys: "#", description: "for MINTO.md" },
81
- { keys: "/", description: "for commands" },
82
- { keys: "ctrl+c", description: "cancel" },
83
- { keys: "ctrl+l", description: "clear" }
81
+ { keys: "!", description: t("ui.hints.forBashMode") },
82
+ { keys: "#", description: t("ui.hints.forMintoMd") },
83
+ { keys: "/", description: t("ui.hints.forCommands") },
84
+ { keys: "ctrl+c", description: t("common.cancel") },
85
+ { keys: "ctrl+l", description: t("common.clear") }
84
86
  ];
85
87
  case "typing":
86
88
  return [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/HotkeyHelpPanel.tsx"],
4
- "sourcesContent": ["/**\n * Hotkey Help Panel Component\n *\n * Displays a compact overlay showing available keyboard shortcuts.\n * Toggled with Ctrl+? or Ctrl+/ for quick reference.\n */\n\nimport { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { t } from '@i18n'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\n\ninterface HotkeyGroup {\n title: string\n hotkeys: Array<{\n keys: string\n description: string\n }>\n}\n\nconst HOTKEY_GROUPS: HotkeyGroup[] = [\n {\n title: 'Navigation',\n hotkeys: [\n { keys: '\u2191/\u2193', description: 'Browse command history' },\n { keys: 'Ctrl+R', description: 'Search command history' },\n { keys: 'Tab', description: 'Autocomplete commands/paths' },\n { keys: 'Esc Esc', description: 'Rollback last response' },\n ],\n },\n {\n title: 'Control',\n hotkeys: [\n { keys: 'Ctrl+C', description: 'Cancel current operation' },\n { keys: 'Ctrl+D', description: 'Exit (press twice)' },\n { keys: 'Ctrl+L', description: 'Clear screen' },\n { keys: 'Enter', description: 'Submit prompt' },\n ],\n },\n {\n title: 'Features',\n hotkeys: [\n { keys: 'Ctrl+T', description: 'Toggle todo panel' },\n { keys: 'Ctrl+O', description: 'Cycle display mode' },\n { keys: 'Ctrl+B', description: 'Execute as bash command' },\n { keys: 'Ctrl+?', description: 'Show/hide this help' },\n ],\n },\n {\n title: 'Input Modes',\n hotkeys: [\n { keys: '/', description: 'Start a slash command' },\n { keys: '!', description: 'Execute bash command' },\n { keys: '#', description: 'Add note to KODING.md' },\n ],\n },\n]\n\ninterface Props {\n onClose: () => void\n isVisible: boolean\n}\n\nexport function HotkeyHelpPanel({\n onClose,\n isVisible,\n}: Props): React.ReactNode {\n // Handle Escape or Ctrl+? to close\n useInput(\n (input, key) => {\n if (key.escape || (key.ctrl && (input === '?' || input === '/'))) {\n onClose()\n }\n },\n { isActive: isVisible },\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={BRAND_GRADIENT.START}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box marginBottom={1}>\n <Text bold color={BRAND_GRADIENT.START}>\n \u2328\uFE0F {t('ui.hints.shortcuts')}\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}>\n {' '}\n ({t('ui.hints.pressEsc')})\n </Text>\n </Box>\n\n <Box flexDirection=\"row\" gap={4}>\n {HOTKEY_GROUPS.map((group, groupIndex) => (\n <Box key={groupIndex} flexDirection=\"column\" minWidth={28}>\n <Text bold underline color={SEMANTIC_COLORS.secondary}>\n {group.title}\n </Text>\n {group.hotkeys.map((hotkey, hotkeyIndex) => (\n <Box key={hotkeyIndex}>\n <Box width={12}>\n <Text bold color={BRAND_GRADIENT.MIDDLE}>\n {hotkey.keys}\n </Text>\n </Box>\n <Text color={SEMANTIC_COLORS.primary}>\n {hotkey.description}\n </Text>\n </Box>\n ))}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{t('ui.hints.tip')}</Text>\n </Box>\n </Box>\n )\n}\n\n/**\n * Compact inline hotkey hint shown in the prompt area\n */\nexport function HotkeyHint(): React.ReactNode {\n return <Text color={SEMANTIC_COLORS.dim}>Ctrl+? for shortcuts</Text>\n}\n\n/**\n * Context state for determining which hints to show\n */\nexport type InputContext =\n | 'idle' // Empty input, ready for new command\n | 'typing' // User is typing a prompt\n | 'loading' // Request is being processed\n | 'completion' // Autocomplete suggestions visible\n | 'history_search' // Ctrl+R history search active\n | 'slash_command' // Typing a slash command\n\ninterface ContextHint {\n keys: string\n description: string\n}\n\n/**\n * Get context-specific hotkey hints based on current input state\n */\nfunction getContextHints(context: InputContext): ContextHint[] {\n switch (context) {\n case 'idle':\n return [\n { keys: '!', description: 'for bash mode' },\n { keys: '#', description: 'for MINTO.md' },\n { keys: '/', description: 'for commands' },\n { keys: 'ctrl+c', description: 'cancel' },\n { keys: 'ctrl+l', description: 'clear' },\n ]\n case 'typing':\n return [\n { keys: 'Enter', description: t('ui.hints.send') },\n { keys: 'Tab', description: t('ui.hints.complete') },\n { keys: 'Ctrl+B', description: t('ui.hints.bash') },\n { keys: 'Esc', description: t('common.clear') },\n ]\n case 'loading':\n return [\n { keys: 'Ctrl+C', description: t('common.cancel') },\n { keys: 'Esc Esc', description: t('ui.hints.rollback') },\n ]\n case 'completion':\n return [\n { keys: '\u2191/\u2193', description: t('ui.hints.select') },\n { keys: 'Tab', description: t('ui.hints.confirm') },\n { keys: 'Esc', description: t('ui.hints.close') },\n ]\n case 'history_search':\n return [\n { keys: '\u2191/\u2193', description: t('ui.hints.browse') },\n { keys: 'Enter', description: t('ui.hints.select') },\n { keys: 'Esc', description: t('common.cancel') },\n ]\n case 'slash_command':\n return [\n { keys: 'Tab', description: t('ui.hints.completeCommand') },\n { keys: 'Enter', description: t('ui.hints.execute') },\n { keys: 'Esc', description: t('common.cancel') },\n ]\n default:\n return [{ keys: 'Ctrl+?', description: t('common.help') }]\n }\n}\n\ninterface ContextAwareHintsProps {\n context: InputContext\n compact?: boolean // When true, show minimal hints\n}\n\n/**\n * Context-aware hotkey hints that adapt based on user's current activity\n * Shows relevant shortcuts for the current state without overwhelming the user\n */\nexport function ContextAwareHints({\n context,\n compact = true,\n}: ContextAwareHintsProps): React.ReactNode {\n const hints = getContextHints(context)\n\n if (compact) {\n // Single line, condensed format (0.1.7 style with \u00B7 separator)\n return (\n <Box>\n {hints.map((hint, i) => (\n <React.Fragment key={i}>\n {i > 0 && <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>}\n <Text color={SEMANTIC_COLORS.dim}>\n {hint.keys} {hint.description}\n </Text>\n </React.Fragment>\n ))}\n </Box>\n )\n }\n\n // Expanded format with more padding\n return (\n <Box gap={2}>\n {hints.map((hint, i) => (\n <Box key={i}>\n <Text bold color={BRAND_GRADIENT.MIDDLE}>\n {hint.keys}\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}> {hint.description}</Text>\n </Box>\n ))}\n </Box>\n )\n}\n"],
5
- "mappings": "AAOA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,gBAAgB,uBAAuB;AAUhD,MAAM,gBAA+B;AAAA,EACnC;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,MACP,EAAE,MAAM,iBAAO,aAAa,yBAAyB;AAAA,MACrD,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,MACxD,EAAE,MAAM,OAAO,aAAa,8BAA8B;AAAA,MAC1D,EAAE,MAAM,WAAW,aAAa,yBAAyB;AAAA,IAC3D;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,MACP,EAAE,MAAM,UAAU,aAAa,2BAA2B;AAAA,MAC1D,EAAE,MAAM,UAAU,aAAa,qBAAqB;AAAA,MACpD,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,MAC9C,EAAE,MAAM,SAAS,aAAa,gBAAgB;AAAA,IAChD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,MACP,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,MACnD,EAAE,MAAM,UAAU,aAAa,qBAAqB;AAAA,MACpD,EAAE,MAAM,UAAU,aAAa,0BAA0B;AAAA,MACzD,EAAE,MAAM,UAAU,aAAa,sBAAsB;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,MACP,EAAE,MAAM,KAAK,aAAa,wBAAwB;AAAA,MAClD,EAAE,MAAM,KAAK,aAAa,uBAAuB;AAAA,MACjD,EAAE,MAAM,KAAK,aAAa,wBAAwB;AAAA,IACpD;AAAA,EACF;AACF;AAOO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAA2B;AAEzB;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,IAAI,UAAW,IAAI,SAAS,UAAU,OAAO,UAAU,MAAO;AAChE,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,EAAE,UAAU,UAAU;AAAA,EACxB;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,aAAY;AAAA,MACZ,aAAa,eAAe;AAAA,MAC5B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,cAAc;AAAA;AAAA,IAEd,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,SAAO,iBAClC,EAAE,oBAAoB,CAC5B,GACA,oCAAC,QAAK,OAAO,gBAAgB,aAC1B,KAAI,KACH,EAAE,mBAAmB,GAAE,GAC3B,CACF;AAAA,IAEA,oCAAC,OAAI,eAAc,OAAM,KAAK,KAC3B,cAAc,IAAI,CAAC,OAAO,eACzB,oCAAC,OAAI,KAAK,YAAY,eAAc,UAAS,UAAU,MACrD,oCAAC,QAAK,MAAI,MAAC,WAAS,MAAC,OAAO,gBAAgB,aACzC,MAAM,KACT,GACC,MAAM,QAAQ,IAAI,CAAC,QAAQ,gBAC1B,oCAAC,OAAI,KAAK,eACR,oCAAC,OAAI,OAAO,MACV,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,UAC9B,OAAO,IACV,CACF,GACA,oCAAC,QAAK,OAAO,gBAAgB,WAC1B,OAAO,WACV,CACF,CACD,CACH,CACD,CACH;AAAA,IAEA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,gBAAgB,OAAM,EAAE,cAAc,CAAE,CACvD;AAAA,EACF;AAEJ;AAKO,SAAS,aAA8B;AAC5C,SAAO,oCAAC,QAAK,OAAO,gBAAgB,OAAK,sBAAoB;AAC/D;AAqBA,SAAS,gBAAgB,SAAsC;AAC7D,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,KAAK,aAAa,gBAAgB;AAAA,QAC1C,EAAE,MAAM,KAAK,aAAa,eAAe;AAAA,QACzC,EAAE,MAAM,KAAK,aAAa,eAAe;AAAA,QACzC,EAAE,MAAM,UAAU,aAAa,SAAS;AAAA,QACxC,EAAE,MAAM,UAAU,aAAa,QAAQ;AAAA,MACzC;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,SAAS,aAAa,EAAE,eAAe,EAAE;AAAA,QACjD,EAAE,MAAM,OAAO,aAAa,EAAE,mBAAmB,EAAE;AAAA,QACnD,EAAE,MAAM,UAAU,aAAa,EAAE,eAAe,EAAE;AAAA,QAClD,EAAE,MAAM,OAAO,aAAa,EAAE,cAAc,EAAE;AAAA,MAChD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,UAAU,aAAa,EAAE,eAAe,EAAE;AAAA,QAClD,EAAE,MAAM,WAAW,aAAa,EAAE,mBAAmB,EAAE;AAAA,MACzD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,iBAAO,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACjD,EAAE,MAAM,OAAO,aAAa,EAAE,kBAAkB,EAAE;AAAA,QAClD,EAAE,MAAM,OAAO,aAAa,EAAE,gBAAgB,EAAE;AAAA,MAClD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,iBAAO,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACjD,EAAE,MAAM,SAAS,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACnD,EAAE,MAAM,OAAO,aAAa,EAAE,eAAe,EAAE;AAAA,MACjD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,OAAO,aAAa,EAAE,0BAA0B,EAAE;AAAA,QAC1D,EAAE,MAAM,SAAS,aAAa,EAAE,kBAAkB,EAAE;AAAA,QACpD,EAAE,MAAM,OAAO,aAAa,EAAE,eAAe,EAAE;AAAA,MACjD;AAAA,IACF;AACE,aAAO,CAAC,EAAE,MAAM,UAAU,aAAa,EAAE,aAAa,EAAE,CAAC;AAAA,EAC7D;AACF;AAWO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,UAAU;AACZ,GAA4C;AAC1C,QAAM,QAAQ,gBAAgB,OAAO;AAErC,MAAI,SAAS;AAEX,WACE,oCAAC,WACE,MAAM,IAAI,CAAC,MAAM,MAChB,oCAAC,MAAM,UAAN,EAAe,KAAK,KAClB,IAAI,KAAK,oCAAC,QAAK,OAAO,gBAAgB,OAAK,QAAG,GAC/C,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,KAAK,MAAK,KAAE,KAAK,WACpB,CACF,CACD,CACH;AAAA,EAEJ;AAGA,SACE,oCAAC,OAAI,KAAK,KACP,MAAM,IAAI,CAAC,MAAM,MAChB,oCAAC,OAAI,KAAK,KACR,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,UAC9B,KAAK,IACR,GACA,oCAAC,QAAK,OAAO,gBAAgB,aAAW,KAAE,KAAK,WAAY,CAC7D,CACD,CACH;AAEJ;",
4
+ "sourcesContent": ["/**\n * Hotkey Help Panel Component\n *\n * Displays a compact overlay showing available keyboard shortcuts.\n * Toggled with Ctrl+? or Ctrl+/ for quick reference.\n */\n\nimport { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { t } from '@i18n'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\n\ninterface HotkeyGroup {\n title: string\n hotkeys: Array<{\n keys: string\n description: string\n }>\n}\n\n// Build hotkey groups dynamically to support i18n\nfunction getHotkeyGroups(): HotkeyGroup[] {\n return [\n {\n title: t('hotkey.navigation'),\n hotkeys: [\n { keys: '\u2191/\u2193', description: t('hotkey.browseHistory') },\n { keys: 'Ctrl+R', description: t('hotkey.searchHistory') },\n { keys: 'Tab', description: t('hotkey.autocomplete') },\n { keys: 'Esc Esc', description: t('hotkey.rollbackResponse') },\n ],\n },\n {\n title: t('hotkey.control'),\n hotkeys: [\n { keys: 'Ctrl+C', description: t('hotkey.cancelOperation') },\n { keys: 'Ctrl+D', description: t('hotkey.exitPressTwice') },\n { keys: 'Ctrl+L', description: t('hotkey.clearScreen') },\n { keys: 'Enter', description: t('hotkey.submitPrompt') },\n ],\n },\n {\n title: t('hotkey.features'),\n hotkeys: [\n { keys: 'Ctrl+T', description: t('hotkey.toggleTodoPanel') },\n { keys: 'Ctrl+O', description: t('hotkey.cycleDisplayMode') },\n { keys: 'Ctrl+B', description: t('hotkey.executeAsBash') },\n { keys: 'Ctrl+?', description: t('hotkey.showHideHelp') },\n ],\n },\n {\n title: t('hotkey.inputModes'),\n hotkeys: [\n { keys: '/', description: t('hotkey.startSlashCommand') },\n { keys: '!', description: t('hotkey.executeBashCommand') },\n { keys: '#', description: t('hotkey.addNoteToKoding') },\n ],\n },\n ]\n}\n\ninterface Props {\n onClose: () => void\n isVisible: boolean\n}\n\nexport function HotkeyHelpPanel({\n onClose,\n isVisible,\n}: Props): React.ReactNode {\n // Handle Escape or Ctrl+? to close\n useInput(\n (input, key) => {\n if (key.escape || (key.ctrl && (input === '?' || input === '/'))) {\n onClose()\n }\n },\n { isActive: isVisible },\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={BRAND_GRADIENT.START}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box marginBottom={1}>\n <Text bold color={BRAND_GRADIENT.START}>\n \u2328\uFE0F {t('ui.hints.shortcuts')}\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}>\n {' '}\n ({t('ui.hints.pressEsc')})\n </Text>\n </Box>\n\n <Box flexDirection=\"row\" gap={4}>\n {getHotkeyGroups().map((group, groupIndex) => (\n <Box key={groupIndex} flexDirection=\"column\" minWidth={28}>\n <Text bold underline color={SEMANTIC_COLORS.secondary}>\n {group.title}\n </Text>\n {group.hotkeys.map((hotkey, hotkeyIndex) => (\n <Box key={hotkeyIndex}>\n <Box width={12}>\n <Text bold color={BRAND_GRADIENT.MIDDLE}>\n {hotkey.keys}\n </Text>\n </Box>\n <Text color={SEMANTIC_COLORS.primary}>\n {hotkey.description}\n </Text>\n </Box>\n ))}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{t('ui.hints.tip')}</Text>\n </Box>\n </Box>\n )\n}\n\n/**\n * Compact inline hotkey hint shown in the prompt area\n */\nexport function HotkeyHint(): React.ReactNode {\n return (\n <Text color={SEMANTIC_COLORS.dim}>\n {t('hotkey.ctrlQuestionForShortcuts')}\n </Text>\n )\n}\n\n/**\n * Context state for determining which hints to show\n */\nexport type InputContext =\n | 'idle' // Empty input, ready for new command\n | 'typing' // User is typing a prompt\n | 'loading' // Request is being processed\n | 'completion' // Autocomplete suggestions visible\n | 'history_search' // Ctrl+R history search active\n | 'slash_command' // Typing a slash command\n\ninterface ContextHint {\n keys: string\n description: string\n}\n\n/**\n * Get context-specific hotkey hints based on current input state\n */\nfunction getContextHints(context: InputContext): ContextHint[] {\n switch (context) {\n case 'idle':\n return [\n { keys: '!', description: t('ui.hints.forBashMode') },\n { keys: '#', description: t('ui.hints.forMintoMd') },\n { keys: '/', description: t('ui.hints.forCommands') },\n { keys: 'ctrl+c', description: t('common.cancel') },\n { keys: 'ctrl+l', description: t('common.clear') },\n ]\n case 'typing':\n return [\n { keys: 'Enter', description: t('ui.hints.send') },\n { keys: 'Tab', description: t('ui.hints.complete') },\n { keys: 'Ctrl+B', description: t('ui.hints.bash') },\n { keys: 'Esc', description: t('common.clear') },\n ]\n case 'loading':\n return [\n { keys: 'Ctrl+C', description: t('common.cancel') },\n { keys: 'Esc Esc', description: t('ui.hints.rollback') },\n ]\n case 'completion':\n return [\n { keys: '\u2191/\u2193', description: t('ui.hints.select') },\n { keys: 'Tab', description: t('ui.hints.confirm') },\n { keys: 'Esc', description: t('ui.hints.close') },\n ]\n case 'history_search':\n return [\n { keys: '\u2191/\u2193', description: t('ui.hints.browse') },\n { keys: 'Enter', description: t('ui.hints.select') },\n { keys: 'Esc', description: t('common.cancel') },\n ]\n case 'slash_command':\n return [\n { keys: 'Tab', description: t('ui.hints.completeCommand') },\n { keys: 'Enter', description: t('ui.hints.execute') },\n { keys: 'Esc', description: t('common.cancel') },\n ]\n default:\n return [{ keys: 'Ctrl+?', description: t('common.help') }]\n }\n}\n\ninterface ContextAwareHintsProps {\n context: InputContext\n compact?: boolean // When true, show minimal hints\n}\n\n/**\n * Context-aware hotkey hints that adapt based on user's current activity\n * Shows relevant shortcuts for the current state without overwhelming the user\n */\nexport function ContextAwareHints({\n context,\n compact = true,\n}: ContextAwareHintsProps): React.ReactNode {\n const hints = getContextHints(context)\n\n if (compact) {\n // Single line, condensed format (0.1.7 style with \u00B7 separator)\n return (\n <Box>\n {hints.map((hint, i) => (\n <React.Fragment key={i}>\n {i > 0 && <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>}\n <Text color={SEMANTIC_COLORS.dim}>\n {hint.keys} {hint.description}\n </Text>\n </React.Fragment>\n ))}\n </Box>\n )\n }\n\n // Expanded format with more padding\n return (\n <Box gap={2}>\n {hints.map((hint, i) => (\n <Box key={i}>\n <Text bold color={BRAND_GRADIENT.MIDDLE}>\n {hint.keys}\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}> {hint.description}</Text>\n </Box>\n ))}\n </Box>\n )\n}\n"],
5
+ "mappings": "AAOA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,gBAAgB,uBAAuB;AAWhD,SAAS,kBAAiC;AACxC,SAAO;AAAA,IACL;AAAA,MACE,OAAO,EAAE,mBAAmB;AAAA,MAC5B,SAAS;AAAA,QACP,EAAE,MAAM,iBAAO,aAAa,EAAE,sBAAsB,EAAE;AAAA,QACtD,EAAE,MAAM,UAAU,aAAa,EAAE,sBAAsB,EAAE;AAAA,QACzD,EAAE,MAAM,OAAO,aAAa,EAAE,qBAAqB,EAAE;AAAA,QACrD,EAAE,MAAM,WAAW,aAAa,EAAE,yBAAyB,EAAE;AAAA,MAC/D;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO,EAAE,gBAAgB;AAAA,MACzB,SAAS;AAAA,QACP,EAAE,MAAM,UAAU,aAAa,EAAE,wBAAwB,EAAE;AAAA,QAC3D,EAAE,MAAM,UAAU,aAAa,EAAE,uBAAuB,EAAE;AAAA,QAC1D,EAAE,MAAM,UAAU,aAAa,EAAE,oBAAoB,EAAE;AAAA,QACvD,EAAE,MAAM,SAAS,aAAa,EAAE,qBAAqB,EAAE;AAAA,MACzD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO,EAAE,iBAAiB;AAAA,MAC1B,SAAS;AAAA,QACP,EAAE,MAAM,UAAU,aAAa,EAAE,wBAAwB,EAAE;AAAA,QAC3D,EAAE,MAAM,UAAU,aAAa,EAAE,yBAAyB,EAAE;AAAA,QAC5D,EAAE,MAAM,UAAU,aAAa,EAAE,sBAAsB,EAAE;AAAA,QACzD,EAAE,MAAM,UAAU,aAAa,EAAE,qBAAqB,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO,EAAE,mBAAmB;AAAA,MAC5B,SAAS;AAAA,QACP,EAAE,MAAM,KAAK,aAAa,EAAE,0BAA0B,EAAE;AAAA,QACxD,EAAE,MAAM,KAAK,aAAa,EAAE,2BAA2B,EAAE;AAAA,QACzD,EAAE,MAAM,KAAK,aAAa,EAAE,wBAAwB,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;AAOO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAA2B;AAEzB;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,IAAI,UAAW,IAAI,SAAS,UAAU,OAAO,UAAU,MAAO;AAChE,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,EAAE,UAAU,UAAU;AAAA,EACxB;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,aAAY;AAAA,MACZ,aAAa,eAAe;AAAA,MAC5B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,cAAc;AAAA;AAAA,IAEd,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,SAAO,iBAClC,EAAE,oBAAoB,CAC5B,GACA,oCAAC,QAAK,OAAO,gBAAgB,aAC1B,KAAI,KACH,EAAE,mBAAmB,GAAE,GAC3B,CACF;AAAA,IAEA,oCAAC,OAAI,eAAc,OAAM,KAAK,KAC3B,gBAAgB,EAAE,IAAI,CAAC,OAAO,eAC7B,oCAAC,OAAI,KAAK,YAAY,eAAc,UAAS,UAAU,MACrD,oCAAC,QAAK,MAAI,MAAC,WAAS,MAAC,OAAO,gBAAgB,aACzC,MAAM,KACT,GACC,MAAM,QAAQ,IAAI,CAAC,QAAQ,gBAC1B,oCAAC,OAAI,KAAK,eACR,oCAAC,OAAI,OAAO,MACV,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,UAC9B,OAAO,IACV,CACF,GACA,oCAAC,QAAK,OAAO,gBAAgB,WAC1B,OAAO,WACV,CACF,CACD,CACH,CACD,CACH;AAAA,IAEA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,gBAAgB,OAAM,EAAE,cAAc,CAAE,CACvD;AAAA,EACF;AAEJ;AAKO,SAAS,aAA8B;AAC5C,SACE,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,EAAE,iCAAiC,CACtC;AAEJ;AAqBA,SAAS,gBAAgB,SAAsC;AAC7D,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,KAAK,aAAa,EAAE,sBAAsB,EAAE;AAAA,QACpD,EAAE,MAAM,KAAK,aAAa,EAAE,qBAAqB,EAAE;AAAA,QACnD,EAAE,MAAM,KAAK,aAAa,EAAE,sBAAsB,EAAE;AAAA,QACpD,EAAE,MAAM,UAAU,aAAa,EAAE,eAAe,EAAE;AAAA,QAClD,EAAE,MAAM,UAAU,aAAa,EAAE,cAAc,EAAE;AAAA,MACnD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,SAAS,aAAa,EAAE,eAAe,EAAE;AAAA,QACjD,EAAE,MAAM,OAAO,aAAa,EAAE,mBAAmB,EAAE;AAAA,QACnD,EAAE,MAAM,UAAU,aAAa,EAAE,eAAe,EAAE;AAAA,QAClD,EAAE,MAAM,OAAO,aAAa,EAAE,cAAc,EAAE;AAAA,MAChD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,UAAU,aAAa,EAAE,eAAe,EAAE;AAAA,QAClD,EAAE,MAAM,WAAW,aAAa,EAAE,mBAAmB,EAAE;AAAA,MACzD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,iBAAO,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACjD,EAAE,MAAM,OAAO,aAAa,EAAE,kBAAkB,EAAE;AAAA,QAClD,EAAE,MAAM,OAAO,aAAa,EAAE,gBAAgB,EAAE;AAAA,MAClD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,iBAAO,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACjD,EAAE,MAAM,SAAS,aAAa,EAAE,iBAAiB,EAAE;AAAA,QACnD,EAAE,MAAM,OAAO,aAAa,EAAE,eAAe,EAAE;AAAA,MACjD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,MAAM,OAAO,aAAa,EAAE,0BAA0B,EAAE;AAAA,QAC1D,EAAE,MAAM,SAAS,aAAa,EAAE,kBAAkB,EAAE;AAAA,QACpD,EAAE,MAAM,OAAO,aAAa,EAAE,eAAe,EAAE;AAAA,MACjD;AAAA,IACF;AACE,aAAO,CAAC,EAAE,MAAM,UAAU,aAAa,EAAE,aAAa,EAAE,CAAC;AAAA,EAC7D;AACF;AAWO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,UAAU;AACZ,GAA4C;AAC1C,QAAM,QAAQ,gBAAgB,OAAO;AAErC,MAAI,SAAS;AAEX,WACE,oCAAC,WACE,MAAM,IAAI,CAAC,MAAM,MAChB,oCAAC,MAAM,UAAN,EAAe,KAAK,KAClB,IAAI,KAAK,oCAAC,QAAK,OAAO,gBAAgB,OAAK,QAAG,GAC/C,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,KAAK,MAAK,KAAE,KAAK,WACpB,CACF,CACD,CACH;AAAA,EAEJ;AAGA,SACE,oCAAC,OAAI,KAAK,KACP,MAAM,IAAI,CAAC,MAAM,MAChB,oCAAC,OAAI,KAAK,KACR,oCAAC,QAAK,MAAI,MAAC,OAAO,eAAe,UAC9B,KAAK,IACR,GACA,oCAAC,QAAK,OAAO,gBAAgB,aAAW,KAAE,KAAK,WAAY,CAC7D,CACD,CACH;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -25,7 +25,10 @@ function Logo({
25
25
  const projectName = path.basename(cwd);
26
26
  const logoLines = ["\u2588\u2580\u2584\u2580\u2588 \u2588 \u2588\u2584 \u2588 \u2580\u2588\u2580 \u2588\u2580\u2588", "\u2588 \u2580 \u2588 \u2588 \u2588 \u2580\u2588 \u2588 \u2588\u2584\u2588"];
27
27
  const terminalWidth = getTerminalWidth();
28
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: terminalWidth }, updateBannerVersion ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "New version available: ", updateBannerVersion, " (current:", " ", MACRO.VERSION, ")"), /* @__PURE__ */ React.createElement(Text, null, "Run the following command to update:"), /* @__PURE__ */ React.createElement(Text, null, " ", updateBannerCommands?.[1] ?? DEFAULT_UPDATE_COMMANDS[1]), process.platform !== "win32" && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, 'Note: you may need to prefix with "sudo" on macOS/Linux.')) : null, /* @__PURE__ */ React.createElement(
28
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: terminalWidth }, updateBannerVersion ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, t("ui.update.newVersionAvailable", {
29
+ version: updateBannerVersion,
30
+ current: MACRO.VERSION
31
+ })), /* @__PURE__ */ React.createElement(Text, null, t("ui.update.runCommand")), /* @__PURE__ */ React.createElement(Text, null, " ", updateBannerCommands?.[1] ?? DEFAULT_UPDATE_COMMANDS[1]), process.platform !== "win32" && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, t("ui.update.sudoNote"))) : null, /* @__PURE__ */ React.createElement(
29
32
  Box,
30
33
  {
31
34
  flexDirection: "column",
@@ -39,7 +42,7 @@ function Logo({
39
42
  paddingX: 1,
40
43
  paddingY: 1
41
44
  },
42
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "\u25C6"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START, bold: true }, logoLines[0]), /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.END, bold: true }, logoLines[1])), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "Strategic AI"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " \xB7 "), /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.END }, "Global Excellence"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " \xB7 v", MACRO.VERSION))),
45
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "\u25C6"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START, bold: true }, logoLines[0]), /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.END, bold: true }, logoLines[1])), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, t("ui.welcome.taglinePart1")), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " \xB7 "), /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.END }, t("ui.welcome.taglinePart2")), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " \xB7 v", MACRO.VERSION))),
43
46
  /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "\u273B"), " ", t("ui.welcome.title"))),
44
47
  /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("ui.welcome.quickStart"), ":"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("ui.welcome.tip1")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("ui.welcome.tip2")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", t("ui.welcome.tip3"))),
45
48
  /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "\u{1F4C2} ", projectName))