autosnippet 2.19.2 → 2.19.3
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/bin/cli.js +52 -28
- package/lib/http/HttpServer.js +38 -0
- package/package.json +2 -13
package/bin/cli.js
CHANGED
|
@@ -457,6 +457,7 @@ program
|
|
|
457
457
|
process.env.PORT = port;
|
|
458
458
|
process.env.HOST = host;
|
|
459
459
|
|
|
460
|
+
let httpServer;
|
|
460
461
|
try {
|
|
461
462
|
const { default: HttpServer } = await import('../lib/http/HttpServer.js');
|
|
462
463
|
|
|
@@ -469,7 +470,7 @@ program
|
|
|
469
470
|
gateway.eventBus = eventBus;
|
|
470
471
|
} catch { /* EventBus 不可用不阻塞启动 */ }
|
|
471
472
|
|
|
472
|
-
|
|
473
|
+
httpServer = new HttpServer({ port, host });
|
|
473
474
|
await httpServer.initialize();
|
|
474
475
|
await httpServer.start();
|
|
475
476
|
|
|
@@ -510,8 +511,13 @@ program
|
|
|
510
511
|
const isDebugMode = process.env.ASD_DEBUG === '1';
|
|
511
512
|
|
|
512
513
|
// 设置 Dashboard URL 供 watcher 跳转浏览器使用
|
|
514
|
+
// 生产模式用 API 同端口,开发模式用 vite dev 5173
|
|
515
|
+
const dashDirCheck = join(__dirname, '..', 'dashboard');
|
|
516
|
+
const isProductionDashboard = existsSync(join(dashDirCheck, 'dist', 'index.html')) && !existsSync(join(dashDirCheck, 'src'));
|
|
513
517
|
if (!opts.apiOnly) {
|
|
514
|
-
process.env.ASD_DASHBOARD_URL =
|
|
518
|
+
process.env.ASD_DASHBOARD_URL = isProductionDashboard
|
|
519
|
+
? `http://127.0.0.1:${port}`
|
|
520
|
+
: `http://localhost:5173`;
|
|
515
521
|
} else {
|
|
516
522
|
process.env.ASD_DASHBOARD_URL = process.env.ASD_DASHBOARD_URL || `http://${host}:${port}`;
|
|
517
523
|
}
|
|
@@ -544,36 +550,54 @@ program
|
|
|
544
550
|
return;
|
|
545
551
|
}
|
|
546
552
|
|
|
547
|
-
// 2.
|
|
553
|
+
// 2. 启动 Dashboard UI
|
|
548
554
|
const dashboardDir = join(__dirname, '..', 'dashboard');
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
555
|
+
const distDir = join(dashboardDir, 'dist');
|
|
556
|
+
const hasPrebuilt = existsSync(join(distDir, 'index.html'));
|
|
557
|
+
const hasSrc = existsSync(join(dashboardDir, 'src'));
|
|
558
|
+
|
|
559
|
+
if (hasPrebuilt && !hasSrc) {
|
|
560
|
+
// ── 生产模式:npm 安装的包,在 API 服务器上直接托管预构建产物 ──
|
|
561
|
+
// 同端口同 origin → /api 路由自然可达,无跨域问题
|
|
562
|
+
httpServer.mountDashboard(distDir);
|
|
563
|
+
console.log(`🎨 Dashboard UI ready at http://127.0.0.1:${port}/`);
|
|
564
|
+
|
|
565
|
+
if (opts.browser) {
|
|
566
|
+
const open = (await import('open')).default;
|
|
567
|
+
open(`http://127.0.0.1:${port}/`);
|
|
568
|
+
}
|
|
556
569
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
});
|
|
570
|
+
} else {
|
|
571
|
+
// ── 开发模式:有源码,启动 Vite Dev Server ──
|
|
572
|
+
if (!existsSync(join(dashboardDir, 'node_modules'))) {
|
|
573
|
+
console.log('📦 Installing dashboard dependencies...');
|
|
574
|
+
const install = spawn('npm', ['install'], { cwd: dashboardDir, stdio: 'inherit' });
|
|
575
|
+
await new Promise((resolve, reject) => {
|
|
576
|
+
install.on('close', code => code === 0 ? resolve() : reject(new Error(`npm install exited with ${code}`)));
|
|
577
|
+
});
|
|
578
|
+
}
|
|
567
579
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
580
|
+
console.log('🎨 Starting Dashboard (dev mode)...');
|
|
581
|
+
const viteArgs = ['--host'];
|
|
582
|
+
if (opts.browser) {
|
|
583
|
+
viteArgs.push('--open');
|
|
584
|
+
}
|
|
585
|
+
const vite = spawn('npx', ['vite', ...viteArgs], {
|
|
586
|
+
cwd: dashboardDir,
|
|
587
|
+
stdio: 'inherit',
|
|
588
|
+
env: { ...process.env, VITE_API_URL: `http://127.0.0.1:${port}` },
|
|
589
|
+
});
|
|
571
590
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
591
|
+
vite.on('error', (err) => {
|
|
592
|
+
console.error(`❌ Vite failed to start: ${err.message}`);
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
process.on('SIGINT', () => {
|
|
596
|
+
console.log('\n🛑 Stopping Dashboard...');
|
|
597
|
+
vite.kill();
|
|
598
|
+
process.exit(0);
|
|
599
|
+
});
|
|
600
|
+
}
|
|
577
601
|
});
|
|
578
602
|
|
|
579
603
|
// ─────────────────────────────────────────────────────
|
package/lib/http/HttpServer.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* 集成监控、缓存和错误追踪
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { join } from 'path';
|
|
7
8
|
import express from 'express';
|
|
8
9
|
import cors from 'cors';
|
|
9
10
|
import helmet from 'helmet';
|
|
@@ -409,6 +410,43 @@ export class HttpServer {
|
|
|
409
410
|
return this.app;
|
|
410
411
|
}
|
|
411
412
|
|
|
413
|
+
/**
|
|
414
|
+
* 挂载 Dashboard 静态资源(生产模式:直接托管预构建产物)
|
|
415
|
+
* 必须在 initialize() + start() 之后调用
|
|
416
|
+
* @param {string} distDir - dashboard/dist 目录的绝对路径
|
|
417
|
+
*/
|
|
418
|
+
mountDashboard(distDir) {
|
|
419
|
+
// 从路由栈中移除最后的 404 catch-all 和根路径 handler
|
|
420
|
+
const layers = this.app._router.stack;
|
|
421
|
+
// 倒序弹出最后 2 层(404 + root handler)
|
|
422
|
+
const removedLayers = [];
|
|
423
|
+
for (let i = layers.length - 1; i >= 0; i--) {
|
|
424
|
+
const layer = layers[i];
|
|
425
|
+
if (layer.route) {
|
|
426
|
+
removedLayers.unshift(layers.splice(i, 1)[0]);
|
|
427
|
+
if (removedLayers.length >= 2) break;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// 注入 express.static 托管 dist 目录
|
|
432
|
+
this.app.use(express.static(distDir));
|
|
433
|
+
|
|
434
|
+
// SPA fallback: 非 API / 非 socket.io 请求返回 index.html
|
|
435
|
+
this.app.get('*', (req, res, next) => {
|
|
436
|
+
if (req.path.startsWith('/api') || req.path.startsWith('/socket.io')) {
|
|
437
|
+
return next();
|
|
438
|
+
}
|
|
439
|
+
res.sendFile(join(distDir, 'index.html'));
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// 放回 404 handler(SPA fallback 之后,作为兜底)
|
|
443
|
+
for (const layer of removedLayers) {
|
|
444
|
+
layers.push(layer);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
this.logger.info('Dashboard mounted (production mode)', { distDir });
|
|
448
|
+
}
|
|
449
|
+
|
|
412
450
|
/**
|
|
413
451
|
* 获取服务器实例
|
|
414
452
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autosnippet",
|
|
3
|
-
"version": "2.19.
|
|
3
|
+
"version": "2.19.3",
|
|
4
4
|
"description": "AutoSnippet - 连接开发者、AI 与项目知识库的工具",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/bootstrap.js",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"ora": "^8.0.1",
|
|
73
73
|
"redis": "^4.7.0",
|
|
74
74
|
"socket.io": "^4.8.1",
|
|
75
|
-
"tree-sitter": "^0.
|
|
75
|
+
"tree-sitter": "^0.22.4",
|
|
76
76
|
"tree-sitter-objc": "^3.0.2",
|
|
77
77
|
"tree-sitter-swift": "^0.7.1",
|
|
78
78
|
"undici": "^6.23.0",
|
|
@@ -81,17 +81,6 @@
|
|
|
81
81
|
"xml2js": "^0.6.2",
|
|
82
82
|
"zod": "^4.3.6"
|
|
83
83
|
},
|
|
84
|
-
"overrides": {
|
|
85
|
-
"tree-sitter-c": {
|
|
86
|
-
"tree-sitter": "$tree-sitter"
|
|
87
|
-
},
|
|
88
|
-
"tree-sitter-objc": {
|
|
89
|
-
"tree-sitter": "$tree-sitter"
|
|
90
|
-
},
|
|
91
|
-
"tree-sitter-swift": {
|
|
92
|
-
"tree-sitter": "$tree-sitter"
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
84
|
"bugs": {
|
|
96
85
|
"url": "https://github.com/GxFn/AutoSnippet/issues"
|
|
97
86
|
},
|