@cjwddz/mirror 1.1.0 → 2.0.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.
- package/README.md +154 -256
- package/dist/cli/cli-commands.d.ts +30 -0
- package/dist/cli/cli-commands.d.ts.map +1 -0
- package/dist/cli/cli-commands.js +391 -0
- package/dist/cli/cli-commands.js.map +1 -0
- package/dist/cli/client.d.ts +19 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +107 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/index-new.d.ts +6 -0
- package/dist/cli/index-new.d.ts.map +1 -0
- package/dist/cli/index-new.js +116 -0
- package/dist/cli/index-new.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +100 -41
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/server.d.ts +19 -0
- package/dist/cli/server.d.ts.map +1 -0
- package/dist/cli/server.js +77 -0
- package/dist/cli/server.js.map +1 -0
- package/dist/core/http-tunnel-client.d.ts +64 -0
- package/dist/core/http-tunnel-client.d.ts.map +1 -0
- package/dist/core/http-tunnel-client.js +315 -0
- package/dist/core/http-tunnel-client.js.map +1 -0
- package/dist/core/http-tunnel-protocol.d.ts +104 -0
- package/dist/core/http-tunnel-protocol.d.ts.map +1 -0
- package/dist/core/http-tunnel-protocol.js +29 -0
- package/dist/core/http-tunnel-protocol.js.map +1 -0
- package/dist/core/http-tunnel-server.d.ts +79 -0
- package/dist/core/http-tunnel-server.d.ts.map +1 -0
- package/dist/core/http-tunnel-server.js +375 -0
- package/dist/core/http-tunnel-server.js.map +1 -0
- package/dist/core/rule-manager.d.ts +71 -0
- package/dist/core/rule-manager.d.ts.map +1 -0
- package/dist/core/rule-manager.js +165 -0
- package/dist/core/rule-manager.js.map +1 -0
- package/dist/index.d.ts +4 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -8
- package/dist/index.js.map +1 -1
- package/package.json +14 -10
- package/dist/cli/exec.d.ts +0 -9
- package/dist/cli/exec.d.ts.map +0 -1
- package/dist/cli/exec.js +0 -32
- package/dist/cli/exec.js.map +0 -1
- package/dist/cli/host-impl.d.ts +0 -58
- package/dist/cli/host-impl.d.ts.map +0 -1
- package/dist/cli/host-impl.js +0 -547
- package/dist/cli/host-impl.js.map +0 -1
- package/dist/cli/host.d.ts +0 -9
- package/dist/cli/host.d.ts.map +0 -1
- package/dist/cli/host.js +0 -57
- package/dist/cli/host.js.map +0 -1
- package/dist/cli/link.d.ts +0 -10
- package/dist/cli/link.d.ts.map +0 -1
- package/dist/cli/link.js +0 -105
- package/dist/cli/link.js.map +0 -1
- package/dist/cli/logs.d.ts +0 -8
- package/dist/cli/logs.d.ts.map +0 -1
- package/dist/cli/logs.js +0 -48
- package/dist/cli/logs.js.map +0 -1
- package/dist/cli/shell.d.ts +0 -6
- package/dist/cli/shell.d.ts.map +0 -1
- package/dist/cli/shell.js +0 -53
- package/dist/cli/shell.js.map +0 -1
- package/dist/cli/status.d.ts +0 -6
- package/dist/cli/status.d.ts.map +0 -1
- package/dist/cli/status.js +0 -33
- package/dist/cli/status.js.map +0 -1
- package/dist/cli/stop.d.ts +0 -6
- package/dist/cli/stop.d.ts.map +0 -1
- package/dist/cli/stop.js +0 -18
- package/dist/cli/stop.js.map +0 -1
- package/dist/cli/ui/MirrorUI.d.ts +0 -22
- package/dist/cli/ui/MirrorUI.d.ts.map +0 -1
- package/dist/cli/ui/MirrorUI.js +0 -71
- package/dist/cli/ui/MirrorUI.js.map +0 -1
- package/dist/cli/ui/interactive-terminal.d.ts +0 -3
- package/dist/cli/ui/interactive-terminal.d.ts.map +0 -1
- package/dist/cli/ui/interactive-terminal.js +0 -150
- package/dist/cli/ui/interactive-terminal.js.map +0 -1
- package/dist/cli/watch.d.ts +0 -6
- package/dist/cli/watch.d.ts.map +0 -1
- package/dist/cli/watch.js +0 -29
- package/dist/cli/watch.js.map +0 -1
- package/dist/core/daemon.d.ts +0 -154
- package/dist/core/daemon.d.ts.map +0 -1
- package/dist/core/daemon.js +0 -590
- package/dist/core/daemon.js.map +0 -1
- package/dist/core/process-manager.d.ts +0 -19
- package/dist/core/process-manager.d.ts.map +0 -1
- package/dist/core/process-manager.js +0 -76
- package/dist/core/process-manager.js.map +0 -1
- package/dist/transport/pty.d.ts +0 -7
- package/dist/transport/pty.d.ts.map +0 -1
- package/dist/transport/pty.js +0 -26
- package/dist/transport/pty.js.map +0 -1
package/dist/cli/host-impl.js
DELETED
|
@@ -1,547 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host 实现类
|
|
3
|
-
*/
|
|
4
|
-
import { randomBytes } from 'crypto';
|
|
5
|
-
import { networkInterfaces } from 'os';
|
|
6
|
-
import { WebSocketTransport } from '../transport/websocket.js';
|
|
7
|
-
import { StateMachine, HostState } from '../core/state-machine.js';
|
|
8
|
-
import { Workspace } from '../core/workspace.js';
|
|
9
|
-
import { ProcessManager } from '../core/process-manager.js';
|
|
10
|
-
import { computeHash, decompressContent } from '../core/file-sync.js';
|
|
11
|
-
export class Host {
|
|
12
|
-
transport;
|
|
13
|
-
stateMachine;
|
|
14
|
-
workspace = null;
|
|
15
|
-
processManager;
|
|
16
|
-
currentClientId = null;
|
|
17
|
-
currentClientWorkspacePath = null;
|
|
18
|
-
sessionToken;
|
|
19
|
-
options;
|
|
20
|
-
snapshotFiles = new Map();
|
|
21
|
-
isSnapshotInProgress = false;
|
|
22
|
-
serverVersion;
|
|
23
|
-
hasProgressLine = false; // 标记是否有进度条在显示
|
|
24
|
-
isCommandRunning = false; // 独立的命令执行标志位
|
|
25
|
-
constructor(options, serverVersion) {
|
|
26
|
-
this.transport = new WebSocketTransport();
|
|
27
|
-
this.stateMachine = new StateMachine();
|
|
28
|
-
this.processManager = new ProcessManager();
|
|
29
|
-
this.options = options;
|
|
30
|
-
this.serverVersion = serverVersion;
|
|
31
|
-
// 如果提供了 token 就使用,否则自动生成
|
|
32
|
-
this.sessionToken = options.token || this.generateToken();
|
|
33
|
-
}
|
|
34
|
-
generateToken() {
|
|
35
|
-
return randomBytes(32).toString('base64url');
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 辅助日志方法:在输出日志前清除进度条
|
|
39
|
-
*/
|
|
40
|
-
log(message) {
|
|
41
|
-
if (this.hasProgressLine) {
|
|
42
|
-
// 清除进度条并换行
|
|
43
|
-
process.stdout.write('\r\x1b[K');
|
|
44
|
-
this.hasProgressLine = false;
|
|
45
|
-
}
|
|
46
|
-
console.log(message);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* 辅助错误日志方法:在输出错误日志前清除进度条
|
|
50
|
-
*/
|
|
51
|
-
logError(message, error) {
|
|
52
|
-
if (this.hasProgressLine) {
|
|
53
|
-
// 清除进度条并换行
|
|
54
|
-
process.stdout.write('\r\x1b[K');
|
|
55
|
-
this.hasProgressLine = false;
|
|
56
|
-
}
|
|
57
|
-
if (error !== undefined) {
|
|
58
|
-
console.error(message, error);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
console.error(message);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async start() {
|
|
65
|
-
const port = this.options.port;
|
|
66
|
-
await this.transport.createServer(port, (ws) => {
|
|
67
|
-
this.handleConnection(ws);
|
|
68
|
-
});
|
|
69
|
-
const hostname = this.getHostname();
|
|
70
|
-
console.log('Mirror host started');
|
|
71
|
-
console.log(`Listening on :${port}`);
|
|
72
|
-
console.log('链接指令: ');
|
|
73
|
-
console.log(`mirror link "${hostname}:${port}?token=${this.sessionToken}"`);
|
|
74
|
-
console.log(`mirror link "wss://mirror.tri-bank.online?token=${this.sessionToken}" (如果部署在服务端)`);
|
|
75
|
-
}
|
|
76
|
-
getHostname() {
|
|
77
|
-
// 尝试获取本机 IP
|
|
78
|
-
const interfaces = networkInterfaces();
|
|
79
|
-
for (const name of Object.keys(interfaces)) {
|
|
80
|
-
const ifaces = interfaces[name];
|
|
81
|
-
if (!ifaces)
|
|
82
|
-
continue;
|
|
83
|
-
for (const iface of ifaces) {
|
|
84
|
-
// 跳过内部(即 127.0.0.1)和非 IPv4 地址
|
|
85
|
-
if (iface.family === 'IPv4' && !iface.internal) {
|
|
86
|
-
return iface.address;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
// 如果没有找到外部 IP,返回 localhost
|
|
91
|
-
return 'localhost';
|
|
92
|
-
}
|
|
93
|
-
async handleConnection(ws) {
|
|
94
|
-
// 获取客户端地址信息,类型安全地访问 _socket
|
|
95
|
-
const socket = Object.getOwnPropertyDescriptor(ws, '_socket')?.value;
|
|
96
|
-
const clientAddress = socket?.remoteAddress ?? 'unknown';
|
|
97
|
-
const clientPort = socket?.remotePort ?? 'unknown';
|
|
98
|
-
this.log(`[${new Date().toISOString()}] 客户端连接: ${clientAddress}:${clientPort}`);
|
|
99
|
-
// 清理旧连接(如果有活跃连接)
|
|
100
|
-
if (this.currentClientId && this.stateMachine.getState() !== HostState.EMPTY) {
|
|
101
|
-
this.log(`[${new Date().toISOString()}] 检测到旧连接,断开旧连接: ${this.currentClientId}`);
|
|
102
|
-
// 断开旧连接时保留工作区
|
|
103
|
-
await this.disconnect();
|
|
104
|
-
}
|
|
105
|
-
ws.on('message', async (data) => {
|
|
106
|
-
try {
|
|
107
|
-
const message = JSON.parse(data.toString());
|
|
108
|
-
// 只记录关键消息,FILE 消息太多不记录
|
|
109
|
-
if (message.type !== 'FILE') {
|
|
110
|
-
if (message.type === 'FILE_DIFF') {
|
|
111
|
-
const diffMsg = message;
|
|
112
|
-
this.log(`[${new Date().toISOString()}] 收到消息: ${message.type} (${diffMsg.op}: ${diffMsg.path})`);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
this.log(`[${new Date().toISOString()}] 收到消息: ${message.type}`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
await this.handleMessage(ws, message);
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
this.logError(`[${new Date().toISOString()}] 处理消息失败:`, error);
|
|
122
|
-
this.sendError(ws, 'Failed to handle message');
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
ws.on('close', async () => {
|
|
126
|
-
this.log(`[${new Date().toISOString()}] 客户端断开连接: ${this.currentClientId || 'unknown'}`);
|
|
127
|
-
// 断开连接时保留工作区
|
|
128
|
-
await this.disconnect();
|
|
129
|
-
// 清除 currentClientId 和 currentClientWorkspacePath,以便下次连接时判断
|
|
130
|
-
this.currentClientId = null;
|
|
131
|
-
this.currentClientWorkspacePath = null;
|
|
132
|
-
});
|
|
133
|
-
ws.on('error', async (error) => {
|
|
134
|
-
// 清除进度条后输出错误
|
|
135
|
-
if (this.hasProgressLine) {
|
|
136
|
-
process.stdout.write('\r\x1b[K');
|
|
137
|
-
this.hasProgressLine = false;
|
|
138
|
-
}
|
|
139
|
-
console.error(`[${new Date().toISOString()}] WebSocket 错误:`, error);
|
|
140
|
-
// 错误时也保留工作区
|
|
141
|
-
await this.disconnect();
|
|
142
|
-
this.currentClientId = null;
|
|
143
|
-
this.currentClientWorkspacePath = null;
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
async handleMessage(ws, message) {
|
|
147
|
-
switch (message.type) {
|
|
148
|
-
case 'HELLO':
|
|
149
|
-
await this.handleHello(ws, message);
|
|
150
|
-
break;
|
|
151
|
-
case 'SNAPSHOT_START':
|
|
152
|
-
await this.handleSnapshotStart(ws, message);
|
|
153
|
-
break;
|
|
154
|
-
case 'FILE':
|
|
155
|
-
await this.handleFile(ws, message);
|
|
156
|
-
break;
|
|
157
|
-
case 'SNAPSHOT_END':
|
|
158
|
-
await this.handleSnapshotEnd(ws, message);
|
|
159
|
-
break;
|
|
160
|
-
case 'FILE_DIFF':
|
|
161
|
-
await this.handleFileDiff(ws, message);
|
|
162
|
-
break;
|
|
163
|
-
case 'EXEC':
|
|
164
|
-
await this.handleExec(ws, message);
|
|
165
|
-
break;
|
|
166
|
-
case 'EXEC_SIGNAL':
|
|
167
|
-
await this.handleExecSignal(ws, message);
|
|
168
|
-
break;
|
|
169
|
-
default:
|
|
170
|
-
this.sendError(ws, `Unknown message type: ${message.type}`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async handleHello(ws, message) {
|
|
174
|
-
// 验证 token
|
|
175
|
-
if (message.token !== this.sessionToken) {
|
|
176
|
-
this.logError(`[${new Date().toISOString()}] Token 验证失败`);
|
|
177
|
-
this.sendError(ws, 'Invalid token');
|
|
178
|
-
ws.close();
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
// 验证版本
|
|
182
|
-
const clientVersion = message.clientVersion || 'unknown';
|
|
183
|
-
if (clientVersion !== this.serverVersion) {
|
|
184
|
-
this.logError(`[${new Date().toISOString()}] 版本不匹配: 客户端版本=${clientVersion}, 服务端版本=${this.serverVersion}`);
|
|
185
|
-
this.sendError(ws, `Version mismatch: client version (${clientVersion}) != server version (${this.serverVersion}). Please update your mirror client.`);
|
|
186
|
-
ws.close();
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
const newClientId = message.clientId;
|
|
190
|
-
const newClientWorkspacePath = message.workspacePath || null;
|
|
191
|
-
// 检查工作区元数据中的工作目录路径(用于判断是否为同一工作目录)
|
|
192
|
-
const workspacePath = this.workspace?.getWorkspacePath();
|
|
193
|
-
// 如果是不同工作目录连接,清理旧工作区
|
|
194
|
-
if (this.workspace && workspacePath !== newClientWorkspacePath) {
|
|
195
|
-
console.log(`[${new Date().toISOString()}] 检测到不同工作目录,清理旧工作区 (旧: ${workspacePath || 'unknown'}, 新: ${newClientWorkspacePath || 'unknown'})`);
|
|
196
|
-
await this.cleanup();
|
|
197
|
-
}
|
|
198
|
-
else if (this.workspace && workspacePath === newClientWorkspacePath) {
|
|
199
|
-
// 同一个工作目录重连,复用工作区
|
|
200
|
-
this.log(`[${new Date().toISOString()}] 检测到同一工作目录重连,复用工作区 (${newClientWorkspacePath || 'unknown'})`);
|
|
201
|
-
// 断开连接时已经保存了元数据,这里不需要额外操作
|
|
202
|
-
}
|
|
203
|
-
this.currentClientId = newClientId;
|
|
204
|
-
this.currentClientWorkspacePath = newClientWorkspacePath;
|
|
205
|
-
this.log(`[${new Date().toISOString()}] HELLO 成功,客户端 ID: ${newClientId}, 工作目录: ${newClientWorkspacePath || 'unknown'}, 版本: ${message.clientVersion || 'unknown'}`);
|
|
206
|
-
this.stateMachine.transitionTo(HostState.SYNCING);
|
|
207
|
-
this.snapshotFiles.clear();
|
|
208
|
-
this.isSnapshotInProgress = false;
|
|
209
|
-
}
|
|
210
|
-
async handleSnapshotStart(ws, message) {
|
|
211
|
-
if (this.stateMachine.getState() !== HostState.SYNCING) {
|
|
212
|
-
this.sendError(ws, 'Invalid state for SNAPSHOT_START');
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const totalFiles = message.totalFiles || 0;
|
|
216
|
-
this.log(`[${new Date().toISOString()}] 开始接收快照,版本: ${message.version}${totalFiles > 0 ? `,预计文件数: ${totalFiles}` : ''}`);
|
|
217
|
-
// 创建或复用 workspace(传入 clientId 和工作目录路径以便复用)
|
|
218
|
-
// 元数据文件保存在工作区目录之外,避免污染同步目录
|
|
219
|
-
if (!this.workspace) {
|
|
220
|
-
this.workspace = await Workspace.create(this.options.workspaceDir, false, this.currentClientId || null, this.currentClientWorkspacePath || null, this.options.metadataDir // 传递元数据目录
|
|
221
|
-
);
|
|
222
|
-
if (this.currentClientId) {
|
|
223
|
-
await this.workspace.setClientInfo(this.currentClientId, this.currentClientWorkspacePath || null);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
this.log(`[${new Date().toISOString()}] 工作空间路径: ${this.workspace.getPath()}`);
|
|
227
|
-
this.isSnapshotInProgress = true;
|
|
228
|
-
this.snapshotFiles.clear();
|
|
229
|
-
this.fileCount = totalFiles; // 设置文件总数
|
|
230
|
-
this.receivedFileCount = 0; // 重置接收计数
|
|
231
|
-
this.writtenFileCount = 0; // 重置写入计数
|
|
232
|
-
this.skippedFileCount = 0; // 重置跳过计数
|
|
233
|
-
}
|
|
234
|
-
fileCount = 0; // 文件计数器(用于显示总文件数)
|
|
235
|
-
snapshotFileCount = 0; // 快照文件总数(初始同步的文件数)
|
|
236
|
-
incrementalSyncCount = 0; // 增量同步计数器(FILE_DIFF 同步的文件数)
|
|
237
|
-
receivedFileCount = 0; // 已接收文件数
|
|
238
|
-
writtenFileCount = 0; // 已写入文件数
|
|
239
|
-
skippedFileCount = 0; // 已跳过文件数(hash相同)
|
|
240
|
-
pendingFileDiffs = new Set(); // 待同步文件集合(用于跟踪 pending 状态)
|
|
241
|
-
async handleFile(ws, message) {
|
|
242
|
-
if (!this.workspace) {
|
|
243
|
-
this.sendError(ws, 'Workspace not initialized');
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
if (!this.isSnapshotInProgress) {
|
|
247
|
-
// 忽略快照完成后收到的 FILE 消息(可能是网络延迟或客户端时序问题)
|
|
248
|
-
this.log(`[${new Date().toISOString()}] 忽略快照完成后的 FILE 消息: ${message.path}`);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
let content = Buffer.from(message.content, 'base64');
|
|
252
|
-
// 如果是压缩的,先解压
|
|
253
|
-
if (message.compressed) {
|
|
254
|
-
try {
|
|
255
|
-
content = Buffer.from(await decompressContent(content));
|
|
256
|
-
}
|
|
257
|
-
catch (error) {
|
|
258
|
-
this.logError(`[${new Date().toISOString()}] 解压失败: ${message.path}`, error);
|
|
259
|
-
this.sendError(ws, `Failed to decompress ${message.path}`);
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
const hash = computeHash(content);
|
|
264
|
-
// 验证 hash
|
|
265
|
-
if (hash !== message.hash) {
|
|
266
|
-
this.logError(`[${new Date().toISOString()}] Hash 验证失败: ${message.path}`);
|
|
267
|
-
this.sendError(ws, `Hash mismatch for ${message.path}`);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
// 检查文件是否已存在且 hash 相同(增量同步)
|
|
271
|
-
const isSkipped = this.workspace.hasFile(message.path, message.hash);
|
|
272
|
-
if (isSkipped) {
|
|
273
|
-
this.skippedFileCount++;
|
|
274
|
-
}
|
|
275
|
-
// 记录到快照中(无论是否需要写入)
|
|
276
|
-
this.snapshotFiles.set(message.path, { hash, content });
|
|
277
|
-
this.receivedFileCount++;
|
|
278
|
-
// 每 10 个文件显示一次接收进度
|
|
279
|
-
if (this.receivedFileCount % 10 === 0 || this.receivedFileCount === this.fileCount) {
|
|
280
|
-
const skippedInfo = this.skippedFileCount > 0 ? ` (跳过 ${this.skippedFileCount})` : '';
|
|
281
|
-
const totalInfo = this.fileCount > 0 ? `/${this.fileCount}` : '';
|
|
282
|
-
process.stdout.write(`\r[${new Date().toISOString()}] 已接收 ${this.receivedFileCount}${totalInfo} 个文件${skippedInfo}...`);
|
|
283
|
-
this.hasProgressLine = true; // 标记有进度条在显示
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
async handleSnapshotEnd(ws, message) {
|
|
287
|
-
if (!this.workspace) {
|
|
288
|
-
this.sendError(ws, 'Workspace not initialized');
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
if (!this.isSnapshotInProgress) {
|
|
292
|
-
this.sendError(ws, 'SNAPSHOT not in progress');
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
// 清除接收进度显示(使用 ANSI 转义序列清除整行)
|
|
296
|
-
process.stdout.write('\r\x1b[K');
|
|
297
|
-
this.hasProgressLine = false; // 清除标记
|
|
298
|
-
console.log(`[${new Date().toISOString()}] 快照接收完成,版本: ${message.version},文件数: ${this.snapshotFiles.size}`);
|
|
299
|
-
// 准备写入文件
|
|
300
|
-
const filesToWrite = [];
|
|
301
|
-
const fileHashes = {};
|
|
302
|
-
// 获取旧的文件列表(用于删除已移除的文件)
|
|
303
|
-
const oldFiles = this.workspace.getOldFiles();
|
|
304
|
-
const newFilePaths = new Set();
|
|
305
|
-
for (const [path, { hash, content }] of this.snapshotFiles) {
|
|
306
|
-
fileHashes[path] = hash;
|
|
307
|
-
newFilePaths.add(path);
|
|
308
|
-
// 只写入需要更新的文件(hash 不同的)
|
|
309
|
-
if (!this.workspace.hasFile(path, hash)) {
|
|
310
|
-
filesToWrite.push([path, content]);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
// 找出需要删除的文件(在旧文件中但不在新快照中)
|
|
314
|
-
const filesToDelete = [];
|
|
315
|
-
for (const oldPath of Object.keys(oldFiles)) {
|
|
316
|
-
if (!newFilePaths.has(oldPath)) {
|
|
317
|
-
filesToDelete.push(oldPath);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const totalFiles = this.snapshotFiles.size;
|
|
321
|
-
const needWriteCount = filesToWrite.length;
|
|
322
|
-
const actualSkippedCount = totalFiles - needWriteCount;
|
|
323
|
-
// 删除已移除的文件
|
|
324
|
-
if (filesToDelete.length > 0) {
|
|
325
|
-
this.log(`[${new Date().toISOString()}] 检测到 ${filesToDelete.length} 个文件已移除,开始删除...`);
|
|
326
|
-
for (const path of filesToDelete) {
|
|
327
|
-
await this.workspace.deleteFile(path);
|
|
328
|
-
}
|
|
329
|
-
this.log(`[${new Date().toISOString()}] 已删除 ${filesToDelete.length} 个文件`);
|
|
330
|
-
}
|
|
331
|
-
if (needWriteCount > 0) {
|
|
332
|
-
this.log(`[${new Date().toISOString()}] 开始写入文件: ${needWriteCount}/${totalFiles} 需要更新...`);
|
|
333
|
-
// 写入文件并显示进度
|
|
334
|
-
for (let i = 0; i < filesToWrite.length; i++) {
|
|
335
|
-
const [path, content] = filesToWrite[i];
|
|
336
|
-
await this.workspace.writeFile(path, content);
|
|
337
|
-
this.writtenFileCount++;
|
|
338
|
-
// 每写入 10 个文件或最后一个文件时显示进度
|
|
339
|
-
if ((i + 1) % 10 === 0 || i === filesToWrite.length - 1) {
|
|
340
|
-
process.stdout.write(`\r[${new Date().toISOString()}] 已写入 ${this.writtenFileCount}/${needWriteCount} 个文件...`);
|
|
341
|
-
this.hasProgressLine = true; // 标记有进度条在显示
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
// 清除写入进度显示(使用 ANSI 转义序列清除整行)
|
|
345
|
-
process.stdout.write('\r\x1b[K');
|
|
346
|
-
this.hasProgressLine = false; // 清除标记
|
|
347
|
-
}
|
|
348
|
-
// 更新文件列表元数据
|
|
349
|
-
await this.workspace.updateFileList(fileHashes);
|
|
350
|
-
this.workspace.setVersion(message.version);
|
|
351
|
-
this.stateMachine.transitionTo(HostState.READY);
|
|
352
|
-
this.isSnapshotInProgress = false;
|
|
353
|
-
const skippedInfo = actualSkippedCount > 0 ? ` (跳过 ${actualSkippedCount} 个未变更文件)` : '';
|
|
354
|
-
this.log(`[${new Date().toISOString()}] 工作空间已就绪,可以执行命令${skippedInfo}`);
|
|
355
|
-
// 记录快照文件数(用于后续的 totalSynced 计算)
|
|
356
|
-
this.snapshotFileCount = this.snapshotFiles.size;
|
|
357
|
-
// 发送文件同步状态消息(初始同步完成)
|
|
358
|
-
ws.send(JSON.stringify({
|
|
359
|
-
type: 'FILE_SYNC_STATUS',
|
|
360
|
-
status: 'synced',
|
|
361
|
-
totalSynced: this.snapshotFileCount,
|
|
362
|
-
pendingCount: 0,
|
|
363
|
-
}));
|
|
364
|
-
// 发送 READY 消息通知客户端
|
|
365
|
-
ws.send(JSON.stringify({
|
|
366
|
-
type: 'READY',
|
|
367
|
-
message: '工作空间已就绪',
|
|
368
|
-
}));
|
|
369
|
-
// 重置计数器(保留 snapshotFileCount 用于后续增量同步计数)
|
|
370
|
-
this.snapshotFiles.clear();
|
|
371
|
-
this.fileCount = 0;
|
|
372
|
-
this.receivedFileCount = 0;
|
|
373
|
-
this.writtenFileCount = 0;
|
|
374
|
-
this.skippedFileCount = 0;
|
|
375
|
-
this.incrementalSyncCount = 0; // 重置增量同步计数器
|
|
376
|
-
this.pendingFileDiffs.clear(); // 清空待同步文件集合
|
|
377
|
-
}
|
|
378
|
-
async handleFileDiff(ws, message) {
|
|
379
|
-
if (!this.workspace) {
|
|
380
|
-
this.sendError(ws, 'Workspace not initialized');
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
const state = this.stateMachine.getState();
|
|
384
|
-
// 只要状态是 READY,就可以同步文件(不管是否有命令在执行)
|
|
385
|
-
if (state === HostState.READY) {
|
|
386
|
-
// 通知客户端正在同步
|
|
387
|
-
ws.send(JSON.stringify({
|
|
388
|
-
type: 'FILE_SYNC_STATUS',
|
|
389
|
-
status: 'syncing',
|
|
390
|
-
path: message.path,
|
|
391
|
-
op: message.op,
|
|
392
|
-
}));
|
|
393
|
-
// 立即应用文件变更
|
|
394
|
-
if (message.op === 'update' && message.content) {
|
|
395
|
-
let content = Buffer.from(message.content, 'base64');
|
|
396
|
-
// 如果是压缩的,先解压
|
|
397
|
-
if (message.compressed) {
|
|
398
|
-
try {
|
|
399
|
-
content = Buffer.from(await decompressContent(content));
|
|
400
|
-
}
|
|
401
|
-
catch (error) {
|
|
402
|
-
this.logError(`[${new Date().toISOString()}] 解压失败: ${message.path}`, error);
|
|
403
|
-
this.sendError(ws, `Failed to decompress ${message.path}`);
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
const hash = computeHash(content);
|
|
408
|
-
if (hash !== message.hash) {
|
|
409
|
-
this.sendError(ws, `Hash mismatch for ${message.path}`);
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
await this.workspace.writeFile(message.path, content);
|
|
413
|
-
}
|
|
414
|
-
else if (message.op === 'delete') {
|
|
415
|
-
await this.workspace.deleteFile(message.path);
|
|
416
|
-
}
|
|
417
|
-
this.workspace.setVersion(message.version);
|
|
418
|
-
// 递增增量同步计数
|
|
419
|
-
this.incrementalSyncCount++;
|
|
420
|
-
// 通知客户端同步完成,包含统计信息
|
|
421
|
-
ws.send(JSON.stringify({
|
|
422
|
-
type: 'FILE_SYNC_STATUS',
|
|
423
|
-
status: 'synced',
|
|
424
|
-
path: message.path,
|
|
425
|
-
op: message.op,
|
|
426
|
-
totalSynced: this.snapshotFileCount + this.incrementalSyncCount, // 总同步数 = snapshot文件数 + 增量同步数
|
|
427
|
-
pendingCount: 0, // 实时同步,无待同步文件
|
|
428
|
-
}));
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
this.sendError(ws, `Invalid state for FILE_DIFF: ${state}`);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
async handleExec(ws, message) {
|
|
435
|
-
if (!this.workspace) {
|
|
436
|
-
this.sendError(ws, 'Workspace not initialized');
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
// 验证状态
|
|
440
|
-
if (!this.stateMachine.canExec()) {
|
|
441
|
-
this.sendError(ws, `Cannot exec in state: ${this.stateMachine.getState()}`);
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
// 验证版本
|
|
445
|
-
if (message.version !== this.workspace.getCurrentVersion()) {
|
|
446
|
-
this.sendError(ws, `Version mismatch: expected ${this.workspace.getCurrentVersion()}, got ${message.version}`);
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
console.log(`[${new Date().toISOString()}] 执行命令: ${message.command} (execId: ${message.execId})`);
|
|
450
|
-
// 标记命令正在执行
|
|
451
|
-
this.isCommandRunning = true;
|
|
452
|
-
// 启动进程
|
|
453
|
-
const ptyProcess = await this.processManager.spawn(message.execId, message.command, this.workspace.getPath());
|
|
454
|
-
// 监听输出
|
|
455
|
-
ptyProcess.onData((data) => {
|
|
456
|
-
ws.send(JSON.stringify({
|
|
457
|
-
type: 'EXEC_OUTPUT',
|
|
458
|
-
execId: message.execId,
|
|
459
|
-
stream: 'stdout',
|
|
460
|
-
data,
|
|
461
|
-
}));
|
|
462
|
-
});
|
|
463
|
-
// 监听退出
|
|
464
|
-
ptyProcess.onExit(async (exit) => {
|
|
465
|
-
console.log(`[${new Date().toISOString()}] 命令执行完成: ${message.command} (execId: ${message.execId}, exitCode: ${exit.exitCode})`);
|
|
466
|
-
ws.send(JSON.stringify({
|
|
467
|
-
type: 'EXEC_EXIT',
|
|
468
|
-
execId: message.execId,
|
|
469
|
-
code: exit.exitCode,
|
|
470
|
-
}));
|
|
471
|
-
// 清理进程
|
|
472
|
-
this.processManager.removeProcess(message.execId);
|
|
473
|
-
// 标记命令执行完成
|
|
474
|
-
this.isCommandRunning = false;
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
async handleExecSignal(ws, message) {
|
|
478
|
-
const processInfo = this.processManager.getProcess(message.execId);
|
|
479
|
-
if (!processInfo) {
|
|
480
|
-
this.sendError(ws, `Process not found: ${message.execId}`);
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
this.log(`[${new Date().toISOString()}] 向进程发送信号: ${message.signal} (execId: ${message.execId})`);
|
|
484
|
-
try {
|
|
485
|
-
processInfo.process.kill(message.signal);
|
|
486
|
-
}
|
|
487
|
-
catch (error) {
|
|
488
|
-
this.logError(`[${new Date().toISOString()}] 发送信号失败:`, error);
|
|
489
|
-
this.sendError(ws, `Failed to send signal to process: ${message.execId}`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
sendError(ws, message, code) {
|
|
493
|
-
ws.send(JSON.stringify({
|
|
494
|
-
type: 'ERROR',
|
|
495
|
-
message,
|
|
496
|
-
code,
|
|
497
|
-
}));
|
|
498
|
-
}
|
|
499
|
-
async cleanup() {
|
|
500
|
-
// 清理进程
|
|
501
|
-
await this.processManager.killAll();
|
|
502
|
-
// 清理 workspace(完全删除)
|
|
503
|
-
if (this.workspace) {
|
|
504
|
-
await this.workspace.cleanup();
|
|
505
|
-
this.workspace = null;
|
|
506
|
-
}
|
|
507
|
-
// 重置状态
|
|
508
|
-
this.stateMachine.reset();
|
|
509
|
-
this.currentClientId = null;
|
|
510
|
-
this.currentClientWorkspacePath = null;
|
|
511
|
-
this.snapshotFiles.clear();
|
|
512
|
-
this.isSnapshotInProgress = false;
|
|
513
|
-
this.isCommandRunning = false;
|
|
514
|
-
this.fileCount = 0;
|
|
515
|
-
this.snapshotFileCount = 0;
|
|
516
|
-
this.incrementalSyncCount = 0;
|
|
517
|
-
this.receivedFileCount = 0;
|
|
518
|
-
this.writtenFileCount = 0;
|
|
519
|
-
this.skippedFileCount = 0;
|
|
520
|
-
this.pendingFileDiffs.clear();
|
|
521
|
-
}
|
|
522
|
-
async disconnect() {
|
|
523
|
-
// 断开连接时保留工作区
|
|
524
|
-
// 清理进程
|
|
525
|
-
await this.processManager.killAll();
|
|
526
|
-
// 保存工作区元数据,但不删除工作区
|
|
527
|
-
if (this.workspace) {
|
|
528
|
-
await this.workspace.disconnect();
|
|
529
|
-
// 不设置为 null,以便重连时复用
|
|
530
|
-
}
|
|
531
|
-
// 重置状态(但保留 workspace、currentClientId 和 currentClientWorkspacePath,以便识别重连)
|
|
532
|
-
this.stateMachine.reset();
|
|
533
|
-
this.snapshotFiles.clear();
|
|
534
|
-
this.isSnapshotInProgress = false;
|
|
535
|
-
this.isCommandRunning = false;
|
|
536
|
-
this.fileCount = 0;
|
|
537
|
-
this.receivedFileCount = 0;
|
|
538
|
-
this.writtenFileCount = 0;
|
|
539
|
-
this.skippedFileCount = 0;
|
|
540
|
-
// 注意:不断开连接时不清除 currentClientId 和 currentClientWorkspacePath
|
|
541
|
-
}
|
|
542
|
-
async stop() {
|
|
543
|
-
await this.cleanup();
|
|
544
|
-
this.transport.close();
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
//# sourceMappingURL=host-impl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host-impl.js","sourceRoot":"","sources":["../../src/cli/host-impl.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/host.d.ts
DELETED
package/dist/cli/host.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/cli/host.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDhB"}
|
package/dist/cli/host.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host CLI 命令处理
|
|
3
|
-
*/
|
|
4
|
-
import { Host } from './host-impl.js';
|
|
5
|
-
export async function hostCommand(options) {
|
|
6
|
-
// 打印版本号
|
|
7
|
-
const { getPackageVersion } = await import('./link.js');
|
|
8
|
-
const version = await getPackageVersion();
|
|
9
|
-
console.log(`mirror v${version}\n`);
|
|
10
|
-
const port = parseInt(options.port, 10);
|
|
11
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
12
|
-
console.error('Invalid port number');
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
// 默认使用当前目录
|
|
16
|
-
let workspaceDir;
|
|
17
|
-
if (options.dir) {
|
|
18
|
-
workspaceDir = options.dir;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
// 尝试获取当前工作目录,如果失败则尝试使用环境变量
|
|
22
|
-
try {
|
|
23
|
-
workspaceDir = process.cwd();
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
// 如果 process.cwd() 失败,尝试使用 PWD 环境变量(shell 通常会设置)
|
|
27
|
-
workspaceDir = process.env.PWD || process.env.HOME || '/tmp';
|
|
28
|
-
if (workspaceDir === '/tmp') {
|
|
29
|
-
console.warn('警告: 无法获取当前工作目录,使用 /tmp 作为默认目录');
|
|
30
|
-
console.warn('建议使用 --dir 选项明确指定工作空间目录');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
console.warn(`警告: 无法获取当前工作目录,使用 ${workspaceDir} 作为默认目录`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const host = new Host({
|
|
38
|
-
port,
|
|
39
|
-
workspaceDir,
|
|
40
|
-
token: options.token,
|
|
41
|
-
}, version);
|
|
42
|
-
// 处理退出信号
|
|
43
|
-
const cleanup = async () => {
|
|
44
|
-
await host.stop();
|
|
45
|
-
process.exit(0);
|
|
46
|
-
};
|
|
47
|
-
process.on('SIGINT', cleanup);
|
|
48
|
-
process.on('SIGTERM', cleanup);
|
|
49
|
-
try {
|
|
50
|
-
await host.start();
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
console.error('Failed to start host:', error);
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=host.js.map
|
package/dist/cli/host.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/cli/host.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAIjC;IACC,QAAQ;IACR,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,IAAI,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,WAAW;IACX,IAAI,YAAoB,CAAC;IACzB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,2BAA2B;QAC3B,IAAI,CAAC;YACH,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iDAAiD;YACjD,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;YAC7D,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;gBAC9C,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,qBAAqB,YAAY,SAAS,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,IAAI,CACnB;QACE,IAAI;QACJ,YAAY;QACZ,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,EACD,OAAO,CACR,CAAC;IAEF,SAAS;IACT,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|