@yivan-lab/pretty-please 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +98 -27
  2. package/bin/pls.tsx +135 -24
  3. package/dist/bin/pls.d.ts +1 -1
  4. package/dist/bin/pls.js +117 -24
  5. package/dist/package.json +80 -0
  6. package/dist/src/ai.d.ts +1 -41
  7. package/dist/src/ai.js +9 -190
  8. package/dist/src/builtin-detector.d.ts +14 -8
  9. package/dist/src/builtin-detector.js +36 -16
  10. package/dist/src/chat-history.d.ts +16 -11
  11. package/dist/src/chat-history.js +26 -4
  12. package/dist/src/components/Chat.js +3 -3
  13. package/dist/src/components/CommandBox.js +1 -16
  14. package/dist/src/components/ConfirmationPrompt.d.ts +2 -1
  15. package/dist/src/components/ConfirmationPrompt.js +7 -3
  16. package/dist/src/components/MultiStepCommandGenerator.d.ts +2 -0
  17. package/dist/src/components/MultiStepCommandGenerator.js +110 -7
  18. package/dist/src/config.d.ts +27 -8
  19. package/dist/src/config.js +92 -33
  20. package/dist/src/history.d.ts +19 -5
  21. package/dist/src/history.js +26 -11
  22. package/dist/src/mastra-agent.d.ts +0 -1
  23. package/dist/src/mastra-agent.js +3 -4
  24. package/dist/src/mastra-chat.d.ts +28 -0
  25. package/dist/src/mastra-chat.js +93 -0
  26. package/dist/src/multi-step.d.ts +2 -2
  27. package/dist/src/multi-step.js +2 -2
  28. package/dist/src/prompts.d.ts +11 -0
  29. package/dist/src/prompts.js +140 -0
  30. package/dist/src/shell-hook.d.ts +35 -13
  31. package/dist/src/shell-hook.js +82 -7
  32. package/dist/src/sysinfo.d.ts +9 -5
  33. package/dist/src/sysinfo.js +2 -2
  34. package/dist/src/utils/console.d.ts +11 -11
  35. package/dist/src/utils/console.js +4 -6
  36. package/package.json +8 -6
  37. package/src/builtin-detector.ts +126 -0
  38. package/src/chat-history.ts +130 -0
  39. package/src/components/Chat.tsx +4 -4
  40. package/src/components/CommandBox.tsx +1 -16
  41. package/src/components/ConfirmationPrompt.tsx +9 -2
  42. package/src/components/MultiStepCommandGenerator.tsx +144 -7
  43. package/src/config.ts +309 -0
  44. package/src/history.ts +160 -0
  45. package/src/mastra-agent.ts +3 -4
  46. package/src/mastra-chat.ts +124 -0
  47. package/src/multi-step.ts +2 -2
  48. package/src/prompts.ts +154 -0
  49. package/src/shell-hook.ts +502 -0
  50. package/src/{sysinfo.js → sysinfo.ts} +28 -16
  51. package/src/utils/{console.js → console.ts} +16 -18
  52. package/bin/pls.js +0 -681
  53. package/src/ai.js +0 -324
  54. package/src/builtin-detector.js +0 -98
  55. package/src/chat-history.js +0 -94
  56. package/src/components/ChatStatus.tsx +0 -53
  57. package/src/components/CommandGenerator.tsx +0 -184
  58. package/src/components/ConfigDisplay.tsx +0 -64
  59. package/src/components/ConfigWizard.tsx +0 -101
  60. package/src/components/HistoryDisplay.tsx +0 -69
  61. package/src/components/HookManager.tsx +0 -150
  62. package/src/config.js +0 -221
  63. package/src/history.js +0 -131
  64. package/src/shell-hook.js +0 -393
@@ -7,26 +7,50 @@
7
7
  // Shell 内置命令列表
8
8
  const SHELL_BUILTINS = [
9
9
  // 目录相关
10
- 'cd', 'pushd', 'popd', 'dirs',
10
+ 'cd',
11
+ 'pushd',
12
+ 'popd',
13
+ 'dirs',
11
14
  // 历史相关
12
15
  'history',
13
16
  // 别名和函数
14
- 'alias', 'unalias',
17
+ 'alias',
18
+ 'unalias',
15
19
  // 环境变量
16
- 'export', 'set', 'unset', 'declare', 'local', 'readonly',
20
+ 'export',
21
+ 'set',
22
+ 'unset',
23
+ 'declare',
24
+ 'local',
25
+ 'readonly',
17
26
  // 脚本执行
18
- 'source', '.',
27
+ 'source',
28
+ '.',
19
29
  // 任务控制
20
- 'jobs', 'fg', 'bg', 'disown',
30
+ 'jobs',
31
+ 'fg',
32
+ 'bg',
33
+ 'disown',
21
34
  // 其他
22
- 'ulimit', 'umask', 'builtin', 'command', 'type',
23
- 'enable', 'hash', 'help', 'let', 'read', 'wait',
24
- 'eval', 'exec', 'trap', 'times', 'shopt'
35
+ 'ulimit',
36
+ 'umask',
37
+ 'builtin',
38
+ 'command',
39
+ 'type',
40
+ 'enable',
41
+ 'hash',
42
+ 'help',
43
+ 'let',
44
+ 'read',
45
+ 'wait',
46
+ 'eval',
47
+ 'exec',
48
+ 'trap',
49
+ 'times',
50
+ 'shopt',
25
51
  ];
26
52
  /**
27
53
  * 提取命令中的所有命令名
28
- * @param {string} command - 完整命令字符串
29
- * @returns {string[]} 命令名数组
30
54
  */
31
55
  function extractCommandNames(command) {
32
56
  // 按分隔符拆分(&&, ||, ;, |, &, 换行)
@@ -39,7 +63,7 @@ function extractCommandNames(command) {
39
63
  continue;
40
64
  // 提取第一个单词(命令名)
41
65
  // 处理 sudo、env 等前缀
42
- let words = trimmed.split(/\s+/);
66
+ const words = trimmed.split(/\s+/);
43
67
  // 跳过 sudo、env 等
44
68
  let i = 0;
45
69
  while (i < words.length && ['sudo', 'env', 'nohup', 'nice'].includes(words[i])) {
@@ -53,8 +77,6 @@ function extractCommandNames(command) {
53
77
  }
54
78
  /**
55
79
  * 检测命令中是否包含 builtin
56
- * @param {string} command - 要检测的命令
57
- * @returns {{ hasBuiltin: boolean, builtins: string[] }} 检测结果
58
80
  */
59
81
  export function detectBuiltin(command) {
60
82
  const commandNames = extractCommandNames(command);
@@ -66,13 +88,11 @@ export function detectBuiltin(command) {
66
88
  }
67
89
  return {
68
90
  hasBuiltin: foundBuiltins.length > 0,
69
- builtins: [...new Set(foundBuiltins)] // 去重
91
+ builtins: [...new Set(foundBuiltins)], // 去重
70
92
  };
71
93
  }
72
94
  /**
73
95
  * 格式化 builtin 列表为易读的字符串
74
- * @param {string[]} builtins - builtin 命令数组
75
- * @returns {string} 格式化后的字符串
76
96
  */
77
97
  export function formatBuiltins(builtins) {
78
98
  if (builtins.length === 0)
@@ -1,26 +1,31 @@
1
1
  /**
2
- * 读取对话历史
3
- * @returns {Array<{role: string, content: string}>} messages 数组
2
+ * 聊天消息
4
3
  */
5
- export function getChatHistory(): Array<{
6
- role: string;
4
+ export interface ChatMessage {
5
+ role: 'user' | 'assistant';
7
6
  content: string;
8
- }>;
7
+ }
8
+ /**
9
+ * 读取对话历史
10
+ */
11
+ export declare function getChatHistory(): ChatMessage[];
9
12
  /**
10
13
  * 添加一轮对话(用户问题 + AI 回答)
11
- * @param {string} userMessage - 用户消息
12
- * @param {string} assistantMessage - AI 回复
13
14
  */
14
- export function addChatMessage(userMessage: string, assistantMessage: string): void;
15
+ export declare function addChatMessage(userMessage: string, assistantMessage: string): void;
15
16
  /**
16
17
  * 清空对话历史
17
18
  */
18
- export function clearChatHistory(): void;
19
+ export declare function clearChatHistory(): void;
19
20
  /**
20
21
  * 获取对话历史文件路径
21
22
  */
22
- export function getChatHistoryFilePath(): string;
23
+ export declare function getChatHistoryFilePath(): string;
23
24
  /**
24
25
  * 获取当前对话轮数
25
26
  */
26
- export function getChatRoundCount(): number;
27
+ export declare function getChatRoundCount(): number;
28
+ /**
29
+ * 显示对话历史(只显示用户的 prompt)
30
+ */
31
+ export declare function displayChatHistory(): void;
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
+ import chalk from 'chalk';
4
5
  import { getConfig } from './config.js';
5
6
  const CONFIG_DIR = path.join(os.homedir(), '.please');
6
7
  const CHAT_HISTORY_FILE = path.join(CONFIG_DIR, 'chat_history.json');
@@ -14,7 +15,6 @@ function ensureConfigDir() {
14
15
  }
15
16
  /**
16
17
  * 读取对话历史
17
- * @returns {Array<{role: string, content: string}>} messages 数组
18
18
  */
19
19
  export function getChatHistory() {
20
20
  ensureConfigDir();
@@ -31,7 +31,6 @@ export function getChatHistory() {
31
31
  }
32
32
  /**
33
33
  * 保存对话历史
34
- * @param {Array<{role: string, content: string}>} history
35
34
  */
36
35
  function saveChatHistory(history) {
37
36
  ensureConfigDir();
@@ -39,8 +38,6 @@ function saveChatHistory(history) {
39
38
  }
40
39
  /**
41
40
  * 添加一轮对话(用户问题 + AI 回答)
42
- * @param {string} userMessage - 用户消息
43
- * @param {string} assistantMessage - AI 回复
44
41
  */
45
42
  export function addChatMessage(userMessage, assistantMessage) {
46
43
  const config = getConfig();
@@ -79,3 +76,28 @@ export function getChatRoundCount() {
79
76
  const history = getChatHistory();
80
77
  return Math.floor(history.length / 2);
81
78
  }
79
+ /**
80
+ * 显示对话历史(只显示用户的 prompt)
81
+ */
82
+ export function displayChatHistory() {
83
+ const history = getChatHistory();
84
+ const config = getConfig();
85
+ if (history.length === 0) {
86
+ console.log('\n' + chalk.gray('暂无对话历史'));
87
+ console.log('');
88
+ return;
89
+ }
90
+ // 只提取用户消息
91
+ const userMessages = history.filter((msg) => msg.role === 'user');
92
+ console.log('');
93
+ console.log(chalk.bold(`对话历史(最近 ${userMessages.length} 轮):`));
94
+ console.log(chalk.gray('━'.repeat(50)));
95
+ userMessages.forEach((msg, index) => {
96
+ const num = index + 1;
97
+ console.log(` ${chalk.cyan(num.toString().padStart(2, ' '))}. ${msg.content}`);
98
+ });
99
+ console.log(chalk.gray('━'.repeat(50)));
100
+ console.log(chalk.gray(`配置: 保留最近 ${config.chatHistoryLimit} 轮对话`));
101
+ console.log(chalk.gray(`文件: ${CHAT_HISTORY_FILE}`));
102
+ console.log('');
103
+ }
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
4
  import { MarkdownDisplay } from './MarkdownDisplay.js';
5
- import { chatWithAI } from '../ai.js';
5
+ import { chatWithMastra } from '../mastra-chat.js';
6
6
  import { getChatRoundCount } from '../chat-history.js';
7
7
  import { theme } from '../ui/theme.js';
8
8
  /**
@@ -23,12 +23,12 @@ export function Chat({ prompt, debug, showRoundCount, onComplete }) {
23
23
  setContent((prev) => prev + chunk);
24
24
  };
25
25
  // 调用 AI
26
- chatWithAI(prompt, { debug: debug || false, onChunk })
26
+ chatWithMastra(prompt, { debug: debug || false, onChunk })
27
27
  .then((result) => {
28
28
  const endTime = Date.now();
29
29
  setDuration(endTime - startTime);
30
30
  setStatus('done');
31
- if (debug && typeof result === 'object' && 'debug' in result) {
31
+ if (debug && typeof result === 'object' && 'debug' in result && result.debug) {
32
32
  setDebugInfo(result.debug);
33
33
  }
34
34
  setTimeout(onComplete, 100);
@@ -1,22 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import { theme } from '../ui/theme.js';
4
- /**
5
- * 计算字符串的显示宽度(中文占2个宽度)
6
- */
7
- function getDisplayWidth(str) {
8
- let width = 0;
9
- for (const char of str) {
10
- // 中文、日文、韩文等宽字符占 2 个宽度
11
- if (char.match(/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef\u3000-\u303f]/)) {
12
- width += 2;
13
- }
14
- else {
15
- width += 1;
16
- }
17
- }
18
- return width;
19
- }
4
+ import { getDisplayWidth } from '../utils/console.js';
20
5
  /**
21
6
  * CommandBox 组件 - 显示带边框和标题的命令框
22
7
  */
@@ -3,10 +3,11 @@ interface ConfirmationPromptProps {
3
3
  prompt: string;
4
4
  onConfirm: () => void;
5
5
  onCancel: () => void;
6
+ onEdit?: () => void;
6
7
  }
7
8
  /**
8
9
  * ConfirmationPrompt 组件 - 单键确认提示
9
- * 回车 = 确认,Esc = 取消,Ctrl+C = 退出
10
+ * 回车 = 确认,E = 编辑,Esc = 取消,Ctrl+C = 退出
10
11
  */
11
12
  export declare const ConfirmationPrompt: React.FC<ConfirmationPromptProps>;
12
13
  export {};
@@ -3,9 +3,9 @@ import { Text, useInput } from 'ink';
3
3
  import { theme } from '../ui/theme.js';
4
4
  /**
5
5
  * ConfirmationPrompt 组件 - 单键确认提示
6
- * 回车 = 确认,Esc = 取消,Ctrl+C = 退出
6
+ * 回车 = 确认,E = 编辑,Esc = 取消,Ctrl+C = 退出
7
7
  */
8
- export const ConfirmationPrompt = ({ prompt, onConfirm, onCancel, }) => {
8
+ export const ConfirmationPrompt = ({ prompt, onConfirm, onCancel, onEdit, }) => {
9
9
  useInput((input, key) => {
10
10
  if (key.return) {
11
11
  // 回车键
@@ -15,6 +15,10 @@ export const ConfirmationPrompt = ({ prompt, onConfirm, onCancel, }) => {
15
15
  // Esc 键
16
16
  onCancel();
17
17
  }
18
+ else if ((input === 'e' || input === 'E') && onEdit) {
19
+ // E 键进入编辑模式
20
+ onEdit();
21
+ }
18
22
  else if (key.ctrl && input === 'c') {
19
23
  // Ctrl+C
20
24
  process.exit(0);
@@ -22,5 +26,5 @@ export const ConfirmationPrompt = ({ prompt, onConfirm, onCancel, }) => {
22
26
  });
23
27
  return (React.createElement(Text, null,
24
28
  React.createElement(Text, { bold: true, color: theme.warning }, prompt),
25
- React.createElement(Text, { color: theme.text.secondary }, " [\u56DE\u8F66\u6267\u884C / Esc \u53D6\u6D88] ")));
29
+ React.createElement(Text, { color: theme.text.secondary }, onEdit ? ' [回车执行 / E 编辑 / Esc 取消] ' : ' [回车执行 / Esc 取消] ')));
26
30
  };
@@ -5,6 +5,8 @@ interface MultiStepCommandGeneratorProps {
5
5
  debug?: boolean;
6
6
  onStepComplete: (step: {
7
7
  command: string;
8
+ aiGeneratedCommand?: string;
9
+ userModified?: boolean;
8
10
  confirmed: boolean;
9
11
  cancelled?: boolean;
10
12
  hasBuiltin?: boolean;
@@ -1,5 +1,6 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { Box, Text } from 'ink';
2
+ import { Box, Text, useInput } from 'ink';
3
+ import TextInput from 'ink-text-input';
3
4
  import Spinner from 'ink-spinner';
4
5
  import { generateMultiStepCommand } from '../multi-step.js';
5
6
  import { detectBuiltin, formatBuiltins } from '../builtin-detector.js';
@@ -7,6 +8,7 @@ import { CommandBox } from './CommandBox.js';
7
8
  import { ConfirmationPrompt } from './ConfirmationPrompt.js';
8
9
  import { Duration } from './Duration.js';
9
10
  import { theme } from '../ui/theme.js';
11
+ import { getConfig } from '../config.js';
10
12
  /**
11
13
  * MultiStepCommandGenerator 组件 - 多步骤命令生成
12
14
  * 每次只生成一个命令,支持 continue 机制
@@ -15,6 +17,13 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
15
17
  const [state, setState] = useState({ type: 'thinking' });
16
18
  const [thinkDuration, setThinkDuration] = useState(0);
17
19
  const [debugInfo, setDebugInfo] = useState(null);
20
+ const [editedCommand, setEditedCommand] = useState(''); // 新增:编辑后的命令
21
+ // 监听编辑模式下的 Esc 键
22
+ useInput((input, key) => {
23
+ if (state.type === 'editing' && key.escape) {
24
+ handleEditCancel();
25
+ }
26
+ }, { isActive: state.type === 'editing' });
18
27
  // 初始化:调用 Mastra 生成命令
19
28
  useEffect(() => {
20
29
  const thinkStart = Date.now();
@@ -26,13 +35,27 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
26
35
  if (debug && result.debugInfo) {
27
36
  setDebugInfo(result.debugInfo);
28
37
  }
29
- setState({
30
- type: 'showing_command',
31
- stepData: result.stepData,
32
- });
33
- // 检测 builtin
38
+ // 如果 AI 返回空命令且决定不继续,说明 AI 放弃了
39
+ // 直接结束,不显示命令框
40
+ if (!result.stepData.command.trim() && result.stepData.continue === false) {
41
+ setTimeout(() => {
42
+ onStepComplete({
43
+ command: '',
44
+ confirmed: false,
45
+ reasoning: result.stepData.reasoning,
46
+ needsContinue: false,
47
+ });
48
+ }, 100);
49
+ return;
50
+ }
51
+ // 检测 builtin(优先检测)
34
52
  const { hasBuiltin, builtins } = detectBuiltin(result.stepData.command);
35
53
  if (hasBuiltin) {
54
+ // 有 builtin,不管什么模式都不编辑,直接提示
55
+ setState({
56
+ type: 'showing_command',
57
+ stepData: result.stepData,
58
+ });
36
59
  setTimeout(() => {
37
60
  onStepComplete({
38
61
  command: result.stepData.command,
@@ -43,6 +66,25 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
43
66
  needsContinue: result.stepData.continue,
44
67
  });
45
68
  }, 100);
69
+ return;
70
+ }
71
+ // 根据 editMode 决定进入哪个状态
72
+ const config = getConfig();
73
+ const autoEdit = config.editMode === 'auto';
74
+ if (autoEdit) {
75
+ // auto 模式:直接进入编辑状态
76
+ setEditedCommand(result.stepData.command);
77
+ setState({
78
+ type: 'editing',
79
+ stepData: result.stepData,
80
+ });
81
+ }
82
+ else {
83
+ // manual 模式:显示命令,等待用户操作
84
+ setState({
85
+ type: 'showing_command',
86
+ stepData: result.stepData,
87
+ });
46
88
  }
47
89
  })
48
90
  .catch((error) => {
@@ -61,6 +103,8 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
61
103
  if (state.type === 'showing_command') {
62
104
  onStepComplete({
63
105
  command: state.stepData.command,
106
+ aiGeneratedCommand: state.stepData.command, // 原始命令
107
+ userModified: false,
64
108
  confirmed: true,
65
109
  reasoning: state.stepData.reasoning,
66
110
  needsContinue: state.stepData.continue,
@@ -69,6 +113,50 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
69
113
  });
70
114
  }
71
115
  };
116
+ // 处理编辑
117
+ const handleEdit = () => {
118
+ if (state.type === 'showing_command') {
119
+ setEditedCommand(state.stepData.command); // 初始化为 AI 生成的命令
120
+ setState({ type: 'editing', stepData: state.stepData });
121
+ }
122
+ };
123
+ // 编辑完成确认
124
+ const handleEditConfirm = () => {
125
+ if (state.type === 'editing') {
126
+ const modified = editedCommand !== state.stepData.command;
127
+ onStepComplete({
128
+ command: editedCommand, // 使用编辑后的命令
129
+ aiGeneratedCommand: state.stepData.command, // 保存 AI 原始命令
130
+ userModified: modified,
131
+ confirmed: true,
132
+ reasoning: state.stepData.reasoning,
133
+ needsContinue: state.stepData.continue,
134
+ nextStepHint: state.stepData.nextStepHint,
135
+ debugInfo: debugInfo,
136
+ });
137
+ }
138
+ };
139
+ // 取消编辑
140
+ const handleEditCancel = () => {
141
+ if (state.type === 'editing') {
142
+ const config = getConfig();
143
+ if (config.editMode === 'auto') {
144
+ // auto 模式:Esc 直接取消整个操作
145
+ setState({ type: 'cancelled', command: state.stepData.command });
146
+ setTimeout(() => {
147
+ onStepComplete({
148
+ command: state.stepData.command,
149
+ confirmed: false,
150
+ cancelled: true,
151
+ });
152
+ }, 100);
153
+ }
154
+ else {
155
+ // manual 模式:Esc 返回到 showing_command 状态
156
+ setState({ type: 'showing_command', stepData: state.stepData });
157
+ }
158
+ }
159
+ };
72
160
  // 处理取消
73
161
  const handleCancel = () => {
74
162
  if (state.type === 'showing_command') {
@@ -132,7 +220,22 @@ export const MultiStepCommandGenerator = ({ prompt, debug, previousSteps = [], c
132
220
  }
133
221
  return null;
134
222
  })(),
135
- !detectBuiltin(state.stepData.command).hasBuiltin && (React.createElement(ConfirmationPrompt, { prompt: "\u6267\u884C\uFF1F", onConfirm: handleConfirm, onCancel: handleCancel })))),
223
+ !detectBuiltin(state.stepData.command).hasBuiltin && (React.createElement(ConfirmationPrompt, { prompt: "\u6267\u884C\uFF1F", onConfirm: handleConfirm, onCancel: handleCancel, onEdit: handleEdit })))),
224
+ state.type === 'editing' && (React.createElement(React.Fragment, null,
225
+ state.stepData.continue === true && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
226
+ React.createElement(Text, { color: theme.text.secondary },
227
+ "\u6B65\u9AA4 ",
228
+ currentStepNumber,
229
+ "/?"),
230
+ state.stepData.reasoning && (React.createElement(Text, { color: theme.text.muted },
231
+ "\u539F\u56E0: ",
232
+ state.stepData.reasoning)))),
233
+ React.createElement(CommandBox, { command: state.stepData.command }),
234
+ React.createElement(Box, { flexDirection: "row" },
235
+ React.createElement(Text, { color: theme.primary }, '> '),
236
+ React.createElement(TextInput, { value: editedCommand, onChange: setEditedCommand, onSubmit: handleEditConfirm })),
237
+ React.createElement(Box, { marginTop: 1 },
238
+ React.createElement(Text, { color: theme.text.secondary }, getConfig().editMode === 'auto' ? '[回车执行 / Esc 取消]' : '[回车执行 / Esc 返回]')))),
136
239
  state.type === 'cancelled' && (React.createElement(Box, { marginTop: 1 },
137
240
  React.createElement(Text, { color: theme.text.secondary }, "\u5DF2\u53D6\u6D88\u6267\u884C"))),
138
241
  state.type === 'error' && (React.createElement(Box, { marginTop: 1 },
@@ -1,29 +1,48 @@
1
+ export declare const CONFIG_DIR: string;
2
+ declare const VALID_PROVIDERS: readonly ["openai", "anthropic", "deepseek", "google", "groq", "mistral", "cohere", "fireworks", "together"];
3
+ type Provider = (typeof VALID_PROVIDERS)[number];
4
+ declare const VALID_EDIT_MODES: readonly ["manual", "auto"];
5
+ type EditMode = (typeof VALID_EDIT_MODES)[number];
6
+ /**
7
+ * 配置接口
8
+ */
9
+ export interface Config {
10
+ apiKey: string;
11
+ baseUrl: string;
12
+ model: string;
13
+ provider: Provider;
14
+ shellHook: boolean;
15
+ chatHistoryLimit: number;
16
+ commandHistoryLimit: number;
17
+ shellHistoryLimit: number;
18
+ editMode: EditMode;
19
+ }
1
20
  /**
2
21
  * 读取配置
3
22
  */
4
- export function getConfig(): any;
23
+ export declare function getConfig(): Config;
5
24
  /**
6
25
  * 保存配置
7
26
  */
8
- export function saveConfig(config: any): void;
27
+ export declare function saveConfig(config: Config): void;
9
28
  /**
10
29
  * 设置单个配置项
11
30
  */
12
- export function setConfigValue(key: any, value: any): any;
31
+ export declare function setConfigValue(key: string, value: string | boolean | number): Config;
13
32
  /**
14
33
  * 检查配置是否有效
15
34
  */
16
- export function isConfigValid(): any;
35
+ export declare function isConfigValid(): boolean;
17
36
  /**
18
37
  * 隐藏 API Key 中间部分
19
38
  */
20
- export function maskApiKey(apiKey: any): any;
39
+ export declare function maskApiKey(apiKey: string): string;
21
40
  /**
22
41
  * 显示当前配置
23
42
  */
24
- export function displayConfig(): void;
43
+ export declare function displayConfig(): void;
25
44
  /**
26
45
  * 交互式配置向导
27
46
  */
28
- export function runConfigWizard(): Promise<void>;
29
- export const CONFIG_DIR: string;
47
+ export declare function runConfigWizard(): Promise<void>;
48
+ export {};