@f2a/network 0.1.3 → 0.2.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.
Files changed (91) hide show
  1. package/README.md +278 -63
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +29 -2
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/config.d.ts +176 -0
  6. package/dist/cli/config.d.ts.map +1 -0
  7. package/dist/cli/config.js +386 -0
  8. package/dist/cli/config.js.map +1 -0
  9. package/dist/cli/daemon.d.ts +54 -0
  10. package/dist/cli/daemon.d.ts.map +1 -0
  11. package/dist/cli/daemon.js +572 -0
  12. package/dist/cli/daemon.js.map +1 -0
  13. package/dist/cli/index.js +90 -16
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/init.d.ts +13 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +352 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/core/e2ee-crypto.d.ts +127 -1
  20. package/dist/core/e2ee-crypto.d.ts.map +1 -1
  21. package/dist/core/e2ee-crypto.js +446 -12
  22. package/dist/core/e2ee-crypto.js.map +1 -1
  23. package/dist/core/f2a.d.ts +2 -1
  24. package/dist/core/f2a.d.ts.map +1 -1
  25. package/dist/core/f2a.js +6 -2
  26. package/dist/core/f2a.js.map +1 -1
  27. package/dist/core/identity/encrypted-key-store.d.ts +19 -0
  28. package/dist/core/identity/encrypted-key-store.d.ts.map +1 -0
  29. package/dist/core/identity/encrypted-key-store.js +72 -0
  30. package/dist/core/identity/encrypted-key-store.js.map +1 -0
  31. package/dist/core/identity/identity-manager.d.ts +133 -0
  32. package/dist/core/identity/identity-manager.d.ts.map +1 -0
  33. package/dist/core/identity/identity-manager.js +454 -0
  34. package/dist/core/identity/identity-manager.js.map +1 -0
  35. package/dist/core/identity/index.d.ts +8 -0
  36. package/dist/core/identity/index.d.ts.map +1 -0
  37. package/dist/core/identity/index.js +7 -0
  38. package/dist/core/identity/index.js.map +1 -0
  39. package/dist/core/identity/types.d.ts +70 -0
  40. package/dist/core/identity/types.d.ts.map +1 -0
  41. package/dist/core/identity/types.js +17 -0
  42. package/dist/core/identity/types.js.map +1 -0
  43. package/dist/core/p2p-network.d.ts +26 -0
  44. package/dist/core/p2p-network.d.ts.map +1 -1
  45. package/dist/core/p2p-network.js +434 -105
  46. package/dist/core/p2p-network.js.map +1 -1
  47. package/dist/core/reputation-security.d.ts +15 -0
  48. package/dist/core/reputation-security.d.ts.map +1 -1
  49. package/dist/core/reputation-security.js +73 -3
  50. package/dist/core/reputation-security.js.map +1 -1
  51. package/dist/core/reputation.d.ts +129 -4
  52. package/dist/core/reputation.d.ts.map +1 -1
  53. package/dist/core/reputation.js +294 -1
  54. package/dist/core/reputation.js.map +1 -1
  55. package/dist/core/review-committee.d.ts +2 -2
  56. package/dist/core/review-committee.d.ts.map +1 -1
  57. package/dist/core/review-committee.js +17 -0
  58. package/dist/core/review-committee.js.map +1 -1
  59. package/dist/daemon/control-server.d.ts.map +1 -1
  60. package/dist/daemon/control-server.js +44 -1
  61. package/dist/daemon/control-server.js.map +1 -1
  62. package/dist/daemon/webhook.d.ts +3 -0
  63. package/dist/daemon/webhook.d.ts.map +1 -1
  64. package/dist/daemon/webhook.js +318 -6
  65. package/dist/daemon/webhook.js.map +1 -1
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +7 -3
  69. package/dist/index.js.map +1 -1
  70. package/dist/types/index.d.ts +4 -0
  71. package/dist/types/index.d.ts.map +1 -1
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/types/result.d.ts +1 -1
  74. package/dist/types/result.d.ts.map +1 -1
  75. package/dist/types/result.js.map +1 -1
  76. package/dist/utils/crypto-utils.d.ts +17 -0
  77. package/dist/utils/crypto-utils.d.ts.map +1 -0
  78. package/dist/utils/crypto-utils.js +28 -0
  79. package/dist/utils/crypto-utils.js.map +1 -0
  80. package/dist/utils/logger.d.ts +1 -0
  81. package/dist/utils/logger.d.ts.map +1 -1
  82. package/dist/utils/logger.js +9 -3
  83. package/dist/utils/logger.js.map +1 -1
  84. package/dist/utils/rate-limiter.d.ts.map +1 -1
  85. package/dist/utils/rate-limiter.js +3 -1
  86. package/dist/utils/rate-limiter.js.map +1 -1
  87. package/dist/utils/signature.d.ts +47 -1
  88. package/dist/utils/signature.d.ts.map +1 -1
  89. package/dist/utils/signature.js +166 -11
  90. package/dist/utils/signature.js.map +1 -1
  91. package/package.json +2 -1
@@ -0,0 +1,572 @@
1
+ /**
2
+ * F2A CLI Daemon Commands
3
+ * Daemon 启动和管理命令
4
+ */
5
+ import { spawn } from 'child_process';
6
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, statSync, renameSync, openSync, closeSync, writeSync } from 'fs';
7
+ import { join, dirname } from 'path';
8
+ import { homedir } from 'os';
9
+ import { request } from 'http';
10
+ import { createServer } from 'net';
11
+ import { fileURLToPath } from 'url';
12
+ const F2A_DIR = join(homedir(), '.f2a');
13
+ const PID_FILE = join(F2A_DIR, 'daemon.pid');
14
+ const LOG_FILE = join(F2A_DIR, 'daemon.log');
15
+ const LOCK_FILE = join(F2A_DIR, 'daemon.lock');
16
+ const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
17
+ // 获取当前模块所在目录(用于定位 daemon 脚本)
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = dirname(__filename);
20
+ /**
21
+ * 确保 .f2a 目录存在
22
+ */
23
+ function ensureF2ADir() {
24
+ if (!existsSync(F2A_DIR)) {
25
+ mkdirSync(F2A_DIR, { recursive: true });
26
+ }
27
+ }
28
+ /**
29
+ * 获取 PID 文件路径
30
+ */
31
+ export function getPidFile() {
32
+ return PID_FILE;
33
+ }
34
+ /**
35
+ * 获取日志文件路径
36
+ */
37
+ export function getLogFile() {
38
+ return LOG_FILE;
39
+ }
40
+ /**
41
+ * 检查进程是否存在
42
+ */
43
+ function isProcessRunning(pid) {
44
+ try {
45
+ process.kill(pid, 0);
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ /**
53
+ * 读取后台 daemon 的 PID
54
+ */
55
+ function readDaemonPid() {
56
+ if (!existsSync(PID_FILE)) {
57
+ return null;
58
+ }
59
+ try {
60
+ const pid = parseInt(readFileSync(PID_FILE, 'utf-8').trim(), 10);
61
+ if (isNaN(pid)) {
62
+ return null;
63
+ }
64
+ return pid;
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ /**
71
+ * 写入 daemon PID 到文件
72
+ */
73
+ function writeDaemonPid(pid) {
74
+ ensureF2ADir();
75
+ writeFileSync(PID_FILE, pid.toString(), 'utf-8');
76
+ }
77
+ /**
78
+ * 删除 PID 文件
79
+ */
80
+ function removePidFile() {
81
+ if (existsSync(PID_FILE)) {
82
+ unlinkSync(PID_FILE);
83
+ }
84
+ }
85
+ /**
86
+ * 获取文件锁(防止竞态条件)
87
+ * @returns 是否成功获取锁
88
+ */
89
+ export function acquireLock() {
90
+ try {
91
+ ensureF2ADir();
92
+ // 检查是否存在过期锁(进程已死亡但锁文件残留)
93
+ if (existsSync(LOCK_FILE)) {
94
+ try {
95
+ const lockPid = parseInt(readFileSync(LOCK_FILE, 'utf-8').trim(), 10);
96
+ if (!isNaN(lockPid) && !isProcessRunning(lockPid)) {
97
+ // 进程已死亡,清理过期锁
98
+ unlinkSync(LOCK_FILE);
99
+ }
100
+ else {
101
+ // 锁被其他活跃进程持有
102
+ return false;
103
+ }
104
+ }
105
+ catch {
106
+ // 无法读取锁文件,尝试删除
107
+ unlinkSync(LOCK_FILE);
108
+ }
109
+ }
110
+ // 尝试创建锁文件(原子操作)
111
+ const fd = openSync(LOCK_FILE, 'wx');
112
+ writeSync(fd, process.pid.toString());
113
+ closeSync(fd);
114
+ return true;
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ }
120
+ /**
121
+ * 释放文件锁(仅释放当前进程持有的锁)
122
+ */
123
+ export function releaseLock() {
124
+ if (!existsSync(LOCK_FILE)) {
125
+ return;
126
+ }
127
+ try {
128
+ // 验证锁文件中的 PID 是否为当前进程,避免误删其他进程的锁
129
+ const lockPid = parseInt(readFileSync(LOCK_FILE, 'utf-8').trim(), 10);
130
+ if (!isNaN(lockPid) && lockPid === process.pid) {
131
+ unlinkSync(LOCK_FILE);
132
+ }
133
+ // 如果 PID 不匹配,说明锁已被其他进程持有,不删除
134
+ }
135
+ catch {
136
+ // 读取失败,可能锁文件已损坏或被删除,忽略
137
+ }
138
+ }
139
+ /**
140
+ * 检查日志文件大小并轮转
141
+ */
142
+ export function rotateLogIfNeeded() {
143
+ if (!existsSync(LOG_FILE)) {
144
+ return;
145
+ }
146
+ try {
147
+ const stats = statSync(LOG_FILE);
148
+ if (stats.size > MAX_LOG_SIZE) {
149
+ const oldLogFile = LOG_FILE + '.old';
150
+ if (existsSync(oldLogFile)) {
151
+ unlinkSync(oldLogFile);
152
+ }
153
+ renameSync(LOG_FILE, oldLogFile);
154
+ }
155
+ }
156
+ catch {
157
+ // 忽略错误
158
+ }
159
+ }
160
+ /**
161
+ * 检查 daemon 是否在运行
162
+ */
163
+ export function isDaemonRunning() {
164
+ const pid = readDaemonPid();
165
+ if (pid === null) {
166
+ return false;
167
+ }
168
+ return isProcessRunning(pid);
169
+ }
170
+ /**
171
+ * 获取控制端口(运行时读取)
172
+ */
173
+ function getControlPort() {
174
+ return parseInt(process.env.F2A_CONTROL_PORT || '9001');
175
+ }
176
+ /**
177
+ * 获取 daemon 状态信息
178
+ */
179
+ export function getDaemonStatus() {
180
+ const pid = readDaemonPid();
181
+ const running = pid !== null && isProcessRunning(pid);
182
+ return {
183
+ running,
184
+ pid: running ? pid : undefined,
185
+ port: getControlPort()
186
+ };
187
+ }
188
+ /**
189
+ * 前台启动 daemon
190
+ */
191
+ export async function startForeground() {
192
+ const controlPort = getControlPort();
193
+ // 检查是否已有 daemon 在运行
194
+ if (isDaemonRunning()) {
195
+ console.error('[F2A] Daemon 已经在运行中');
196
+ console.error('[F2A] 使用 "f2a daemon stop" 停止后再启动');
197
+ process.exit(1);
198
+ }
199
+ // 检查端口是否被占用
200
+ const portInUse = await checkPortInUse(controlPort);
201
+ if (portInUse) {
202
+ console.error(`[F2A] 端口 ${controlPort} 已被占用`);
203
+ console.error('[F2A] 请检查是否有其他 F2A daemon 在运行,或使用 F2A_CONTROL_PORT 环境变量指定其他端口');
204
+ process.exit(1);
205
+ }
206
+ ensureF2ADir();
207
+ rotateLogIfNeeded();
208
+ console.log('[F2A] 启动 daemon (前台模式)...');
209
+ console.log(`[F2A] 控制端口: ${controlPort}`);
210
+ console.log('[F2A] 按 Ctrl+C 停止');
211
+ // 动态导入 daemon 模块并启动
212
+ const { F2ADaemon } = await import('../daemon/index.js');
213
+ // 解析引导节点
214
+ const bootstrapPeers = process.env.BOOTSTRAP_PEERS
215
+ ? process.env.BOOTSTRAP_PEERS.split(',').filter(Boolean)
216
+ : undefined;
217
+ // P2P 端口
218
+ const p2pPort = parseInt(process.env.F2A_P2P_PORT || '0');
219
+ const daemon = new F2ADaemon({
220
+ controlPort,
221
+ network: {
222
+ listenPort: p2pPort,
223
+ bootstrapPeers,
224
+ },
225
+ });
226
+ // 处理信号
227
+ const shutdown = async () => {
228
+ console.log('\n[F2A] 正在停止 daemon...');
229
+ await daemon.stop();
230
+ removePidFile();
231
+ console.log('[F2A] Daemon 已停止');
232
+ process.exit(0);
233
+ };
234
+ process.on('SIGINT', shutdown);
235
+ process.on('SIGTERM', shutdown);
236
+ try {
237
+ await daemon.start();
238
+ console.log(`[F2A] Daemon 已启动,Peer ID: ${daemon.getF2A()?.peerId?.slice(0, 16)}...`);
239
+ // 保持进程运行
240
+ await new Promise((resolve) => {
241
+ process.on('exit', () => resolve());
242
+ });
243
+ }
244
+ catch (error) {
245
+ console.error('[F2A] 启动失败:', error instanceof Error ? error.message : String(error));
246
+ process.exit(1);
247
+ }
248
+ }
249
+ /**
250
+ * 后台启动 daemon
251
+ */
252
+ export async function startBackground() {
253
+ const controlPort = getControlPort();
254
+ // 检查是否已有 daemon 在运行
255
+ if (isDaemonRunning()) {
256
+ console.error('[F2A] Daemon 已经在运行中');
257
+ const status = getDaemonStatus();
258
+ if (status.pid) {
259
+ console.error(`[F2A] PID: ${status.pid}`);
260
+ }
261
+ process.exit(1);
262
+ }
263
+ // 检查端口是否被占用
264
+ const portInUse = await checkPortInUse(controlPort);
265
+ if (portInUse) {
266
+ console.error(`[F2A] 端口 ${controlPort} 已被占用`);
267
+ console.error('[F2A] 请检查是否有其他 F2A daemon 在运行,或使用 F2A_CONTROL_PORT 环境变量指定其他端口');
268
+ process.exit(1);
269
+ }
270
+ ensureF2ADir();
271
+ // 日志轮转
272
+ rotateLogIfNeeded();
273
+ console.log('[F2A] 启动 daemon (后台模式)...');
274
+ console.log(`[F2A] 控制端口: ${controlPort}`);
275
+ console.log(`[F2A] 日志文件: ${LOG_FILE}`);
276
+ // 使用脚本所在目录定位 daemon 脚本,而不是 process.cwd()
277
+ // 这样可以在任何目录执行 f2a daemon 命令
278
+ const nodePath = process.execPath;
279
+ const daemonScript = join(__dirname, '..', '..', 'daemon', 'main.js');
280
+ // 检查 daemon 脚本是否存在
281
+ if (!existsSync(daemonScript)) {
282
+ console.error('[F2A] 错误: 找不到 daemon 脚本');
283
+ console.error('[F2A] 请先运行 npm run build');
284
+ process.exit(1);
285
+ }
286
+ // 构建环境变量
287
+ const env = { ...process.env };
288
+ if (!env.F2A_CONTROL_PORT) {
289
+ env.F2A_CONTROL_PORT = controlPort.toString();
290
+ }
291
+ // 获取文件锁(防止竞态条件)
292
+ if (!acquireLock()) {
293
+ console.error('[F2A] 无法获取锁,可能有其他 daemon 实例正在启动或刚刚启动');
294
+ console.error('[F2A] 请稍后重试,或检查是否有其他 f2a daemon 进程在运行');
295
+ process.exit(1);
296
+ }
297
+ try {
298
+ // 启动后台进程
299
+ const child = spawn(nodePath, [daemonScript], {
300
+ detached: true,
301
+ stdio: ['ignore', 'pipe', 'pipe'],
302
+ env,
303
+ // 使用跨平台的工作目录
304
+ cwd: homedir(),
305
+ });
306
+ // 创建日志写入流
307
+ const { createWriteStream } = await import('fs');
308
+ const logStream = createWriteStream(LOG_FILE, { flags: 'a' });
309
+ child.stdout?.pipe(logStream);
310
+ child.stderr?.pipe(logStream);
311
+ // 等待 daemon 进程启动
312
+ await new Promise((resolve, reject) => {
313
+ const timeout = setTimeout(() => {
314
+ reject(new Error('启动超时'));
315
+ }, 10000);
316
+ let started = false;
317
+ child.on('spawn', () => {
318
+ // 再次检查竞态条件:确保没有其他进程同时写入 PID 文件
319
+ const currentPid = readDaemonPid();
320
+ if (currentPid !== null && currentPid !== child.pid && isProcessRunning(currentPid)) {
321
+ // 另一个进程已启动,终止当前进程
322
+ child.kill();
323
+ removePidFile();
324
+ clearTimeout(timeout);
325
+ reject(new Error('另一个 daemon 实例已启动'));
326
+ return;
327
+ }
328
+ // 写入 PID 文件
329
+ writeDaemonPid(child.pid);
330
+ console.log(`[F2A] Daemon 已启动,PID: ${child.pid}`);
331
+ started = true;
332
+ clearTimeout(timeout);
333
+ resolve();
334
+ });
335
+ child.on('error', (err) => {
336
+ clearTimeout(timeout);
337
+ if (!started) {
338
+ reject(err);
339
+ }
340
+ });
341
+ // 检查进程是否立即退出
342
+ child.on('exit', (code) => {
343
+ clearTimeout(timeout);
344
+ if (!started) {
345
+ reject(new Error(`Daemon 启动失败,退出码: ${code}`));
346
+ }
347
+ });
348
+ });
349
+ // 分离子进程
350
+ child.unref();
351
+ }
352
+ catch (error) {
353
+ // 启动失败,释放锁
354
+ releaseLock();
355
+ throw error;
356
+ }
357
+ // 释放文件锁(daemon 已成功启动)
358
+ releaseLock();
359
+ // 等待 daemon HTTP 服务就绪(轮询 /health 端点)
360
+ // 可通过 F2A_HEALTH_TIMEOUT 环境变量配置超时时间(毫秒,默认 15000)
361
+ console.log('[F2A] 等待 daemon 服务就绪...');
362
+ const healthTimeout = parseInt(process.env.F2A_HEALTH_TIMEOUT || '15000', 10);
363
+ const healthReady = await waitForDaemonHealth(controlPort, healthTimeout);
364
+ if (healthReady) {
365
+ console.log('[F2A] Daemon 服务已就绪');
366
+ }
367
+ else {
368
+ console.warn('[F2A] 警告: Daemon 服务可能未完全就绪,请检查日志');
369
+ }
370
+ console.log('[F2A] 使用 "f2a daemon status" 查看状态');
371
+ console.log('[F2A] 使用 "f2a daemon stop" 停止 daemon');
372
+ }
373
+ /**
374
+ * 停止后台 daemon
375
+ */
376
+ export async function stopDaemon() {
377
+ const pid = readDaemonPid();
378
+ if (pid === null) {
379
+ console.log('[F2A] 没有运行中的 daemon');
380
+ return;
381
+ }
382
+ if (!isProcessRunning(pid)) {
383
+ console.log('[F2A] Daemon 进程已不存在,清理 PID 文件');
384
+ removePidFile();
385
+ return;
386
+ }
387
+ console.log(`[F2A] 正在停止 daemon (PID: ${pid})...`);
388
+ try {
389
+ // 跨平台信号处理
390
+ // Windows 不支持 SIGTERM,使用 SIGKILL 或 taskkill
391
+ const isWindows = process.platform === 'win32';
392
+ if (isWindows) {
393
+ // Windows: 使用 taskkill 强制终止进程树
394
+ const { execSync } = await import('child_process');
395
+ try {
396
+ execSync(`taskkill /pid ${pid} /T /F`, { stdio: 'ignore' });
397
+ }
398
+ catch {
399
+ // 如果 taskkill 失败,尝试使用 process.kill
400
+ process.kill(pid, 'SIGKILL');
401
+ }
402
+ }
403
+ else {
404
+ // Unix: 发送 SIGTERM 信号
405
+ process.kill(pid, 'SIGTERM');
406
+ // 等待进程退出
407
+ let attempts = 0;
408
+ const maxAttempts = 30; // 最多等待 3 秒
409
+ while (attempts < maxAttempts) {
410
+ await new Promise(resolve => setTimeout(resolve, 100));
411
+ if (!isProcessRunning(pid)) {
412
+ break;
413
+ }
414
+ attempts++;
415
+ }
416
+ // 如果进程还在运行,强制终止
417
+ if (isProcessRunning(pid)) {
418
+ console.log('[F2A] Daemon 未响应 SIGTERM,强制终止...');
419
+ process.kill(pid, 'SIGKILL');
420
+ await new Promise(resolve => setTimeout(resolve, 500));
421
+ }
422
+ }
423
+ // 再次检查进程状态
424
+ await new Promise(resolve => setTimeout(resolve, 100));
425
+ if (!isProcessRunning(pid)) {
426
+ console.log('[F2A] Daemon 已停止');
427
+ removePidFile();
428
+ }
429
+ else {
430
+ console.error('[F2A] 无法停止 daemon');
431
+ process.exit(1);
432
+ }
433
+ }
434
+ catch (error) {
435
+ if (error.code === 'EPERM') {
436
+ console.error('[F2A] 没有权限停止 daemon');
437
+ process.exit(1);
438
+ }
439
+ else if (error.code === 'ESRCH') {
440
+ console.log('[F2A] Daemon 进程已不存在');
441
+ removePidFile();
442
+ }
443
+ else {
444
+ throw error;
445
+ }
446
+ }
447
+ }
448
+ /**
449
+ * 显示 daemon 状态
450
+ */
451
+ export async function showStatus() {
452
+ const status = getDaemonStatus();
453
+ const port = getControlPort();
454
+ console.log('F2A Daemon 状态:');
455
+ console.log(` 运行中: ${status.running ? '是' : '否'}`);
456
+ console.log(` 控制端口: ${port}`);
457
+ if (status.running && status.pid) {
458
+ console.log(` PID: ${status.pid}`);
459
+ console.log(` 日志文件: ${LOG_FILE}`);
460
+ // 尝试获取更多信息
461
+ try {
462
+ const info = await fetchDaemonInfo(port);
463
+ if (info) {
464
+ console.log(` Peer ID: ${info.peerId?.slice(0, 16)}...`);
465
+ }
466
+ }
467
+ catch {
468
+ // 忽略错误
469
+ }
470
+ }
471
+ else {
472
+ console.log(' 使用 "f2a daemon" 启动 daemon');
473
+ }
474
+ }
475
+ /**
476
+ * 检查端口是否被占用
477
+ * 使用 net 模块直接检测,比 HTTP 请求更可靠
478
+ */
479
+ async function checkPortInUse(port) {
480
+ return new Promise((resolve) => {
481
+ const server = createServer();
482
+ server.once('error', (err) => {
483
+ if (err.code === 'EADDRINUSE') {
484
+ resolve(true); // 端口被占用
485
+ }
486
+ else {
487
+ resolve(false);
488
+ }
489
+ });
490
+ server.once('listening', () => {
491
+ server.close(() => resolve(false)); // 端口可用
492
+ });
493
+ server.listen(port, '127.0.0.1');
494
+ });
495
+ }
496
+ /**
497
+ * 等待 daemon HTTP 服务就绪
498
+ * 轮询 /health 端点直到服务可用
499
+ */
500
+ async function waitForDaemonHealth(port, timeoutMs) {
501
+ const startTime = Date.now();
502
+ const pollInterval = 200; // 每 200ms 检查一次
503
+ while (Date.now() - startTime < timeoutMs) {
504
+ try {
505
+ const healthy = await checkDaemonHealth(port);
506
+ if (healthy) {
507
+ return true;
508
+ }
509
+ }
510
+ catch {
511
+ // 忽略错误,继续轮询
512
+ }
513
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
514
+ }
515
+ return false;
516
+ }
517
+ /**
518
+ * 检查 daemon 健康状态
519
+ */
520
+ async function checkDaemonHealth(port) {
521
+ return new Promise((resolve) => {
522
+ const req = request({
523
+ hostname: '127.0.0.1',
524
+ port,
525
+ path: '/health',
526
+ method: 'GET',
527
+ timeout: 1000,
528
+ }, (res) => {
529
+ resolve(res.statusCode === 200);
530
+ });
531
+ req.on('error', () => {
532
+ resolve(false);
533
+ });
534
+ req.on('timeout', () => {
535
+ req.destroy();
536
+ resolve(false);
537
+ });
538
+ req.end();
539
+ });
540
+ }
541
+ /**
542
+ * 从运行中的 daemon 获取信息
543
+ */
544
+ async function fetchDaemonInfo(port) {
545
+ return new Promise((resolve) => {
546
+ const req = request({
547
+ hostname: '127.0.0.1',
548
+ port: port || getControlPort(),
549
+ path: '/health',
550
+ method: 'GET',
551
+ timeout: 2000,
552
+ }, (res) => {
553
+ let data = '';
554
+ res.on('data', chunk => data += chunk);
555
+ res.on('end', () => {
556
+ try {
557
+ resolve(JSON.parse(data));
558
+ }
559
+ catch {
560
+ resolve(null);
561
+ }
562
+ });
563
+ });
564
+ req.on('error', () => resolve(null));
565
+ req.on('timeout', () => {
566
+ req.destroy();
567
+ resolve(null);
568
+ });
569
+ req.end();
570
+ });
571
+ }
572
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}