@lcap/wave-sandbox-sdk 0.0.1
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/README.md +1154 -0
- package/dist/client.d.ts +64 -0
- package/dist/client.js +126 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/modules/agent.d.ts +448 -0
- package/dist/modules/agent.js +251 -0
- package/dist/modules/exec.d.ts +27 -0
- package/dist/modules/exec.js +35 -0
- package/dist/modules/file-system.d.ts +64 -0
- package/dist/modules/file-system.js +172 -0
- package/dist/modules/port.d.ts +30 -0
- package/dist/modules/port.js +41 -0
- package/dist/modules/project.d.ts +37 -0
- package/dist/modules/project.js +64 -0
- package/dist/types/agent-types.d.ts +127 -0
- package/dist/types/agent-types.js +5 -0
- package/dist/types/index.d.ts +105 -0
- package/dist/types/index.js +10 -0
- package/dist/utils/socket.d.ts +10 -0
- package/dist/utils/socket.js +27 -0
- package/package.json +34 -0
- package/src/client.ts +152 -0
- package/src/index.ts +60 -0
- package/src/modules/agent.ts +624 -0
- package/src/modules/exec.ts +49 -0
- package/src/modules/file-system.ts +212 -0
- package/src/modules/port.ts +47 -0
- package/src/modules/project.ts +77 -0
- package/src/types/agent-types.ts +140 -0
- package/src/types/index.ts +136 -0
- package/src/utils/socket.ts +34 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agent 模块
|
|
4
|
+
*/
|
|
5
|
+
export class AgentModule {
|
|
6
|
+
constructor(socket, baseUrl, projectId) {
|
|
7
|
+
this.socket = socket;
|
|
8
|
+
this.baseUrl = baseUrl;
|
|
9
|
+
this.projectId = projectId;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 获取查询参数
|
|
13
|
+
*/
|
|
14
|
+
getQueryParams() {
|
|
15
|
+
if (this.projectId) {
|
|
16
|
+
return `projectId=${encodeURIComponent(this.projectId)}`;
|
|
17
|
+
}
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 发送消息
|
|
22
|
+
* @param options 发送消息选项
|
|
23
|
+
* @returns Promise<string> 返回 assistantMessageId
|
|
24
|
+
*/
|
|
25
|
+
async sendMessage(options) {
|
|
26
|
+
const result = await createSocketHandler(this.socket, 'agent:sendMessage', () => options);
|
|
27
|
+
return result.assistantMessageId;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 中止消息
|
|
31
|
+
* @param messageId 消息 ID
|
|
32
|
+
*/
|
|
33
|
+
async abortMessage(messageId) {
|
|
34
|
+
return createSocketHandler(this.socket, 'agent:abortMessage', () => ({
|
|
35
|
+
messageId,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 删除 session,包括日志记录和 agent 对象
|
|
40
|
+
* @param sessionId 会话 ID
|
|
41
|
+
* @throws 如果当前正在处理该 session 的消息,则抛出错误
|
|
42
|
+
*/
|
|
43
|
+
async removeSession(sessionId) {
|
|
44
|
+
return createSocketHandler(this.socket, 'agent:removeSession', () => ({
|
|
45
|
+
sessionId,
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 获取指定 session 的消息日志文件列表
|
|
50
|
+
* @param sessionId 会话 ID
|
|
51
|
+
* @returns Promise<string[] | null> 返回文件列表(倒序,最新的在前),如果没有文件则返回 null
|
|
52
|
+
*/
|
|
53
|
+
async getSessionFiles(sessionId) {
|
|
54
|
+
const result = await createSocketHandler(this.socket, 'agent:getSessionFiles', () => ({ sessionId }));
|
|
55
|
+
return result ? result.files : null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 获取当前 wave-agent 的完整状态
|
|
59
|
+
* @returns Promise<MessageQueueChangedEvent | null> 返回当前状态,如果没有活动状态则返回 null
|
|
60
|
+
*/
|
|
61
|
+
async getCurrentState() {
|
|
62
|
+
const queryParams = this.getQueryParams();
|
|
63
|
+
const url = `${this.baseUrl}/api/agent/currentState${queryParams ? `?${queryParams}` : ''}`;
|
|
64
|
+
const response = await fetch(url);
|
|
65
|
+
const result = await response.json();
|
|
66
|
+
if (result.status === 'error') {
|
|
67
|
+
throw new Error(result.message);
|
|
68
|
+
}
|
|
69
|
+
return result.data;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 监听消息发送事件
|
|
73
|
+
* @param callback 回调函数
|
|
74
|
+
* @returns 取消监听的函数
|
|
75
|
+
*/
|
|
76
|
+
onMessageSend(callback) {
|
|
77
|
+
return onSocketEvent(this.socket, 'agent:message-send', callback);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 监听消息运行事件
|
|
81
|
+
* @param callback 回调函数
|
|
82
|
+
* @returns 取消监听的函数
|
|
83
|
+
*/
|
|
84
|
+
onMessageRunning(callback) {
|
|
85
|
+
return onSocketEvent(this.socket, 'agent:message-running', callback);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 监听消息完成事件
|
|
89
|
+
* @param callback 回调函数
|
|
90
|
+
* @returns 取消监听的函数
|
|
91
|
+
*/
|
|
92
|
+
onMessageFinished(callback) {
|
|
93
|
+
return onSocketEvent(this.socket, 'agent:message-finished', callback);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 监听消息队列变化事件
|
|
97
|
+
* @param callback 回调函数
|
|
98
|
+
* @returns 取消监听的函数
|
|
99
|
+
*/
|
|
100
|
+
onMessageQueueChanged(callback) {
|
|
101
|
+
return onSocketEvent(this.socket, 'agent:message-queue-changed', callback);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 监听初始化事件
|
|
105
|
+
* @param callback 回调函数
|
|
106
|
+
* @returns 取消监听的函数
|
|
107
|
+
*/
|
|
108
|
+
onInitializing(callback) {
|
|
109
|
+
return onSocketEvent(this.socket, 'agent:initializing', callback);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 监听初始化完成事件
|
|
113
|
+
* @param callback 回调函数
|
|
114
|
+
* @returns 取消监听的函数
|
|
115
|
+
*/
|
|
116
|
+
onInitialized(callback) {
|
|
117
|
+
return onSocketEvent(this.socket, 'agent:initialized', callback);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 监听消息块添加事件
|
|
121
|
+
* @param callback 回调函数
|
|
122
|
+
* @returns 取消监听的函数
|
|
123
|
+
*/
|
|
124
|
+
onMessageBlockAdded(callback) {
|
|
125
|
+
return onSocketEvent(this.socket, 'agent:message-block-added', callback);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 监听消息块更新事件(用于流式内容更新)
|
|
129
|
+
* @param callback 回调函数
|
|
130
|
+
* @returns 取消监听的函数
|
|
131
|
+
*/
|
|
132
|
+
onMessageBlockUpdated(callback) {
|
|
133
|
+
return onSocketEvent(this.socket, 'agent:message-block-updated', callback);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 监听工具块更新事件
|
|
137
|
+
* @param callback 回调函数
|
|
138
|
+
* @returns 取消监听的函数
|
|
139
|
+
*/
|
|
140
|
+
onMessageToolBlockUpdated(callback) {
|
|
141
|
+
return onSocketEvent(this.socket, 'agent:message-tool-block-updated', callback);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 监听子代理块添加事件
|
|
145
|
+
* @param callback 回调函数
|
|
146
|
+
* @returns 取消监听的函数
|
|
147
|
+
*/
|
|
148
|
+
onMessageSubagentBlockAdd(callback) {
|
|
149
|
+
return onSocketEvent(this.socket, 'agent:message-subagent-block-add', callback);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 监听子代理块状态更新事件
|
|
153
|
+
* @param callback 回调函数
|
|
154
|
+
* @returns 取消监听的函数
|
|
155
|
+
*/
|
|
156
|
+
onMessageSubagentBlockStatusUpdated(callback) {
|
|
157
|
+
return onSocketEvent(this.socket, 'agent:message-subagent-block-status-updated', callback);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 监听子代理块内容更新事件
|
|
161
|
+
* @param callback 回调函数
|
|
162
|
+
* @returns 取消监听的函数
|
|
163
|
+
*/
|
|
164
|
+
onMessageSubagentBlockContentUpdated(callback) {
|
|
165
|
+
return onSocketEvent(this.socket, 'agent:message-subagent-block-content-updated', callback);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 监听子代理工具块更新事件
|
|
169
|
+
* @param callback 回调函数
|
|
170
|
+
* @returns 取消监听的函数
|
|
171
|
+
*/
|
|
172
|
+
onMessageSubagentToolBlockUpdated(callback) {
|
|
173
|
+
return onSocketEvent(this.socket, 'agent:message-subagent-tool-block-updated', callback);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 监听错误块添加事件
|
|
177
|
+
* @param callback 回调函数
|
|
178
|
+
* @returns 取消监听的函数
|
|
179
|
+
*/
|
|
180
|
+
onMessageErrorBlockAdded(callback) {
|
|
181
|
+
return onSocketEvent(this.socket, 'agent:message-error-block-added', callback);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 监听命令输出消息添加事件
|
|
185
|
+
* @param callback 回调函数
|
|
186
|
+
* @returns 取消监听的函数
|
|
187
|
+
*/
|
|
188
|
+
onMessageCommandOutputMessageAdded(callback) {
|
|
189
|
+
return onSocketEvent(this.socket, 'agent:message-command-output-message-added', callback);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 监听命令输出消息更新事件
|
|
193
|
+
* @param callback 回调函数
|
|
194
|
+
* @returns 取消监听的函数
|
|
195
|
+
*/
|
|
196
|
+
onMessageCommandOutputMessageUpdated(callback) {
|
|
197
|
+
return onSocketEvent(this.socket, 'agent:message-command-output-message-updated', callback);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 监听命令输出消息完成事件
|
|
201
|
+
* @param callback 回调函数
|
|
202
|
+
* @returns 取消监听的函数
|
|
203
|
+
*/
|
|
204
|
+
onMessageCommandOutputMessageCompleted(callback) {
|
|
205
|
+
return onSocketEvent(this.socket, 'agent:message-command-output-message-completed', callback);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* 监听 MCP 服务器变化事件
|
|
209
|
+
* @param callback 回调函数
|
|
210
|
+
* @returns 取消监听的函数
|
|
211
|
+
*/
|
|
212
|
+
onMcpServersChange(callback) {
|
|
213
|
+
return onSocketEvent(this.socket, 'agent:mcp-servers-change', callback);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 监听文档解析开始事件
|
|
217
|
+
* @param callback 回调函数
|
|
218
|
+
* @returns 取消监听的函数
|
|
219
|
+
*/
|
|
220
|
+
onDocumentParseStart(callback) {
|
|
221
|
+
return onSocketEvent(this.socket, 'agent:document-parse-start', callback);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 监听文档解析完成事件
|
|
225
|
+
* @param callback 回调函数
|
|
226
|
+
* @returns 取消监听的函数
|
|
227
|
+
*/
|
|
228
|
+
onDocumentParseComplete(callback) {
|
|
229
|
+
return onSocketEvent(this.socket, 'agent:document-parse-complete', callback);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 监听文档解析错误事件
|
|
233
|
+
* @param callback 回调函数
|
|
234
|
+
* @returns 取消监听的函数
|
|
235
|
+
*/
|
|
236
|
+
onDocumentParseError(callback) {
|
|
237
|
+
return onSocketEvent(this.socket, 'agent:document-parse-error', callback);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 通用事件监听方法,用于监听自定义事件
|
|
241
|
+
* @param eventName 事件名称(必须以 'agent:' 开头)
|
|
242
|
+
* @param callback 回调函数
|
|
243
|
+
* @returns 取消监听的函数
|
|
244
|
+
*/
|
|
245
|
+
on(eventName, callback) {
|
|
246
|
+
if (!eventName.startsWith('agent:')) {
|
|
247
|
+
throw new Error(`事件名称必须以 'agent:' 开头,当前事件名称: ${eventName}`);
|
|
248
|
+
}
|
|
249
|
+
return onSocketEvent(this.socket, eventName, callback);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Socket } from 'socket.io-client';
|
|
2
|
+
/**
|
|
3
|
+
* 命令执行模块
|
|
4
|
+
*/
|
|
5
|
+
export declare class ExecModule {
|
|
6
|
+
private socket;
|
|
7
|
+
constructor(socket: Socket);
|
|
8
|
+
/**
|
|
9
|
+
* 执行命令
|
|
10
|
+
* @param sessionId 会话 ID
|
|
11
|
+
* @param command 要执行的命令
|
|
12
|
+
* @returns Promise<number> 命令退出码
|
|
13
|
+
*/
|
|
14
|
+
exec(sessionId: string, command: string): Promise<number>;
|
|
15
|
+
/**
|
|
16
|
+
* 中止命令执行
|
|
17
|
+
* @param sessionId 会话 ID
|
|
18
|
+
*/
|
|
19
|
+
abort(sessionId: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* 监听命令输出
|
|
22
|
+
* @param sessionId 会话 ID
|
|
23
|
+
* @param callback 输出回调函数,接收 Uint8Array 数据(浏览器环境)
|
|
24
|
+
* @returns 取消监听的函数
|
|
25
|
+
*/
|
|
26
|
+
onOutput(sessionId: string, callback: (data: Uint8Array) => void): () => void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
/**
|
|
3
|
+
* 命令执行模块
|
|
4
|
+
*/
|
|
5
|
+
export class ExecModule {
|
|
6
|
+
constructor(socket) {
|
|
7
|
+
this.socket = socket;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 执行命令
|
|
11
|
+
* @param sessionId 会话 ID
|
|
12
|
+
* @param command 要执行的命令
|
|
13
|
+
* @returns Promise<number> 命令退出码
|
|
14
|
+
*/
|
|
15
|
+
async exec(sessionId, command) {
|
|
16
|
+
return createSocketHandler(this.socket, 'cmd:exec', () => ({ sessionId, command }));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 中止命令执行
|
|
20
|
+
* @param sessionId 会话 ID
|
|
21
|
+
*/
|
|
22
|
+
async abort(sessionId) {
|
|
23
|
+
return createSocketHandler(this.socket, 'cmd:abort', () => ({ sessionId }));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 监听命令输出
|
|
27
|
+
* @param sessionId 会话 ID
|
|
28
|
+
* @param callback 输出回调函数,接收 Uint8Array 数据(浏览器环境)
|
|
29
|
+
* @returns 取消监听的函数
|
|
30
|
+
*/
|
|
31
|
+
onOutput(sessionId, callback) {
|
|
32
|
+
const eventName = `cmd:exec-output-${sessionId}`;
|
|
33
|
+
return onSocketEvent(this.socket, eventName, callback);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Socket } from 'socket.io-client';
|
|
2
|
+
import type { FileStat, DirectoryItem, FileChangeEvent } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* 文件系统模块
|
|
5
|
+
*/
|
|
6
|
+
export declare class FileSystemModule {
|
|
7
|
+
private socket;
|
|
8
|
+
private baseUrl;
|
|
9
|
+
private projectId?;
|
|
10
|
+
constructor(socket: Socket, baseUrl: string, projectId?: string | undefined);
|
|
11
|
+
/**
|
|
12
|
+
* 获取查询参数
|
|
13
|
+
*/
|
|
14
|
+
private getQueryParams;
|
|
15
|
+
/**
|
|
16
|
+
* 获取文件状态
|
|
17
|
+
*/
|
|
18
|
+
stat(filePath: string): Promise<FileStat>;
|
|
19
|
+
/**
|
|
20
|
+
* 读取文件
|
|
21
|
+
* @param filePath 文件路径
|
|
22
|
+
* @param asText 是否以文本形式读取,默认 false(返回 Blob)
|
|
23
|
+
* @returns Promise<string | Blob> 文件内容
|
|
24
|
+
*/
|
|
25
|
+
read(filePath: string, asText: false): Promise<Blob>;
|
|
26
|
+
read(filePath: string, asText: true): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* 读取文件内容(文本形式)
|
|
29
|
+
* @param filePath 文件路径
|
|
30
|
+
* @returns Promise<string> 文件文本内容
|
|
31
|
+
*/
|
|
32
|
+
readFile(filePath: string): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* 读取目录
|
|
35
|
+
*/
|
|
36
|
+
readdir(filePath: string): Promise<DirectoryItem[]>;
|
|
37
|
+
/**
|
|
38
|
+
* 写入文件(流式)
|
|
39
|
+
* @param filePath 文件路径
|
|
40
|
+
* @param data 文件数据(可以是字符串、Blob、ArrayBuffer 或 Buffer)
|
|
41
|
+
* @param chunkSize 分块大小(字节),默认 64KB
|
|
42
|
+
*/
|
|
43
|
+
writeFile(filePath: string, data: string | Blob | ArrayBuffer | Uint8Array, chunkSize?: number): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 创建目录
|
|
46
|
+
*/
|
|
47
|
+
mkdir(filePath: string): Promise<string | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* 重命名文件或目录
|
|
50
|
+
*/
|
|
51
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* 删除文件或目录
|
|
54
|
+
*/
|
|
55
|
+
rm(filePath: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* 监听文件变化
|
|
58
|
+
* @param paths 要监听的文件路径数组
|
|
59
|
+
* @param ignored 要忽略的文件路径数组
|
|
60
|
+
* @param callback 文件变化回调函数
|
|
61
|
+
* @returns 取消监听的函数
|
|
62
|
+
*/
|
|
63
|
+
watch(paths: string[], ignored: string[] | undefined, callback: (event: FileChangeEvent) => void): () => void;
|
|
64
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
/**
|
|
3
|
+
* 文件系统模块
|
|
4
|
+
*/
|
|
5
|
+
export class FileSystemModule {
|
|
6
|
+
constructor(socket, baseUrl, projectId) {
|
|
7
|
+
this.socket = socket;
|
|
8
|
+
this.baseUrl = baseUrl;
|
|
9
|
+
this.projectId = projectId;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 获取查询参数
|
|
13
|
+
*/
|
|
14
|
+
getQueryParams(filePath) {
|
|
15
|
+
const params = new URLSearchParams({ filePath });
|
|
16
|
+
if (this.projectId) {
|
|
17
|
+
params.set('projectId', this.projectId);
|
|
18
|
+
}
|
|
19
|
+
return params.toString();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 获取文件状态
|
|
23
|
+
*/
|
|
24
|
+
async stat(filePath) {
|
|
25
|
+
const url = `${this.baseUrl}/api/fs/stat?${this.getQueryParams(filePath)}`;
|
|
26
|
+
const response = await fetch(url);
|
|
27
|
+
const result = await response.json();
|
|
28
|
+
if (result.status === 'error') {
|
|
29
|
+
throw new Error(result.message);
|
|
30
|
+
}
|
|
31
|
+
return result.data;
|
|
32
|
+
}
|
|
33
|
+
async read(filePath, asText = false) {
|
|
34
|
+
if (asText) {
|
|
35
|
+
// 使用 readFile 端点获取文本内容
|
|
36
|
+
const url = `${this.baseUrl}/api/fs/readFile?${this.getQueryParams(filePath)}`;
|
|
37
|
+
const response = await fetch(url);
|
|
38
|
+
const result = await response.json();
|
|
39
|
+
if (result.status === 'error') {
|
|
40
|
+
throw new Error(result.message);
|
|
41
|
+
}
|
|
42
|
+
return result.data;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// 使用 read 端点获取原始文件(支持二进制)
|
|
46
|
+
const url = `${this.baseUrl}/api/fs/read?${this.getQueryParams(filePath)}`;
|
|
47
|
+
const response = await fetch(url);
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Failed to read file: ${response.statusText}`);
|
|
50
|
+
}
|
|
51
|
+
return response.blob();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 读取文件内容(文本形式)
|
|
56
|
+
* @param filePath 文件路径
|
|
57
|
+
* @returns Promise<string> 文件文本内容
|
|
58
|
+
*/
|
|
59
|
+
async readFile(filePath) {
|
|
60
|
+
return this.read(filePath, true);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 读取目录
|
|
64
|
+
*/
|
|
65
|
+
async readdir(filePath) {
|
|
66
|
+
const url = `${this.baseUrl}/api/fs/readdir?${this.getQueryParams(filePath)}`;
|
|
67
|
+
const response = await fetch(url);
|
|
68
|
+
const result = await response.json();
|
|
69
|
+
if (result.status === 'error') {
|
|
70
|
+
throw new Error(result.message);
|
|
71
|
+
}
|
|
72
|
+
return result.data;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 写入文件(流式)
|
|
76
|
+
* @param filePath 文件路径
|
|
77
|
+
* @param data 文件数据(可以是字符串、Blob、ArrayBuffer 或 Buffer)
|
|
78
|
+
* @param chunkSize 分块大小(字节),默认 64KB
|
|
79
|
+
*/
|
|
80
|
+
async writeFile(filePath, data, chunkSize = 64 * 1024) {
|
|
81
|
+
// 开始写入
|
|
82
|
+
const { taskId } = await createSocketHandler(this.socket, 'fs:writeFileStart', () => ({ filePath }));
|
|
83
|
+
try {
|
|
84
|
+
// 将数据转换为 Uint8Array
|
|
85
|
+
let buffer;
|
|
86
|
+
if (typeof data === 'string') {
|
|
87
|
+
buffer = new TextEncoder().encode(data);
|
|
88
|
+
}
|
|
89
|
+
else if (data instanceof Blob) {
|
|
90
|
+
const arrayBuffer = await data.arrayBuffer();
|
|
91
|
+
buffer = new Uint8Array(arrayBuffer);
|
|
92
|
+
}
|
|
93
|
+
else if (data instanceof ArrayBuffer) {
|
|
94
|
+
buffer = new Uint8Array(data);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
buffer = data;
|
|
98
|
+
}
|
|
99
|
+
// 分块发送数据
|
|
100
|
+
for (let i = 0; i < buffer.length; i += chunkSize) {
|
|
101
|
+
const chunk = buffer.slice(i, i + chunkSize);
|
|
102
|
+
// 将 Uint8Array 转换为 ArrayBuffer,Socket.IO 会自动处理
|
|
103
|
+
await createSocketHandler(this.socket, 'fs:writeFileChunk', () => ({ taskId, chunk }));
|
|
104
|
+
}
|
|
105
|
+
// 结束写入
|
|
106
|
+
await createSocketHandler(this.socket, 'fs:writeFileEnd', () => ({ taskId }));
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// 如果出错,尝试结束写入以清理资源
|
|
110
|
+
try {
|
|
111
|
+
await createSocketHandler(this.socket, 'fs:writeFileEnd', () => ({ taskId }));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// 忽略清理错误
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 创建目录
|
|
121
|
+
*/
|
|
122
|
+
async mkdir(filePath) {
|
|
123
|
+
return createSocketHandler(this.socket, 'fs:mkdir', () => ({ filePath }));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 重命名文件或目录
|
|
127
|
+
*/
|
|
128
|
+
async rename(oldPath, newPath) {
|
|
129
|
+
return createSocketHandler(this.socket, 'fs:rename', () => ({
|
|
130
|
+
oldPath,
|
|
131
|
+
newPath,
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 删除文件或目录
|
|
136
|
+
*/
|
|
137
|
+
async rm(filePath) {
|
|
138
|
+
return createSocketHandler(this.socket, 'fs:rm', () => ({ filePath }));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 监听文件变化
|
|
142
|
+
* @param paths 要监听的文件路径数组
|
|
143
|
+
* @param ignored 要忽略的文件路径数组
|
|
144
|
+
* @param callback 文件变化回调函数
|
|
145
|
+
* @returns 取消监听的函数
|
|
146
|
+
*/
|
|
147
|
+
watch(paths, ignored = [], callback) {
|
|
148
|
+
let taskId = null;
|
|
149
|
+
// 启动监听
|
|
150
|
+
createSocketHandler(this.socket, 'fs:watch', () => ({
|
|
151
|
+
paths,
|
|
152
|
+
ignored,
|
|
153
|
+
}))
|
|
154
|
+
.then((result) => {
|
|
155
|
+
taskId = result.taskId;
|
|
156
|
+
// 监听文件变化事件
|
|
157
|
+
const eventName = `fs:file-change:${taskId}`;
|
|
158
|
+
onSocketEvent(this.socket, eventName, callback);
|
|
159
|
+
})
|
|
160
|
+
.catch((error) => {
|
|
161
|
+
console.error('Failed to start file watch:', error);
|
|
162
|
+
});
|
|
163
|
+
// 返回取消监听的函数
|
|
164
|
+
return () => {
|
|
165
|
+
if (taskId) {
|
|
166
|
+
createSocketHandler(this.socket, 'fs:unwatch', () => ({ taskId: taskId })).catch((error) => {
|
|
167
|
+
console.error('Failed to stop file watch:', error);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Socket } from 'socket.io-client';
|
|
2
|
+
import type { PortStatusChangedEvent } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* 端口监听模块
|
|
5
|
+
*/
|
|
6
|
+
export declare class PortModule {
|
|
7
|
+
private socket;
|
|
8
|
+
constructor(socket: Socket);
|
|
9
|
+
/**
|
|
10
|
+
* 获取可用端口
|
|
11
|
+
* @param count 需要获取的端口数量,默认 2
|
|
12
|
+
* @returns Promise<number[]> 可用端口数组
|
|
13
|
+
*/
|
|
14
|
+
getPorts(count?: number): Promise<number[]>;
|
|
15
|
+
/**
|
|
16
|
+
* 开始监听端口状态
|
|
17
|
+
* @param ports 要监听的端口数组
|
|
18
|
+
*/
|
|
19
|
+
startWatch(ports: number[]): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* 停止监听端口状态
|
|
22
|
+
*/
|
|
23
|
+
stopWatch(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 监听端口状态变化
|
|
26
|
+
* @param callback 端口状态变化回调函数
|
|
27
|
+
* @returns 取消监听的函数
|
|
28
|
+
*/
|
|
29
|
+
onStatusChanged(callback: (event: PortStatusChangedEvent) => void): () => void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
/**
|
|
3
|
+
* 端口监听模块
|
|
4
|
+
*/
|
|
5
|
+
export class PortModule {
|
|
6
|
+
constructor(socket) {
|
|
7
|
+
this.socket = socket;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 获取可用端口
|
|
11
|
+
* @param count 需要获取的端口数量,默认 2
|
|
12
|
+
* @returns Promise<number[]> 可用端口数组
|
|
13
|
+
*/
|
|
14
|
+
async getPorts(count = 2) {
|
|
15
|
+
const result = await createSocketHandler(this.socket, 'port:find', () => ({
|
|
16
|
+
count,
|
|
17
|
+
}));
|
|
18
|
+
return result.ports;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 开始监听端口状态
|
|
22
|
+
* @param ports 要监听的端口数组
|
|
23
|
+
*/
|
|
24
|
+
async startWatch(ports) {
|
|
25
|
+
return createSocketHandler(this.socket, 'port:watch', () => ({ ports }));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 停止监听端口状态
|
|
29
|
+
*/
|
|
30
|
+
async stopWatch() {
|
|
31
|
+
return createSocketHandler(this.socket, 'port:unwatch', () => undefined);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 监听端口状态变化
|
|
35
|
+
* @param callback 端口状态变化回调函数
|
|
36
|
+
* @returns 取消监听的函数
|
|
37
|
+
*/
|
|
38
|
+
onStatusChanged(callback) {
|
|
39
|
+
return onSocketEvent(this.socket, 'portStatusChanged', callback);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Socket } from 'socket.io-client';
|
|
2
|
+
import type { ProjectInfo, ProjectFile, FileChangeEvent } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* 项目模块
|
|
5
|
+
*/
|
|
6
|
+
export declare class ProjectModule {
|
|
7
|
+
private socket;
|
|
8
|
+
private baseUrl;
|
|
9
|
+
private projectId?;
|
|
10
|
+
constructor(socket: Socket, baseUrl: string, projectId?: string | undefined);
|
|
11
|
+
/**
|
|
12
|
+
* 获取查询参数
|
|
13
|
+
*/
|
|
14
|
+
private getQueryParams;
|
|
15
|
+
/**
|
|
16
|
+
* 获取项目信息
|
|
17
|
+
*/
|
|
18
|
+
getInfo(): Promise<ProjectInfo>;
|
|
19
|
+
/**
|
|
20
|
+
* 获取项目文件列表
|
|
21
|
+
*/
|
|
22
|
+
getFiles(): Promise<ProjectFile[]>;
|
|
23
|
+
/**
|
|
24
|
+
* 开始监听项目变化
|
|
25
|
+
*/
|
|
26
|
+
watch(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* 停止监听项目变化
|
|
29
|
+
*/
|
|
30
|
+
unwatch(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* 监听项目文件变化
|
|
33
|
+
* @param callback 文件变化回调函数
|
|
34
|
+
* @returns 取消监听的函数
|
|
35
|
+
*/
|
|
36
|
+
onFileChange(callback: (event: FileChangeEvent) => void): () => void;
|
|
37
|
+
}
|