@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.
- package/{cli.js → cli.cjs} +25 -23
- package/dist/commands/language.js +137 -0
- package/dist/commands/language.js.map +7 -0
- package/dist/commands/new.js +56 -0
- package/dist/commands/new.js.map +7 -0
- package/dist/commands/resume.js +251 -16
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +7 -0
- package/dist/commands/setup.js +3 -2
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +235 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/status.js +11 -5
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +26 -16
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js +6 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/Config.js +9 -8
- package/dist/components/Config.js.map +2 -2
- package/dist/components/HeaderBar.js +2 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +2 -1
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +46 -44
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/Logo.js +5 -2
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +6 -5
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +5 -4
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModelConfig.js +13 -12
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/PromptInput.js +72 -39
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +12 -8
- package/dist/components/SensitiveFileWarning.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +91 -0
- package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
- package/dist/components/TabbedListView/SearchInput.js +23 -0
- package/dist/components/TabbedListView/SearchInput.js.map +7 -0
- package/dist/components/TabbedListView/TabBar.js +20 -0
- package/dist/components/TabbedListView/TabBar.js.map +7 -0
- package/dist/components/TabbedListView/TabbedListView.js +171 -0
- package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
- package/dist/components/TabbedListView/index.js +11 -0
- package/dist/components/TabbedListView/index.js.map +7 -0
- package/dist/components/TabbedListView/types.js +1 -0
- package/dist/components/TabbedListView/types.js.map +7 -0
- package/dist/components/TodoChangeBlock.js +6 -5
- package/dist/components/TodoChangeBlock.js.map +3 -3
- package/dist/components/TodoPanel.js +6 -3
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TrustDialog.js +6 -5
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
- package/dist/constants/macros.js +1 -1
- package/dist/constants/macros.js.map +1 -1
- package/dist/constants/product.js +2 -2
- package/dist/constants/product.js.map +1 -1
- package/dist/constants/prompts.js +17 -0
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/toolInputExamples.js +5 -1
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/core/tokenStatsManager.js +5 -0
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +54 -0
- package/dist/entrypoints/bootstrap.js.map +7 -0
- package/dist/entrypoints/cli.js +132 -23
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/history.js +75 -15
- package/dist/history.js.map +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/i18n/locales/en.js +283 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +283 -1
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/messages.js +11 -0
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +9 -0
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +45 -7
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/customCommands.js +14 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +176 -1
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/prompt.js +21 -0
- package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +14 -9
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +12 -6
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/types/PermissionMode.js +30 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +106 -0
- package/dist/utils/agentHookExecutor.js.map +7 -0
- package/dist/utils/agentLoader.js +212 -26
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js +134 -0
- package/dist/utils/agentMemory.js.map +7 -0
- package/dist/utils/config.js +51 -1
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configPaths.js +199 -0
- package/dist/utils/configPaths.js.map +7 -0
- package/dist/utils/historyManager.js +234 -0
- package/dist/utils/historyManager.js.map +7 -0
- package/dist/utils/messages.js +13 -8
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/migration/index.js +37 -0
- package/dist/utils/migration/index.js.map +7 -0
- package/dist/utils/migration/migrateHistory.js +273 -0
- package/dist/utils/migration/migrateHistory.js.map +7 -0
- package/dist/utils/migration/migrateTodos.js +323 -0
- package/dist/utils/migration/migrateTodos.js.map +7 -0
- package/dist/utils/pasteCache.js +309 -0
- package/dist/utils/pasteCache.js.map +7 -0
- package/dist/utils/pluginLoader.js +6 -3
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/sessionIndex.js +192 -0
- package/dist/utils/sessionIndex.js.map +7 -0
- package/dist/utils/sessionTracker.js +170 -0
- package/dist/utils/sessionTracker.js.map +7 -0
- package/dist/utils/skillLoader.js +91 -5
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stats.js +417 -0
- package/dist/utils/stats.js.map +7 -0
- package/dist/utils/stringSubstitution.js +107 -0
- package/dist/utils/stringSubstitution.js.map +7 -0
- package/dist/utils/teamConfig.js +3 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/todoStorage.js +51 -19
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +71 -28
- 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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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 }, "
|
|
158
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, "
|
|
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 }, "
|
|
174
|
-
/* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, editingString ? "
|
|
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: '
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,gBAAgB;AACzB,OAAO,aAAa;AACpB,SAAS,gBAAgB;AACzB,SAAuB,kBAAkB,uBAAuB;AAEhE,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,oBAAoB,0BAA0B;AAEvD,SAAS,uBAAuB;
|
|
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 "
|
|
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 // \
|
|
5
|
-
"mappings": "AAUA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAC1B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB,uBAAuB;
|
|
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
|
}
|
package/dist/components/Help.js
CHANGED
|
@@ -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,
|
|
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}'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 "question"</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 > How does foo.py work?\n </Text>\n </Text>\n <Text>\n \u2022 Edit files{' '}\n <Text color={getTheme().secondaryText}>\n > Update bar.ts to...\n </Text>\n </Text>\n <Text>\n \u2022 Fix errors{' '}\n <Text color={getTheme().secondaryText}>> cargo build</Text>\n </Text>\n <Text>\n \u2022 Run commands{' '}\n <Text color={getTheme().secondaryText}>> /help</Text>\n </Text>\n <Text>\n \u2022 Run bash commands{' '}\n <Text color={getTheme().secondaryText}>> !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": "AACA,SAAS,iBAAiB,oBAAoB;AAC9C;AAAA,EAEE;AAAA,OAEK;AACP,YAAY,WAAW;AACvB,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AACrC,SAAS,aAAa;
|
|
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 "question"</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 > How does foo.py work?\n </Text>\n </Text>\n <Text>\n \u2022 {t('help.taskEditFiles')}{' '}\n <Text color={getTheme().secondaryText}>\n > Update bar.ts to...\n </Text>\n </Text>\n <Text>\n \u2022 {t('help.taskFixErrors')}{' '}\n <Text color={getTheme().secondaryText}>> cargo build</Text>\n </Text>\n <Text>\n \u2022 {t('help.taskRunCommands')}{' '}\n <Text color={getTheme().secondaryText}>> /help</Text>\n </Text>\n <Text>\n \u2022 {t('help.taskRunBash')}{' '}\n <Text color={getTheme().secondaryText}>> !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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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 },
|
|
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 }, "
|
|
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: "
|
|
80
|
-
{ keys: "#", description: "
|
|
81
|
-
{ keys: "/", description: "
|
|
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\
|
|
5
|
-
"mappings": "AAOA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,gBAAgB,uBAAuB;
|
|
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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/components/Logo.js
CHANGED
|
@@ -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 },
|
|
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 }, "
|
|
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))
|