@within-7/minto 0.3.6 → 0.3.10
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/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +110 -0
- package/dist/commands/language.js.map +7 -0
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/new.js +56 -0
- package/dist/commands/new.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +251 -16
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +7 -0
- package/dist/commands/setup.js +596 -109
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +292 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/status.js +75 -7
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +154 -180
- 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 +166 -32
- 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/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- 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/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +77 -44
- 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/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +117 -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 +246 -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/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/tokenStatsManager.js +5 -0
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +56 -0
- package/dist/entrypoints/bootstrap.js.map +7 -0
- package/dist/entrypoints/cli.js +164 -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 +582 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +582 -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 +44 -16
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +179 -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 +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +103 -0
- package/dist/utils/agentHookExecutor.js.map +7 -0
- package/dist/utils/agentLoader.js +272 -32
- 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/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +52 -24
- 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/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/historyManager.js +234 -0
- package/dist/utils/historyManager.js.map +7 -0
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- 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/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +54 -28
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- 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 +103 -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 +106 -0
- package/dist/utils/stringSubstitution.js.map +7 -0
- package/dist/utils/teamConfig.js +156 -14
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/status.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Status Command\n *\n * Shows version information, connection status, and system health.\n */\n\nimport React from 'react'\nimport
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Status Command\n *\n * Shows version information, connection status, and system health.\n * Uses InfoPanel for consistent UI.\n */\n\nimport React from 'react'\nimport type { Command } from '@commands'\nimport { getModelManager } from '@utils/model'\nimport { getCwd } from '@utils/state'\nimport { MACRO } from '@constants/macros'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { InfoPanel } from '@components/InfoPanel'\nimport type { InfoSection } from '@components/InfoPanel'\nimport { t } from '@i18n'\n\ninterface StatusInfo {\n version: string\n nodeVersion: string\n bunVersion: string | null\n platform: string\n cwd: string\n modelInfo: {\n name: string\n provider: string\n contextLength: number\n } | null\n apiConnected: boolean\n}\n\nasync function getStatusInfo(): Promise<StatusInfo> {\n let modelInfo: StatusInfo['modelInfo'] = null\n let apiConnected = false\n\n try {\n const modelManager = getModelManager()\n const profile = modelManager.resolveModel('main')\n if (profile) {\n modelInfo = {\n name: profile.name || profile.modelName,\n provider: profile.provider || 'anthropic',\n contextLength: profile.contextLength || 200_000,\n }\n apiConnected = true\n }\n } catch {\n // Model not configured\n }\n\n let bunVersion: string | null = null\n if (typeof Bun !== 'undefined') {\n bunVersion = Bun.version\n }\n\n return {\n version: MACRO.VERSION,\n nodeVersion: process.version,\n bunVersion,\n platform: `${process.platform} (${process.arch})`,\n cwd: getCwd(),\n modelInfo,\n apiConnected,\n }\n}\n\nfunction buildSections(status: StatusInfo): InfoSection[] {\n const sections: InfoSection[] = []\n\n // Version Info\n const versionItems = [\n {\n label: 'Minto',\n value: `v${status.version}`,\n valueColor: SEMANTIC_COLORS.success,\n },\n { label: 'Node.js', value: status.nodeVersion },\n ]\n if (status.bunVersion) {\n versionItems.push({ label: 'Bun', value: status.bunVersion })\n }\n versionItems.push({ label: 'Platform', value: status.platform })\n sections.push({\n title: t('commands.status.versionInfo'),\n items: versionItems,\n })\n\n // Environment\n sections.push({\n title: t('commands.status.environment'),\n items: [{ label: 'CWD', value: status.cwd }],\n })\n\n // Model Configuration\n if (status.modelInfo) {\n sections.push({\n title: t('commands.status.modelConfiguration'),\n items: [\n {\n label: 'Model',\n value: status.modelInfo.name,\n valueColor: SEMANTIC_COLORS.info,\n },\n { label: 'Provider', value: status.modelInfo.provider },\n {\n label: 'Context',\n value: `${(status.modelInfo.contextLength / 1000).toFixed(0)}k tokens`,\n },\n ],\n })\n } else {\n sections.push({\n title: t('commands.status.modelConfiguration'),\n items: [\n {\n label: 'Status',\n value: t('commands.status.notConfigured'),\n valueColor: '#FFB86C',\n },\n ],\n })\n }\n\n // API Connection\n sections.push({\n title: t('commands.status.apiConnection'),\n items: [\n {\n label: 'Status',\n value: status.apiConnected\n ? `\\u25CF ${t('commands.status.connected')}`\n : `\\u25CB ${t('commands.status.notConnected')}`,\n valueColor: status.apiConnected\n ? SEMANTIC_COLORS.success\n : SEMANTIC_COLORS.error,\n },\n ],\n })\n\n return sections\n}\n\nconst command: Command = {\n name: 'status',\n description: t('commands.status.description'),\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n type: 'local-jsx',\n\n userFacingName() {\n return this.name\n },\n\n async call(onDone) {\n const status = await getStatusInfo()\n const sections = buildSections(status)\n\n return (\n <InfoPanel\n title={t('commands.status.title')}\n sections={sections}\n onClose={onDone}\n />\n )\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/undo.js
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import { Box, Text, useInput } from "ink";
|
|
3
|
-
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
|
4
2
|
import { getCwd } from "../utils/state.js";
|
|
5
3
|
import {
|
|
6
4
|
listBackedUpFiles,
|
|
7
5
|
getBackupVersions,
|
|
8
6
|
restoreBackup
|
|
9
7
|
} from "../core/backupManager.js";
|
|
8
|
+
import { TabbedListView } from "../components/TabbedListView/TabbedListView.js";
|
|
9
|
+
import { t } from "../i18n/index.js";
|
|
10
10
|
function formatTimestamp(timestamp) {
|
|
11
11
|
const date = new Date(timestamp);
|
|
12
12
|
const now = /* @__PURE__ */ new Date();
|
|
13
13
|
const diff = now.getTime() - timestamp;
|
|
14
|
+
const timeStr = `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
|
|
14
15
|
if (diff < 60 * 60 * 1e3) {
|
|
15
16
|
const minutes = Math.floor(diff / (60 * 1e3));
|
|
16
|
-
return minutes <= 1 ? "
|
|
17
|
+
return minutes <= 1 ? t("commands.undo.justNow") : t("commands.undo.minutesAgo", { count: minutes });
|
|
17
18
|
}
|
|
18
19
|
if (date.getDate() === now.getDate() && date.getMonth() === now.getMonth() && date.getFullYear() === now.getFullYear()) {
|
|
19
|
-
return
|
|
20
|
+
return `${t("commands.undo.today")} ${timeStr}`;
|
|
20
21
|
}
|
|
21
22
|
if (diff < 7 * 24 * 60 * 60 * 1e3) {
|
|
22
|
-
const
|
|
23
|
-
|
|
23
|
+
const weekdayKeys = [
|
|
24
|
+
"commands.undo.weekday.sun",
|
|
25
|
+
"commands.undo.weekday.mon",
|
|
26
|
+
"commands.undo.weekday.tue",
|
|
27
|
+
"commands.undo.weekday.wed",
|
|
28
|
+
"commands.undo.weekday.thu",
|
|
29
|
+
"commands.undo.weekday.fri",
|
|
30
|
+
"commands.undo.weekday.sat"
|
|
31
|
+
];
|
|
32
|
+
return `${t(weekdayKeys[date.getDay()])} ${timeStr}`;
|
|
24
33
|
}
|
|
25
|
-
return `${date.getMonth() + 1}/${date.getDate()} ${
|
|
34
|
+
return `${date.getMonth() + 1}/${date.getDate()} ${timeStr}`;
|
|
26
35
|
}
|
|
27
36
|
function getRelativePath(filePath) {
|
|
28
37
|
const cwd = getCwd();
|
|
@@ -32,205 +41,170 @@ function getRelativePath(filePath) {
|
|
|
32
41
|
}
|
|
33
42
|
return filePath;
|
|
34
43
|
}
|
|
35
|
-
const FileListView = ({ files, selectedIndex, onSelect, onClose }) => {
|
|
36
|
-
useInput((input, key) => {
|
|
37
|
-
if (key.escape || input === "q") {
|
|
38
|
-
onClose();
|
|
39
|
-
} else if (key.return) {
|
|
40
|
-
if (files.length > 0 && files[selectedIndex]) {
|
|
41
|
-
onSelect(files[selectedIndex]);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
if (files.length === 0) {
|
|
46
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.brand }, "\u64A4\u9500\u6587\u4EF6\u4FEE\u6539")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u6682\u65E0\u53EF\u64A4\u9500\u7684\u6587\u4EF6\u4FEE\u6539\u3002"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, " "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u63D0\u793A\uFF1A\u4F7F\u7528 ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.info }, "--smart"), " ", "\u6A21\u5F0F\u542F\u52A8 Minto \u4EE5\u542F\u7528\u81EA\u52A8\u5907\u4EFD\u529F\u80FD\uFF1A"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, " minto --smart")), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "\u6309 q \u6216 Esc \u9000\u51FA")));
|
|
47
|
-
}
|
|
48
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.brand }, "\u64A4\u9500\u6587\u4EF6\u4FEE\u6539"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " - \u9009\u62E9\u8981\u6062\u590D\u7684\u6587\u4EF6")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, files.map((file, index) => {
|
|
49
|
-
const isSelected = index === selectedIndex;
|
|
50
|
-
const relativePath = getRelativePath(file.filePath);
|
|
51
|
-
return /* @__PURE__ */ React.createElement(Box, { key: file.filePath, paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? SEMANTIC_COLORS.info : void 0 }, isSelected ? "\u25B6 " : " ", /* @__PURE__ */ React.createElement(
|
|
52
|
-
Text,
|
|
53
|
-
{
|
|
54
|
-
color: isSelected ? SEMANTIC_COLORS.primary : SEMANTIC_COLORS.secondary
|
|
55
|
-
},
|
|
56
|
-
relativePath
|
|
57
|
-
), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "(", file.versionCount, " \u4E2A\u7248\u672C)")));
|
|
58
|
-
})), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "\u2191/\u2193: \u9009\u62E9 | Enter: \u67E5\u770B\u7248\u672C | q/Esc: \u9000\u51FA")));
|
|
59
|
-
};
|
|
60
|
-
const VersionListView = ({ file, versions, selectedIndex, onSelect, onBack }) => {
|
|
61
|
-
useInput((input, key) => {
|
|
62
|
-
if (key.escape || input === "q") {
|
|
63
|
-
onBack();
|
|
64
|
-
} else if (key.return) {
|
|
65
|
-
if (versions.length > 0 && versions[selectedIndex]) {
|
|
66
|
-
onSelect(versions[selectedIndex]);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
const relativePath = getRelativePath(file.filePath);
|
|
71
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.brand }, "\u9009\u62E9\u8981\u6062\u590D\u7684\u7248\u672C")), /* @__PURE__ */ React.createElement(Box, { marginBottom: 1, paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u6587\u4EF6: "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, relativePath)), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, versions.map((version, index) => {
|
|
72
|
-
const isSelected = index === selectedIndex;
|
|
73
|
-
return /* @__PURE__ */ React.createElement(Box, { key: version.version, paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? SEMANTIC_COLORS.info : void 0 }, isSelected ? "\u25B6 " : " ", /* @__PURE__ */ React.createElement(
|
|
74
|
-
Text,
|
|
75
|
-
{
|
|
76
|
-
color: isSelected ? SEMANTIC_COLORS.primary : SEMANTIC_COLORS.secondary
|
|
77
|
-
},
|
|
78
|
-
"v",
|
|
79
|
-
version.version
|
|
80
|
-
), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, ": ", version.operation, " - ", formatTimestamp(version.timestamp))));
|
|
81
|
-
})), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "\u2191/\u2193: \u9009\u62E9 | Enter: \u6062\u590D\u6B64\u7248\u672C | Esc: \u8FD4\u56DE")));
|
|
82
|
-
};
|
|
83
|
-
const SuccessView = ({ file, version, onClose }) => {
|
|
84
|
-
useInput((input, key) => {
|
|
85
|
-
if (key.escape || input === "q" || key.return) {
|
|
86
|
-
onClose();
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
const relativePath = getRelativePath(file.filePath);
|
|
90
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.success }, "\u2713 \u6587\u4EF6\u5DF2\u6062\u590D")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u6587\u4EF6: "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, relativePath)), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u5DF2\u6062\u590D\u5230: ", version.operation, " (", formatTimestamp(version.timestamp), ")")), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.muted }, "\u6309\u4EFB\u610F\u952E\u9000\u51FA")));
|
|
91
|
-
};
|
|
92
44
|
const UndoCommand = ({ onClose }) => {
|
|
93
|
-
const [
|
|
45
|
+
const [phase, setPhase] = useState({ type: "file-list" });
|
|
94
46
|
const [files, setFiles] = useState([]);
|
|
95
|
-
const [selectedFileIndex, setSelectedFileIndex] = useState(0);
|
|
96
|
-
const [selectedFile, setSelectedFile] = useState(
|
|
97
|
-
null
|
|
98
|
-
);
|
|
99
47
|
const [versions, setVersions] = useState([]);
|
|
100
|
-
const [
|
|
101
|
-
const [
|
|
102
|
-
null
|
|
103
|
-
);
|
|
104
|
-
const [error, setError] = useState(null);
|
|
105
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
48
|
+
const [loading, setLoading] = useState(true);
|
|
49
|
+
const [statusOverlay, setStatusOverlay] = useState(null);
|
|
106
50
|
useEffect(() => {
|
|
107
51
|
const loadFiles = async () => {
|
|
108
52
|
try {
|
|
109
53
|
const backupFiles = await listBackedUpFiles();
|
|
110
54
|
setFiles(backupFiles);
|
|
111
|
-
} catch
|
|
112
|
-
|
|
55
|
+
} catch {
|
|
56
|
+
setFiles([]);
|
|
113
57
|
} finally {
|
|
114
|
-
|
|
58
|
+
setLoading(false);
|
|
115
59
|
}
|
|
116
60
|
};
|
|
117
61
|
loadFiles();
|
|
118
62
|
}, []);
|
|
119
|
-
|
|
120
|
-
(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (phase.type === "version-list") {
|
|
65
|
+
const loadVersions = async () => {
|
|
66
|
+
setLoading(true);
|
|
67
|
+
try {
|
|
68
|
+
const fileVersions = await getBackupVersions(phase.file.filePath);
|
|
69
|
+
setVersions(fileVersions);
|
|
70
|
+
} catch {
|
|
71
|
+
setVersions([]);
|
|
72
|
+
} finally {
|
|
73
|
+
setLoading(false);
|
|
126
74
|
}
|
|
75
|
+
};
|
|
76
|
+
loadVersions();
|
|
77
|
+
}
|
|
78
|
+
}, [phase]);
|
|
79
|
+
const { tabs, items, title, footerHint, emptyText } = useMemo(() => {
|
|
80
|
+
switch (phase.type) {
|
|
81
|
+
case "file-list": {
|
|
82
|
+
const fileTabs = [
|
|
83
|
+
{ id: "files", label: t("commands.undo.tabFiles") }
|
|
84
|
+
];
|
|
85
|
+
const fileItems = files.map((file) => ({
|
|
86
|
+
id: file.filePath,
|
|
87
|
+
label: getRelativePath(file.filePath),
|
|
88
|
+
description: t("commands.undo.versions", {
|
|
89
|
+
count: file.versionCount
|
|
90
|
+
}),
|
|
91
|
+
data: { file }
|
|
92
|
+
}));
|
|
93
|
+
return {
|
|
94
|
+
tabs: fileTabs,
|
|
95
|
+
items: fileItems,
|
|
96
|
+
title: t("commands.undo.title"),
|
|
97
|
+
footerHint: "\u2191\u2193 Navigate \xB7 Enter Select \xB7 Esc Close",
|
|
98
|
+
emptyText: t("commands.undo.noBackups")
|
|
99
|
+
};
|
|
127
100
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
101
|
+
case "version-list": {
|
|
102
|
+
const versionTabs = [
|
|
103
|
+
{ id: "versions", label: t("commands.undo.tabVersions") }
|
|
104
|
+
];
|
|
105
|
+
const versionItems = versions.map((version) => ({
|
|
106
|
+
id: String(version.version),
|
|
107
|
+
label: `v${version.version}: ${version.operation}`,
|
|
108
|
+
description: formatTimestamp(version.timestamp),
|
|
109
|
+
data: { version }
|
|
110
|
+
}));
|
|
111
|
+
return {
|
|
112
|
+
tabs: versionTabs,
|
|
113
|
+
items: versionItems,
|
|
114
|
+
title: getRelativePath(phase.file.filePath),
|
|
115
|
+
footerHint: "\u2191\u2193 Navigate \xB7 Enter Restore \xB7 Esc Back",
|
|
116
|
+
emptyText: "No versions found"
|
|
117
|
+
};
|
|
141
118
|
}
|
|
142
|
-
},
|
|
143
|
-
{ isActive: view === "version-list" }
|
|
144
|
-
);
|
|
145
|
-
const handleFileSelect = async (file) => {
|
|
146
|
-
setSelectedFile(file);
|
|
147
|
-
try {
|
|
148
|
-
const fileVersions = await getBackupVersions(file.filePath);
|
|
149
|
-
setVersions(fileVersions);
|
|
150
|
-
setSelectedVersionIndex(0);
|
|
151
|
-
setView("version-list");
|
|
152
|
-
} catch (err) {
|
|
153
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
154
119
|
}
|
|
155
|
-
};
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
setRestoredVersion(version);
|
|
165
|
-
setView("success");
|
|
166
|
-
} else {
|
|
167
|
-
setError("\u6062\u590D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
168
|
-
}
|
|
169
|
-
} catch (err) {
|
|
170
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
120
|
+
}, [phase, files, versions]);
|
|
121
|
+
const handleStatusDismiss = useCallback(() => {
|
|
122
|
+
setStatusOverlay(null);
|
|
123
|
+
onClose();
|
|
124
|
+
}, [onClose]);
|
|
125
|
+
const handleBack = useCallback(() => {
|
|
126
|
+
if (statusOverlay && statusOverlay.type !== "loading") {
|
|
127
|
+
handleStatusDismiss();
|
|
128
|
+
return;
|
|
171
129
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
FileListView,
|
|
189
|
-
{
|
|
190
|
-
files,
|
|
191
|
-
selectedIndex: selectedFileIndex,
|
|
192
|
-
onSelect: handleFileSelect,
|
|
193
|
-
onClose
|
|
130
|
+
if (phase.type === "file-list") {
|
|
131
|
+
onClose();
|
|
132
|
+
} else {
|
|
133
|
+
setPhase({ type: "file-list" });
|
|
134
|
+
}
|
|
135
|
+
}, [phase, statusOverlay, onClose, handleStatusDismiss]);
|
|
136
|
+
const handleClose = handleBack;
|
|
137
|
+
const handleTabChange = useCallback(() => {
|
|
138
|
+
}, []);
|
|
139
|
+
const handleSelect = useCallback(
|
|
140
|
+
async (item) => {
|
|
141
|
+
switch (phase.type) {
|
|
142
|
+
case "file-list": {
|
|
143
|
+
const data = item.data;
|
|
144
|
+
setPhase({ type: "version-list", file: data.file });
|
|
145
|
+
break;
|
|
194
146
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
147
|
+
case "version-list": {
|
|
148
|
+
const data = item.data;
|
|
149
|
+
setStatusOverlay({
|
|
150
|
+
type: "loading",
|
|
151
|
+
message: "Restoring file..."
|
|
152
|
+
});
|
|
153
|
+
try {
|
|
154
|
+
const success = await restoreBackup(
|
|
155
|
+
phase.file.filePath,
|
|
156
|
+
data.version.version
|
|
157
|
+
);
|
|
158
|
+
if (success) {
|
|
159
|
+
setStatusOverlay({
|
|
160
|
+
type: "success",
|
|
161
|
+
message: `${t("commands.undo.fileRestored")}: v${data.version.version}`
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
setStatusOverlay({
|
|
165
|
+
type: "error",
|
|
166
|
+
message: t("commands.undo.restoreFailed")
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
} catch (err) {
|
|
170
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
171
|
+
setStatusOverlay({ type: "error", message: msg });
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
209
174
|
}
|
|
210
|
-
);
|
|
211
|
-
case "success":
|
|
212
|
-
if (!selectedFile || !restoredVersion) {
|
|
213
|
-
onClose();
|
|
214
|
-
return null;
|
|
215
175
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
176
|
+
},
|
|
177
|
+
[phase]
|
|
178
|
+
);
|
|
179
|
+
const currentTab = phase.type === "file-list" ? "files" : "versions";
|
|
180
|
+
return /* @__PURE__ */ React.createElement(
|
|
181
|
+
TabbedListView,
|
|
182
|
+
{
|
|
183
|
+
title,
|
|
184
|
+
tabs,
|
|
185
|
+
activeTab: currentTab,
|
|
186
|
+
onTabChange: handleTabChange,
|
|
187
|
+
items,
|
|
188
|
+
searchEnabled: false,
|
|
189
|
+
onSelect: handleSelect,
|
|
190
|
+
onClose: handleClose,
|
|
191
|
+
onBack: handleBack,
|
|
192
|
+
statusOverlay,
|
|
193
|
+
footerHint,
|
|
194
|
+
isLoading: loading,
|
|
195
|
+
loadingText: t("commands.undo.loading"),
|
|
196
|
+
emptyText,
|
|
197
|
+
statusDismissHint: "Enter Close"
|
|
198
|
+
}
|
|
199
|
+
);
|
|
227
200
|
};
|
|
228
201
|
const command = {
|
|
229
202
|
name: "undo",
|
|
230
|
-
description: "
|
|
203
|
+
description: t("commands.undo.description"),
|
|
231
204
|
type: "local-jsx",
|
|
232
205
|
isEnabled: true,
|
|
233
206
|
isHidden: false,
|
|
207
|
+
hidePromptInput: true,
|
|
234
208
|
userFacingName() {
|
|
235
209
|
return "undo";
|
|
236
210
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/undo.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Undo Command\n *\n * Interactive command to restore file versions from backups.\n * Requires --smart mode to have backups available.\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport type { Command } from '@commands'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { getCwd } from '@utils/state'\nimport {\n listBackedUpFiles,\n getBackupVersions,\n restoreBackup,\n type BackupFileSummary,\n type BackupMetadata,\n} from '../core/backupManager'\n\ntype ViewState = 'file-list' | 'version-list' | 'success'\n\ninterface UndoCommandProps {\n onClose: () => void\n}\n\n/**\n * Format a timestamp as a human-readable string\n */\nfunction formatTimestamp(timestamp: number): string {\n const date = new Date(timestamp)\n const now = new Date()\n const diff = now.getTime() - timestamp\n\n // Within last hour - show minutes\n if (diff < 60 * 60 * 1000) {\n const minutes = Math.floor(diff / (60 * 1000))\n return minutes <= 1 ? '\u521A\u521A' : `${minutes} \u5206\u949F\u524D`\n }\n\n // Within today - show time\n if (\n date.getDate() === now.getDate() &&\n date.getMonth() === now.getMonth() &&\n date.getFullYear() === now.getFullYear()\n ) {\n return `\u4ECA\u5929 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\n }\n\n // Within this week - show day and time\n if (diff < 7 * 24 * 60 * 60 * 1000) {\n const days = ['\u65E5', '\u4E00', '\u4E8C', '\u4E09', '\u56DB', '\u4E94', '\u516D']\n return `\u5468${days[date.getDay()]} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\n }\n\n // Otherwise - show date\n return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\n}\n\n/**\n * Get relative path from cwd\n */\nfunction getRelativePath(filePath: string): string {\n const cwd = getCwd()\n if (filePath.startsWith(cwd)) {\n const relative = filePath.slice(cwd.length)\n return relative.startsWith('/') ? relative.slice(1) : relative\n }\n return filePath\n}\n\n/**\n * File List View - shows all files with backups\n */\nconst FileListView: React.FC<{\n files: BackupFileSummary[]\n selectedIndex: number\n onSelect: (file: BackupFileSummary) => void\n onClose: () => void\n}> = ({ files, selectedIndex, onSelect, onClose }) => {\n useInput((input, key) => {\n if (key.escape || input === 'q') {\n onClose()\n } else if (key.return) {\n if (files.length > 0 && files[selectedIndex]) {\n onSelect(files[selectedIndex])\n }\n }\n })\n\n if (files.length === 0) {\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={SEMANTIC_COLORS.brand}>\n \u64A4\u9500\u6587\u4EF6\u4FEE\u6539\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" paddingLeft={1}>\n <Text color={SEMANTIC_COLORS.dim}>\u6682\u65E0\u53EF\u64A4\u9500\u7684\u6587\u4EF6\u4FEE\u6539\u3002</Text>\n <Text color={SEMANTIC_COLORS.muted}> </Text>\n <Text color={SEMANTIC_COLORS.dim}>\n \u63D0\u793A\uFF1A\u4F7F\u7528 <Text color={SEMANTIC_COLORS.info}>--smart</Text>{' '}\n \u6A21\u5F0F\u542F\u52A8 Minto \u4EE5\u542F\u7528\u81EA\u52A8\u5907\u4EFD\u529F\u80FD\uFF1A\n </Text>\n <Text color={SEMANTIC_COLORS.muted}> minto --smart</Text>\n </Box>\n\n <Box marginTop={2}>\n <Text color={SEMANTIC_COLORS.muted}>\u6309 q \u6216 Esc \u9000\u51FA</Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={SEMANTIC_COLORS.brand}>\n \u64A4\u9500\u6587\u4EF6\u4FEE\u6539\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> - \u9009\u62E9\u8981\u6062\u590D\u7684\u6587\u4EF6</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {files.map((file, index) => {\n const isSelected = index === selectedIndex\n const relativePath = getRelativePath(file.filePath)\n\n return (\n <Box key={file.filePath} paddingLeft={1}>\n <Text color={isSelected ? SEMANTIC_COLORS.info : undefined}>\n {isSelected ? '\u25B6 ' : ' '}\n <Text\n color={\n isSelected\n ? SEMANTIC_COLORS.primary\n : SEMANTIC_COLORS.secondary\n }\n >\n {relativePath}\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n ({file.versionCount} \u4E2A\u7248\u672C)\n </Text>\n </Text>\n </Box>\n )\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={SEMANTIC_COLORS.muted}>\n \u2191/\u2193: \u9009\u62E9 | Enter: \u67E5\u770B\u7248\u672C | q/Esc: \u9000\u51FA\n </Text>\n </Box>\n </Box>\n )\n}\n\n/**\n * Version List View - shows all versions for a selected file\n */\nconst VersionListView: React.FC<{\n file: BackupFileSummary\n versions: BackupMetadata[]\n selectedIndex: number\n onSelect: (version: BackupMetadata) => void\n onBack: () => void\n}> = ({ file, versions, selectedIndex, onSelect, onBack }) => {\n useInput((input, key) => {\n if (key.escape || input === 'q') {\n onBack()\n } else if (key.return) {\n if (versions.length > 0 && versions[selectedIndex]) {\n onSelect(versions[selectedIndex])\n }\n }\n })\n\n const relativePath = getRelativePath(file.filePath)\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={SEMANTIC_COLORS.brand}>\n \u9009\u62E9\u8981\u6062\u590D\u7684\u7248\u672C\n </Text>\n </Box>\n\n <Box marginBottom={1} paddingLeft={1}>\n <Text color={SEMANTIC_COLORS.dim}>\u6587\u4EF6: </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{relativePath}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n {versions.map((version, index) => {\n const isSelected = index === selectedIndex\n\n return (\n <Box key={version.version} paddingLeft={1}>\n <Text color={isSelected ? SEMANTIC_COLORS.info : undefined}>\n {isSelected ? '\u25B6 ' : ' '}\n <Text\n color={\n isSelected\n ? SEMANTIC_COLORS.primary\n : SEMANTIC_COLORS.secondary\n }\n >\n v{version.version}\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>\n : {version.operation} - {formatTimestamp(version.timestamp)}\n </Text>\n </Text>\n </Box>\n )\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={SEMANTIC_COLORS.muted}>\n \u2191/\u2193: \u9009\u62E9 | Enter: \u6062\u590D\u6B64\u7248\u672C | Esc: \u8FD4\u56DE\n </Text>\n </Box>\n </Box>\n )\n}\n\n/**\n * Success View - shows restoration confirmation\n */\nconst SuccessView: React.FC<{\n file: BackupFileSummary\n version: BackupMetadata\n onClose: () => void\n}> = ({ file, version, onClose }) => {\n useInput((input, key) => {\n if (key.escape || input === 'q' || key.return) {\n onClose()\n }\n })\n\n const relativePath = getRelativePath(file.filePath)\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={SEMANTIC_COLORS.success}>\n \u2713 \u6587\u4EF6\u5DF2\u6062\u590D\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" paddingLeft={1}>\n <Text color={SEMANTIC_COLORS.dim}>\u6587\u4EF6: </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{relativePath}</Text>\n </Box>\n\n <Box paddingLeft={1} marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n \u5DF2\u6062\u590D\u5230: {version.operation} ({formatTimestamp(version.timestamp)})\n </Text>\n </Box>\n\n <Box marginTop={2}>\n <Text color={SEMANTIC_COLORS.muted}>\u6309\u4EFB\u610F\u952E\u9000\u51FA</Text>\n </Box>\n </Box>\n )\n}\n\n/**\n * Main Undo Command Component\n */\nconst UndoCommand: React.FC<UndoCommandProps> = ({ onClose }) => {\n const [view, setView] = useState<ViewState>('file-list')\n const [files, setFiles] = useState<BackupFileSummary[]>([])\n const [selectedFileIndex, setSelectedFileIndex] = useState(0)\n const [selectedFile, setSelectedFile] = useState<BackupFileSummary | null>(\n null,\n )\n const [versions, setVersions] = useState<BackupMetadata[]>([])\n const [selectedVersionIndex, setSelectedVersionIndex] = useState(0)\n const [restoredVersion, setRestoredVersion] = useState<BackupMetadata | null>(\n null,\n )\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n\n // Load files with backups on mount\n useEffect(() => {\n const loadFiles = async () => {\n try {\n const backupFiles = await listBackedUpFiles()\n // Already sorted by most recent in listBackedUpFiles\n setFiles(backupFiles)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setIsLoading(false)\n }\n }\n loadFiles()\n }, [])\n\n // Handle keyboard navigation for file list\n useInput(\n (input, key) => {\n if (view === 'file-list' && files.length > 0) {\n if (key.upArrow) {\n setSelectedFileIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow) {\n setSelectedFileIndex(prev => Math.min(files.length - 1, prev + 1))\n }\n }\n },\n { isActive: view === 'file-list' },\n )\n\n // Handle keyboard navigation for version list\n useInput(\n (input, key) => {\n if (view === 'version-list' && versions.length > 0) {\n if (key.upArrow) {\n setSelectedVersionIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow) {\n setSelectedVersionIndex(prev =>\n Math.min(versions.length - 1, prev + 1),\n )\n }\n }\n },\n { isActive: view === 'version-list' },\n )\n\n // Handle file selection\n const handleFileSelect = async (file: BackupFileSummary) => {\n setSelectedFile(file)\n try {\n const fileVersions = await getBackupVersions(file.filePath)\n // Already sorted by newest first in getBackupVersions\n setVersions(fileVersions)\n setSelectedVersionIndex(0)\n setView('version-list')\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n // Handle version selection and restore\n const handleVersionSelect = async (version: BackupMetadata) => {\n if (!selectedFile) return\n\n try {\n const success = await restoreBackup(\n selectedFile.filePath,\n version.version,\n )\n if (success) {\n setRestoredVersion(version)\n setView('success')\n } else {\n setError('\u6062\u590D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002')\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n // Handle back navigation\n const handleBack = () => {\n setView('file-list')\n setSelectedFile(null)\n setVersions([])\n setSelectedVersionIndex(0)\n }\n\n // Loading state\n if (isLoading) {\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Text color={SEMANTIC_COLORS.dim}>\u52A0\u8F7D\u5907\u4EFD\u4FE1\u606F...</Text>\n </Box>\n )\n }\n\n // Error display\n if (error) {\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box marginBottom={1}>\n <Text bold color={SEMANTIC_COLORS.error}>\n \u9519\u8BEF\n </Text>\n </Box>\n <Box paddingLeft={1}>\n <Text color={SEMANTIC_COLORS.dim}>{error}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={SEMANTIC_COLORS.muted}>\u6309\u4EFB\u610F\u952E\u9000\u51FA</Text>\n </Box>\n </Box>\n )\n }\n\n // Render current view\n switch (view) {\n case 'file-list':\n return (\n <FileListView\n files={files}\n selectedIndex={selectedFileIndex}\n onSelect={handleFileSelect}\n onClose={onClose}\n />\n )\n\n case 'version-list':\n if (!selectedFile) {\n handleBack()\n return null\n }\n return (\n <VersionListView\n file={selectedFile}\n versions={versions}\n selectedIndex={selectedVersionIndex}\n onSelect={handleVersionSelect}\n onBack={handleBack}\n />\n )\n\n case 'success':\n if (!selectedFile || !restoredVersion) {\n onClose()\n return null\n }\n return (\n <SuccessView\n file={selectedFile}\n version={restoredVersion}\n onClose={onClose}\n />\n )\n\n default:\n return null\n }\n}\n\n/**\n * Undo Command Export\n */\nconst command: Command = {\n name: 'undo',\n description: '\u64A4\u9500\u6587\u4EF6\u4FEE\u6539\uFF08\u9700\u8981 --smart \u6A21\u5F0F\uFF09',\n type: 'local-jsx' as const,\n isEnabled: true,\n isHidden: false,\n\n userFacingName() {\n return 'undo'\n },\n\n async call(onDone: (result?: string) => void) {\n return <UndoCommand onClose={onDone} />\n },\n}\n\nexport default command\n"],
|
|
5
|
-
"mappings": "AAOA,OAAO,SAAS,UAAU,
|
|
4
|
+
"sourcesContent": ["/**\n * Undo Command\n *\n * Interactive command to restore file versions from backups.\n * Uses TabbedListView with a phase state machine for consistent UI.\n */\n\nimport React, { useState, useEffect, useCallback, useMemo } from 'react'\nimport type { Command } from '@commands'\nimport { getCwd } from '@utils/state'\nimport {\n listBackedUpFiles,\n getBackupVersions,\n restoreBackup,\n type BackupFileSummary,\n type BackupMetadata,\n} from '../core/backupManager'\nimport { TabbedListView } from '@components/TabbedListView/TabbedListView'\nimport type {\n ListItem,\n TabDefinition,\n StatusOverlay,\n} from '@components/TabbedListView/types'\nimport { t } from '@i18n'\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction formatTimestamp(timestamp: number): string {\n const date = new Date(timestamp)\n const now = new Date()\n const diff = now.getTime() - timestamp\n const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\n\n if (diff < 60 * 60 * 1000) {\n const minutes = Math.floor(diff / (60 * 1000))\n return minutes <= 1\n ? t('commands.undo.justNow')\n : t('commands.undo.minutesAgo', { count: minutes })\n }\n\n if (\n date.getDate() === now.getDate() &&\n date.getMonth() === now.getMonth() &&\n date.getFullYear() === now.getFullYear()\n ) {\n return `${t('commands.undo.today')} ${timeStr}`\n }\n\n if (diff < 7 * 24 * 60 * 60 * 1000) {\n const weekdayKeys = [\n 'commands.undo.weekday.sun',\n 'commands.undo.weekday.mon',\n 'commands.undo.weekday.tue',\n 'commands.undo.weekday.wed',\n 'commands.undo.weekday.thu',\n 'commands.undo.weekday.fri',\n 'commands.undo.weekday.sat',\n ] as const\n return `${t(weekdayKeys[date.getDay()])} ${timeStr}`\n }\n\n return `${date.getMonth() + 1}/${date.getDate()} ${timeStr}`\n}\n\nfunction getRelativePath(filePath: string): string {\n const cwd = getCwd()\n if (filePath.startsWith(cwd)) {\n const relative = filePath.slice(cwd.length)\n return relative.startsWith('/') ? relative.slice(1) : relative\n }\n return filePath\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype UndoPhase =\n | { type: 'file-list' }\n | { type: 'version-list'; file: BackupFileSummary }\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nconst UndoCommand: React.FC<{ onClose: () => void }> = ({ onClose }) => {\n const [phase, setPhase] = useState<UndoPhase>({ type: 'file-list' })\n const [files, setFiles] = useState<BackupFileSummary[]>([])\n const [versions, setVersions] = useState<BackupMetadata[]>([])\n const [loading, setLoading] = useState(true)\n const [statusOverlay, setStatusOverlay] = useState<StatusOverlay | null>(null)\n\n // Load files on mount\n useEffect(() => {\n const loadFiles = async () => {\n try {\n const backupFiles = await listBackedUpFiles()\n setFiles(backupFiles)\n } catch {\n setFiles([])\n } finally {\n setLoading(false)\n }\n }\n loadFiles()\n }, [])\n\n // Load versions when entering version-list phase\n useEffect(() => {\n if (phase.type === 'version-list') {\n const loadVersions = async () => {\n setLoading(true)\n try {\n const fileVersions = await getBackupVersions(phase.file.filePath)\n setVersions(fileVersions)\n } catch {\n setVersions([])\n } finally {\n setLoading(false)\n }\n }\n loadVersions()\n }\n }, [phase])\n\n // Build tabs, items, title based on phase\n const { tabs, items, title, footerHint, emptyText } = useMemo(() => {\n switch (phase.type) {\n case 'file-list': {\n const fileTabs: TabDefinition[] = [\n { id: 'files', label: t('commands.undo.tabFiles') },\n ]\n\n const fileItems: ListItem[] = files.map(file => ({\n id: file.filePath,\n label: getRelativePath(file.filePath),\n description: t('commands.undo.versions', {\n count: file.versionCount,\n }),\n data: { file },\n }))\n\n return {\n tabs: fileTabs,\n items: fileItems,\n title: t('commands.undo.title'),\n footerHint: '\u2191\u2193 Navigate \u00B7 Enter Select \u00B7 Esc Close',\n emptyText: t('commands.undo.noBackups'),\n }\n }\n\n case 'version-list': {\n const versionTabs: TabDefinition[] = [\n { id: 'versions', label: t('commands.undo.tabVersions') },\n ]\n\n const versionItems: ListItem[] = versions.map(version => ({\n id: String(version.version),\n label: `v${version.version}: ${version.operation}`,\n description: formatTimestamp(version.timestamp),\n data: { version },\n }))\n\n return {\n tabs: versionTabs,\n items: versionItems,\n title: getRelativePath(phase.file.filePath),\n footerHint: '\u2191\u2193 Navigate \u00B7 Enter Restore \u00B7 Esc Back',\n emptyText: 'No versions found',\n }\n }\n }\n }, [phase, files, versions])\n\n // Handle status overlay dismiss\n const handleStatusDismiss = useCallback(() => {\n setStatusOverlay(null)\n onClose()\n }, [onClose])\n\n // Handle back / close\n const handleBack = useCallback(() => {\n if (statusOverlay && statusOverlay.type !== 'loading') {\n handleStatusDismiss()\n return\n }\n if (phase.type === 'file-list') {\n onClose()\n } else {\n setPhase({ type: 'file-list' })\n }\n }, [phase, statusOverlay, onClose, handleStatusDismiss])\n\n const handleClose = handleBack\n\n // Handle tab change (no-op, single tab per phase)\n const handleTabChange = useCallback(() => {}, [])\n\n // Handle item selection\n const handleSelect = useCallback(\n async (item: ListItem) => {\n switch (phase.type) {\n case 'file-list': {\n const data = item.data as { file: BackupFileSummary }\n setPhase({ type: 'version-list', file: data.file })\n break\n }\n\n case 'version-list': {\n const data = item.data as { version: BackupMetadata }\n setStatusOverlay({\n type: 'loading',\n message: 'Restoring file...',\n })\n\n try {\n const success = await restoreBackup(\n phase.file.filePath,\n data.version.version,\n )\n if (success) {\n setStatusOverlay({\n type: 'success',\n message: `${t('commands.undo.fileRestored')}: v${data.version.version}`,\n })\n } else {\n setStatusOverlay({\n type: 'error',\n message: t('commands.undo.restoreFailed'),\n })\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n setStatusOverlay({ type: 'error', message: msg })\n }\n break\n }\n }\n },\n [phase],\n )\n\n const currentTab = phase.type === 'file-list' ? 'files' : 'versions'\n\n return (\n <TabbedListView\n title={title}\n tabs={tabs}\n activeTab={currentTab}\n onTabChange={handleTabChange}\n items={items}\n searchEnabled={false}\n onSelect={handleSelect}\n onClose={handleClose}\n onBack={handleBack}\n statusOverlay={statusOverlay}\n footerHint={footerHint}\n isLoading={loading}\n loadingText={t('commands.undo.loading')}\n emptyText={emptyText}\n statusDismissHint=\"Enter Close\"\n />\n )\n}\n\n// =============================================================================\n// Command Export\n// =============================================================================\n\nconst command: Command = {\n name: 'undo',\n description: t('commands.undo.description'),\n type: 'local-jsx' as const,\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n\n userFacingName() {\n return 'undo'\n },\n\n async call(onDone: (result?: string) => void) {\n return <UndoCommand onClose={onDone} />\n },\n}\n\nexport default command\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands.js
CHANGED
|
@@ -16,10 +16,13 @@ import setup from "./commands/setup.js";
|
|
|
16
16
|
import status from "./commands/status.js";
|
|
17
17
|
import terminalSetup from "./commands/terminalSetup.js";
|
|
18
18
|
import resume from "./commands/resume.js";
|
|
19
|
+
import newCmd from "./commands/new.js";
|
|
19
20
|
import agents from "./commands/agents/index.js";
|
|
20
21
|
import plugin from "./commands/plugin.js";
|
|
21
22
|
import undo from "./commands/undo.js";
|
|
23
|
+
import language from "./commands/language.js";
|
|
22
24
|
import { quit } from "./commands/quit.js";
|
|
25
|
+
import stats from "./commands/stats.js";
|
|
23
26
|
import doctor from "./commands/doctor.js";
|
|
24
27
|
import bug from "./commands/bug.js";
|
|
25
28
|
import tasks from "./commands/tasks.js";
|
|
@@ -43,14 +46,17 @@ const COMMANDS = memoize(() => [
|
|
|
43
46
|
exportCmd,
|
|
44
47
|
help,
|
|
45
48
|
init,
|
|
49
|
+
language,
|
|
46
50
|
mcp,
|
|
47
51
|
model,
|
|
52
|
+
newCmd,
|
|
48
53
|
permissions,
|
|
49
54
|
plugin,
|
|
50
55
|
quit,
|
|
51
56
|
resume,
|
|
52
57
|
sandbox,
|
|
53
58
|
setup,
|
|
59
|
+
stats,
|
|
54
60
|
status,
|
|
55
61
|
tasks,
|
|
56
62
|
todos,
|