mobilecoder-mcp 2.0.0 → 2.1.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/dist/agent.d.ts +13 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +202 -56
- package/dist/agent.js.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +243 -59
package/dist/agent.d.ts
CHANGED
|
@@ -3,15 +3,27 @@ export declare class ZKRelayAgent {
|
|
|
3
3
|
private ptyProcess;
|
|
4
4
|
private secretCode;
|
|
5
5
|
private roomId;
|
|
6
|
-
private
|
|
6
|
+
private masterKey;
|
|
7
|
+
private sessionKey;
|
|
8
|
+
private sessionCounter;
|
|
9
|
+
private seenNonces;
|
|
10
|
+
private nonceCleanupInterval;
|
|
11
|
+
private keyRotationInterval;
|
|
7
12
|
private spinner;
|
|
8
13
|
constructor();
|
|
9
14
|
private setupSecurity;
|
|
15
|
+
private deriveSessionKey;
|
|
16
|
+
private rotateKey;
|
|
17
|
+
private startSecurityMaintenance;
|
|
10
18
|
private initPTY;
|
|
11
19
|
private connectToRelay;
|
|
20
|
+
private encrypt;
|
|
21
|
+
private decrypt;
|
|
12
22
|
private handleIncomingMessage;
|
|
23
|
+
private handleToolCall;
|
|
13
24
|
private sendSecurePayload;
|
|
14
25
|
private sendEnvInfo;
|
|
15
26
|
private printBanner;
|
|
27
|
+
destroy(): void;
|
|
16
28
|
}
|
|
17
29
|
//# sourceMappingURL=agent.d.ts.map
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAoBA,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,oBAAoB,CAA+B;IAC3D,OAAO,CAAC,mBAAmB,CAA+B;IAE1D,OAAO,CAAC,OAAO,CAAwC;;IAUvD,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,cAAc;IAwCtB,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,qBAAqB;YAyEf,cAAc;IAyC5B,OAAO,CAAC,iBAAiB;IAqCzB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,WAAW;IAeZ,OAAO;CAMjB"}
|
package/dist/agent.js
CHANGED
|
@@ -1,32 +1,72 @@
|
|
|
1
1
|
import { io } from 'socket.io-client';
|
|
2
2
|
import * as os from 'os';
|
|
3
3
|
import * as pty from 'node-pty';
|
|
4
|
-
import
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import ora from 'ora';
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
7
9
|
// 🚨 BURAYI KENDİ DOMAIN ADRESİNLE DEĞİŞTİR!
|
|
8
10
|
const RELAY_SERVER_URL = 'https://api.mobilecoder.xyz';
|
|
11
|
+
// Security Constants
|
|
12
|
+
const PBKDF2_ITERATIONS = 100000;
|
|
13
|
+
const KEY_LENGTH = 32; // 256 bits
|
|
14
|
+
const SALT = 'mobilecoder-salt-v2';
|
|
15
|
+
const KEY_ROTATION_INTERVAL = 600000; // 10 minutes
|
|
16
|
+
const MESSAGE_MAX_AGE = 300000; // 5 minutes
|
|
9
17
|
export class ZKRelayAgent {
|
|
10
18
|
socket;
|
|
11
19
|
ptyProcess;
|
|
12
20
|
secretCode;
|
|
13
21
|
roomId;
|
|
14
|
-
|
|
22
|
+
// 🔐 Güçlendirilmiş Güvenlik Değişkenleri
|
|
23
|
+
masterKey;
|
|
24
|
+
sessionKey;
|
|
25
|
+
sessionCounter = 0;
|
|
26
|
+
seenNonces = new Set();
|
|
27
|
+
nonceCleanupInterval = null;
|
|
28
|
+
keyRotationInterval = null;
|
|
15
29
|
spinner = ora('Initializing Secure Tunnel...');
|
|
16
30
|
constructor() {
|
|
17
31
|
this.setupSecurity();
|
|
18
32
|
this.initPTY();
|
|
19
33
|
this.connectToRelay();
|
|
34
|
+
this.startSecurityMaintenance();
|
|
20
35
|
}
|
|
21
|
-
// 1. Güvenlik Katmanı:
|
|
36
|
+
// 1. Güvenlik Katmanı: PBKDF2 ile Güçlendirilmiş Anahtar Türetme
|
|
22
37
|
setupSecurity() {
|
|
23
38
|
// 6 Haneli rastgele kod (Kullanıcının göreceği)
|
|
24
39
|
const randomNum = Math.floor(100000 + Math.random() * 900000);
|
|
25
40
|
this.secretCode = randomNum.toString();
|
|
26
41
|
// Oda ID'si: Kodun Hash'i (Sunucu sadece bunu görür, kodu göremez)
|
|
27
|
-
this.roomId =
|
|
28
|
-
//
|
|
29
|
-
this.
|
|
42
|
+
this.roomId = crypto.createHash('sha256').update(this.secretCode).digest('hex');
|
|
43
|
+
// 🔐 PBKDF2 ile Master Key Türetme (Brute-force'a karşı savunma)
|
|
44
|
+
this.masterKey = crypto.pbkdf2Sync(this.secretCode, SALT, PBKDF2_ITERATIONS, KEY_LENGTH, 'sha256');
|
|
45
|
+
// Session Key (PFS için rotasyonlu)
|
|
46
|
+
this.sessionKey = this.deriveSessionKey(0);
|
|
47
|
+
}
|
|
48
|
+
// 🔐 Session Key Türetme (Perfect Forward Secrecy)
|
|
49
|
+
deriveSessionKey(counter) {
|
|
50
|
+
return crypto.pbkdf2Sync(this.masterKey, `session-${counter}`, 10000, KEY_LENGTH, 'sha256');
|
|
51
|
+
}
|
|
52
|
+
// 🔄 Key Rotation (Her 10 dakikada bir)
|
|
53
|
+
rotateKey() {
|
|
54
|
+
this.sessionCounter++;
|
|
55
|
+
this.sessionKey = this.deriveSessionKey(this.sessionCounter);
|
|
56
|
+
console.log(chalk.cyan(`🔄 Session key rotated to #${this.sessionCounter}`));
|
|
57
|
+
// Notify peer about key rotation
|
|
58
|
+
this.sendSecurePayload('key_rotation', { counter: this.sessionCounter });
|
|
59
|
+
}
|
|
60
|
+
// 🧹 Güvenlik Bakımı
|
|
61
|
+
startSecurityMaintenance() {
|
|
62
|
+
// Nonce temizliği (5 dakikadan eski nonce'ları sil)
|
|
63
|
+
this.nonceCleanupInterval = setInterval(() => {
|
|
64
|
+
this.seenNonces.clear();
|
|
65
|
+
}, MESSAGE_MAX_AGE);
|
|
66
|
+
// Key rotation
|
|
67
|
+
this.keyRotationInterval = setInterval(() => {
|
|
68
|
+
this.rotateKey();
|
|
69
|
+
}, KEY_ROTATION_INTERVAL);
|
|
30
70
|
}
|
|
31
71
|
// 2. Terminal (PTY) Başlatma
|
|
32
72
|
initPTY() {
|
|
@@ -55,8 +95,6 @@ export class ZKRelayAgent {
|
|
|
55
95
|
this.spinner.succeed(chalk.green('Connected to Relay Node!'));
|
|
56
96
|
// Odaya Katıl (Sadece Hash ID gönderilir)
|
|
57
97
|
this.socket.emit('join_room', { code: this.roomId, type: 'agent' });
|
|
58
|
-
// Note: Changed 'join_secure_room' to 'join_room' to match server implementation
|
|
59
|
-
// Server implementation in index.ts: socket.on('join_room', (data: { code: string; type: 'agent' | 'client' }) => ...)
|
|
60
98
|
this.printBanner();
|
|
61
99
|
});
|
|
62
100
|
this.socket.on('disconnect', () => {
|
|
@@ -68,27 +106,7 @@ export class ZKRelayAgent {
|
|
|
68
106
|
this.sendEnvInfo();
|
|
69
107
|
});
|
|
70
108
|
// Mobilden şifreli veri geldiğinde
|
|
71
|
-
// RelayManager emits 'term_data' and 'meta_data'.
|
|
72
|
-
// Server implementation:
|
|
73
|
-
// socket.on('term_data', ...) -> pass through term_data
|
|
74
|
-
// socket.on('meta_data', ...) -> pass through meta_data
|
|
75
|
-
// Agent connects to /, Server index.ts uses / (global namespace) BUT has:
|
|
76
|
-
// const relayNamespace = io.of('/terminal');
|
|
77
|
-
// WAIT. Previous user setup had /terminal.
|
|
78
|
-
// My previous edit REMOVED /terminal and used RelayManager on root io.
|
|
79
|
-
// But RelayManager implementation listens on 'relay_data'.
|
|
80
|
-
// My RelayManager uses: socket.on('relay_data', ...)
|
|
81
|
-
// But user snippet provided for Agent uses 'relay_encrypted' and listens on 'stream_encrypted'.
|
|
82
|
-
// I need to align Agent and Server.
|
|
83
|
-
// The previous edit to server/index.ts instantiates RelayManager.
|
|
84
|
-
// RelayManager listens to 'relay_data'.
|
|
85
|
-
// So the Agent MUST emit 'relay_data'.
|
|
86
109
|
this.socket.on('relay_data', (message) => {
|
|
87
|
-
// RelayManager checks payload structure?
|
|
88
|
-
// Wait, RelayManager implementation:
|
|
89
|
-
// socket.on('relay_data', (data) => { ... socket.to(room).emit('relay_data', data.payload) ... })
|
|
90
|
-
// So client receives `payload`.
|
|
91
|
-
// If payload is encrypted string, handle it.
|
|
92
110
|
this.handleIncomingMessage(message);
|
|
93
111
|
});
|
|
94
112
|
// Also listen for connect_error
|
|
@@ -96,73 +114,190 @@ export class ZKRelayAgent {
|
|
|
96
114
|
// console.error(err);
|
|
97
115
|
});
|
|
98
116
|
}
|
|
117
|
+
// 🔐 AES-256-CBC ile Şifreleme (Nonce tabanlı)
|
|
118
|
+
encrypt(data) {
|
|
119
|
+
const nonce = crypto.randomBytes(16);
|
|
120
|
+
const cipher = crypto.createCipheriv('aes-256-cbc', this.sessionKey, nonce);
|
|
121
|
+
const encrypted = Buffer.concat([
|
|
122
|
+
cipher.update(data, 'utf8'),
|
|
123
|
+
cipher.final()
|
|
124
|
+
]);
|
|
125
|
+
return {
|
|
126
|
+
nonce: nonce.toString('base64'),
|
|
127
|
+
data: encrypted.toString('base64'),
|
|
128
|
+
timestamp: Date.now()
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// 🔐 AES-256-CBC ile Şifre Çözme (Replay Attack Korumalı)
|
|
132
|
+
decrypt(packet) {
|
|
133
|
+
// Timestamp kontrolü (5 dakikadan eski mesajları reddet)
|
|
134
|
+
if (Date.now() - packet.timestamp > MESSAGE_MAX_AGE) {
|
|
135
|
+
throw new Error('Message too old - potential replay attack');
|
|
136
|
+
}
|
|
137
|
+
// Nonce uniqueness kontrolü (Replay attack önleme)
|
|
138
|
+
if (this.seenNonces.has(packet.nonce)) {
|
|
139
|
+
throw new Error('Replay attack detected - duplicate nonce');
|
|
140
|
+
}
|
|
141
|
+
this.seenNonces.add(packet.nonce);
|
|
142
|
+
const decipher = crypto.createDecipheriv('aes-256-cbc', this.sessionKey, Buffer.from(packet.nonce, 'base64'));
|
|
143
|
+
return Buffer.concat([
|
|
144
|
+
decipher.update(Buffer.from(packet.data, 'base64')),
|
|
145
|
+
decipher.final()
|
|
146
|
+
]).toString('utf8');
|
|
147
|
+
}
|
|
99
148
|
// Gelen veriyi çöz ve işle
|
|
100
149
|
handleIncomingMessage(encryptedPayload) {
|
|
101
150
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (typeof encryptedPayload === 'object' && encryptedPayload.
|
|
105
|
-
|
|
151
|
+
let decryptedText;
|
|
152
|
+
// Yeni format: { nonce, data, timestamp }
|
|
153
|
+
if (typeof encryptedPayload === 'object' && encryptedPayload.nonce) {
|
|
154
|
+
decryptedText = this.decrypt(encryptedPayload);
|
|
155
|
+
}
|
|
156
|
+
// Legacy format: { e: ciphertext } (CryptoJS uyumluluğu)
|
|
157
|
+
else if (typeof encryptedPayload === 'object' && encryptedPayload.e) {
|
|
158
|
+
// Legacy CryptoJS decrypt fallback
|
|
159
|
+
const CryptoJS = require('crypto-js');
|
|
160
|
+
const bytes = CryptoJS.AES.decrypt(encryptedPayload.e, this.secretCode);
|
|
161
|
+
decryptedText = bytes.toString(CryptoJS.enc.Utf8);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return;
|
|
106
165
|
}
|
|
107
|
-
|
|
108
|
-
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
|
109
|
-
if (!originalText)
|
|
166
|
+
if (!decryptedText)
|
|
110
167
|
return;
|
|
111
168
|
// Veri JSON mu? (Resize komutu vs olabilir)
|
|
112
169
|
try {
|
|
113
|
-
const cmd = JSON.parse(
|
|
114
|
-
|
|
115
|
-
|
|
170
|
+
const cmd = JSON.parse(decryptedText);
|
|
171
|
+
// Handle key rotation from peer
|
|
172
|
+
if (cmd.type === 'key_rotation') {
|
|
173
|
+
this.sessionCounter = cmd.counter;
|
|
174
|
+
this.sessionKey = this.deriveSessionKey(this.sessionCounter);
|
|
175
|
+
console.log(chalk.cyan(`🔄 Key synced to session #${this.sessionCounter}`));
|
|
116
176
|
return;
|
|
117
177
|
}
|
|
178
|
+
// 1. Terminal Input (Keystrokes)
|
|
118
179
|
if (cmd.type === 'input') {
|
|
119
180
|
this.ptyProcess.write(cmd.data);
|
|
120
181
|
return;
|
|
121
182
|
}
|
|
122
|
-
//
|
|
183
|
+
// 2. Terminal Resize
|
|
184
|
+
if (cmd.type === 'resize') {
|
|
185
|
+
this.ptyProcess.resize(cmd.cols, cmd.rows);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// 3. Chat Commands (e.g. "ls -la")
|
|
189
|
+
if (cmd.type === 'command') {
|
|
190
|
+
this.ptyProcess.write(cmd.text + '\r');
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// 4. CLI Tool/Button Commands (e.g. "git status")
|
|
194
|
+
if (cmd.type === 'cli_command') {
|
|
195
|
+
this.ptyProcess.write(cmd.command + '\r');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// 5. Tool Calls (File System Access)
|
|
199
|
+
if (cmd.type === 'tool_call') {
|
|
200
|
+
this.handleToolCall(cmd.tool, cmd.data, cmd.id);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
123
203
|
}
|
|
124
204
|
catch (e) {
|
|
125
205
|
// JSON değilse saf terminal girdisidir
|
|
126
|
-
this.ptyProcess.write(
|
|
206
|
+
this.ptyProcess.write(decryptedText);
|
|
127
207
|
}
|
|
128
208
|
}
|
|
129
209
|
catch (error) {
|
|
130
210
|
// Şifre çözülemezse (Yanlış anahtar vb.) sessizce yut
|
|
211
|
+
console.error(chalk.red('Decryption failed:'), error.message);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async handleToolCall(tool, args, id) {
|
|
215
|
+
try {
|
|
216
|
+
let result = null;
|
|
217
|
+
if (tool === 'list_directory') {
|
|
218
|
+
const dirPath = args.path ? path.resolve(args.path) : process.cwd();
|
|
219
|
+
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
220
|
+
const files = entries.map(entry => ({
|
|
221
|
+
name: entry.name,
|
|
222
|
+
type: entry.isDirectory() ? 'directory' : 'file',
|
|
223
|
+
size: 0 // Simplification for speed
|
|
224
|
+
}));
|
|
225
|
+
result = { files };
|
|
226
|
+
}
|
|
227
|
+
else if (tool === 'read_file') {
|
|
228
|
+
const filePath = path.resolve(args.path);
|
|
229
|
+
const content = await fs.promises.readFile(filePath, 'utf-8');
|
|
230
|
+
result = { content };
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
throw new Error(`Unknown tool: ${tool}`);
|
|
234
|
+
}
|
|
235
|
+
this.sendSecurePayload('tool_result', {
|
|
236
|
+
id,
|
|
237
|
+
result
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
this.sendSecurePayload('tool_result', {
|
|
242
|
+
id,
|
|
243
|
+
error: error.message,
|
|
244
|
+
type: 'error'
|
|
245
|
+
});
|
|
131
246
|
}
|
|
132
247
|
}
|
|
133
248
|
// Veriyi şifrele ve gönder
|
|
134
249
|
sendSecurePayload(type, data) {
|
|
135
|
-
let payloadStr =
|
|
136
|
-
if (type === 'meta') {
|
|
250
|
+
let payloadStr = '';
|
|
251
|
+
if (type === 'meta' || type === 'tool_result' || type === 'key_rotation') {
|
|
137
252
|
// Standardize format
|
|
138
|
-
|
|
253
|
+
if (type === 'tool_result') {
|
|
254
|
+
if (data.type === 'error') {
|
|
255
|
+
payloadStr = JSON.stringify({ ...data });
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
payloadStr = JSON.stringify({ type: 'result', ...data });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (type === 'key_rotation') {
|
|
262
|
+
payloadStr = JSON.stringify({ type: 'key_rotation', ...data });
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
payloadStr = JSON.stringify(data);
|
|
266
|
+
}
|
|
139
267
|
}
|
|
140
|
-
else if (type === 'term_data'
|
|
141
|
-
// Wrap output in { type: 'output', data: ... }
|
|
142
|
-
|
|
143
|
-
|
|
268
|
+
else if (type === 'term_data') {
|
|
269
|
+
// Wrap output in { type: 'output', data: ... }
|
|
270
|
+
if (typeof data === 'string') {
|
|
271
|
+
payloadStr = JSON.stringify({ type: 'output', data: data });
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
payloadStr = JSON.stringify(data);
|
|
275
|
+
}
|
|
144
276
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
277
|
+
// Fallback if empty (shouldn't happen with above logic)
|
|
278
|
+
if (!payloadStr)
|
|
279
|
+
payloadStr = JSON.stringify(data);
|
|
280
|
+
// 🔐 Yeni şifreleme formatı ile gönder
|
|
281
|
+
const encrypted = this.encrypt(payloadStr);
|
|
148
282
|
this.socket.emit('relay_data', {
|
|
149
283
|
room: this.roomId,
|
|
150
|
-
payload:
|
|
284
|
+
payload: encrypted
|
|
151
285
|
});
|
|
152
286
|
}
|
|
153
287
|
sendEnvInfo() {
|
|
154
288
|
const info = {
|
|
155
|
-
type: 'host_info',
|
|
156
|
-
username: os.userInfo().username,
|
|
157
|
-
hostname: os.hostname(),
|
|
289
|
+
type: 'host_info',
|
|
290
|
+
username: os.userInfo().username,
|
|
291
|
+
hostname: os.hostname(),
|
|
158
292
|
platform: os.platform(),
|
|
159
293
|
cwd: process.cwd()
|
|
160
294
|
};
|
|
161
295
|
this.sendSecurePayload('meta', info);
|
|
162
296
|
}
|
|
163
297
|
printBanner() {
|
|
164
|
-
console.log('\n' + chalk.bgBlue.bold(' MOBILECODER ZK-RELAY v2.0 '));
|
|
165
|
-
console.log(chalk.gray('
|
|
298
|
+
console.log('\n' + chalk.bgBlue.bold(' MOBILECODER ZK-RELAY v2.1.0 '));
|
|
299
|
+
console.log(chalk.gray('🔐 PBKDF2-SHA256 + AES-256-CBC + Nonce-Based Replay Protection'));
|
|
300
|
+
console.log(chalk.gray('🔄 Perfect Forward Secrecy with 10-min Key Rotation\n'));
|
|
166
301
|
console.log(chalk.yellow('┌──────────────────────────────────────┐'));
|
|
167
302
|
console.log(chalk.yellow('│ 🔑 CONNECTION CODE (ENTER ON APP) │'));
|
|
168
303
|
console.log(chalk.yellow('│ │'));
|
|
@@ -171,5 +306,16 @@ export class ZKRelayAgent {
|
|
|
171
306
|
console.log(chalk.yellow('└──────────────────────────────────────┘'));
|
|
172
307
|
console.log(chalk.cyan('\nWaiting for mobile connection...'));
|
|
173
308
|
}
|
|
309
|
+
// Cleanup
|
|
310
|
+
destroy() {
|
|
311
|
+
if (this.nonceCleanupInterval)
|
|
312
|
+
clearInterval(this.nonceCleanupInterval);
|
|
313
|
+
if (this.keyRotationInterval)
|
|
314
|
+
clearInterval(this.keyRotationInterval);
|
|
315
|
+
if (this.socket)
|
|
316
|
+
this.socket.disconnect();
|
|
317
|
+
if (this.ptyProcess)
|
|
318
|
+
this.ptyProcess.kill();
|
|
319
|
+
}
|
|
174
320
|
}
|
|
175
321
|
//# sourceMappingURL=agent.js.map
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAU,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,6CAA6C;AAC7C,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAEvD,qBAAqB;AACrB,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,WAAW;AAClC,MAAM,IAAI,GAAG,qBAAqB,CAAC;AACnC,MAAM,qBAAqB,GAAG,MAAM,CAAC,CAAC,aAAa;AACnD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,YAAY;AAE5C,MAAM,OAAO,YAAY;IACb,MAAM,CAAS;IACf,UAAU,CAAM;IAChB,UAAU,CAAS;IACnB,MAAM,CAAS;IAEvB,0CAA0C;IAClC,SAAS,CAAS;IAClB,UAAU,CAAS;IACnB,cAAc,GAAW,CAAC,CAAC;IAC3B,UAAU,GAAgB,IAAI,GAAG,EAAE,CAAC;IACpC,oBAAoB,GAA0B,IAAI,CAAC;IACnD,mBAAmB,GAA0B,IAAI,CAAC;IAElD,OAAO,GAAG,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAEvD;QACI,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACpC,CAAC;IAED,iEAAiE;IACzD,aAAa;QACjB,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QAEvC,mEAAmE;QACnE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEhF,iEAAiE;QACjE,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAC9B,IAAI,CAAC,UAAU,EACf,IAAI,EACJ,iBAAiB,EACjB,UAAU,EACV,QAAQ,CACX,CAAC;QAEF,oCAAoC;QACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,mDAAmD;IAC3C,gBAAgB,CAAC,OAAe;QACpC,OAAO,MAAM,CAAC,UAAU,CACpB,IAAI,CAAC,SAAS,EACd,WAAW,OAAO,EAAE,EACpB,KAAK,EACL,UAAU,EACV,QAAQ,CACX,CAAC;IACN,CAAC;IAED,wCAAwC;IAChC,SAAS;QACb,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAE7E,iCAAiC;QACjC,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,qBAAqB;IACb,wBAAwB;QAC5B,oDAAoD;QACpD,IAAI,CAAC,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;YACzC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC,EAAE,eAAe,CAAC,CAAC;QAEpB,eAAe;QACf,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;YACxC,IAAI,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAC9B,CAAC;IAED,6BAA6B;IACrB,OAAO;QACX,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QAE3F,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACnC,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,EAAE;YACR,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;SACnB,CAAC,CAAC;QAEH,4CAA4C;QAC5C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;YACpC,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACP,CAAC;IAED,+BAA+B;IACvB,cAAc;QAClB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAEjE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,gBAAgB,EAAE;YAC/B,UAAU,EAAE,CAAC,WAAW,CAAC,EAAE,4BAA4B;YACvD,YAAY,EAAE,IAAI;YAClB,oBAAoB,EAAE,QAAQ;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAE9D,0CAA0C;YAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAEpE,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,8BAA8B;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,OAAuC,EAAE,EAAE;YACrE,IAAI,CAAC,qBAAqB,CAAC,OAAc,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,gCAAgC;QAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE;YACpC,sBAAsB;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,+CAA+C;IACvC,OAAO,CAAC,IAAY;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE5E,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;YAC3B,MAAM,CAAC,KAAK,EAAE;SACjB,CAAC,CAAC;QAEH,OAAO;YACH,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC/B,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAClC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAC;IACN,CAAC;IAED,0DAA0D;IAClD,OAAO,CAAC,MAA0D;QACtE,yDAAyD;QACzD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,eAAe,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,CAAC;QAED,mDAAmD;QACnD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAElC,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CACpC,aAAa,EACb,IAAI,CAAC,UAAU,EACf,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CACtC,CAAC;QAEF,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnD,QAAQ,CAAC,KAAK,EAAE;SACnB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,2BAA2B;IACnB,qBAAqB,CAAC,gBAAqB;QAC/C,IAAI,CAAC;YACD,IAAI,aAAqB,CAAC;YAE1B,0CAA0C;YAC1C,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;gBACjE,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACnD,CAAC;YACD,yDAAyD;iBACpD,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,CAAC,CAAC,EAAE,CAAC;gBAClE,mCAAmC;gBACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;gBACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACxE,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC;iBACI,CAAC;gBACF,OAAO;YACX,CAAC;YAED,IAAI,CAAC,aAAa;gBAAE,OAAO;YAE3B,4CAA4C;YAC5C,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBAEtC,gCAAgC;gBAChC,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAC9B,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC;oBAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;oBAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;oBAC5E,OAAO;gBACX,CAAC;gBAED,iCAAiC;gBACjC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAChC,OAAO;gBACX,CAAC;gBAED,qBAAqB;gBACrB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACxB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC3C,OAAO;gBACX,CAAC;gBAED,mCAAmC;gBACnC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;oBACvC,OAAO;gBACX,CAAC;gBAED,kDAAkD;gBAClD,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBAC7B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;oBAC1C,OAAO;gBACX,CAAC;gBAED,qCAAqC;gBACrC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChD,OAAO;gBACX,CAAC;YAEL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,uCAAuC;gBACvC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACzC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,sDAAsD;YACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAAS,EAAE,EAAU;QAC5D,IAAI,CAAC;YACD,IAAI,MAAM,GAAQ,IAAI,CAAC;YAEvB,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACpE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE5E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAChC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;oBAChD,IAAI,EAAE,CAAC,CAAC,2BAA2B;iBACtC,CAAC,CAAC,CAAC;gBAEJ,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC;YACvB,CAAC;iBAEI,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC9D,MAAM,GAAG,EAAE,OAAO,EAAE,CAAC;YACzB,CAAC;iBACI,CAAC;gBACF,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE;gBAClC,EAAE;gBACF,MAAM;aACT,CAAC,CAAC;QAEP,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE;gBAClC,EAAE;gBACF,KAAK,EAAE,KAAK,CAAC,OAAO;gBACpB,IAAI,EAAE,OAAO;aAChB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,2BAA2B;IACnB,iBAAiB,CAAC,IAAY,EAAE,IAAS;QAC7C,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACvE,qBAAqB;YACrB,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACxB,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;gBAC7C,CAAC;qBAAM,CAAC;oBACJ,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBACjC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACJ,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,+CAA+C;YAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACJ,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;QAED,wDAAwD;QACxD,IAAI,CAAC,UAAU;YAAE,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAEnD,uCAAuC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE;YAC3B,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,OAAO,EAAE,SAAS;SACrB,CAAC,CAAC;IACP,CAAC;IAEO,WAAW;QACf,MAAM,IAAI,GAAG;YACT,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ;YAChC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;YACvB,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;YACvB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;SACrB,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAEO,WAAW;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;QAEjF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9I,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,UAAU;IACH,OAAO;QACV,IAAI,IAAI,CAAC,oBAAoB;YAAE,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACxE,IAAI,IAAI,CAAC,mBAAmB;YAAE,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;CACJ"}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -2,38 +2,99 @@
|
|
|
2
2
|
import { io, Socket } from 'socket.io-client';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as pty from 'node-pty';
|
|
5
|
-
import
|
|
5
|
+
import * as crypto from 'crypto';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import ora from 'ora';
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
8
10
|
|
|
9
11
|
// 🚨 BURAYI KENDİ DOMAIN ADRESİNLE DEĞİŞTİR!
|
|
10
12
|
const RELAY_SERVER_URL = 'https://api.mobilecoder.xyz';
|
|
11
13
|
|
|
14
|
+
// Security Constants
|
|
15
|
+
const PBKDF2_ITERATIONS = 100000;
|
|
16
|
+
const KEY_LENGTH = 32; // 256 bits
|
|
17
|
+
const SALT = 'mobilecoder-salt-v2';
|
|
18
|
+
const KEY_ROTATION_INTERVAL = 600000; // 10 minutes
|
|
19
|
+
const MESSAGE_MAX_AGE = 300000; // 5 minutes
|
|
20
|
+
|
|
12
21
|
export class ZKRelayAgent {
|
|
13
22
|
private socket: Socket;
|
|
14
23
|
private ptyProcess: any;
|
|
15
24
|
private secretCode: string;
|
|
16
25
|
private roomId: string;
|
|
17
|
-
|
|
26
|
+
|
|
27
|
+
// 🔐 Güçlendirilmiş Güvenlik Değişkenleri
|
|
28
|
+
private masterKey: Buffer;
|
|
29
|
+
private sessionKey: Buffer;
|
|
30
|
+
private sessionCounter: number = 0;
|
|
31
|
+
private seenNonces: Set<string> = new Set();
|
|
32
|
+
private nonceCleanupInterval: NodeJS.Timeout | null = null;
|
|
33
|
+
private keyRotationInterval: NodeJS.Timeout | null = null;
|
|
34
|
+
|
|
18
35
|
private spinner = ora('Initializing Secure Tunnel...');
|
|
19
36
|
|
|
20
37
|
constructor() {
|
|
21
38
|
this.setupSecurity();
|
|
22
39
|
this.initPTY();
|
|
23
40
|
this.connectToRelay();
|
|
41
|
+
this.startSecurityMaintenance();
|
|
24
42
|
}
|
|
25
43
|
|
|
26
|
-
// 1. Güvenlik Katmanı:
|
|
44
|
+
// 1. Güvenlik Katmanı: PBKDF2 ile Güçlendirilmiş Anahtar Türetme
|
|
27
45
|
private setupSecurity() {
|
|
28
46
|
// 6 Haneli rastgele kod (Kullanıcının göreceği)
|
|
29
47
|
const randomNum = Math.floor(100000 + Math.random() * 900000);
|
|
30
48
|
this.secretCode = randomNum.toString();
|
|
31
49
|
|
|
32
50
|
// Oda ID'si: Kodun Hash'i (Sunucu sadece bunu görür, kodu göremez)
|
|
33
|
-
this.roomId =
|
|
51
|
+
this.roomId = crypto.createHash('sha256').update(this.secretCode).digest('hex');
|
|
52
|
+
|
|
53
|
+
// 🔐 PBKDF2 ile Master Key Türetme (Brute-force'a karşı savunma)
|
|
54
|
+
this.masterKey = crypto.pbkdf2Sync(
|
|
55
|
+
this.secretCode,
|
|
56
|
+
SALT,
|
|
57
|
+
PBKDF2_ITERATIONS,
|
|
58
|
+
KEY_LENGTH,
|
|
59
|
+
'sha256'
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Session Key (PFS için rotasyonlu)
|
|
63
|
+
this.sessionKey = this.deriveSessionKey(0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 🔐 Session Key Türetme (Perfect Forward Secrecy)
|
|
67
|
+
private deriveSessionKey(counter: number): Buffer {
|
|
68
|
+
return crypto.pbkdf2Sync(
|
|
69
|
+
this.masterKey,
|
|
70
|
+
`session-${counter}`,
|
|
71
|
+
10000,
|
|
72
|
+
KEY_LENGTH,
|
|
73
|
+
'sha256'
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 🔄 Key Rotation (Her 10 dakikada bir)
|
|
78
|
+
private rotateKey() {
|
|
79
|
+
this.sessionCounter++;
|
|
80
|
+
this.sessionKey = this.deriveSessionKey(this.sessionCounter);
|
|
81
|
+
console.log(chalk.cyan(`🔄 Session key rotated to #${this.sessionCounter}`));
|
|
34
82
|
|
|
35
|
-
//
|
|
36
|
-
this.
|
|
83
|
+
// Notify peer about key rotation
|
|
84
|
+
this.sendSecurePayload('key_rotation', { counter: this.sessionCounter });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 🧹 Güvenlik Bakımı
|
|
88
|
+
private startSecurityMaintenance() {
|
|
89
|
+
// Nonce temizliği (5 dakikadan eski nonce'ları sil)
|
|
90
|
+
this.nonceCleanupInterval = setInterval(() => {
|
|
91
|
+
this.seenNonces.clear();
|
|
92
|
+
}, MESSAGE_MAX_AGE);
|
|
93
|
+
|
|
94
|
+
// Key rotation
|
|
95
|
+
this.keyRotationInterval = setInterval(() => {
|
|
96
|
+
this.rotateKey();
|
|
97
|
+
}, KEY_ROTATION_INTERVAL);
|
|
37
98
|
}
|
|
38
99
|
|
|
39
100
|
// 2. Terminal (PTY) Başlatma
|
|
@@ -69,8 +130,6 @@ export class ZKRelayAgent {
|
|
|
69
130
|
|
|
70
131
|
// Odaya Katıl (Sadece Hash ID gönderilir)
|
|
71
132
|
this.socket.emit('join_room', { code: this.roomId, type: 'agent' });
|
|
72
|
-
// Note: Changed 'join_secure_room' to 'join_room' to match server implementation
|
|
73
|
-
// Server implementation in index.ts: socket.on('join_room', (data: { code: string; type: 'agent' | 'client' }) => ...)
|
|
74
133
|
|
|
75
134
|
this.printBanner();
|
|
76
135
|
});
|
|
@@ -80,34 +139,13 @@ export class ZKRelayAgent {
|
|
|
80
139
|
});
|
|
81
140
|
|
|
82
141
|
// Mobilden biri bağlandığında
|
|
83
|
-
this.socket.on('peer_joined', () => {
|
|
142
|
+
this.socket.on('peer_joined', () => {
|
|
84
143
|
console.log(chalk.green('\n📱 Mobile Client Connected via Encrypted Tunnel!'));
|
|
85
144
|
this.sendEnvInfo();
|
|
86
145
|
});
|
|
87
146
|
|
|
88
147
|
// Mobilden şifreli veri geldiğinde
|
|
89
|
-
// RelayManager emits 'term_data' and 'meta_data'.
|
|
90
|
-
// Server implementation:
|
|
91
|
-
// socket.on('term_data', ...) -> pass through term_data
|
|
92
|
-
// socket.on('meta_data', ...) -> pass through meta_data
|
|
93
|
-
// Agent connects to /, Server index.ts uses / (global namespace) BUT has:
|
|
94
|
-
// const relayNamespace = io.of('/terminal');
|
|
95
|
-
// WAIT. Previous user setup had /terminal.
|
|
96
|
-
// My previous edit REMOVED /terminal and used RelayManager on root io.
|
|
97
|
-
// But RelayManager implementation listens on 'relay_data'.
|
|
98
|
-
// My RelayManager uses: socket.on('relay_data', ...)
|
|
99
|
-
// But user snippet provided for Agent uses 'relay_encrypted' and listens on 'stream_encrypted'.
|
|
100
|
-
// I need to align Agent and Server.
|
|
101
|
-
// The previous edit to server/index.ts instantiates RelayManager.
|
|
102
|
-
// RelayManager listens to 'relay_data'.
|
|
103
|
-
// So the Agent MUST emit 'relay_data'.
|
|
104
|
-
|
|
105
148
|
this.socket.on('relay_data', (message: { room: string, payload: any }) => {
|
|
106
|
-
// RelayManager checks payload structure?
|
|
107
|
-
// Wait, RelayManager implementation:
|
|
108
|
-
// socket.on('relay_data', (data) => { ... socket.to(room).emit('relay_data', data.payload) ... })
|
|
109
|
-
// So client receives `payload`.
|
|
110
|
-
// If payload is encrypted string, handle it.
|
|
111
149
|
this.handleIncomingMessage(message as any);
|
|
112
150
|
});
|
|
113
151
|
|
|
@@ -117,68 +155,205 @@ export class ZKRelayAgent {
|
|
|
117
155
|
});
|
|
118
156
|
}
|
|
119
157
|
|
|
158
|
+
// 🔐 AES-256-CBC ile Şifreleme (Nonce tabanlı)
|
|
159
|
+
private encrypt(data: string): { nonce: string; data: string; timestamp: number } {
|
|
160
|
+
const nonce = crypto.randomBytes(16);
|
|
161
|
+
const cipher = crypto.createCipheriv('aes-256-cbc', this.sessionKey, nonce);
|
|
162
|
+
|
|
163
|
+
const encrypted = Buffer.concat([
|
|
164
|
+
cipher.update(data, 'utf8'),
|
|
165
|
+
cipher.final()
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
nonce: nonce.toString('base64'),
|
|
170
|
+
data: encrypted.toString('base64'),
|
|
171
|
+
timestamp: Date.now()
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 🔐 AES-256-CBC ile Şifre Çözme (Replay Attack Korumalı)
|
|
176
|
+
private decrypt(packet: { nonce: string; data: string; timestamp: number }): string {
|
|
177
|
+
// Timestamp kontrolü (5 dakikadan eski mesajları reddet)
|
|
178
|
+
if (Date.now() - packet.timestamp > MESSAGE_MAX_AGE) {
|
|
179
|
+
throw new Error('Message too old - potential replay attack');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Nonce uniqueness kontrolü (Replay attack önleme)
|
|
183
|
+
if (this.seenNonces.has(packet.nonce)) {
|
|
184
|
+
throw new Error('Replay attack detected - duplicate nonce');
|
|
185
|
+
}
|
|
186
|
+
this.seenNonces.add(packet.nonce);
|
|
187
|
+
|
|
188
|
+
const decipher = crypto.createDecipheriv(
|
|
189
|
+
'aes-256-cbc',
|
|
190
|
+
this.sessionKey,
|
|
191
|
+
Buffer.from(packet.nonce, 'base64')
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
return Buffer.concat([
|
|
195
|
+
decipher.update(Buffer.from(packet.data, 'base64')),
|
|
196
|
+
decipher.final()
|
|
197
|
+
]).toString('utf8');
|
|
198
|
+
}
|
|
199
|
+
|
|
120
200
|
// Gelen veriyi çöz ve işle
|
|
121
201
|
private handleIncomingMessage(encryptedPayload: any) {
|
|
122
202
|
try {
|
|
123
|
-
|
|
124
|
-
let ciphertext = encryptedPayload;
|
|
125
|
-
if (typeof encryptedPayload === 'object' && encryptedPayload.e) {
|
|
126
|
-
ciphertext = encryptedPayload.e;
|
|
127
|
-
}
|
|
203
|
+
let decryptedText: string;
|
|
128
204
|
|
|
129
|
-
|
|
130
|
-
|
|
205
|
+
// Yeni format: { nonce, data, timestamp }
|
|
206
|
+
if (typeof encryptedPayload === 'object' && encryptedPayload.nonce) {
|
|
207
|
+
decryptedText = this.decrypt(encryptedPayload);
|
|
208
|
+
}
|
|
209
|
+
// Legacy format: { e: ciphertext } (CryptoJS uyumluluğu)
|
|
210
|
+
else if (typeof encryptedPayload === 'object' && encryptedPayload.e) {
|
|
211
|
+
// Legacy CryptoJS decrypt fallback
|
|
212
|
+
const CryptoJS = require('crypto-js');
|
|
213
|
+
const bytes = CryptoJS.AES.decrypt(encryptedPayload.e, this.secretCode);
|
|
214
|
+
decryptedText = bytes.toString(CryptoJS.enc.Utf8);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
131
219
|
|
|
132
|
-
if (!
|
|
220
|
+
if (!decryptedText) return;
|
|
133
221
|
|
|
134
222
|
// Veri JSON mu? (Resize komutu vs olabilir)
|
|
135
223
|
try {
|
|
136
|
-
const cmd = JSON.parse(
|
|
137
|
-
|
|
138
|
-
|
|
224
|
+
const cmd = JSON.parse(decryptedText);
|
|
225
|
+
|
|
226
|
+
// Handle key rotation from peer
|
|
227
|
+
if (cmd.type === 'key_rotation') {
|
|
228
|
+
this.sessionCounter = cmd.counter;
|
|
229
|
+
this.sessionKey = this.deriveSessionKey(this.sessionCounter);
|
|
230
|
+
console.log(chalk.cyan(`🔄 Key synced to session #${this.sessionCounter}`));
|
|
139
231
|
return;
|
|
140
232
|
}
|
|
233
|
+
|
|
234
|
+
// 1. Terminal Input (Keystrokes)
|
|
141
235
|
if (cmd.type === 'input') {
|
|
142
236
|
this.ptyProcess.write(cmd.data);
|
|
143
237
|
return;
|
|
144
238
|
}
|
|
145
|
-
|
|
239
|
+
|
|
240
|
+
// 2. Terminal Resize
|
|
241
|
+
if (cmd.type === 'resize') {
|
|
242
|
+
this.ptyProcess.resize(cmd.cols, cmd.rows);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// 3. Chat Commands (e.g. "ls -la")
|
|
247
|
+
if (cmd.type === 'command') {
|
|
248
|
+
this.ptyProcess.write(cmd.text + '\r');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// 4. CLI Tool/Button Commands (e.g. "git status")
|
|
253
|
+
if (cmd.type === 'cli_command') {
|
|
254
|
+
this.ptyProcess.write(cmd.command + '\r');
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// 5. Tool Calls (File System Access)
|
|
259
|
+
if (cmd.type === 'tool_call') {
|
|
260
|
+
this.handleToolCall(cmd.tool, cmd.data, cmd.id);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
146
264
|
} catch (e) {
|
|
147
265
|
// JSON değilse saf terminal girdisidir
|
|
148
|
-
this.ptyProcess.write(
|
|
266
|
+
this.ptyProcess.write(decryptedText);
|
|
149
267
|
}
|
|
150
268
|
} catch (error) {
|
|
151
269
|
// Şifre çözülemezse (Yanlış anahtar vb.) sessizce yut
|
|
270
|
+
console.error(chalk.red('Decryption failed:'), (error as Error).message);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private async handleToolCall(tool: string, args: any, id: string) {
|
|
275
|
+
try {
|
|
276
|
+
let result: any = null;
|
|
277
|
+
|
|
278
|
+
if (tool === 'list_directory') {
|
|
279
|
+
const dirPath = args.path ? path.resolve(args.path) : process.cwd();
|
|
280
|
+
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
281
|
+
|
|
282
|
+
const files = entries.map(entry => ({
|
|
283
|
+
name: entry.name,
|
|
284
|
+
type: entry.isDirectory() ? 'directory' : 'file',
|
|
285
|
+
size: 0 // Simplification for speed
|
|
286
|
+
}));
|
|
287
|
+
|
|
288
|
+
result = { files };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
else if (tool === 'read_file') {
|
|
292
|
+
const filePath = path.resolve(args.path);
|
|
293
|
+
const content = await fs.promises.readFile(filePath, 'utf-8');
|
|
294
|
+
result = { content };
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
throw new Error(`Unknown tool: ${tool}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
this.sendSecurePayload('tool_result', {
|
|
301
|
+
id,
|
|
302
|
+
result
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
} catch (error: any) {
|
|
306
|
+
this.sendSecurePayload('tool_result', {
|
|
307
|
+
id,
|
|
308
|
+
error: error.message,
|
|
309
|
+
type: 'error'
|
|
310
|
+
});
|
|
152
311
|
}
|
|
153
312
|
}
|
|
154
313
|
|
|
155
314
|
// Veriyi şifrele ve gönder
|
|
156
315
|
private sendSecurePayload(type: string, data: any) {
|
|
157
|
-
let payloadStr =
|
|
158
|
-
|
|
316
|
+
let payloadStr = '';
|
|
317
|
+
|
|
318
|
+
if (type === 'meta' || type === 'tool_result' || type === 'key_rotation') {
|
|
159
319
|
// Standardize format
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
320
|
+
if (type === 'tool_result') {
|
|
321
|
+
if (data.type === 'error') {
|
|
322
|
+
payloadStr = JSON.stringify({ ...data });
|
|
323
|
+
} else {
|
|
324
|
+
payloadStr = JSON.stringify({ type: 'result', ...data });
|
|
325
|
+
}
|
|
326
|
+
} else if (type === 'key_rotation') {
|
|
327
|
+
payloadStr = JSON.stringify({ type: 'key_rotation', ...data });
|
|
328
|
+
} else {
|
|
329
|
+
payloadStr = JSON.stringify(data);
|
|
330
|
+
}
|
|
331
|
+
} else if (type === 'term_data') {
|
|
332
|
+
// Wrap output in { type: 'output', data: ... }
|
|
333
|
+
if (typeof data === 'string') {
|
|
334
|
+
payloadStr = JSON.stringify({ type: 'output', data: data });
|
|
335
|
+
} else {
|
|
336
|
+
payloadStr = JSON.stringify(data);
|
|
337
|
+
}
|
|
165
338
|
}
|
|
166
339
|
|
|
167
|
-
|
|
340
|
+
// Fallback if empty (shouldn't happen with above logic)
|
|
341
|
+
if (!payloadStr) payloadStr = JSON.stringify(data);
|
|
342
|
+
|
|
343
|
+
// 🔐 Yeni şifreleme formatı ile gönder
|
|
344
|
+
const encrypted = this.encrypt(payloadStr);
|
|
168
345
|
|
|
169
|
-
// RelayManager expects 'relay_data' event with { room, payload }
|
|
170
|
-
// It emits 'relay_data' with just payload to other peer.
|
|
171
346
|
this.socket.emit('relay_data', {
|
|
172
347
|
room: this.roomId,
|
|
173
|
-
payload:
|
|
348
|
+
payload: encrypted
|
|
174
349
|
});
|
|
175
350
|
}
|
|
176
351
|
|
|
177
352
|
private sendEnvInfo() {
|
|
178
353
|
const info = {
|
|
179
|
-
type: 'host_info',
|
|
180
|
-
username: os.userInfo().username,
|
|
181
|
-
hostname: os.hostname(),
|
|
354
|
+
type: 'host_info',
|
|
355
|
+
username: os.userInfo().username,
|
|
356
|
+
hostname: os.hostname(),
|
|
182
357
|
platform: os.platform(),
|
|
183
358
|
cwd: process.cwd()
|
|
184
359
|
};
|
|
@@ -186,8 +361,9 @@ export class ZKRelayAgent {
|
|
|
186
361
|
}
|
|
187
362
|
|
|
188
363
|
private printBanner() {
|
|
189
|
-
console.log('\n' + chalk.bgBlue.bold(' MOBILECODER ZK-RELAY v2.0 '));
|
|
190
|
-
console.log(chalk.gray('
|
|
364
|
+
console.log('\n' + chalk.bgBlue.bold(' MOBILECODER ZK-RELAY v2.1.0 '));
|
|
365
|
+
console.log(chalk.gray('🔐 PBKDF2-SHA256 + AES-256-CBC + Nonce-Based Replay Protection'));
|
|
366
|
+
console.log(chalk.gray('🔄 Perfect Forward Secrecy with 10-min Key Rotation\n'));
|
|
191
367
|
|
|
192
368
|
console.log(chalk.yellow('┌──────────────────────────────────────┐'));
|
|
193
369
|
console.log(chalk.yellow('│ 🔑 CONNECTION CODE (ENTER ON APP) │'));
|
|
@@ -197,4 +373,12 @@ export class ZKRelayAgent {
|
|
|
197
373
|
console.log(chalk.yellow('└──────────────────────────────────────┘'));
|
|
198
374
|
console.log(chalk.cyan('\nWaiting for mobile connection...'));
|
|
199
375
|
}
|
|
376
|
+
|
|
377
|
+
// Cleanup
|
|
378
|
+
public destroy() {
|
|
379
|
+
if (this.nonceCleanupInterval) clearInterval(this.nonceCleanupInterval);
|
|
380
|
+
if (this.keyRotationInterval) clearInterval(this.keyRotationInterval);
|
|
381
|
+
if (this.socket) this.socket.disconnect();
|
|
382
|
+
if (this.ptyProcess) this.ptyProcess.kill();
|
|
383
|
+
}
|
|
200
384
|
}
|