triflux 8.11.2 → 8.12.1
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/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { existsSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { join, dirname } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
9
|
import { fileURLToPath } from 'node:url';
|
|
10
10
|
|
|
@@ -35,18 +35,16 @@ function hasManifest() {
|
|
|
35
35
|
return existsSync(PID_FILE);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/** mcp-gateway-start.mjs를
|
|
38
|
+
/** mcp-gateway-start.mjs를 독립 프로세스로 기동 */
|
|
39
39
|
function startGateway() {
|
|
40
40
|
const scriptPath = join(PLUGIN_ROOT, 'scripts', 'mcp-gateway-start.mjs');
|
|
41
41
|
if (!existsSync(scriptPath)) return false;
|
|
42
42
|
|
|
43
43
|
try {
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
child.unref();
|
|
44
|
+
// PowerShell Start-Process: Windows Job Object에서 벗어나 부모 종료 후 생존
|
|
45
|
+
execSync(
|
|
46
|
+
`powershell -NoProfile -Command "Start-Process -WindowStyle Hidden -FilePath '${process.execPath}' -ArgumentList '${scriptPath.replaceAll("'", "''")}'"`
|
|
47
|
+
, { stdio: 'ignore', timeout: 10000 });
|
|
50
48
|
return true;
|
|
51
49
|
} catch {
|
|
52
50
|
return false;
|
|
@@ -57,23 +57,43 @@ function sleep(ms) {
|
|
|
57
57
|
// ── 시작 ──
|
|
58
58
|
|
|
59
59
|
function spawnGateway(srv) {
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
// 임시 .cmd 파일로 quoting 문제 회피
|
|
61
|
+
const cmdContent = `@echo off\nnpx -y supergateway --stdio "${srv.cmd}" --port ${srv.port} --outputTransport sse --healthEndpoint /healthz --cors "http://localhost"`;
|
|
62
|
+
const cmdFile = join(tmpdir(), `tfx-sg-${srv.name}.cmd`);
|
|
63
|
+
writeFileSync(cmdFile, cmdContent);
|
|
64
|
+
|
|
65
|
+
// PowerShell Start-Process: Windows Job Object에서 벗어나 부모 종료 후 생존
|
|
66
|
+
execSync(
|
|
67
|
+
`powershell -NoProfile -Command "Start-Process -WindowStyle Hidden -FilePath cmd.exe -ArgumentList '/c','${cmdFile.replaceAll("'", "''")}'"`
|
|
68
|
+
, { stdio: 'ignore', timeout: 10000 });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function ensureFirewallRule() {
|
|
72
|
+
if (process.platform !== 'win32') return;
|
|
73
|
+
const ports = SERVERS.map((s) => s.port).join(',');
|
|
74
|
+
const ruleName = 'TFX-MCP-Gateway-Block-External';
|
|
75
|
+
try {
|
|
76
|
+
// 기존 규칙 있으면 스킵
|
|
77
|
+
const check = execSync(
|
|
78
|
+
`netsh advfirewall firewall show rule name="${ruleName}" 2>&1`,
|
|
79
|
+
{ encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000 },
|
|
80
|
+
);
|
|
81
|
+
if (check.includes(ruleName)) return;
|
|
82
|
+
} catch { /* 규칙 없음 — 생성 */ }
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
execSync(
|
|
86
|
+
`netsh advfirewall firewall add rule name="${ruleName}" dir=in action=block protocol=tcp localport=${ports} remoteip=any profile=any`,
|
|
87
|
+
{ stdio: 'ignore', timeout: 5000 },
|
|
88
|
+
);
|
|
89
|
+
console.log(`[SEC] Firewall rule added: block external access to ports ${ports}`);
|
|
90
|
+
} catch {
|
|
91
|
+
console.log(`[SEC] WARNING: Could not add firewall rule — run as admin or manually block ports ${ports}`);
|
|
92
|
+
}
|
|
74
93
|
}
|
|
75
94
|
|
|
76
95
|
async function startAll() {
|
|
96
|
+
ensureFirewallRule();
|
|
77
97
|
const launched = [];
|
|
78
98
|
|
|
79
99
|
for (const srv of SERVERS) {
|
|
@@ -136,8 +156,14 @@ async function startAll() {
|
|
|
136
156
|
function stopAll() {
|
|
137
157
|
// supergateway + 하위 MCP 프로세스를 포트 기반으로 찾아 종료
|
|
138
158
|
try {
|
|
139
|
-
|
|
140
|
-
const
|
|
159
|
+
// temp .ps1 파일로 bash/cmd 쿼팅 충돌 회피
|
|
160
|
+
const psFile = join(tmpdir(), 'tfx-sg-stop.ps1');
|
|
161
|
+
writeFileSync(psFile, [
|
|
162
|
+
`Get-CimInstance Win32_Process -Filter "Name='node.exe' OR Name='cmd.exe'" |`,
|
|
163
|
+
` Where-Object { $_.CommandLine -match 'supergateway' } |`,
|
|
164
|
+
` ForEach-Object { taskkill /F /T /PID $_.ProcessId 2>$null; Write-Output "[STOP] PID $($_.ProcessId)" }`,
|
|
165
|
+
].join('\n'));
|
|
166
|
+
const output = execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${psFile}"`, {
|
|
141
167
|
encoding: 'utf8',
|
|
142
168
|
timeout: 10000,
|
|
143
169
|
stdio: ['pipe', 'pipe', 'ignore'],
|