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.
Files changed (86) hide show
  1. package/dist/api/filesystem.routes.js +13 -4
  2. package/dist/api/filesystem.routes.js.map +1 -1
  3. package/dist/components/App.backup.d.ts +34 -0
  4. package/dist/components/App.backup.d.ts.map +1 -0
  5. package/dist/components/App.backup.js +692 -0
  6. package/dist/components/App.backup.js.map +1 -0
  7. package/dist/components/App.d.ts +33 -24
  8. package/dist/components/App.d.ts.map +1 -1
  9. package/dist/components/App.js +182 -718
  10. package/dist/components/App.js.map +1 -1
  11. package/dist/components/FileSelector.d.ts +47 -0
  12. package/dist/components/FileSelector.d.ts.map +1 -0
  13. package/dist/components/FileSelector.js +40 -0
  14. package/dist/components/FileSelector.js.map +1 -0
  15. package/dist/components/Header.d.ts +3 -0
  16. package/dist/components/Header.d.ts.map +1 -0
  17. package/dist/components/Header.js +17 -0
  18. package/dist/components/Header.js.map +1 -0
  19. package/dist/components/InputArea.d.ts +50 -0
  20. package/dist/components/InputArea.d.ts.map +1 -0
  21. package/dist/components/InputArea.js +52 -0
  22. package/dist/components/InputArea.js.map +1 -0
  23. package/dist/components/MainContent.d.ts +11 -0
  24. package/dist/components/MainContent.d.ts.map +1 -0
  25. package/dist/components/MainContent.js +118 -0
  26. package/dist/components/MainContent.js.map +1 -0
  27. package/dist/components/MessageList.d.ts +11 -0
  28. package/dist/components/MessageList.d.ts.map +1 -0
  29. package/dist/components/MessageList.js +129 -0
  30. package/dist/components/MessageList.js.map +1 -0
  31. package/dist/components/ModelSelector.d.ts +42 -0
  32. package/dist/components/ModelSelector.d.ts.map +1 -0
  33. package/dist/components/ModelSelector.js +36 -0
  34. package/dist/components/ModelSelector.js.map +1 -0
  35. package/dist/components/StatusBar.d.ts +14 -0
  36. package/dist/components/StatusBar.d.ts.map +1 -0
  37. package/dist/components/StatusBar.js +21 -0
  38. package/dist/components/StatusBar.js.map +1 -0
  39. package/dist/components/hooks/useChat.d.ts +69 -0
  40. package/dist/components/hooks/useChat.d.ts.map +1 -0
  41. package/dist/components/hooks/useChat.js +270 -0
  42. package/dist/components/hooks/useChat.js.map +1 -0
  43. package/dist/components/hooks/useFileSelect.d.ts +58 -0
  44. package/dist/components/hooks/useFileSelect.d.ts.map +1 -0
  45. package/dist/components/hooks/useFileSelect.js +182 -0
  46. package/dist/components/hooks/useFileSelect.js.map +1 -0
  47. package/dist/components/hooks/useModelSelect.d.ts +54 -0
  48. package/dist/components/hooks/useModelSelect.d.ts.map +1 -0
  49. package/dist/components/hooks/useModelSelect.js +137 -0
  50. package/dist/components/hooks/useModelSelect.js.map +1 -0
  51. package/dist/components/useInputHandler.d.ts +33 -0
  52. package/dist/components/useInputHandler.d.ts.map +1 -0
  53. package/dist/components/useInputHandler.js +130 -0
  54. package/dist/components/useInputHandler.js.map +1 -0
  55. package/dist/hooks/useAlternateBuffer.d.ts +14 -0
  56. package/dist/hooks/useAlternateBuffer.d.ts.map +1 -0
  57. package/dist/hooks/useAlternateBuffer.js +20 -0
  58. package/dist/hooks/useAlternateBuffer.js.map +1 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +0 -1
  61. package/dist/index.js.map +1 -1
  62. package/package.json +7 -5
  63. package/scripts/ink-scroll-demo.tsx +147 -0
  64. package/web/dist/assets/{AiLogsView-D_SQ6qo4.js → AiLogsView-3J-YAusV.js} +1 -1
  65. package/web/dist/assets/{DevWorkflowView-C5VnPngb.css → DevWorkflowView-BRvigFN5.css} +1 -1
  66. package/web/dist/assets/{DevWorkflowView-iHAv9LC0.js → DevWorkflowView-DMCpylwg.js} +5 -5
  67. package/web/dist/assets/{Layout-CQhbIJxB.js → Layout-B905ASbH.js} +1 -1
  68. package/web/dist/assets/{TasksView-B9B2H3-S.js → TasksView-CCzwoCHn.js} +1 -1
  69. package/web/dist/assets/{TerminalView-BKhdi5UF.js → TerminalView-CxtZwfd-.js} +1 -1
  70. package/web/dist/assets/{cssMode-C_gwipb0.js → cssMode-tUnhOlEq.js} +1 -1
  71. package/web/dist/assets/{freemarker2-WCA_pR0J.js → freemarker2-BkGxlHtf.js} +1 -1
  72. package/web/dist/assets/{handlebars-fzVGzXHj.js → handlebars-BCSYP3By.js} +1 -1
  73. package/web/dist/assets/{html-C4Rga6DD.js → html-D_GMhfaP.js} +1 -1
  74. package/web/dist/assets/{htmlMode-BvrJ57rW.js → htmlMode-DDgBAK4r.js} +1 -1
  75. package/web/dist/assets/{index-9RP8PAfk.js → index-CUPB0bCv.js} +13 -13
  76. package/web/dist/assets/{javascript-cXKyuP98.js → javascript-CGc1uqdW.js} +1 -1
  77. package/web/dist/assets/{jsonMode-Q4CMzwiX.js → jsonMode-Ce0FYmxJ.js} +1 -1
  78. package/web/dist/assets/{liquid-CrbU0gmK.js → liquid-BwNgZkfv.js} +1 -1
  79. package/web/dist/assets/{mdx-D72Dcs66.js → mdx-CF1JkZ9f.js} +1 -1
  80. package/web/dist/assets/{python-DPqkZ_Xm.js → python-CXnk0DYj.js} +1 -1
  81. package/web/dist/assets/{razor-DknXaqXN.js → razor-CWGzlt3Z.js} +1 -1
  82. package/web/dist/assets/{tsMode-DZAV3Wgo.js → tsMode-CXhn7HXH.js} +1 -1
  83. package/web/dist/assets/{typescript-DenKTmW3.js → typescript-DF01mLhp.js} +1 -1
  84. package/web/dist/assets/{xml-C_uqJta0.js → xml-ZLfViiJc.js} +1 -1
  85. package/web/dist/assets/{yaml-vwb3U7d7.js → yaml-CV_nX5Yg.js} +1 -1
  86. package/web/dist/index.html +1 -1
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ModelSelector 组件 - 模型选择器 UI
3
+ *
4
+ * 职责:
5
+ * - 显示模型选择提示
6
+ * - 渲染可选择的模型列表
7
+ * - 高亮当前选中的模型
8
+ *
9
+ * UI 布局:
10
+ * - 第一行:选择提示 + 操作说明
11
+ * - 后续行:模型列表
12
+ * - 选中项:绿色粗体 + ▶ 标记
13
+ * - 未选中项:灰色 + 空格前缀
14
+ *
15
+ * 使用方式:
16
+ * <ModelSelector
17
+ * modelList={[]}
18
+ * modelSelectedIndex={0}
19
+ * />
20
+ */
21
+ import React from 'react';
22
+ import { ModelInfo } from './hooks/useModelSelect.js';
23
+ /**
24
+ * ModelSelector 组件属性
25
+ * @property modelList - 模型列表
26
+ * @property modelSelectedIndex - 当前选中的模型索引
27
+ */
28
+ interface ModelSelectorProps {
29
+ /** 模型列表 */
30
+ modelList: ModelInfo[];
31
+ /** 当前选中的模型索引 */
32
+ modelSelectedIndex: number;
33
+ }
34
+ /**
35
+ * 模型选择器组件
36
+ *
37
+ * @param props - 组件属性
38
+ * @returns 模型选择器 UI 元素
39
+ */
40
+ export declare function ModelSelector({ modelList, modelSelectedIndex }: ModelSelectorProps): React.JSX.Element;
41
+ export {};
42
+ //# sourceMappingURL=ModelSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD;;;;GAIG;AACH,UAAU,kBAAkB;IAC3B,WAAW;IACX,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,gBAAgB;IAChB,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,kBAAkB,qBAoBlF"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * ModelSelector 组件 - 模型选择器 UI
3
+ *
4
+ * 职责:
5
+ * - 显示模型选择提示
6
+ * - 渲染可选择的模型列表
7
+ * - 高亮当前选中的模型
8
+ *
9
+ * UI 布局:
10
+ * - 第一行:选择提示 + 操作说明
11
+ * - 后续行:模型列表
12
+ * - 选中项:绿色粗体 + ▶ 标记
13
+ * - 未选中项:灰色 + 空格前缀
14
+ *
15
+ * 使用方式:
16
+ * <ModelSelector
17
+ * modelList={[]}
18
+ * modelSelectedIndex={0}
19
+ * />
20
+ */
21
+ import React from 'react';
22
+ import { Box, Text } from 'ink';
23
+ /**
24
+ * 模型选择器组件
25
+ *
26
+ * @param props - 组件属性
27
+ * @returns 模型选择器 UI 元素
28
+ */
29
+ export function ModelSelector({ modelList, modelSelectedIndex }) {
30
+ return (React.createElement(Box, { flexDirection: "column", paddingX: 1 },
31
+ React.createElement(Text, { dimColor: true }, "\u9009\u62E9\u6A21\u578B (\u2191\u2193 \u9009\u62E9, Enter \u786E\u8BA4, ESC \u53D6\u6D88):"),
32
+ modelList.slice(0, 10).map((model, index) => (React.createElement(Text, { key: model.id }, index === modelSelectedIndex ? (React.createElement(Text, { bold: true, color: "green" }, `▶ ${model.name}`)) : (
33
+ /* 未选中项:灰色 + 空格前缀 */
34
+ React.createElement(Text, { dimColor: true }, ` ${model.name}`)))))));
35
+ }
36
+ //# sourceMappingURL=ModelSelector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelSelector.js","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAehC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAsB;IAClF,OAAO,CACN,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC;QAEtC,oBAAC,IAAI,IAAC,QAAQ,wGAAuC;QAGpD,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7C,oBAAC,IAAI,IAAC,GAAG,EAAE,KAAK,CAAC,EAAE,IAEjB,KAAK,KAAK,kBAAkB,CAAC,CAAC,CAAC,CAC/B,oBAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,OAAO,IAAE,KAAK,KAAK,CAAC,IAAI,EAAE,CAAQ,CACnD,CAAC,CAAC,CAAC;QACH,oBAAoB;QACpB,oBAAC,IAAI,IAAC,QAAQ,UAAE,KAAK,KAAK,CAAC,IAAI,EAAE,CAAQ,CACzC,CACK,CACP,CAAC,CACG,CACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface StatusBarProps {
3
+ status: 'idle' | 'thinking' | 'stopping';
4
+ currentModelName: string;
5
+ tokenStats: {
6
+ promptTokens: number;
7
+ completionTokens: number;
8
+ totalTokens: number;
9
+ };
10
+ sessionId?: string | null;
11
+ }
12
+ export declare function StatusBar({ status, currentModelName, tokenStats, sessionId }: StatusBarProps): React.JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=StatusBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,cAAc;IACvB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,cAAc,qBAwB5F"}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+ export function StatusBar({ status, currentModelName, tokenStats, sessionId }) {
4
+ const sessionText = sessionId ? `${sessionId.slice(0, 8)}` : '无会话';
5
+ // 根据状态显示不同的文本和颜色
6
+ const statusText = status === 'thinking'
7
+ ? '思考中... | 按 ESC 停止'
8
+ : status === 'stopping'
9
+ ? '等待停止...'
10
+ : '✓ 就绪';
11
+ // 思考中状态使用红色,其他状态使用灰色
12
+ const statusColor = status === 'thinking' ? 'red' : undefined;
13
+ return (React.createElement(Box, { paddingX: 2 },
14
+ React.createElement(Text, { dimColor: true },
15
+ React.createElement(Text, { color: statusColor }, statusText),
16
+ ` | 模型:${currentModelName}`,
17
+ ` | 会话:${sessionText}`,
18
+ ` | token:${tokenStats.totalTokens}`,
19
+ ` | 帮助 /help | 退出 ctrl+c`)));
20
+ }
21
+ //# sourceMappingURL=StatusBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAahC,MAAM,UAAU,SAAS,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAkB;IAC5F,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAEnE,iBAAiB;IACjB,MAAM,UAAU,GAAG,MAAM,KAAK,UAAU;QACvC,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,MAAM,KAAK,UAAU;YACtB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,MAAM,CAAC;IAEX,qBAAqB;IACrB,MAAM,WAAW,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9D,OAAO,CACN,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC;QACf,oBAAC,IAAI,IAAC,QAAQ;YACb,oBAAC,IAAI,IAAC,KAAK,EAAE,WAAW,IAAG,UAAU,CAAQ;YAC5C,SAAS,gBAAgB,EAAE;YAC3B,SAAS,WAAW,EAAE;YACtB,YAAY,UAAU,CAAC,WAAW,EAAE;YACpC,yBAAyB,CACpB,CACF,CACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * useChat Hook - 聊天功能逻辑管理
3
+ *
4
+ * 职责:
5
+ * - 管理消息列表状态 (messages)
6
+ * - 管理聊天状态 (idle/thinking/stopping)
7
+ * - 管理 token 统计信息
8
+ * - 处理用户输入提交 (handleSubmit)
9
+ * - 处理聊天中断 (stop)
10
+ *
11
+ * 使用方式:
12
+ * const chat = useChat({ sessionId, onSessionChange });
13
+ */
14
+ /**
15
+ * 消息类型定义
16
+ * @property id - 消息唯一标识
17
+ * @property content - 消息内容
18
+ * @property role - 消息角色:user(用户)、assistant(AI)、system(系统)、tool(工具)
19
+ * @property timestamp - 消息时间戳
20
+ */
21
+ export interface Message {
22
+ id: string;
23
+ content: string;
24
+ role: 'user' | 'assistant' | 'system' | 'tool';
25
+ timestamp: Date;
26
+ }
27
+ /**
28
+ * Token 统计信息
29
+ * @property promptTokens - 提示词消耗的 token 数量
30
+ * @property completionTokens - 回复消耗的 token 数量
31
+ * @property totalTokens - 总共消耗的 token 数量
32
+ */
33
+ export interface TokenStats {
34
+ promptTokens: number;
35
+ completionTokens: number;
36
+ totalTokens: number;
37
+ }
38
+ /**
39
+ * 聊天状态类型
40
+ * - idle: 空闲状态,可以接收输入
41
+ * - thinking: AI 正在思考/处理中
42
+ * - stopping: 正在停止 AI 操作
43
+ */
44
+ export type Status = 'idle' | 'thinking' | 'stopping';
45
+ /**
46
+ * useChat Hook 配置选项
47
+ * @property sessionId - 当前会话 ID
48
+ * @property onSessionChange - 会话变化回调
49
+ */
50
+ interface UseChatOptions {
51
+ sessionId: string | null;
52
+ onSessionChange?: (sessionId: string) => void;
53
+ }
54
+ /**
55
+ * 聊天功能 Hook
56
+ * @param options - 配置选项
57
+ * @returns 聊天相关的状态和方法
58
+ */
59
+ export declare function useChat(options: UseChatOptions): {
60
+ messages: Message[];
61
+ setMessages: import("react").Dispatch<import("react").SetStateAction<Message[]>>;
62
+ status: Status;
63
+ tokenStats: TokenStats;
64
+ addMessage: (role: Message["role"], content: string) => void;
65
+ handleSubmit: (inputText: string) => Promise<void>;
66
+ stop: () => void;
67
+ };
68
+ export {};
69
+ //# sourceMappingURL=useChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useChat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACvB,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;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAEtD;;;;GAIG;AACH,UAAU,cAAc;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc;;;;;uBAuBR,OAAO,CAAC,MAAM,CAAC,WAAW,MAAM;8BA0DnB,MAAM;;EAiLzD"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * useChat Hook - 聊天功能逻辑管理
3
+ *
4
+ * 职责:
5
+ * - 管理消息列表状态 (messages)
6
+ * - 管理聊天状态 (idle/thinking/stopping)
7
+ * - 管理 token 统计信息
8
+ * - 处理用户输入提交 (handleSubmit)
9
+ * - 处理聊天中断 (stop)
10
+ *
11
+ * 使用方式:
12
+ * const chat = useChat({ sessionId, onSessionChange });
13
+ */
14
+ import { useState, useCallback, useRef } from 'react';
15
+ import { v4 as uuidv4 } from 'uuid';
16
+ import { codeChatService } from '../../services/codeChat/index.js';
17
+ import { commandChatService } from '../../services/commandChat/index.js';
18
+ /**
19
+ * 聊天功能 Hook
20
+ * @param options - 配置选项
21
+ * @returns 聊天相关的状态和方法
22
+ */
23
+ export function useChat(options) {
24
+ const { sessionId, onSessionChange } = options;
25
+ /** 消息列表状态 */
26
+ const [messages, setMessages] = useState([]);
27
+ /** 当前聊天状态 */
28
+ const [status, setStatus] = useState('idle');
29
+ /** Token 消耗统计 */
30
+ const [tokenStats, setTokenStats] = useState({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });
31
+ /** AbortController 引用,用于中断 AI 请求 */
32
+ const abortControllerRef = useRef(null);
33
+ /**
34
+ * 添加消息到列表
35
+ * - 自动过滤连续重复的消息
36
+ * - 限制最多保存 500 条消息,超出时移除最早的
37
+ *
38
+ * @param role - 消息角色
39
+ * @param content - 消息内容
40
+ */
41
+ const addMessage = useCallback((role, content) => {
42
+ setMessages(prev => {
43
+ const lastMsg = prev[prev.length - 1];
44
+ // 过滤连续重复消息
45
+ if (lastMsg && lastMsg.role === role && lastMsg.content === content) {
46
+ return prev;
47
+ }
48
+ const msg = {
49
+ id: uuidv4(),
50
+ role,
51
+ content,
52
+ timestamp: new Date(),
53
+ };
54
+ const maxMessages = 500;
55
+ const newMessages = [...prev, msg];
56
+ // 超过最大消息数时,移除最早的
57
+ if (newMessages.length > maxMessages) {
58
+ return newMessages.slice(-maxMessages);
59
+ }
60
+ return newMessages;
61
+ });
62
+ }, []);
63
+ /**
64
+ * 停止当前 AI 操作
65
+ * - 将状态设置为 stopping
66
+ * - 调用 abortController 中断请求
67
+ */
68
+ const stop = useCallback(() => {
69
+ if (status === 'thinking' && abortControllerRef.current) {
70
+ setStatus('stopping');
71
+ abortControllerRef.current.abort();
72
+ }
73
+ }, [status]);
74
+ /**
75
+ * 处理用户提交的内容
76
+ *
77
+ * 处理流程:
78
+ * 1. 判断是否以 / 开头,如果是则作为命令处理
79
+ * 2. 否则作为普通聊天消息处理
80
+ * 3. 调用 codeChatService 或 commandChatService
81
+ * 4. 通过回调函数处理 AI 响应的每个步骤
82
+ *
83
+ * 命令模式:
84
+ * - 以 / 开头的输入会被识别为命令
85
+ * - 通过 commandChatService 处理
86
+ * - 支持切换会话等操作
87
+ *
88
+ * 聊天模式:
89
+ * - 普通聊天输入
90
+ * - 通过 codeChatService 处理
91
+ * - 支持流式响应和工具调用
92
+ * - onStep 回调:处理 AI 的每个思考步骤和工具调用
93
+ * - onCompact 回调:处理上下文压缩完成事件
94
+ *
95
+ * @param inputText - 用户输入的文本
96
+ */
97
+ const handleSubmit = useCallback(async (inputText) => {
98
+ const trimmedInput = inputText.trim();
99
+ // 空输入或正在思考时忽略
100
+ if (!trimmedInput || status === 'thinking') {
101
+ return;
102
+ }
103
+ // 命令模式:以 / 开头
104
+ if (trimmedInput.startsWith('/')) {
105
+ setStatus('thinking');
106
+ try {
107
+ const result = await commandChatService.handleCommand({
108
+ message: trimmedInput,
109
+ sessionId: sessionId || undefined,
110
+ });
111
+ if (result.answer) {
112
+ addMessage('system', result.answer);
113
+ }
114
+ if (result.sessionId && result.success) {
115
+ onSessionChange?.(result.sessionId);
116
+ }
117
+ }
118
+ catch (err) {
119
+ addMessage('system', `命令执行异常: ${err instanceof Error ? err.message : String(err)}`);
120
+ }
121
+ finally {
122
+ setStatus('idle');
123
+ }
124
+ return;
125
+ }
126
+ // 将用户消息添加到列表
127
+ addMessage('user', trimmedInput);
128
+ // 设置状态为思考中
129
+ setStatus('thinking');
130
+ // 创建 AbortController 用于中断请求
131
+ abortControllerRef.current = new AbortController();
132
+ try {
133
+ const result = await codeChatService.handleChat({
134
+ message: trimmedInput,
135
+ sessionId: sessionId || undefined,
136
+ abortSignal: abortControllerRef.current.signal,
137
+ /**
138
+ * AI 步骤回调 - 处理每个思考步骤
139
+ * @param step - AI 执行步骤信息
140
+ * @param iteration - 当前迭代次数
141
+ * @param usage - token 使用情况
142
+ */
143
+ onStep: (step, iteration, usage) => {
144
+ // 更新 prompt tokens 和 totalTokens
145
+ if (usage?.promptTokens) {
146
+ setTokenStats(prev => ({
147
+ ...prev,
148
+ promptTokens: usage.promptTokens,
149
+ totalTokens: usage.totalTokens
150
+ }));
151
+ }
152
+ // 显示 AI 的思考过程
153
+ if (step.thought) {
154
+ addMessage('system', `💭 ${step.thought}`);
155
+ }
156
+ // 工具名称映射表
157
+ const actionNames = {
158
+ 'read_file': '读取文件',
159
+ 'write_file': '创建文件',
160
+ 'edit_file': '编辑文件',
161
+ 'execute_bash': '执行命令',
162
+ 'bash': '执行命令',
163
+ 'find_files': '搜索文件',
164
+ 'grep': '搜索内容',
165
+ 'glob': '文件匹配',
166
+ };
167
+ // 处理工具调用
168
+ const toolCalls = step.toolCalls || [];
169
+ for (const tc of toolCalls) {
170
+ const name = tc.function.name;
171
+ const actionName = actionNames[name] || name;
172
+ let stepInfo = `🔧 ${actionName}`;
173
+ // 解析工具参数并生成描述
174
+ if (tc.function.arguments) {
175
+ try {
176
+ const inputObj = typeof tc.function.arguments === 'string'
177
+ ? JSON.parse(tc.function.arguments)
178
+ : tc.function.arguments;
179
+ // 根据不同工具生成对应的描述信息
180
+ if (name === 'read_file') {
181
+ const offset = inputObj.offset ?? 1;
182
+ const limit = inputObj.limit ?? 300;
183
+ stepInfo += `: ${inputObj.file_path} offset:${offset} limit:${limit}`;
184
+ }
185
+ else if (name === 'edit_file') {
186
+ stepInfo += `: ${inputObj.file_path}`;
187
+ }
188
+ else if (name === 'write_file') {
189
+ stepInfo += `: ${inputObj.file_path}`;
190
+ }
191
+ else if (name === 'execute_bash' || name === 'bash') {
192
+ stepInfo += `: ${inputObj.command?.slice(0, 50)}`;
193
+ }
194
+ else if (name === 'find_files' || name === 'glob') {
195
+ stepInfo += `: ${inputObj.pattern}`;
196
+ }
197
+ else if (name === 'grep') {
198
+ stepInfo += `: ${inputObj.pattern}`;
199
+ }
200
+ else {
201
+ const keys = Object.keys(inputObj).slice(0, 2);
202
+ stepInfo += ': ' + keys.map(k => `${k}: ${String(inputObj[k]).slice(0, 30)}`).join(' ');
203
+ }
204
+ }
205
+ catch { }
206
+ }
207
+ // 显示工具执行结果
208
+ if (step.success === false) {
209
+ addMessage('system', `${stepInfo} ❌`);
210
+ }
211
+ else {
212
+ addMessage('system', `${stepInfo} ✓`);
213
+ }
214
+ }
215
+ },
216
+ /**
217
+ * 上下文压缩完成回调
218
+ * @param info - 压缩信息,包含压缩前后的 token 数量和摘要
219
+ */
220
+ onCompact: (info) => {
221
+ addMessage('system', `【压缩完成】${info.summary || ''}`);
222
+ },
223
+ });
224
+ // 添加 AI 回复
225
+ if (result.answer) {
226
+ addMessage('assistant', result.answer);
227
+ }
228
+ // 更新 token 统计
229
+ if (result.usage) {
230
+ setTokenStats({
231
+ promptTokens: result.usage.promptTokens || 0,
232
+ completionTokens: result.usage.completionTokens || 0,
233
+ totalTokens: result.usage.totalTokens || 0,
234
+ });
235
+ }
236
+ // 更新会话 ID
237
+ if (result.sessionId) {
238
+ onSessionChange?.(result.sessionId);
239
+ }
240
+ }
241
+ catch (err) {
242
+ const errorMsg = err instanceof Error ? err.message : 'Unknown error';
243
+ if (errorMsg === 'ABORTED') {
244
+ addMessage('system', '已停止');
245
+ }
246
+ else {
247
+ addMessage('system', `错误: ${errorMsg}`);
248
+ }
249
+ }
250
+ finally {
251
+ // 清理状态
252
+ abortControllerRef.current = null;
253
+ setStatus('idle');
254
+ }
255
+ }, [status, sessionId, addMessage, onSessionChange]);
256
+ /**
257
+ * 返回 Hook 的结果
258
+ * 包含所有状态和操作方法
259
+ */
260
+ return {
261
+ messages, // 消息列表
262
+ setMessages, // 设置消息列表(用于外部初始化)
263
+ status, // 当前状态
264
+ tokenStats, // Token 统计
265
+ addMessage, // 添加消息方法
266
+ handleSubmit, // 提交输入方法
267
+ stop, // 停止方法
268
+ };
269
+ }
270
+ //# sourceMappingURL=useChat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChat.js","sourceRoot":"","sources":["../../../src/components/hooks/useChat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
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
+ /**
22
+ * 文件信息类型定义
23
+ * @property name - 文件/目录名称
24
+ * @property path - 完整路径
25
+ * @property isDirectory - 是否为目录
26
+ */
27
+ export interface FileInfo {
28
+ name: string;
29
+ path: string;
30
+ isDirectory?: boolean;
31
+ }
32
+ /**
33
+ * useFileSelect Hook 配置选项
34
+ * @property onFileSelected - 文件选择完成后的回调,参数为相对路径
35
+ */
36
+ interface UseFileSelectOptions {
37
+ onFileSelected?: (relativePath: string) => void;
38
+ }
39
+ /**
40
+ * 文件选择功能 Hook
41
+ * @param options - 配置选项
42
+ * @returns 文件选择相关的状态和方法
43
+ */
44
+ export declare function useFileSelect(options?: UseFileSelectOptions): {
45
+ fileSelectMode: boolean;
46
+ currentDir: string;
47
+ baseDir: string;
48
+ fileList: FileInfo[];
49
+ selectedIndex: number;
50
+ loadDirectory: (dir: string, resetBaseDir?: boolean) => void;
51
+ open: () => void;
52
+ confirm: () => void;
53
+ cancel: () => void;
54
+ moveUp: () => void;
55
+ moveDown: () => void;
56
+ };
57
+ export {};
58
+ //# sourceMappingURL=useFileSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFileSelect.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useFileSelect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,UAAU,oBAAoB;IAC7B,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB;;;;;;yBA+BvB,MAAM,iBAAgB,OAAO;;;;;;EAuIrE"}