@modootoday/datalab-extension-mcp 1.11.3 → 1.11.4
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/README.en.md +16 -16
- package/README.md +16 -16
- package/dist/{chunk-HGE7QMS4.js → chunk-RF6L4PSA.js} +42 -26
- package/dist/cli.js +3 -3
- package/dist/{dist-V4J6UN5K.js → dist-ITPO7PMQ.js} +63 -29
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -14,11 +14,11 @@ and it answers with the **real numbers** from your Naver blog, keywords, and ads
|
|
|
14
14
|
|
|
15
15
|
Set this up once per computer.
|
|
16
16
|
|
|
17
|
-
| Need | How
|
|
18
|
-
| ------------------------------------ |
|
|
19
|
-
| Chrome + the DataLab Tools extension | If you don't have it yet, install from [app.datalab.tools](https://app.datalab.tools/).
|
|
20
|
-
| An AI app | The program that answers your questions. It must be an **app installed on your computer** (websites won't work). Claude Desktop is free at [claude.ai](https://claude.ai/download); ChatGPT works as the **desktop app only**, from [openai.com](https://openai.com/).
|
|
21
|
-
| Node.js | The free program that runs the connector. Get it from [nodejs.org](https://nodejs.org/) via the **LTS** button.
|
|
17
|
+
| Need | How |
|
|
18
|
+
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| Chrome + the DataLab Tools extension | If you don't have it yet, install from [app.datalab.tools](https://app.datalab.tools/). |
|
|
20
|
+
| An AI app | The program that answers your questions. It must be an **app installed on your computer** (websites won't work). Claude Desktop is free at [claude.ai](https://claude.ai/download); ChatGPT works as the **desktop app only**, from [openai.com](https://openai.com/). |
|
|
21
|
+
| Node.js | The free program that runs the connector. Get it from [nodejs.org](https://nodejs.org/) via the **LTS** button. On Windows, `winget install OpenJS.NodeJS.LTS` also installs it. On Mac and Linux, the one-liner in [Step 2](#step-2--install) installs Node.js for you in one go. |
|
|
22
22
|
|
|
23
23
|
> A work computer may block installs by policy. Check with your IT team first to avoid wasting time.
|
|
24
24
|
|
|
@@ -61,7 +61,7 @@ One command finds **every** AI app on your computer and connects them automatica
|
|
|
61
61
|
2. **Paste this command and press Enter.** The saved command names an exact bootstrap version. At startup and while idle, the connector checks the canonical release and promotes itself to the current secure, compatible version. Diagnostic environments can opt out with `--no-self-update`.
|
|
62
62
|
|
|
63
63
|
```
|
|
64
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
64
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 install
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
Lines of English scrolling by is normal. This only downloads and runs the connector — it touches nothing else.
|
|
@@ -96,12 +96,12 @@ One command finds **every** AI app on your computer and connects them automatica
|
|
|
96
96
|
<details>
|
|
97
97
|
<summary><strong>No Node.js? — install it in one go</strong></summary>
|
|
98
98
|
|
|
99
|
-
If the command errors with `'npx' is not recognized`, Node.js isn't installed.
|
|
99
|
+
If the command errors with `'npx' is not recognized`, Node.js isn't installed. On Windows, install Node.js first and run the command again. On Mac and Linux, this one command installs Node.js (no admin rights) and then continues to connect, skipping the install if Node.js is already there.
|
|
100
100
|
|
|
101
|
-
- **Windows** (open PowerShell and paste):
|
|
101
|
+
- **Windows** (open PowerShell and paste): installs the official Node.js package; then open a new PowerShell window and run the Step 2 command again. Without winget, get the LTS installer from [nodejs.org](https://nodejs.org/).
|
|
102
102
|
|
|
103
103
|
```
|
|
104
|
-
|
|
104
|
+
winget install OpenJS.NodeJS.LTS
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
- **Mac · Linux** (open the terminal and paste):
|
|
@@ -151,10 +151,10 @@ diagnosis, Place reputation, Pumasi, photo/video production, and automatic tool
|
|
|
151
151
|
discovery. Press Enter to keep the recommended set.
|
|
152
152
|
|
|
153
153
|
```
|
|
154
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
155
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
156
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
157
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
154
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills list
|
|
155
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills status
|
|
156
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills attach <name>
|
|
157
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills detach <name>
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
- `list` shows everything in this version, name and description.
|
|
@@ -275,10 +275,10 @@ Start it again after a full quit and it picks the tools up. If they still aren't
|
|
|
275
275
|
- **When the connection disappears** — run the very command you used at the start once more; it safely re-registers. (Some AI apps clean up their settings file and drop the connection.)
|
|
276
276
|
|
|
277
277
|
```
|
|
278
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
278
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 install
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
-
- **`'npx' is not recognized...`** — Node.js isn't installed.
|
|
281
|
+
- **`'npx' is not recognized...`** — Node.js isn't installed. Follow "No Node.js?" in Step 2, then run the command again.
|
|
282
282
|
|
|
283
283
|
- **None of the above** — the connector writes down what happened to it. One file:
|
|
284
284
|
|
|
@@ -305,7 +305,7 @@ Start it again after a full quit and it picks the tools up. If they still aren't
|
|
|
305
305
|
1. Run this in a terminal (it removes the entries registered in your AI apps).
|
|
306
306
|
|
|
307
307
|
```
|
|
308
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
308
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 uninstall
|
|
309
309
|
```
|
|
310
310
|
|
|
311
311
|
2. Turn **MCP 연결** off in the extension settings. The panel is the bridge, so with it off a leftover config line can look nothing up.
|
package/README.md
CHANGED
|
@@ -12,11 +12,11 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
12
12
|
|
|
13
13
|
컴퓨터마다 한 번씩만 준비하면 돼요.
|
|
14
14
|
|
|
15
|
-
| 준비물 | 어떻게
|
|
16
|
-
| -------------------------- |
|
|
17
|
-
| Chrome + 데이터랩툴즈 확장 | 아직 없다면 [app.datalab.tools](https://app.datalab.tools/)에서 설치해요.
|
|
18
|
-
| AI 앱 | 질문을 받을 프로그램이에요. **컴퓨터에 설치하는 앱**만 돼요(웹사이트는 안 돼요). Claude Desktop은 [claude.ai](https://claude.ai/download)에서 무료로, ChatGPT는 **데스크톱 앱만** 되고 [openai.com](https://openai.com/)에서 받아요.
|
|
19
|
-
| Node.js | 연결 프로그램을 실행하는 무료 프로그램이에요. [nodejs.org](https://nodejs.org/)의 **LTS** 버튼으로 받아요.
|
|
15
|
+
| 준비물 | 어떻게 |
|
|
16
|
+
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| Chrome + 데이터랩툴즈 확장 | 아직 없다면 [app.datalab.tools](https://app.datalab.tools/)에서 설치해요. |
|
|
18
|
+
| AI 앱 | 질문을 받을 프로그램이에요. **컴퓨터에 설치하는 앱**만 돼요(웹사이트는 안 돼요). Claude Desktop은 [claude.ai](https://claude.ai/download)에서 무료로, ChatGPT는 **데스크톱 앱만** 되고 [openai.com](https://openai.com/)에서 받아요. |
|
|
19
|
+
| Node.js | 연결 프로그램을 실행하는 무료 프로그램이에요. [nodejs.org](https://nodejs.org/)의 **LTS** 버튼으로 받아요. Windows는 `winget install OpenJS.NodeJS.LTS` 로도 설치돼요. Mac · Linux는 아래 [2단계](#2단계--설치)의 한 줄 설치가 Node.js까지 한 번에 깔아 줘요. |
|
|
20
20
|
|
|
21
21
|
> 회사 컴퓨터는 보안 정책 때문에 설치가 막혀 있을 수 있어요. 시작 전에 회사 IT 담당자와 먼저 상의하면 시간을 아낄 수 있어요.
|
|
22
22
|
|
|
@@ -55,7 +55,7 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
55
55
|
2. **아래 명령을 붙여넣고 Enter를 눌러요.** 저장되는 명령은 정확한 시작 버전을 적습니다. 연결 프로그램은 시작할 때와 유휴 상태에서 정본 릴리스를 확인해 현재의 안전하고 호환되는 버전으로 승격합니다. 진단 환경에서는 `--no-self-update`로 승격을 끌 수 있어요.
|
|
56
56
|
|
|
57
57
|
```
|
|
58
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
58
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 install
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
영어 글자가 여러 줄 올라오는 건 정상이에요. 이 명령은 연결 프로그램을 다운로드해 실행할 뿐, 다른 건 건드리지 않아요.
|
|
@@ -84,12 +84,12 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
84
84
|
<details>
|
|
85
85
|
<summary><strong>Node.js가 없다면 — 한 줄로 한 번에 설치</strong></summary>
|
|
86
86
|
|
|
87
|
-
위 명령이 `'npx'을(를) 찾을 수 없습니다` 오류를 내면 Node.js가 없는 거예요. 아래 명령 하나면 Node.js까지 설치(관리자 권한 없이)한 뒤 연결까지 이어
|
|
87
|
+
위 명령이 `'npx'을(를) 찾을 수 없습니다` 오류를 내면 Node.js가 없는 거예요. Windows는 Node.js를 먼저 설치하고 위 명령을 다시 실행해요. Mac · Linux는 아래 명령 하나면 Node.js까지 설치(관리자 권한 없이)한 뒤 연결까지 이어 주고, 이미 있으면 설치는 건너뛰어요.
|
|
88
88
|
|
|
89
|
-
- **Windows** (PowerShell을 열고 붙여넣어요):
|
|
89
|
+
- **Windows** (PowerShell을 열고 붙여넣어요): Node.js 공식 패키지를 설치한 뒤, PowerShell을 새로 열고 위 2단계 명령을 다시 실행해요. winget이 없으면 [nodejs.org](https://nodejs.org/)에서 LTS를 받아 설치해도 돼요.
|
|
90
90
|
|
|
91
91
|
```
|
|
92
|
-
|
|
92
|
+
winget install OpenJS.NodeJS.LTS
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
- **Mac · Linux** (터미널을 열고 붙여넣어요):
|
|
@@ -137,10 +137,10 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
137
137
|
도움말을 번호로 여러 개 고를 수 있어요. Enter를 누르면 추천 구성만 설치됩니다.
|
|
138
138
|
|
|
139
139
|
```
|
|
140
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
141
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
142
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
143
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
140
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills list
|
|
141
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills status
|
|
142
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills attach <이름>
|
|
143
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 skills detach <이름>
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
- `list` 는 이 버전에 들어 있는 전부를 이름과 설명으로 보여 줘요.
|
|
@@ -242,10 +242,10 @@ AI가 "그런 기능은 없다" 고 답하면, **"숨은 도구를 찾아보고
|
|
|
242
242
|
- **연결이 사라졌을 때** — 처음 실행했던 그 명령을 한 번 더 실행하면 안전하게 다시 등록돼요. (일부 AI 앱이 설정 파일을 정리하며 연결을 지우기도 해요.)
|
|
243
243
|
|
|
244
244
|
```
|
|
245
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
245
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 install
|
|
246
246
|
```
|
|
247
247
|
|
|
248
|
-
- **`'npx'을(는) 내부 또는 외부 명령...`** — Node.js가 없는 거예요. 위 2단계의 "Node.js가 없다면"
|
|
248
|
+
- **`'npx'을(는) 내부 또는 외부 명령...`** — Node.js가 없는 거예요. 위 2단계의 "Node.js가 없다면"을 따라 설치한 뒤 다시 실행해요.
|
|
249
249
|
|
|
250
250
|
- **위 어느 것도 아닐 때** — 연결 프로그램이 무슨 일을 겪었는지 기록해 둬요. 파일 하나만 열어 보면 돼요.
|
|
251
251
|
|
|
@@ -272,7 +272,7 @@ AI가 "그런 기능은 없다" 고 답하면, **"숨은 도구를 찾아보고
|
|
|
272
272
|
1. 터미널에서 아래 명령을 실행해요(AI 앱에 등록된 설정을 지워 줘요).
|
|
273
273
|
|
|
274
274
|
```
|
|
275
|
-
npx -y @modootoday/datalab-extension-mcp@1.11.
|
|
275
|
+
npx -y @modootoday/datalab-extension-mcp@1.11.4 uninstall
|
|
276
276
|
```
|
|
277
277
|
|
|
278
278
|
2. 확장 설정에서 **MCP 연결을 꺼요.** 패널이 브릿지라, 꺼 두면 어딘가 설정 줄이 남아 있어도 AI 앱이 아무것도 조회할 수 없어요.
|
|
@@ -22751,41 +22751,57 @@ function runDaemon(env, deps = {}) {
|
|
|
22751
22751
|
|
|
22752
22752
|
// ../mcp-server/dist/index.js
|
|
22753
22753
|
import { spawnSync } from "child_process";
|
|
22754
|
-
function
|
|
22755
|
-
const
|
|
22754
|
+
function parseNetstatListeners(output3, port) {
|
|
22755
|
+
const pids = /* @__PURE__ */ new Set();
|
|
22756
|
+
for (const line of output3.split(/\r?\n/)) {
|
|
22757
|
+
const cols = line.trim().split(/\s+/);
|
|
22758
|
+
if (cols.length < 5 || cols[0]?.toUpperCase() !== "TCP") continue;
|
|
22759
|
+
if (cols[3]?.toUpperCase() !== "LISTENING") continue;
|
|
22760
|
+
const local = cols[1] ?? "";
|
|
22761
|
+
if (local.slice(local.lastIndexOf(":") + 1) !== String(port)) continue;
|
|
22762
|
+
const pid = Number(cols[4]);
|
|
22763
|
+
if (Number.isInteger(pid) && pid > 0) pids.add(pid);
|
|
22764
|
+
}
|
|
22765
|
+
return [...pids];
|
|
22766
|
+
}
|
|
22767
|
+
function parseLsofPids(output3) {
|
|
22768
|
+
return output3.split(/\r?\n/).map((l) => Number(l.trim())).filter((n) => Number.isInteger(n) && n > 0);
|
|
22769
|
+
}
|
|
22770
|
+
function listenerQuery(platform, port) {
|
|
22756
22771
|
if (platform === "win32") {
|
|
22757
|
-
return {
|
|
22758
|
-
command: "powershell",
|
|
22759
|
-
args: [
|
|
22760
|
-
"-NoProfile",
|
|
22761
|
-
"-Command",
|
|
22762
|
-
`Get-NetTCPConnection -LocalPort ${p} -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
22763
|
-
],
|
|
22764
|
-
shell: true
|
|
22765
|
-
};
|
|
22772
|
+
return { command: "netstat", args: ["-ano", "-p", "TCP"] };
|
|
22766
22773
|
}
|
|
22767
22774
|
if (platform === "darwin" || platform === "linux") {
|
|
22768
|
-
return {
|
|
22769
|
-
command: "sh",
|
|
22770
|
-
args: [
|
|
22771
|
-
"-c",
|
|
22772
|
-
`pids=$(lsof -ti tcp:${p} -sTCP:LISTEN 2>/dev/null); if [ -n "$pids" ]; then kill -9 $pids; fi`
|
|
22773
|
-
],
|
|
22774
|
-
shell: false
|
|
22775
|
-
};
|
|
22775
|
+
return { command: "lsof", args: ["-ti", `tcp:${port}`, "-sTCP:LISTEN"] };
|
|
22776
22776
|
}
|
|
22777
22777
|
return null;
|
|
22778
22778
|
}
|
|
22779
|
+
function listenerPids(platform, port, run, selfPid) {
|
|
22780
|
+
const query = listenerQuery(platform, port);
|
|
22781
|
+
if (query === null) return [];
|
|
22782
|
+
const output3 = run(query.command, query.args);
|
|
22783
|
+
const pids = platform === "win32" ? parseNetstatListeners(output3, port) : parseLsofPids(output3);
|
|
22784
|
+
return pids.filter((pid) => pid !== selfPid);
|
|
22785
|
+
}
|
|
22786
|
+
function runQuiet(command, args) {
|
|
22787
|
+
const res = spawnSync(command, args, {
|
|
22788
|
+
encoding: "utf8",
|
|
22789
|
+
windowsHide: true,
|
|
22790
|
+
timeout: 1e4
|
|
22791
|
+
});
|
|
22792
|
+
return typeof res.stdout === "string" ? res.stdout : "";
|
|
22793
|
+
}
|
|
22779
22794
|
function killPortOwner(port, platform = process.platform) {
|
|
22780
22795
|
if (process.env["VITEST"] !== void 0) return false;
|
|
22781
|
-
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
|
|
22785
|
-
|
|
22786
|
-
|
|
22787
|
-
|
|
22796
|
+
let signalled = false;
|
|
22797
|
+
for (const pid of listenerPids(platform, port, runQuiet, process.pid)) {
|
|
22798
|
+
try {
|
|
22799
|
+
process.kill(pid, "SIGKILL");
|
|
22800
|
+
signalled = true;
|
|
22801
|
+
} catch {
|
|
22802
|
+
}
|
|
22788
22803
|
}
|
|
22804
|
+
return signalled;
|
|
22789
22805
|
}
|
|
22790
22806
|
|
|
22791
22807
|
// src/adapter.ts
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
dispatchCli,
|
|
4
4
|
runAdapter,
|
|
5
5
|
runDaemon
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RF6L4PSA.js";
|
|
7
7
|
import "./chunk-MLKGABMK.js";
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
@@ -15,7 +15,7 @@ function log(message) {
|
|
|
15
15
|
`);
|
|
16
16
|
}
|
|
17
17
|
async function runInstaller(sub, argv) {
|
|
18
|
-
const { createNodeIo, runInstall, runUninstall } = await import("./dist-
|
|
18
|
+
const { createNodeIo, runInstall, runUninstall } = await import("./dist-ITPO7PMQ.js");
|
|
19
19
|
const opts = { version: VERSION };
|
|
20
20
|
for (let i = 0; i < argv.length; i += 1) {
|
|
21
21
|
const flag = argv[i];
|
|
@@ -72,7 +72,7 @@ async function main() {
|
|
|
72
72
|
attachSkill,
|
|
73
73
|
detachSkill,
|
|
74
74
|
skillsPayloadRoot
|
|
75
|
-
} = await import("./dist-
|
|
75
|
+
} = await import("./dist-ITPO7PMQ.js");
|
|
76
76
|
const io = createNodeIo();
|
|
77
77
|
const root = skillsPayloadRoot();
|
|
78
78
|
const code = await runSkills(argv, {
|
|
@@ -3,7 +3,7 @@ import "./chunk-MLKGABMK.js";
|
|
|
3
3
|
// ../mcp-installer/dist/index.js
|
|
4
4
|
import { join as joinNative } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
|
-
import { spawn as nodeSpawn } from "child_process";
|
|
6
|
+
import { execFile, spawn as nodeSpawn } from "child_process";
|
|
7
7
|
import { promises as fs } from "fs";
|
|
8
8
|
import { homedir } from "os";
|
|
9
9
|
import { createInterface } from "readline";
|
|
@@ -1260,6 +1260,47 @@ function validateUninstallOptions(opts) {
|
|
|
1260
1260
|
}
|
|
1261
1261
|
return null;
|
|
1262
1262
|
}
|
|
1263
|
+
function parseNetstatListeners(output, port) {
|
|
1264
|
+
const pids = /* @__PURE__ */ new Set();
|
|
1265
|
+
for (const line of output.split(/\r?\n/)) {
|
|
1266
|
+
const cols = line.trim().split(/\s+/);
|
|
1267
|
+
if (cols.length < 5 || cols[0]?.toUpperCase() !== "TCP") continue;
|
|
1268
|
+
if (cols[3]?.toUpperCase() !== "LISTENING") continue;
|
|
1269
|
+
const local = cols[1] ?? "";
|
|
1270
|
+
if (local.slice(local.lastIndexOf(":") + 1) !== String(port)) continue;
|
|
1271
|
+
const pid = Number(cols[4]);
|
|
1272
|
+
if (Number.isInteger(pid) && pid > 0) pids.add(pid);
|
|
1273
|
+
}
|
|
1274
|
+
return [...pids];
|
|
1275
|
+
}
|
|
1276
|
+
function parseLsofPids(output) {
|
|
1277
|
+
return output.split(/\r?\n/).map((l) => Number(l.trim())).filter((n) => Number.isInteger(n) && n > 0);
|
|
1278
|
+
}
|
|
1279
|
+
function listenerQuery(platform, port) {
|
|
1280
|
+
if (platform === "win32") {
|
|
1281
|
+
return { command: "netstat", args: ["-ano", "-p", "TCP"] };
|
|
1282
|
+
}
|
|
1283
|
+
if (platform === "darwin" || platform === "linux") {
|
|
1284
|
+
return { command: "lsof", args: ["-ti", `tcp:${port}`, "-sTCP:LISTEN"] };
|
|
1285
|
+
}
|
|
1286
|
+
return null;
|
|
1287
|
+
}
|
|
1288
|
+
async function endPortListener(platform, port, deps) {
|
|
1289
|
+
const query = listenerQuery(platform, port);
|
|
1290
|
+
if (query === null) return false;
|
|
1291
|
+
const output = await deps.capture(query.command, query.args);
|
|
1292
|
+
const pids = platform === "win32" ? parseNetstatListeners(output, port) : parseLsofPids(output);
|
|
1293
|
+
let signalled = false;
|
|
1294
|
+
for (const pid of pids) {
|
|
1295
|
+
if (pid === deps.selfPid) continue;
|
|
1296
|
+
try {
|
|
1297
|
+
deps.killPid(pid);
|
|
1298
|
+
signalled = true;
|
|
1299
|
+
} catch {
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return signalled;
|
|
1303
|
+
}
|
|
1263
1304
|
var DEFAULT_PORT2 = 8765;
|
|
1264
1305
|
var HOST = "127.0.0.1";
|
|
1265
1306
|
var CONNECTOR_NAME = "datalab-extension-mcp-server";
|
|
@@ -1319,31 +1360,6 @@ async function probePort(fetchImpl, port) {
|
|
|
1319
1360
|
return { state: "foreign", version: null };
|
|
1320
1361
|
}
|
|
1321
1362
|
}
|
|
1322
|
-
function killCommand(platform, port) {
|
|
1323
|
-
const p = String(port);
|
|
1324
|
-
if (platform === "win32") {
|
|
1325
|
-
return {
|
|
1326
|
-
command: "powershell",
|
|
1327
|
-
args: [
|
|
1328
|
-
"-NoProfile",
|
|
1329
|
-
"-Command",
|
|
1330
|
-
`Get-NetTCPConnection -LocalPort ${p} -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
1331
|
-
],
|
|
1332
|
-
shell: true
|
|
1333
|
-
};
|
|
1334
|
-
}
|
|
1335
|
-
if (platform === "darwin" || platform === "linux") {
|
|
1336
|
-
return {
|
|
1337
|
-
command: "sh",
|
|
1338
|
-
args: [
|
|
1339
|
-
"-c",
|
|
1340
|
-
`pids=$(lsof -ti tcp:${p} -sTCP:LISTEN 2>/dev/null); if [ -n "$pids" ]; then kill -9 $pids; fi`
|
|
1341
|
-
],
|
|
1342
|
-
shell: false
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
return null;
|
|
1346
|
-
}
|
|
1347
1363
|
async function reclaimPort(io, token, deps = {}) {
|
|
1348
1364
|
const asked = typeof deps.port === "string" ? Number(deps.port) : deps.port;
|
|
1349
1365
|
const port = asked !== void 0 && Number.isInteger(asked) && asked > 0 ? asked : DEFAULT_PORT2;
|
|
@@ -1367,9 +1383,12 @@ async function reclaimPort(io, token, deps = {}) {
|
|
|
1367
1383
|
return false;
|
|
1368
1384
|
};
|
|
1369
1385
|
if (stood?.status === 200 && await gone()) return { kind: "retired" };
|
|
1370
|
-
const
|
|
1371
|
-
|
|
1372
|
-
|
|
1386
|
+
const ended = await endPortListener(io.platform, port, {
|
|
1387
|
+
capture: io.capture,
|
|
1388
|
+
killPid: io.killPid,
|
|
1389
|
+
selfPid: process.pid
|
|
1390
|
+
});
|
|
1391
|
+
if (!ended) return { kind: "failed" };
|
|
1373
1392
|
return await gone() ? { kind: "forced" } : { kind: "failed" };
|
|
1374
1393
|
}
|
|
1375
1394
|
var BACKUP_KEEP = 3;
|
|
@@ -2525,6 +2544,21 @@ function createNodeIo() {
|
|
|
2525
2544
|
});
|
|
2526
2545
|
});
|
|
2527
2546
|
},
|
|
2547
|
+
capture(command, args) {
|
|
2548
|
+
return new Promise((resolve) => {
|
|
2549
|
+
execFile(
|
|
2550
|
+
command,
|
|
2551
|
+
args,
|
|
2552
|
+
{ windowsHide: true, timeout: 1e4 },
|
|
2553
|
+
(err, stdout) => {
|
|
2554
|
+
resolve(err && !stdout ? "" : String(stdout ?? ""));
|
|
2555
|
+
}
|
|
2556
|
+
);
|
|
2557
|
+
});
|
|
2558
|
+
},
|
|
2559
|
+
killPid(pid) {
|
|
2560
|
+
process.kill(pid, "SIGKILL");
|
|
2561
|
+
},
|
|
2528
2562
|
async ask(question) {
|
|
2529
2563
|
const rl = createInterface({
|
|
2530
2564
|
input: process.stdin,
|
package/dist/index.js
CHANGED