@modootoday/datalab-extension-mcp 1.11.2 → 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 +18 -17
- package/README.md +18 -17
- package/dist/{chunk-U4NWY74P.js → chunk-RF6L4PSA.js} +59 -27
- package/dist/cli.js +3 -3
- package/dist/{dist-X23C5DSV.js → dist-ITPO7PMQ.js} +65 -31
- package/dist/index.d.ts +4 -0
- 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.
|
|
@@ -244,7 +244,7 @@ Exactly what it says. Open Chrome, keep the DataLab Tools side panel open, and i
|
|
|
244
244
|
|
|
245
245
|
That's expected — **it's deliberate.**
|
|
246
246
|
|
|
247
|
-
There are
|
|
247
|
+
There are 213 tools. Sending all of them as a list runs into the cap each AI app
|
|
248
248
|
sets: some quietly drop whatever doesn't fit, some refuse the connection outright.
|
|
249
249
|
So only the discovery tools go in the list, and **the rest are selected from the
|
|
250
250
|
user's intent and handed over as an answer.**
|
|
@@ -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.
|
|
@@ -322,6 +322,7 @@ Deleting the extension also renders any leftover connector inert. A leftover lin
|
|
|
322
322
|
- **Do I keep it always on?** No. It connects only while the panel is open.
|
|
323
323
|
- **What data does it read?** Blog stats, keywords, ads — what DataLab Tools shows. Scoped to the Naver account you're logged into in Chrome.
|
|
324
324
|
- **Other computers?** Yes, but set it up once per computer; the connection key is per-computer too.
|
|
325
|
+
|
|
325
326
|
</details>
|
|
326
327
|
|
|
327
328
|
## Developer appendix
|
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` 는 이 버전에 들어 있는 전부를 이름과 설명으로 보여 줘요.
|
|
@@ -214,7 +214,7 @@ MCP 를 켜 두었지만 **네이버 페이지가 한 곳도 열려 있지 않
|
|
|
214
214
|
|
|
215
215
|
정상이에요. **일부러 그렇게 보냅니다.**
|
|
216
216
|
|
|
217
|
-
전체 도구는
|
|
217
|
+
전체 도구는 213개인데, 그걸 전부 목록으로 보내면 AI 앱마다 정해 둔 상한에 걸려요.
|
|
218
218
|
어떤 앱은 넘치는 만큼 조용히 잘라내고, 어떤 앱은 아예 연결을 거부해요. 그래서 자주 쓰는
|
|
219
219
|
탐색 도구만 목록에 올리고, 나머지는 **AI가 요청 의도를 찾아 답으로 건네받습니다.**
|
|
220
220
|
|
|
@@ -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 앱이 아무것도 조회할 수 없어요.
|
|
@@ -289,6 +289,7 @@ AI가 "그런 기능은 없다" 고 답하면, **"숨은 도구를 찾아보고
|
|
|
289
289
|
- **항상 켜 둬야 하나요?** 아니요. 패널이 열려 있을 때만 연결돼요.
|
|
290
290
|
- **어떤 데이터를 읽나요?** 블로그 통계·키워드·광고 등 데이터랩툴즈가 보여 주는 것들이에요. 기준은 지금 Chrome에 로그인해 둔 네이버 계정이에요.
|
|
291
291
|
- **다른 컴퓨터에서도 되나요?** 네. 컴퓨터마다 한 번씩 설치하고, 연결 키도 컴퓨터마다 따로예요.
|
|
292
|
+
|
|
292
293
|
</details>
|
|
293
294
|
|
|
294
295
|
## 개발자 부록
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
__export
|
|
3
3
|
} from "./chunk-MLKGABMK.js";
|
|
4
4
|
|
|
5
|
-
// ../mcp-server/dist/chunk-
|
|
5
|
+
// ../mcp-server/dist/chunk-PCVVHMPP.js
|
|
6
6
|
import { createHash } from "crypto";
|
|
7
7
|
import { createHash as createHash2, randomUUID } from "crypto";
|
|
8
8
|
import { mkdir, readFile, readdir, rm, writeFile } from "fs/promises";
|
|
@@ -20074,6 +20074,8 @@ var TOOL_TIERS = Object.freeze({
|
|
|
20074
20074
|
// ── Post editor: reads ──────────────────────────────────────────
|
|
20075
20075
|
editor_read: "read",
|
|
20076
20076
|
editor_read_structure: "read",
|
|
20077
|
+
editor_read_document: "read",
|
|
20078
|
+
editor_operation_status: "read",
|
|
20077
20079
|
// ── Post editor: writes ─────────────────────────────────────────
|
|
20078
20080
|
//
|
|
20079
20081
|
// Every injection is bracketed by a vendor autosave, plus a separate copy
|
|
@@ -22749,41 +22751,57 @@ function runDaemon(env, deps = {}) {
|
|
|
22749
22751
|
|
|
22750
22752
|
// ../mcp-server/dist/index.js
|
|
22751
22753
|
import { spawnSync } from "child_process";
|
|
22752
|
-
function
|
|
22753
|
-
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) {
|
|
22754
22771
|
if (platform === "win32") {
|
|
22755
|
-
return {
|
|
22756
|
-
command: "powershell",
|
|
22757
|
-
args: [
|
|
22758
|
-
"-NoProfile",
|
|
22759
|
-
"-Command",
|
|
22760
|
-
`Get-NetTCPConnection -LocalPort ${p} -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
22761
|
-
],
|
|
22762
|
-
shell: true
|
|
22763
|
-
};
|
|
22772
|
+
return { command: "netstat", args: ["-ano", "-p", "TCP"] };
|
|
22764
22773
|
}
|
|
22765
22774
|
if (platform === "darwin" || platform === "linux") {
|
|
22766
|
-
return {
|
|
22767
|
-
command: "sh",
|
|
22768
|
-
args: [
|
|
22769
|
-
"-c",
|
|
22770
|
-
`pids=$(lsof -ti tcp:${p} -sTCP:LISTEN 2>/dev/null); if [ -n "$pids" ]; then kill -9 $pids; fi`
|
|
22771
|
-
],
|
|
22772
|
-
shell: false
|
|
22773
|
-
};
|
|
22775
|
+
return { command: "lsof", args: ["-ti", `tcp:${port}`, "-sTCP:LISTEN"] };
|
|
22774
22776
|
}
|
|
22775
22777
|
return null;
|
|
22776
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
|
+
}
|
|
22777
22794
|
function killPortOwner(port, platform = process.platform) {
|
|
22778
22795
|
if (process.env["VITEST"] !== void 0) return false;
|
|
22779
|
-
|
|
22780
|
-
|
|
22781
|
-
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
|
|
22785
|
-
|
|
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
|
+
}
|
|
22786
22803
|
}
|
|
22804
|
+
return signalled;
|
|
22787
22805
|
}
|
|
22788
22806
|
|
|
22789
22807
|
// src/adapter.ts
|
|
@@ -42888,6 +42906,8 @@ var TOOL_TIERS2 = Object.freeze({
|
|
|
42888
42906
|
// ── Post editor: reads ──────────────────────────────────────────
|
|
42889
42907
|
editor_read: "read",
|
|
42890
42908
|
editor_read_structure: "read",
|
|
42909
|
+
editor_read_document: "read",
|
|
42910
|
+
editor_operation_status: "read",
|
|
42891
42911
|
// ── Post editor: writes ─────────────────────────────────────────
|
|
42892
42912
|
//
|
|
42893
42913
|
// Every injection is bracketed by a vendor autosave, plus a separate copy
|
|
@@ -43631,6 +43651,7 @@ async function pushToolChanges(deps) {
|
|
|
43631
43651
|
prev = wait;
|
|
43632
43652
|
}
|
|
43633
43653
|
}
|
|
43654
|
+
var SESSION_EXIT_GRACE_MS = 200;
|
|
43634
43655
|
async function selfUpdateAndRestart(selfVersion, log, deps = {}) {
|
|
43635
43656
|
if (!selfVersion) return false;
|
|
43636
43657
|
const target = await (deps.resolve ?? canonicalVersion)();
|
|
@@ -43699,11 +43720,22 @@ async function runAdapter(deps = {}) {
|
|
|
43699
43720
|
const port = deps.port ?? DEFAULT_PORT;
|
|
43700
43721
|
const controller = new AbortController();
|
|
43701
43722
|
const prevOnClose = transport.onclose;
|
|
43723
|
+
const exit = deps.exit ?? (deps.transport ? null : process.exit.bind(process));
|
|
43702
43724
|
transport.onclose = () => {
|
|
43703
43725
|
if (watch) clearInterval(watch);
|
|
43704
43726
|
controller.abort();
|
|
43705
43727
|
prevOnClose?.();
|
|
43728
|
+
if (exit) setTimeout(exit, SESSION_EXIT_GRACE_MS, 0);
|
|
43706
43729
|
};
|
|
43730
|
+
const stdin = deps.stdin ?? (deps.transport ? null : process.stdin);
|
|
43731
|
+
if (stdin) {
|
|
43732
|
+
const endSession = () => {
|
|
43733
|
+
void transport.close().catch(() => {
|
|
43734
|
+
});
|
|
43735
|
+
};
|
|
43736
|
+
stdin.once("end", endSession);
|
|
43737
|
+
stdin.once("close", endSession);
|
|
43738
|
+
}
|
|
43707
43739
|
void pushToolChanges({
|
|
43708
43740
|
mcpUrl: `http://${host}:${port}/mcp`,
|
|
43709
43741
|
notifyHost: () => server.notification({ method: "notifications/tools/list_changed" }).catch(() => {
|
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;
|
|
@@ -2185,7 +2204,7 @@ async function runInstall(opts, io) {
|
|
|
2185
2204
|
if (staged === null || staged.length === 0) {
|
|
2186
2205
|
printBody(
|
|
2187
2206
|
(line) => io.out(line),
|
|
2188
|
-
"\uC774 \uC124\uCE58 \uD30C\uC77C\uC5D0\uB294 \uC2A4\uD0AC\uC774 \uC5C6\uC5B4 \uC5F0\uACB0 \uD504\uB85C\uADF8\uB7A8\uB9CC \uC124\uCE58\
|
|
2207
|
+
"\uC774 \uC124\uCE58 \uD30C\uC77C\uC5D0\uB294 \uC2A4\uD0AC\uC774 \uC5C6\uC5B4 \uC5F0\uACB0 \uD504\uB85C\uADF8\uB7A8\uB9CC \uC124\uCE58\uD574\uC694."
|
|
2189
2208
|
);
|
|
2190
2209
|
} else {
|
|
2191
2210
|
skillPlan = await chooseSkillSelection(io, staged, {
|
|
@@ -2199,7 +2218,7 @@ async function runInstall(opts, io) {
|
|
|
2199
2218
|
}
|
|
2200
2219
|
printBody(
|
|
2201
2220
|
(line) => io.out(line),
|
|
2202
|
-
`\uCD94\uCC9C ${skillPlan.defaultCount}\uAC1C + \uC120\uD0DD ${skillPlan.selected.size}\uAC1C = ${skillPlan.total}\uAC1C\uB97C \uC124\uCE58\
|
|
2221
|
+
`\uCD94\uCC9C ${skillPlan.defaultCount}\uAC1C + \uC120\uD0DD ${skillPlan.selected.size}\uAC1C = ${skillPlan.total}\uAC1C\uB97C \uC124\uCE58\uD574\uC694.`
|
|
2203
2222
|
);
|
|
2204
2223
|
}
|
|
2205
2224
|
}
|
|
@@ -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.d.ts
CHANGED
|
@@ -132,6 +132,10 @@ interface RunAdapterDeps extends AdapterServerDeps {
|
|
|
132
132
|
subscribe?: SubscribeImpl;
|
|
133
133
|
/** false pins this build — `--no-self-update`. Default promotes to canonical. */
|
|
134
134
|
selfUpdate?: boolean;
|
|
135
|
+
/** Injected in tests; the host's end of the session. Defaults to process.stdin. */
|
|
136
|
+
stdin?: NodeJS.EventEmitter;
|
|
137
|
+
/** Injected in tests; defaults to process.exit. */
|
|
138
|
+
exit?: (code: number) => void;
|
|
135
139
|
}
|
|
136
140
|
declare function runAdapter(deps?: RunAdapterDeps): Promise<void>;
|
|
137
141
|
interface CliHandlers {
|
package/dist/index.js
CHANGED