tianxincode 1.0.13 → 1.0.14
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/dist/api/filesystem.routes.js +13 -4
- package/dist/api/filesystem.routes.js.map +1 -1
- package/dist/components/App.backup.d.ts +34 -0
- package/dist/components/App.backup.d.ts.map +1 -0
- package/dist/components/App.backup.js +692 -0
- package/dist/components/App.backup.js.map +1 -0
- package/dist/components/App.d.ts +33 -24
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +182 -718
- package/dist/components/App.js.map +1 -1
- package/dist/components/FileSelector.d.ts +47 -0
- package/dist/components/FileSelector.d.ts.map +1 -0
- package/dist/components/FileSelector.js +40 -0
- package/dist/components/FileSelector.js.map +1 -0
- package/dist/components/Header.d.ts +3 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +17 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/InputArea.d.ts +50 -0
- package/dist/components/InputArea.d.ts.map +1 -0
- package/dist/components/InputArea.js +52 -0
- package/dist/components/InputArea.js.map +1 -0
- package/dist/components/MainContent.d.ts +11 -0
- package/dist/components/MainContent.d.ts.map +1 -0
- package/dist/components/MainContent.js +118 -0
- package/dist/components/MainContent.js.map +1 -0
- package/dist/components/MessageList.d.ts +11 -0
- package/dist/components/MessageList.d.ts.map +1 -0
- package/dist/components/MessageList.js +129 -0
- package/dist/components/MessageList.js.map +1 -0
- package/dist/components/ModelSelector.d.ts +42 -0
- package/dist/components/ModelSelector.d.ts.map +1 -0
- package/dist/components/ModelSelector.js +36 -0
- package/dist/components/ModelSelector.js.map +1 -0
- package/dist/components/StatusBar.d.ts +14 -0
- package/dist/components/StatusBar.d.ts.map +1 -0
- package/dist/components/StatusBar.js +21 -0
- package/dist/components/StatusBar.js.map +1 -0
- package/dist/components/hooks/useChat.d.ts +69 -0
- package/dist/components/hooks/useChat.d.ts.map +1 -0
- package/dist/components/hooks/useChat.js +270 -0
- package/dist/components/hooks/useChat.js.map +1 -0
- package/dist/components/hooks/useFileSelect.d.ts +58 -0
- package/dist/components/hooks/useFileSelect.d.ts.map +1 -0
- package/dist/components/hooks/useFileSelect.js +182 -0
- package/dist/components/hooks/useFileSelect.js.map +1 -0
- package/dist/components/hooks/useModelSelect.d.ts +54 -0
- package/dist/components/hooks/useModelSelect.d.ts.map +1 -0
- package/dist/components/hooks/useModelSelect.js +137 -0
- package/dist/components/hooks/useModelSelect.js.map +1 -0
- package/dist/components/useInputHandler.d.ts +33 -0
- package/dist/components/useInputHandler.d.ts.map +1 -0
- package/dist/components/useInputHandler.js +130 -0
- package/dist/components/useInputHandler.js.map +1 -0
- package/dist/hooks/useAlternateBuffer.d.ts +14 -0
- package/dist/hooks/useAlternateBuffer.d.ts.map +1 -0
- package/dist/hooks/useAlternateBuffer.js +20 -0
- package/dist/hooks/useAlternateBuffer.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
- package/scripts/ink-scroll-demo.tsx +147 -0
- package/web/dist/assets/{AiLogsView-D_SQ6qo4.js → AiLogsView-3J-YAusV.js} +1 -1
- package/web/dist/assets/{DevWorkflowView-C5VnPngb.css → DevWorkflowView-BRvigFN5.css} +1 -1
- package/web/dist/assets/{DevWorkflowView-iHAv9LC0.js → DevWorkflowView-DMCpylwg.js} +5 -5
- package/web/dist/assets/{Layout-CQhbIJxB.js → Layout-B905ASbH.js} +1 -1
- package/web/dist/assets/{TasksView-B9B2H3-S.js → TasksView-CCzwoCHn.js} +1 -1
- package/web/dist/assets/{TerminalView-BKhdi5UF.js → TerminalView-CxtZwfd-.js} +1 -1
- package/web/dist/assets/{cssMode-C_gwipb0.js → cssMode-tUnhOlEq.js} +1 -1
- package/web/dist/assets/{freemarker2-WCA_pR0J.js → freemarker2-BkGxlHtf.js} +1 -1
- package/web/dist/assets/{handlebars-fzVGzXHj.js → handlebars-BCSYP3By.js} +1 -1
- package/web/dist/assets/{html-C4Rga6DD.js → html-D_GMhfaP.js} +1 -1
- package/web/dist/assets/{htmlMode-BvrJ57rW.js → htmlMode-DDgBAK4r.js} +1 -1
- package/web/dist/assets/{index-9RP8PAfk.js → index-CUPB0bCv.js} +13 -13
- package/web/dist/assets/{javascript-cXKyuP98.js → javascript-CGc1uqdW.js} +1 -1
- package/web/dist/assets/{jsonMode-Q4CMzwiX.js → jsonMode-Ce0FYmxJ.js} +1 -1
- package/web/dist/assets/{liquid-CrbU0gmK.js → liquid-BwNgZkfv.js} +1 -1
- package/web/dist/assets/{mdx-D72Dcs66.js → mdx-CF1JkZ9f.js} +1 -1
- package/web/dist/assets/{python-DPqkZ_Xm.js → python-CXnk0DYj.js} +1 -1
- package/web/dist/assets/{razor-DknXaqXN.js → razor-CWGzlt3Z.js} +1 -1
- package/web/dist/assets/{tsMode-DZAV3Wgo.js → tsMode-CXhn7HXH.js} +1 -1
- package/web/dist/assets/{typescript-DenKTmW3.js → typescript-DF01mLhp.js} +1 -1
- package/web/dist/assets/{xml-C_uqJta0.js → xml-ZLfViiJc.js} +1 -1
- package/web/dist/assets/{yaml-vwb3U7d7.js → yaml-CV_nX5Yg.js} +1 -1
- package/web/dist/index.html +1 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useFileSelect Hook - 文件选择功能逻辑管理
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - 管理文件选择模式状态 (fileSelectMode)
|
|
6
|
+
* - 管理文件列表和导航状态
|
|
7
|
+
* - 处理目录加载和文件选择逻辑
|
|
8
|
+
*
|
|
9
|
+
* 功能:
|
|
10
|
+
* - 打开文件选择器时从当前工作目录开始
|
|
11
|
+
* - 支持目录导航(进入/返回)
|
|
12
|
+
* - 文件按目录优先、字母顺序排序
|
|
13
|
+
* - 选择文件后自动转换为相对路径
|
|
14
|
+
*
|
|
15
|
+
* 使用方式:
|
|
16
|
+
* const fileSelect = useFileSelect({ onFileSelected: (path) => {} });
|
|
17
|
+
* // 使用 fileSelect.open() 打开选择器
|
|
18
|
+
* // 使用 fileSelect.confirm() 确认选择
|
|
19
|
+
* // 使用 fileSelect.moveUp/moveDown 导航
|
|
20
|
+
*/
|
|
21
|
+
import { useState, useCallback } from 'react';
|
|
22
|
+
import * as fs from 'fs';
|
|
23
|
+
import * as path from 'path';
|
|
24
|
+
/**
|
|
25
|
+
* 文件选择功能 Hook
|
|
26
|
+
* @param options - 配置选项
|
|
27
|
+
* @returns 文件选择相关的状态和方法
|
|
28
|
+
*/
|
|
29
|
+
export function useFileSelect(options = {}) {
|
|
30
|
+
const { onFileSelected } = options;
|
|
31
|
+
/** 是否处于文件选择模式 */
|
|
32
|
+
const [fileSelectMode, setFileSelectMode] = useState(false);
|
|
33
|
+
/** 当前浏览的目录路径 */
|
|
34
|
+
const [currentDir, setCurrentDir] = useState('');
|
|
35
|
+
/** 基准目录(首次打开时的目录,用于计算相对路径) */
|
|
36
|
+
const [baseDir, setBaseDir] = useState('');
|
|
37
|
+
/** 当前目录下的文件和目录列表 */
|
|
38
|
+
const [fileList, setFileList] = useState([]);
|
|
39
|
+
/** 当前选中的文件索引 */
|
|
40
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
41
|
+
/**
|
|
42
|
+
* 加载指定目录的内容
|
|
43
|
+
*
|
|
44
|
+
* 处理逻辑:
|
|
45
|
+
* 1. 如果是首次加载(resetBaseDir=true)或没有基准目录,设置基准目录
|
|
46
|
+
* 2. 添加 ".." 目录项(如果不在根目录)
|
|
47
|
+
* 3. 读取目录内容并过滤隐藏文件
|
|
48
|
+
* 4. 排序:目录优先,然后按字母顺序
|
|
49
|
+
* 5. 限制最多显示 50 个文件
|
|
50
|
+
*
|
|
51
|
+
* @param dir - 要加载的目录路径
|
|
52
|
+
* @param resetBaseDir - 是否重置基准目录(首次打开时为 true)
|
|
53
|
+
*/
|
|
54
|
+
const loadDirectory = useCallback((dir, resetBaseDir = false) => {
|
|
55
|
+
try {
|
|
56
|
+
// 设置基准目录
|
|
57
|
+
if (!baseDir || resetBaseDir) {
|
|
58
|
+
setBaseDir(dir);
|
|
59
|
+
}
|
|
60
|
+
const files = [];
|
|
61
|
+
const parentDir = path.dirname(dir);
|
|
62
|
+
// 添加上级目录入口(如果不是根目录)
|
|
63
|
+
if (parentDir !== dir) {
|
|
64
|
+
files.push({ name: '..', path: parentDir, isDirectory: true });
|
|
65
|
+
}
|
|
66
|
+
// 读取目录内容
|
|
67
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
68
|
+
// 遍历目录项,跳过隐藏文件
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
if (entry.name === '.' || entry.name === '..')
|
|
71
|
+
continue;
|
|
72
|
+
const fullPath = path.join(dir, entry.name);
|
|
73
|
+
files.push({
|
|
74
|
+
name: entry.name,
|
|
75
|
+
path: fullPath,
|
|
76
|
+
isDirectory: entry.isDirectory()
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// 排序:目录优先,然后按名称字母顺序
|
|
80
|
+
files.sort((a, b) => {
|
|
81
|
+
if (a.name === '..')
|
|
82
|
+
return -1;
|
|
83
|
+
if (b.name === '..')
|
|
84
|
+
return 1;
|
|
85
|
+
if (a.isDirectory && !b.isDirectory)
|
|
86
|
+
return -1;
|
|
87
|
+
if (!a.isDirectory && b.isDirectory)
|
|
88
|
+
return 1;
|
|
89
|
+
return a.name.localeCompare(b.name);
|
|
90
|
+
});
|
|
91
|
+
// 限制显示数量,更新状态
|
|
92
|
+
setFileList(files.slice(0, 50));
|
|
93
|
+
setCurrentDir(dir);
|
|
94
|
+
setSelectedIndex(0);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
// 读取失败时清空列表
|
|
98
|
+
setFileList([]);
|
|
99
|
+
}
|
|
100
|
+
}, [baseDir]);
|
|
101
|
+
/**
|
|
102
|
+
* 打开文件选择器
|
|
103
|
+
* - 设置为选择模式
|
|
104
|
+
* - 从当前工作目录开始加载
|
|
105
|
+
*/
|
|
106
|
+
const open = useCallback(() => {
|
|
107
|
+
setFileSelectMode(true);
|
|
108
|
+
loadDirectory(process.cwd(), true);
|
|
109
|
+
}, [loadDirectory]);
|
|
110
|
+
/**
|
|
111
|
+
* 确认当前选择
|
|
112
|
+
*
|
|
113
|
+
* 处理逻辑:
|
|
114
|
+
* 1. 如果选中的是目录或 "..",进入该目录
|
|
115
|
+
* 2. 如果选中的是文件,计算相对路径并触发回调
|
|
116
|
+
* 3. 选择完成后退出选择模式
|
|
117
|
+
*/
|
|
118
|
+
const confirm = useCallback(() => {
|
|
119
|
+
if (fileList[selectedIndex]) {
|
|
120
|
+
const selected = fileList[selectedIndex];
|
|
121
|
+
// 选中目录:进入该目录
|
|
122
|
+
if (selected.isDirectory || selected.name === '..') {
|
|
123
|
+
loadDirectory(selected.path);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// 选中文件:计算相对路径
|
|
127
|
+
const fullPath = selected.path;
|
|
128
|
+
const effectiveBaseDir = baseDir || process.cwd();
|
|
129
|
+
let relativePath = path.relative(effectiveBaseDir, fullPath);
|
|
130
|
+
// 统一使用正斜杠
|
|
131
|
+
relativePath = relativePath.split(path.sep).join('/');
|
|
132
|
+
// 触发回调
|
|
133
|
+
onFileSelected?.(relativePath);
|
|
134
|
+
// 退出选择模式
|
|
135
|
+
setFileSelectMode(false);
|
|
136
|
+
setFileList([]);
|
|
137
|
+
setBaseDir('');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}, [fileList, selectedIndex, loadDirectory, baseDir, onFileSelected]);
|
|
141
|
+
/**
|
|
142
|
+
* 取消文件选择
|
|
143
|
+
* - 退出选择模式
|
|
144
|
+
* - 清空文件列表和基准目录
|
|
145
|
+
*/
|
|
146
|
+
const cancel = useCallback(() => {
|
|
147
|
+
setFileSelectMode(false);
|
|
148
|
+
setFileList([]);
|
|
149
|
+
setBaseDir('');
|
|
150
|
+
}, []);
|
|
151
|
+
/**
|
|
152
|
+
* 向上移动选择焦点
|
|
153
|
+
* - 最小值为 0
|
|
154
|
+
*/
|
|
155
|
+
const moveUp = useCallback(() => {
|
|
156
|
+
setSelectedIndex(prev => Math.max(0, prev - 1));
|
|
157
|
+
}, []);
|
|
158
|
+
/**
|
|
159
|
+
* 向下移动选择焦点
|
|
160
|
+
* - 最大值为文件列表长度 - 1
|
|
161
|
+
*/
|
|
162
|
+
const moveDown = useCallback(() => {
|
|
163
|
+
setSelectedIndex(prev => Math.min(fileList.length - 1, prev + 1));
|
|
164
|
+
}, [fileList]);
|
|
165
|
+
/**
|
|
166
|
+
* 返回 Hook 的结果
|
|
167
|
+
*/
|
|
168
|
+
return {
|
|
169
|
+
fileSelectMode, // 是否处于选择模式
|
|
170
|
+
currentDir, // 当前目录
|
|
171
|
+
baseDir, // 基准目录
|
|
172
|
+
fileList, // 文件列表
|
|
173
|
+
selectedIndex, // 当前选中索引
|
|
174
|
+
loadDirectory, // 加载目录方法
|
|
175
|
+
open, // 打开选择器
|
|
176
|
+
confirm, // 确认选择
|
|
177
|
+
cancel, // 取消选择
|
|
178
|
+
moveUp, // 上移
|
|
179
|
+
moveDown, // 下移
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=useFileSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFileSelect.js","sourceRoot":"","sources":["../../../src/components/hooks/useFileSelect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useModelSelect Hook - 模型选择功能逻辑管理
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - 管理模型选择模式状态 (modelSelectMode)
|
|
6
|
+
* - 管理模型列表和选中状态
|
|
7
|
+
* - 从配置服务加载可用模型
|
|
8
|
+
* - 处理模型选择确认逻辑
|
|
9
|
+
*
|
|
10
|
+
* 功能:
|
|
11
|
+
* - 从配置服务获取所有可用的 AI 模型
|
|
12
|
+
* - 支持多个 provider 的模型
|
|
13
|
+
* - 选择模型后自动保存为默认模型
|
|
14
|
+
*
|
|
15
|
+
* 使用方式:
|
|
16
|
+
* const modelSelect = useModelSelect({ onModelSelected: (name) => {} });
|
|
17
|
+
* // 使用 modelSelect.open() 打开选择器
|
|
18
|
+
* // 使用 modelSelect.confirm() 确认选择
|
|
19
|
+
* // 使用 modelSelect.moveUp/moveDown 导航
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* 模型信息类型定义
|
|
23
|
+
* @property id - 模型唯一标识
|
|
24
|
+
* @property name - 模型显示名称
|
|
25
|
+
*/
|
|
26
|
+
export interface ModelInfo {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* useModelSelect Hook 配置选项
|
|
32
|
+
* @property onModelSelected - 模型选择完成后的回调,参数为模型名称
|
|
33
|
+
*/
|
|
34
|
+
interface UseModelSelectOptions {
|
|
35
|
+
onModelSelected?: (modelName: string) => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 模型选择功能 Hook
|
|
39
|
+
* @param options - 配置选项
|
|
40
|
+
* @returns 模型选择相关的状态和方法
|
|
41
|
+
*/
|
|
42
|
+
export declare function useModelSelect(options?: UseModelSelectOptions): {
|
|
43
|
+
modelSelectMode: boolean;
|
|
44
|
+
modelList: ModelInfo[];
|
|
45
|
+
modelSelectedIndex: number;
|
|
46
|
+
loadModels: () => Promise<void>;
|
|
47
|
+
open: () => void;
|
|
48
|
+
confirm: () => void;
|
|
49
|
+
cancel: () => void;
|
|
50
|
+
moveUp: () => void;
|
|
51
|
+
moveDown: () => void;
|
|
52
|
+
};
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=useModelSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useModelSelect.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useModelSelect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,UAAU,qBAAqB;IAC9B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B;;;;;;;;;;EAwHjE"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useModelSelect Hook - 模型选择功能逻辑管理
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - 管理模型选择模式状态 (modelSelectMode)
|
|
6
|
+
* - 管理模型列表和选中状态
|
|
7
|
+
* - 从配置服务加载可用模型
|
|
8
|
+
* - 处理模型选择确认逻辑
|
|
9
|
+
*
|
|
10
|
+
* 功能:
|
|
11
|
+
* - 从配置服务获取所有可用的 AI 模型
|
|
12
|
+
* - 支持多个 provider 的模型
|
|
13
|
+
* - 选择模型后自动保存为默认模型
|
|
14
|
+
*
|
|
15
|
+
* 使用方式:
|
|
16
|
+
* const modelSelect = useModelSelect({ onModelSelected: (name) => {} });
|
|
17
|
+
* // 使用 modelSelect.open() 打开选择器
|
|
18
|
+
* // 使用 modelSelect.confirm() 确认选择
|
|
19
|
+
* // 使用 modelSelect.moveUp/moveDown 导航
|
|
20
|
+
*/
|
|
21
|
+
import { useState, useCallback } from 'react';
|
|
22
|
+
import { configService } from '../../modules/config/index.js';
|
|
23
|
+
/**
|
|
24
|
+
* 模型选择功能 Hook
|
|
25
|
+
* @param options - 配置选项
|
|
26
|
+
* @returns 模型选择相关的状态和方法
|
|
27
|
+
*/
|
|
28
|
+
export function useModelSelect(options = {}) {
|
|
29
|
+
const { onModelSelected } = options;
|
|
30
|
+
/** 是否处于模型选择模式 */
|
|
31
|
+
const [modelSelectMode, setModelSelectMode] = useState(false);
|
|
32
|
+
/** 可用模型列表 */
|
|
33
|
+
const [modelList, setModelList] = useState([]);
|
|
34
|
+
/** 当前选中的模型索引 */
|
|
35
|
+
const [modelSelectedIndex, setModelSelectedIndex] = useState(0);
|
|
36
|
+
/**
|
|
37
|
+
* 加载可用的模型列表
|
|
38
|
+
*
|
|
39
|
+
* 处理逻辑:
|
|
40
|
+
* 1. 从配置服务获取所有 provider
|
|
41
|
+
* 2. 遍历每个 provider 获取其模型列表
|
|
42
|
+
* 3. 如果没有可用模型,添加默认的 deepseek-chat
|
|
43
|
+
*
|
|
44
|
+
* @returns Promise - 加载完成
|
|
45
|
+
*/
|
|
46
|
+
const loadModels = useCallback(async () => {
|
|
47
|
+
try {
|
|
48
|
+
// 获取所有 provider
|
|
49
|
+
const providers = configService.getProviders();
|
|
50
|
+
const models = [];
|
|
51
|
+
// 遍历每个 provider 获取模型
|
|
52
|
+
for (const provider of providers) {
|
|
53
|
+
const providerModels = configService.getModels(provider.id);
|
|
54
|
+
for (const m of providerModels) {
|
|
55
|
+
models.push({ id: m.id, name: m.name });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 如果没有可用模型,使用默认值
|
|
59
|
+
if (models.length === 0) {
|
|
60
|
+
models.push({ id: 'deepseek-chat', name: 'deepseek-chat' });
|
|
61
|
+
}
|
|
62
|
+
setModelList(models);
|
|
63
|
+
setModelSelectedIndex(0);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
setModelList([]);
|
|
67
|
+
}
|
|
68
|
+
}, []);
|
|
69
|
+
/**
|
|
70
|
+
* 打开模型选择器
|
|
71
|
+
* - 设置为选择模式
|
|
72
|
+
* - 加载可用模型列表
|
|
73
|
+
*/
|
|
74
|
+
const open = useCallback(() => {
|
|
75
|
+
setModelSelectMode(true);
|
|
76
|
+
loadModels();
|
|
77
|
+
}, [loadModels]);
|
|
78
|
+
/**
|
|
79
|
+
* 确认当前选择的模型
|
|
80
|
+
*
|
|
81
|
+
* 处理逻辑:
|
|
82
|
+
* 1. 获取选中的模型名称
|
|
83
|
+
* 2. 通过 configService 保存为默认模型
|
|
84
|
+
* 3. 触发 onModelSelected 回调
|
|
85
|
+
* 4. 退出选择模式并清空列表
|
|
86
|
+
*/
|
|
87
|
+
const confirm = useCallback(() => {
|
|
88
|
+
if (modelList[modelSelectedIndex]) {
|
|
89
|
+
const modelName = modelList[modelSelectedIndex].name;
|
|
90
|
+
// 保存为默认模型
|
|
91
|
+
configService.set('defaultModel', modelName);
|
|
92
|
+
// 触发回调
|
|
93
|
+
onModelSelected?.(modelName);
|
|
94
|
+
}
|
|
95
|
+
// 退出选择模式
|
|
96
|
+
setModelSelectMode(false);
|
|
97
|
+
setModelList([]);
|
|
98
|
+
}, [modelList, modelSelectedIndex, onModelSelected]);
|
|
99
|
+
/**
|
|
100
|
+
* 取消模型选择
|
|
101
|
+
* - 退出选择模式
|
|
102
|
+
* - 清空模型列表
|
|
103
|
+
*/
|
|
104
|
+
const cancel = useCallback(() => {
|
|
105
|
+
setModelSelectMode(false);
|
|
106
|
+
setModelList([]);
|
|
107
|
+
}, []);
|
|
108
|
+
/**
|
|
109
|
+
* 向上移动选择焦点
|
|
110
|
+
* - 最小值为 0
|
|
111
|
+
*/
|
|
112
|
+
const moveUp = useCallback(() => {
|
|
113
|
+
setModelSelectedIndex(prev => Math.max(0, prev - 1));
|
|
114
|
+
}, []);
|
|
115
|
+
/**
|
|
116
|
+
* 向下移动选择焦点
|
|
117
|
+
* - 最大值为模型列表长度 - 1
|
|
118
|
+
*/
|
|
119
|
+
const moveDown = useCallback(() => {
|
|
120
|
+
setModelSelectedIndex(prev => Math.min(modelList.length - 1, prev + 1));
|
|
121
|
+
}, [modelList]);
|
|
122
|
+
/**
|
|
123
|
+
* 返回 Hook 的结果
|
|
124
|
+
*/
|
|
125
|
+
return {
|
|
126
|
+
modelSelectMode, // 是否处于选择模式
|
|
127
|
+
modelList, // 模型列表
|
|
128
|
+
modelSelectedIndex, // 当前选中索引
|
|
129
|
+
loadModels, // 加载模型方法
|
|
130
|
+
open, // 打开选择器
|
|
131
|
+
confirm, // 确认选择
|
|
132
|
+
cancel, // 取消选择
|
|
133
|
+
moveUp, // 上移
|
|
134
|
+
moveDown, // 下移
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=useModelSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useModelSelect.js","sourceRoot":"","sources":["../../../src/components/hooks/useModelSelect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
interface Message {
|
|
2
|
+
id: string;
|
|
3
|
+
content: string;
|
|
4
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
5
|
+
timestamp: Date;
|
|
6
|
+
}
|
|
7
|
+
interface UseInputHandlerProps {
|
|
8
|
+
onSubmit: (input: string) => void;
|
|
9
|
+
onEscape: () => void;
|
|
10
|
+
onFileSelect: () => void;
|
|
11
|
+
onModelSelect: () => void;
|
|
12
|
+
fileSelectMode: boolean;
|
|
13
|
+
modelSelectMode: boolean;
|
|
14
|
+
onFileSelectConfirm: () => void;
|
|
15
|
+
onFileSelectCancel: () => void;
|
|
16
|
+
onModelSelectConfirm: () => void;
|
|
17
|
+
onModelSelectCancel: () => void;
|
|
18
|
+
onFileSelectUp: () => void;
|
|
19
|
+
onFileSelectDown: () => void;
|
|
20
|
+
onModelSelectUp: () => void;
|
|
21
|
+
onModelSelectDown: () => void;
|
|
22
|
+
onFileSelected?: (filePath: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function useInputHandler(messages: Message[], setMessages: React.Dispatch<React.SetStateAction<Message[]>>, contentHeight: number, props: UseInputHandlerProps): {
|
|
25
|
+
input: string;
|
|
26
|
+
cursorPosition: number;
|
|
27
|
+
scrollTop: number;
|
|
28
|
+
handleSubmit: () => void;
|
|
29
|
+
setInput: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
30
|
+
setCursorPosition: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=useInputHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputHandler.d.ts","sourceRoot":"","sources":["../../src/components/useInputHandler.ts"],"names":[],"mappings":"AAGA,UAAU,OAAO;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,SAAS,EAAE,IAAI,CAAC;CAChB;AAgBD,UAAU,oBAAoB;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,EAC5D,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,oBAAoB;;;;;;;EA6H3B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { useInput as useInkInput } from 'ink';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
function getLines(input) {
|
|
4
|
+
return input.split('\n');
|
|
5
|
+
}
|
|
6
|
+
function getLineStartPositions(input) {
|
|
7
|
+
const positions = [0];
|
|
8
|
+
for (let i = 0; i < input.length; i++) {
|
|
9
|
+
if (input[i] === '\n') {
|
|
10
|
+
positions.push(i + 1);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return positions;
|
|
14
|
+
}
|
|
15
|
+
export function useInputHandler(messages, setMessages, contentHeight, props) {
|
|
16
|
+
const { onSubmit, onEscape, onFileSelect, onModelSelect, fileSelectMode, modelSelectMode, onFileSelectConfirm, onFileSelectCancel, onModelSelectConfirm, onModelSelectCancel, onFileSelectUp, onFileSelectDown, onModelSelectUp, onModelSelectDown, onFileSelected } = props;
|
|
17
|
+
const [input, setInput] = useState('');
|
|
18
|
+
const [cursorPosition, setCursorPosition] = useState(0);
|
|
19
|
+
const [scrollTop, setScrollTop] = useState(0);
|
|
20
|
+
const handleSubmit = () => {
|
|
21
|
+
if (!input.trim())
|
|
22
|
+
return;
|
|
23
|
+
setMessages(prev => [...prev, {
|
|
24
|
+
id: `msg-${Date.now()}`,
|
|
25
|
+
content: input,
|
|
26
|
+
role: 'user',
|
|
27
|
+
timestamp: new Date(),
|
|
28
|
+
}]);
|
|
29
|
+
setInput('');
|
|
30
|
+
setCursorPosition(0);
|
|
31
|
+
setScrollTop(0);
|
|
32
|
+
onSubmit(input);
|
|
33
|
+
};
|
|
34
|
+
useInkInput((char, key) => {
|
|
35
|
+
if (fileSelectMode) {
|
|
36
|
+
if (key.upArrow) {
|
|
37
|
+
onFileSelectUp();
|
|
38
|
+
}
|
|
39
|
+
else if (key.downArrow) {
|
|
40
|
+
onFileSelectDown();
|
|
41
|
+
}
|
|
42
|
+
else if (key.return) {
|
|
43
|
+
onFileSelectConfirm();
|
|
44
|
+
}
|
|
45
|
+
else if (key.escape) {
|
|
46
|
+
onFileSelectCancel();
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (modelSelectMode) {
|
|
51
|
+
if (key.upArrow) {
|
|
52
|
+
onModelSelectUp();
|
|
53
|
+
}
|
|
54
|
+
else if (key.downArrow) {
|
|
55
|
+
onModelSelectDown();
|
|
56
|
+
}
|
|
57
|
+
else if (key.return) {
|
|
58
|
+
onModelSelectConfirm();
|
|
59
|
+
}
|
|
60
|
+
else if (key.escape) {
|
|
61
|
+
onModelSelectCancel();
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const lineStarts = getLineStartPositions(input);
|
|
66
|
+
const currentLineIndex = lineStarts.findIndex((pos, i) => pos <= cursorPosition && (i === lineStarts.length - 1 || lineStarts[i + 1] > cursorPosition));
|
|
67
|
+
const currentLineStart = lineStarts[currentLineIndex];
|
|
68
|
+
const currentLineLength = currentLineIndex < lineStarts.length - 1
|
|
69
|
+
? lineStarts[currentLineIndex + 1] - currentLineStart - 1
|
|
70
|
+
: input.length - currentLineStart;
|
|
71
|
+
const positionInLine = cursorPosition - currentLineStart;
|
|
72
|
+
if (key.upArrow) {
|
|
73
|
+
if (currentLineIndex > 0) {
|
|
74
|
+
const prevLineStart = lineStarts[currentLineIndex - 1];
|
|
75
|
+
const prevLineLength = currentLineIndex - 1 < lineStarts.length - 1
|
|
76
|
+
? lineStarts[currentLineIndex] - prevLineStart - 1
|
|
77
|
+
: input.length - prevLineStart;
|
|
78
|
+
const newPos = prevLineStart + Math.min(positionInLine, prevLineLength);
|
|
79
|
+
setCursorPosition(newPos);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (key.downArrow) {
|
|
83
|
+
if (currentLineIndex < lineStarts.length - 1) {
|
|
84
|
+
const nextLineStart = lineStarts[currentLineIndex + 1];
|
|
85
|
+
const nextLineLength = currentLineIndex + 1 < lineStarts.length - 1
|
|
86
|
+
? lineStarts[currentLineIndex + 2] - nextLineStart - 1
|
|
87
|
+
: input.length - nextLineStart;
|
|
88
|
+
const newPos = nextLineStart + Math.min(positionInLine, nextLineLength);
|
|
89
|
+
setCursorPosition(newPos);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (key.leftArrow) {
|
|
93
|
+
setCursorPosition(prev => Math.max(0, prev - 1));
|
|
94
|
+
}
|
|
95
|
+
if (key.rightArrow) {
|
|
96
|
+
setCursorPosition(prev => Math.min(input.length, prev + 1));
|
|
97
|
+
}
|
|
98
|
+
if (key.escape) {
|
|
99
|
+
onEscape();
|
|
100
|
+
}
|
|
101
|
+
if (key.return && !key.ctrl) {
|
|
102
|
+
handleSubmit();
|
|
103
|
+
}
|
|
104
|
+
if (key.return && key.ctrl) {
|
|
105
|
+
const newInput = input.slice(0, cursorPosition) + '\n' + input.slice(cursorPosition);
|
|
106
|
+
setInput(newInput);
|
|
107
|
+
setCursorPosition(prev => prev + 1);
|
|
108
|
+
}
|
|
109
|
+
if (key.backspace || key.delete) {
|
|
110
|
+
if (cursorPosition > 0) {
|
|
111
|
+
const newInput = input.slice(0, cursorPosition - 1) + input.slice(cursorPosition);
|
|
112
|
+
setInput(newInput);
|
|
113
|
+
setCursorPosition(prev => prev - 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (char && !key.ctrl && !key.meta) {
|
|
117
|
+
const newInput = input.slice(0, cursorPosition) + char + input.slice(cursorPosition);
|
|
118
|
+
setInput(newInput);
|
|
119
|
+
setCursorPosition(prev => prev + char.length);
|
|
120
|
+
if (char === '@') {
|
|
121
|
+
onFileSelect();
|
|
122
|
+
}
|
|
123
|
+
if (newInput === '/model') {
|
|
124
|
+
onModelSelect();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return { input, cursorPosition, scrollTop, handleSubmit, setInput, setCursorPosition };
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=useInputHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputHandler.js","sourceRoot":"","sources":["../../src/components/useInputHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alternate Buffer 模式 Hook
|
|
3
|
+
* 简化版本 - 禁用 Alternate Buffer
|
|
4
|
+
*/
|
|
5
|
+
export declare function isAlternateBufferEnabled(): boolean;
|
|
6
|
+
export declare function useAlternateBuffer(enabled?: boolean): boolean;
|
|
7
|
+
export declare function enterAlternateScreen(): void;
|
|
8
|
+
export declare function exitAlternateScreen(): void;
|
|
9
|
+
export declare function enableMouseEvents(): void;
|
|
10
|
+
export declare function disableMouseEvents(): void;
|
|
11
|
+
export declare function disableLineWrapping(): void;
|
|
12
|
+
export declare function enableLineWrapping(): void;
|
|
13
|
+
export declare function useRefreshStatic(): () => void;
|
|
14
|
+
//# sourceMappingURL=useAlternateBuffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAlternateBuffer.d.ts","sourceRoot":"","sources":["../../src/hooks/useAlternateBuffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,OAAc,GAAG,OAAO,CAEnE;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAAG;AAE/C,wBAAgB,mBAAmB,IAAI,IAAI,CAAG;AAE9C,wBAAgB,iBAAiB,IAAI,IAAI,CAAG;AAE5C,wBAAgB,kBAAkB,IAAI,IAAI,CAAG;AAE7C,wBAAgB,mBAAmB,IAAI,IAAI,CAAG;AAE9C,wBAAgB,kBAAkB,IAAI,IAAI,CAAG;AAE7C,wBAAgB,gBAAgB,eAE/B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alternate Buffer 模式 Hook
|
|
3
|
+
* 简化版本 - 禁用 Alternate Buffer
|
|
4
|
+
*/
|
|
5
|
+
export function isAlternateBufferEnabled() {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
export function useAlternateBuffer(enabled = true) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
export function enterAlternateScreen() { }
|
|
12
|
+
export function exitAlternateScreen() { }
|
|
13
|
+
export function enableMouseEvents() { }
|
|
14
|
+
export function disableMouseEvents() { }
|
|
15
|
+
export function disableLineWrapping() { }
|
|
16
|
+
export function enableLineWrapping() { }
|
|
17
|
+
export function useRefreshStatic() {
|
|
18
|
+
return () => { };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=useAlternateBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAlternateBuffer.js","sourceRoot":"","sources":["../../src/hooks/useAlternateBuffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,wBAAwB;IACtC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAmB,IAAI;IACxD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,KAAU,CAAC;AAE/C,MAAM,UAAU,mBAAmB,KAAU,CAAC;AAE9C,MAAM,UAAU,iBAAiB,KAAU,CAAC;AAE5C,MAAM,UAAU,kBAAkB,KAAU,CAAC;AAE7C,MAAM,UAAU,mBAAmB,KAAU,CAAC;AAE9C,MAAM,UAAU,kBAAkB,KAAU,CAAC;AAE7C,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAEhC,KAAK,UAAU,iBAAiB,CAAC,IAAY;YAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;gBAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;oBACvB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACpC,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAC5B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;oBACnD,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACpB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,aAAa,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,aAAa,aAAa,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN;;;;;;;;;;;;;;;;;;WAkBG;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACpD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC5D,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,6BAA6B;AAC7B,qBAAqB;AACrB,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|