aicodeswitch 2.0.10 → 2.0.11
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/CHANGELOG.md +2 -0
- package/CLAUDE.md +4 -1
- package/dist/server/main.js +38 -0
- package/dist/server/proxy-server.js +28 -1
- package/dist/server/rules-status-service.js +197 -0
- package/dist/server/tools-service.js +202 -0
- package/dist/server/websocket-service.js +148 -0
- package/dist/ui/assets/index-BC_wSFXP.js +452 -0
- package/dist/ui/index.html +1 -1
- package/package.json +3 -2
- package/dist/ui/assets/index-BYeFnkER.js +0 -431
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ToolInstallationWS = void 0;
|
|
7
|
+
exports.createToolInstallationWSServer = createToolInstallationWSServer;
|
|
8
|
+
// @ts-ignore - ws 类型声明可能需要手动安装 @types/ws
|
|
9
|
+
const ws_1 = require("ws");
|
|
10
|
+
const tools_service_1 = require("./tools-service");
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
/**
|
|
13
|
+
* WebSocket 连接管理
|
|
14
|
+
*/
|
|
15
|
+
class ToolInstallationWS {
|
|
16
|
+
constructor(ws, req) {
|
|
17
|
+
Object.defineProperty(this, "ws", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "childProcess", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: null
|
|
28
|
+
});
|
|
29
|
+
this.ws = ws;
|
|
30
|
+
console.log(`[WS] 新的 WebSocket 连接: ${req.socket.remoteAddress}`);
|
|
31
|
+
this.ws.on('message', (data) => {
|
|
32
|
+
try {
|
|
33
|
+
const message = JSON.parse(data.toString());
|
|
34
|
+
console.log(`[WS] 收到消息:`, message.type);
|
|
35
|
+
if (message.type === 'input') {
|
|
36
|
+
// 用户输入(如密码),发送到子进程的 stdin
|
|
37
|
+
if (this.childProcess && this.childProcess.stdin) {
|
|
38
|
+
console.log(`[WS] 发送用户输入到子进程:`, message.data.slice(0, 10));
|
|
39
|
+
this.childProcess.stdin.write(message.data);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.warn(`[WS] 子进程不存在或无 stdin,无法发送输入`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.error(`[WS] 解析消息失败:`, err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
this.ws.on('close', () => {
|
|
51
|
+
console.log(`[WS] WebSocket 连接关闭`);
|
|
52
|
+
this.cleanup();
|
|
53
|
+
});
|
|
54
|
+
this.ws.on('error', (err) => {
|
|
55
|
+
console.error(`[WS] WebSocket 错误:`, err);
|
|
56
|
+
this.cleanup();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 开始安装工具
|
|
61
|
+
*/
|
|
62
|
+
startInstallation(toolName) {
|
|
63
|
+
console.log(`[WS] 开始安装 ${toolName}`);
|
|
64
|
+
const callbacks = {
|
|
65
|
+
onData: (data) => {
|
|
66
|
+
this.sendMessage({ type: 'stdout', data });
|
|
67
|
+
},
|
|
68
|
+
onError: (data) => {
|
|
69
|
+
this.sendMessage({ type: 'stderr', data });
|
|
70
|
+
},
|
|
71
|
+
onClose: (code) => {
|
|
72
|
+
const success = code === 0;
|
|
73
|
+
this.sendMessage({ type: 'close', data: { code, success } });
|
|
74
|
+
// 延迟关闭连接,让客户端收到最终消息
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
this.ws.close();
|
|
77
|
+
}, 1000);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
// 启动安装进程
|
|
81
|
+
this.childProcess = (0, tools_service_1.installTool)(toolName, callbacks);
|
|
82
|
+
// 发送启动信息
|
|
83
|
+
const platform = os_1.default.platform();
|
|
84
|
+
const command = platform === 'win32'
|
|
85
|
+
? `npm install -g ${toolName === 'claude-code' ? '@anthropic-ai/claude-code' : '@openai/codex'}`
|
|
86
|
+
: `sudo npm install -g ${toolName === 'claude-code' ? '@anthropic-ai/claude-code' : '@openai/codex'}`;
|
|
87
|
+
this.sendMessage({
|
|
88
|
+
type: 'start',
|
|
89
|
+
data: {
|
|
90
|
+
tool: toolName,
|
|
91
|
+
os: platform,
|
|
92
|
+
command,
|
|
93
|
+
pid: this.childProcess.pid || 0,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 发送消息到客户端
|
|
99
|
+
*/
|
|
100
|
+
sendMessage(message) {
|
|
101
|
+
if (this.ws.readyState === ws_1.WebSocket.OPEN) {
|
|
102
|
+
this.ws.send(JSON.stringify(message));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 清理资源
|
|
107
|
+
*/
|
|
108
|
+
cleanup() {
|
|
109
|
+
if (this.childProcess) {
|
|
110
|
+
console.log(`[WS] 清理资源,终止子进程`);
|
|
111
|
+
// 给进程5秒时间正常退出
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
if (this.childProcess && !this.childProcess.killed) {
|
|
114
|
+
this.childProcess.kill('SIGTERM');
|
|
115
|
+
}
|
|
116
|
+
}, 5000);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.ToolInstallationWS = ToolInstallationWS;
|
|
121
|
+
/**
|
|
122
|
+
* 创建 WebSocket 服务器
|
|
123
|
+
*/
|
|
124
|
+
function createToolInstallationWSServer() {
|
|
125
|
+
const wss = new ws_1.WebSocketServer({ noServer: true });
|
|
126
|
+
wss.on('connection', (ws, req) => {
|
|
127
|
+
const wsHandler = new ToolInstallationWS(ws, req);
|
|
128
|
+
// 监听第一次消息,获取要安装的工具名称
|
|
129
|
+
ws.once('message', (data) => {
|
|
130
|
+
try {
|
|
131
|
+
const message = JSON.parse(data.toString());
|
|
132
|
+
if (message.type === 'install' && message.tool) {
|
|
133
|
+
wsHandler.startInstallation(message.tool);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
ws.send(JSON.stringify({ type: 'error', data: '无效的请求' }));
|
|
137
|
+
ws.close();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(`[WS] 解析安装请求失败:`, error);
|
|
142
|
+
ws.send(JSON.stringify({ type: 'error', data: '解析请求失败' }));
|
|
143
|
+
ws.close();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
return wss;
|
|
148
|
+
}
|