@modootoday/datalab-extension-mcp 1.8.10 → 1.8.11
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 +11 -11
- package/README.md +11 -11
- package/dist/{browsers-AGEUPMJA.js → browsers-EMS5V4M4.js} +3 -3
- package/dist/{chunk-YB7L4SZC.js → chunk-65FDP6LF.js} +15 -4
- package/dist/{chunk-DOPJ4OZ4.js → chunk-Q6SOGGKF.js} +157 -93
- package/dist/{chunk-5S7RFXIU.js → chunk-S6D7YVBB.js} +1 -1
- package/dist/cli.js +6 -6
- package/dist/{dist-JICXADYR.js → dist-63JYX33Z.js} +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -55,10 +55,10 @@ Avoid sharing a screenshot or the copied setup. If it may have leaked, press **[
|
|
|
55
55
|
One command finds **every** AI app on your computer and connects them automatically. Nothing to do per app.
|
|
56
56
|
|
|
57
57
|
1. **Open a terminal** — on Windows type `cmd` in the search box → "Command Prompt"; on Mac press `⌘+Space` and type `Terminal`; on Linux open your terminal app (often `Ctrl+Alt+T`).
|
|
58
|
-
2. **Paste this command and press Enter.** (`@1.8.
|
|
58
|
+
2. **Paste this command and press Enter.** (`@1.8.11` is the pinned version, so the connector never changes behind your back.)
|
|
59
59
|
|
|
60
60
|
```
|
|
61
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
61
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 install
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Lines of English scrolling by is normal. This only downloads and runs the connector — it touches nothing else.
|
|
@@ -130,10 +130,10 @@ Apps it **only prints instructions for** (follow the on-screen guide): VS Code,
|
|
|
130
130
|
Installing also places the bundled **writing skills**. An AI app reads the name and description of every installed skill on every start, so the more are installed the less room the conversation has. The default therefore places only the ones that work right away.
|
|
131
131
|
|
|
132
132
|
```
|
|
133
|
-
npx -y @modootoday/datalab-extension-mcp skills list
|
|
134
|
-
npx -y @modootoday/datalab-extension-mcp skills status
|
|
135
|
-
npx -y @modootoday/datalab-extension-mcp skills attach <name>
|
|
136
|
-
npx -y @modootoday/datalab-extension-mcp skills detach <name>
|
|
133
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills list
|
|
134
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills status
|
|
135
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills attach <name>
|
|
136
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills detach <name>
|
|
137
137
|
```
|
|
138
138
|
|
|
139
139
|
- `list` shows everything in this version, name and description.
|
|
@@ -152,9 +152,9 @@ The **workbench** is this computer, where the connector runs. If you use more th
|
|
|
152
152
|
Make the code from the panel with [등록 코드 만들기], or from the terminal.
|
|
153
153
|
|
|
154
154
|
```
|
|
155
|
-
npx -y @modootoday/datalab-extension-mcp browsers add "Work Chrome"
|
|
156
|
-
npx -y @modootoday/datalab-extension-mcp browsers list
|
|
157
|
-
npx -y @modootoday/datalab-extension-mcp browsers revoke <handle>
|
|
155
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers add "Work Chrome"
|
|
156
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers list
|
|
157
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers revoke <handle>
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
`add` **asks you to paste the pairing token** — the same value you used to
|
|
@@ -252,7 +252,7 @@ Start it again after a full quit and it picks the tools up. If they still aren't
|
|
|
252
252
|
- **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.)
|
|
253
253
|
|
|
254
254
|
```
|
|
255
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
255
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 install
|
|
256
256
|
```
|
|
257
257
|
|
|
258
258
|
- **`'npx' is not recognized...`** — Node.js isn't installed. The "No Node.js?" one-liner in Step 2 is the simplest fix.
|
|
@@ -282,7 +282,7 @@ Start it again after a full quit and it picks the tools up. If they still aren't
|
|
|
282
282
|
1. Run this in a terminal (it removes the entries registered in your AI apps).
|
|
283
283
|
|
|
284
284
|
```
|
|
285
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
285
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 uninstall
|
|
286
286
|
```
|
|
287
287
|
|
|
288
288
|
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
|
@@ -49,10 +49,10 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
49
49
|
명령 한 줄이면 컴퓨터에 있는 AI 앱을 **모두 자동으로** 찾아 연결해 줘요. 앱마다 따로 할 일은 없어요.
|
|
50
50
|
|
|
51
51
|
1. **터미널을 열어요** — Windows는 검색창에 `cmd` → "명령 프롬프트", Mac은 `⌘+스페이스`로 `터미널`, Linux는 터미널 앱(보통 `Ctrl+Alt+T`)이에요.
|
|
52
|
-
2. **아래 명령을 붙여넣고 Enter를 눌러요.** (`@1.8.
|
|
52
|
+
2. **아래 명령을 붙여넣고 Enter를 눌러요.** (`@1.8.11`은 커넥터가 나도 모르게 바뀌지 않도록 고정한 버전이에요.)
|
|
53
53
|
|
|
54
54
|
```
|
|
55
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
55
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 install
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
영어 글자가 여러 줄 올라오는 건 정상이에요. 이 명령은 커넥터를 내려받아 실행할 뿐, 다른 건 건드리지 않아요.
|
|
@@ -118,10 +118,10 @@ Claude 같은 AI 앱을 데이터랩툴즈에 연결해 주는 작은 무료 프
|
|
|
118
118
|
설치할 때 **글쓰기 도움말(스킬)** 도 함께 놓입니다. AI 앱은 켜질 때마다 설치된 도움말의 이름과 설명을 전부 읽기 때문에, 많이 깔수록 대화에 쓸 자리가 줄어들어요. 그래서 기본은 **바로 쓸 수 있는 것만** 놓습니다.
|
|
119
119
|
|
|
120
120
|
```
|
|
121
|
-
npx -y @modootoday/datalab-extension-mcp skills list
|
|
122
|
-
npx -y @modootoday/datalab-extension-mcp skills status
|
|
123
|
-
npx -y @modootoday/datalab-extension-mcp skills attach <이름>
|
|
124
|
-
npx -y @modootoday/datalab-extension-mcp skills detach <이름>
|
|
121
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills list
|
|
122
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills status
|
|
123
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills attach <이름>
|
|
124
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 skills detach <이름>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
- `list` 는 이 버전에 들어 있는 전부를 이름과 설명으로 보여 줘요.
|
|
@@ -140,9 +140,9 @@ npx -y @modootoday/datalab-extension-mcp skills detach <이름>
|
|
|
140
140
|
패널에서 [등록 코드 만들기]를 눌러도 되고, 터미널을 쓰셔도 돼요.
|
|
141
141
|
|
|
142
142
|
```
|
|
143
|
-
npx -y @modootoday/datalab-extension-mcp browsers add "회사 크롬"
|
|
144
|
-
npx -y @modootoday/datalab-extension-mcp browsers list
|
|
145
|
-
npx -y @modootoday/datalab-extension-mcp browsers revoke <handle>
|
|
143
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers add "회사 크롬"
|
|
144
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers list
|
|
145
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 browsers revoke <handle>
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
`add` 를 실행하면 **연결 토큰을 붙여넣으라고 물어봐요** — 설치할 때와 같은 값이고, 패널의 `복사` 버튼으로 얻습니다. 그러면 코드가 **한 번만** 출력돼요. 커넥터는 그 코드를 저장하지 않고 지문만 남기므로 다시 보여 줄 수 없어요.
|
|
@@ -220,7 +220,7 @@ AI가 "그런 기능은 없다" 고 답하면, **"도구 목록을 확인해 보
|
|
|
220
220
|
- **연결이 사라졌을 때** — 처음 실행했던 그 명령을 한 번 더 실행하면 안전하게 다시 등록돼요. (일부 AI 앱이 설정 파일을 정리하며 연결을 지우기도 해요.)
|
|
221
221
|
|
|
222
222
|
```
|
|
223
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
223
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 install
|
|
224
224
|
```
|
|
225
225
|
|
|
226
226
|
- **`'npx'을(는) 내부 또는 외부 명령...`** — Node.js가 없는 거예요. 위 2단계의 "Node.js가 없다면" 한 줄 설치가 가장 간단해요.
|
|
@@ -250,7 +250,7 @@ AI가 "그런 기능은 없다" 고 답하면, **"도구 목록을 확인해 보
|
|
|
250
250
|
1. 터미널에서 아래 명령을 실행해요(AI 앱에 등록된 설정을 지워 줘요).
|
|
251
251
|
|
|
252
252
|
```
|
|
253
|
-
npx -y @modootoday/datalab-extension-mcp@1.8.
|
|
253
|
+
npx -y @modootoday/datalab-extension-mcp@1.8.11 uninstall
|
|
254
254
|
```
|
|
255
255
|
|
|
256
256
|
2. 확장 설정에서 **MCP 연결을 꺼요.** 패널이 브릿지라, 꺼 두면 어딘가 설정 줄이 남아 있어도 AI 앱이 아무것도 조회할 수 없어요.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_HOST,
|
|
3
3
|
DEFAULT_PORT
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q6SOGGKF.js";
|
|
5
5
|
import {
|
|
6
6
|
TOKEN_PROMPT_GUIDE,
|
|
7
7
|
TOKEN_PROMPT_QUESTION,
|
|
8
8
|
TOKEN_REQUIRED_NON_INTERACTIVE
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-S6D7YVBB.js";
|
|
10
10
|
import "./chunk-MLKGABMK.js";
|
|
11
11
|
|
|
12
12
|
// src/browsers.ts
|
|
@@ -105,7 +105,7 @@ async function runBrowsers(argv, deps) {
|
|
|
105
105
|
return 0;
|
|
106
106
|
}
|
|
107
107
|
for (const row of rows) {
|
|
108
|
-
const state = row.browserId === null ? "waiting" : "connected";
|
|
108
|
+
const state = row.browserId === null ? "waiting" : row.connected === true ? "connected" : "detached";
|
|
109
109
|
deps.out(`${row.handle} ${state.padEnd(9)} ${row.label}`);
|
|
110
110
|
}
|
|
111
111
|
return 0;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
mediaToolDescriptors,
|
|
5
5
|
spawnDaemon,
|
|
6
6
|
tryConnect
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-Q6SOGGKF.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -14583,6 +14583,14 @@ var HelloSchema = external_exports.object({
|
|
|
14583
14583
|
*/
|
|
14584
14584
|
capabilities: external_exports.array(external_exports.string()).default([])
|
|
14585
14585
|
});
|
|
14586
|
+
var BRIDGE_AUTH_CAPABILITY = "bridge-auth-bearer";
|
|
14587
|
+
var BROWSER_ROUTING_CAPABILITY = "browser-routing-v1";
|
|
14588
|
+
var LOCAL_FILE_REQUEST_CAPABILITY = "local-file-request-v1";
|
|
14589
|
+
var REQUIRED_BROWSER_CAPABILITIES = Object.freeze([
|
|
14590
|
+
BRIDGE_AUTH_CAPABILITY,
|
|
14591
|
+
BROWSER_ROUTING_CAPABILITY,
|
|
14592
|
+
LOCAL_FILE_REQUEST_CAPABILITY
|
|
14593
|
+
]);
|
|
14586
14594
|
var HelloAckSchema = external_exports.object({
|
|
14587
14595
|
t: external_exports.literal("hello_ack"),
|
|
14588
14596
|
/** The single version both sides will use for this session. */
|
|
@@ -14603,7 +14611,9 @@ var HelloNackReasonSchema = external_exports.enum([
|
|
|
14603
14611
|
/** This browser already has an active event stream. */
|
|
14604
14612
|
"session_active",
|
|
14605
14613
|
/** Root authority cannot open a browser session. */
|
|
14606
|
-
"browser_registration_required"
|
|
14614
|
+
"browser_registration_required",
|
|
14615
|
+
/** This panel predates mandatory browser routing and file permits. */
|
|
14616
|
+
"browser_capability_required"
|
|
14607
14617
|
]);
|
|
14608
14618
|
var BrowserRoutingSchema = external_exports.object({
|
|
14609
14619
|
targetBrowserId: external_exports.string(),
|
|
@@ -15033,6 +15043,7 @@ var REASON_POLICY = Object.freeze({
|
|
|
15033
15043
|
// --- The request itself must change ---
|
|
15034
15044
|
unknown_tool: Object.freeze({ retryable: false }),
|
|
15035
15045
|
invalid_args: Object.freeze({ retryable: false }),
|
|
15046
|
+
browser_required: Object.freeze({ retryable: false }),
|
|
15036
15047
|
tool_closed: Object.freeze({ retryable: false }),
|
|
15037
15048
|
missing_in_build: Object.freeze({ retryable: false }),
|
|
15038
15049
|
// --- A human must act; re-calling only nags them ---
|
|
@@ -15446,7 +15457,7 @@ var BRIDGE_USER_MESSAGES = Object.freeze({
|
|
|
15446
15457
|
panelClosed: "\uD06C\uB86C\uC5D0\uC11C \uB370\uC774\uD130\uB7A9\uD234\uC988 \uD328\uB110\uC774 \uB2EB\uD600 \uC788\uC5B4\uC694. \uD06C\uB86C\uC744 \uC5F4\uACE0 \uB370\uC774\uD130\uB7A9\uD234\uC988 \uD328\uB110\uC744 \uC5F4\uC5B4 \uB450\uBA74 \uBC14\uB85C \uB3D9\uC791\uD574\uC694.",
|
|
15447
15458
|
/** The panel accepted the call but never answered inside the deadline. */
|
|
15448
15459
|
toolTimeout: "\uBE0C\uB77C\uC6B0\uC800 \uC751\uB2F5\uC774 \uB2A6\uC5B4\uC9C0\uACE0 \uC788\uC5B4\uC694. \uD06C\uB86C\uC5D0\uC11C \uB124\uC774\uBC84\uC5D0 \uB85C\uADF8\uC778\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
15449
|
-
/** The
|
|
15460
|
+
/** The daemon request budget is empty. */
|
|
15450
15461
|
rateLimited: "\uC694\uCCAD\uC774 \uB108\uBB34 \uC7A6\uC544\uC694. \uC7A0\uAE50 \uAE30\uB2E4\uB838\uB2E4\uAC00 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
15451
15462
|
/**
|
|
15452
15463
|
* The local connector accepted nothing back inside its ceiling. Distinct
|
|
@@ -15458,7 +15469,7 @@ var BRIDGE_USER_MESSAGES = Object.freeze({
|
|
|
15458
15469
|
var BRIDGE_AGENT_HINT = Object.freeze({
|
|
15459
15470
|
/** Panel closed / not connected — the panel must be open for any tool to run. */
|
|
15460
15471
|
notConnected: "The Datalab extension side panel is not open, so this tool cannot run right now. Ask the user to open the extension side panel in their browser, then call this tool again.",
|
|
15461
|
-
/**
|
|
15472
|
+
/** Daemon-wide rate limit tripped — transient. */
|
|
15462
15473
|
rateLimited: "This tool is temporarily rate-limited. Wait a few seconds, then call it again.",
|
|
15463
15474
|
/** The local connector did not answer at all — retrying immediately will not help. */
|
|
15464
15475
|
connectorStuck: "The local connector stopped responding, so this tool cannot run right now. Do not retry immediately; ask the user to turn the MCP connection off and on again in the extension side panel."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../mcp-server/dist/chunk-
|
|
1
|
+
// ../mcp-server/dist/chunk-377F4BGN.js
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
3
|
import { createHash as createHash2, randomUUID } from "crypto";
|
|
4
4
|
import { mkdir, readFile, readdir, rm, writeFile } from "fs/promises";
|
|
@@ -14439,6 +14439,11 @@ var HelloSchema = external_exports.object({
|
|
|
14439
14439
|
var BRIDGE_AUTH_CAPABILITY = "bridge-auth-bearer";
|
|
14440
14440
|
var BROWSER_ROUTING_CAPABILITY = "browser-routing-v1";
|
|
14441
14441
|
var LOCAL_FILE_REQUEST_CAPABILITY = "local-file-request-v1";
|
|
14442
|
+
var REQUIRED_BROWSER_CAPABILITIES = Object.freeze([
|
|
14443
|
+
BRIDGE_AUTH_CAPABILITY,
|
|
14444
|
+
BROWSER_ROUTING_CAPABILITY,
|
|
14445
|
+
LOCAL_FILE_REQUEST_CAPABILITY
|
|
14446
|
+
]);
|
|
14442
14447
|
function bearerToken(header) {
|
|
14443
14448
|
if (typeof header !== "string") return null;
|
|
14444
14449
|
const match = /^Bearer (.+)$/i.exec(header.trim());
|
|
@@ -14464,7 +14469,9 @@ var HelloNackReasonSchema = external_exports.enum([
|
|
|
14464
14469
|
/** This browser already has an active event stream. */
|
|
14465
14470
|
"session_active",
|
|
14466
14471
|
/** Root authority cannot open a browser session. */
|
|
14467
|
-
"browser_registration_required"
|
|
14472
|
+
"browser_registration_required",
|
|
14473
|
+
/** This panel predates mandatory browser routing and file permits. */
|
|
14474
|
+
"browser_capability_required"
|
|
14468
14475
|
]);
|
|
14469
14476
|
var BrowserRoutingSchema = external_exports.object({
|
|
14470
14477
|
targetBrowserId: external_exports.string(),
|
|
@@ -15024,6 +15031,7 @@ var REASON_POLICY = Object.freeze({
|
|
|
15024
15031
|
// --- The request itself must change ---
|
|
15025
15032
|
unknown_tool: Object.freeze({ retryable: false }),
|
|
15026
15033
|
invalid_args: Object.freeze({ retryable: false }),
|
|
15034
|
+
browser_required: Object.freeze({ retryable: false }),
|
|
15027
15035
|
tool_closed: Object.freeze({ retryable: false }),
|
|
15028
15036
|
missing_in_build: Object.freeze({ retryable: false }),
|
|
15029
15037
|
// --- A human must act; re-calling only nags them ---
|
|
@@ -15492,7 +15500,7 @@ var BRIDGE_USER_MESSAGES = Object.freeze({
|
|
|
15492
15500
|
panelClosed: "\uD06C\uB86C\uC5D0\uC11C \uB370\uC774\uD130\uB7A9\uD234\uC988 \uD328\uB110\uC774 \uB2EB\uD600 \uC788\uC5B4\uC694. \uD06C\uB86C\uC744 \uC5F4\uACE0 \uB370\uC774\uD130\uB7A9\uD234\uC988 \uD328\uB110\uC744 \uC5F4\uC5B4 \uB450\uBA74 \uBC14\uB85C \uB3D9\uC791\uD574\uC694.",
|
|
15493
15501
|
/** The panel accepted the call but never answered inside the deadline. */
|
|
15494
15502
|
toolTimeout: "\uBE0C\uB77C\uC6B0\uC800 \uC751\uB2F5\uC774 \uB2A6\uC5B4\uC9C0\uACE0 \uC788\uC5B4\uC694. \uD06C\uB86C\uC5D0\uC11C \uB124\uC774\uBC84\uC5D0 \uB85C\uADF8\uC778\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
15495
|
-
/** The
|
|
15503
|
+
/** The daemon request budget is empty. */
|
|
15496
15504
|
rateLimited: "\uC694\uCCAD\uC774 \uB108\uBB34 \uC7A6\uC544\uC694. \uC7A0\uAE50 \uAE30\uB2E4\uB838\uB2E4\uAC00 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
15497
15505
|
/**
|
|
15498
15506
|
* The local connector accepted nothing back inside its ceiling. Distinct
|
|
@@ -15504,7 +15512,7 @@ var BRIDGE_USER_MESSAGES = Object.freeze({
|
|
|
15504
15512
|
var BRIDGE_AGENT_HINT = Object.freeze({
|
|
15505
15513
|
/** Panel closed / not connected — the panel must be open for any tool to run. */
|
|
15506
15514
|
notConnected: "The Datalab extension side panel is not open, so this tool cannot run right now. Ask the user to open the extension side panel in their browser, then call this tool again.",
|
|
15507
|
-
/**
|
|
15515
|
+
/** Daemon-wide rate limit tripped — transient. */
|
|
15508
15516
|
rateLimited: "This tool is temporarily rate-limited. Wait a few seconds, then call it again.",
|
|
15509
15517
|
/** The local connector did not answer at all — retrying immediately will not help. */
|
|
15510
15518
|
connectorStuck: "The local connector stopped responding, so this tool cannot run right now. Do not retry immediately; ask the user to turn the MCP connection off and on again in the extension side panel."
|
|
@@ -15634,7 +15642,6 @@ var Bridge = class {
|
|
|
15634
15642
|
#idTag = daemonIdTag();
|
|
15635
15643
|
#sessionSeq = 0;
|
|
15636
15644
|
#defaultKey = null;
|
|
15637
|
-
#retireSession = null;
|
|
15638
15645
|
#bucketTokens = 0;
|
|
15639
15646
|
#bucketRefilledAt = 0;
|
|
15640
15647
|
// Last catalog the panel reported, kept across disconnects: many hosts cache
|
|
@@ -15643,12 +15650,9 @@ var Bridge = class {
|
|
|
15643
15650
|
#cachedTools = [];
|
|
15644
15651
|
constructor(deps) {
|
|
15645
15652
|
this.#deps = deps;
|
|
15646
|
-
|
|
15647
|
-
|
|
15648
|
-
|
|
15649
|
-
throw new Error("bridge transport retirement is already bound");
|
|
15650
|
-
}
|
|
15651
|
-
this.#retireSession = retire;
|
|
15653
|
+
const limit = deps.rateLimit ?? DEFAULT_RATE_LIMIT;
|
|
15654
|
+
this.#bucketTokens = limit.capacity;
|
|
15655
|
+
this.#bucketRefilledAt = (deps.now ?? Date.now)();
|
|
15652
15656
|
}
|
|
15653
15657
|
/**
|
|
15654
15658
|
* The session a request with no browser named goes to. Map preserves
|
|
@@ -15674,7 +15678,7 @@ var Bridge = class {
|
|
|
15674
15678
|
*/
|
|
15675
15679
|
connectedBrowsers() {
|
|
15676
15680
|
const keys = [...this.#sessions.values()].filter((entry) => entry.streamActive).map((entry) => entry.key);
|
|
15677
|
-
const primary = this.#
|
|
15681
|
+
const primary = this.#primary()?.key ?? null;
|
|
15678
15682
|
return keys.map((id) => ({
|
|
15679
15683
|
id,
|
|
15680
15684
|
name: this.#deps.browserLabels.get(id) ?? null,
|
|
@@ -15946,6 +15950,32 @@ var Bridge = class {
|
|
|
15946
15950
|
message: idCheck.message
|
|
15947
15951
|
};
|
|
15948
15952
|
}
|
|
15953
|
+
const negotiated = negotiateProtocol(parsed.data.protocolVersions);
|
|
15954
|
+
if (!negotiated.ok) {
|
|
15955
|
+
return {
|
|
15956
|
+
t: "hello_nack",
|
|
15957
|
+
reason: negotiated.reason,
|
|
15958
|
+
supported: negotiated.supported,
|
|
15959
|
+
message: negotiated.message
|
|
15960
|
+
};
|
|
15961
|
+
}
|
|
15962
|
+
const bearerRequired = parsed.data.capabilities.includes(
|
|
15963
|
+
BRIDGE_AUTH_CAPABILITY
|
|
15964
|
+
);
|
|
15965
|
+
const routingRequired = parsed.data.capabilities.includes(
|
|
15966
|
+
BROWSER_ROUTING_CAPABILITY
|
|
15967
|
+
);
|
|
15968
|
+
const fileRequestBound = parsed.data.capabilities.includes(
|
|
15969
|
+
LOCAL_FILE_REQUEST_CAPABILITY
|
|
15970
|
+
);
|
|
15971
|
+
if (!bearerRequired || !routingRequired || !fileRequestBound) {
|
|
15972
|
+
return {
|
|
15973
|
+
t: "hello_nack",
|
|
15974
|
+
reason: "browser_capability_required",
|
|
15975
|
+
supported: [],
|
|
15976
|
+
message: "This browser panel is outdated. Close and reopen the side panel before reconnecting."
|
|
15977
|
+
};
|
|
15978
|
+
}
|
|
15949
15979
|
const tokenHash = digestToken(parsed.data.token);
|
|
15950
15980
|
const browserId = parsed.data.browserId;
|
|
15951
15981
|
if (browserId !== void 0 && browserId.length > 0 && !this.#deps.claimedBrowsers.has(browserId)) {
|
|
@@ -15974,19 +16004,15 @@ var Bridge = class {
|
|
|
15974
16004
|
message: "The root token is management-only. Register this browser with its own token."
|
|
15975
16005
|
};
|
|
15976
16006
|
}
|
|
15977
|
-
const negotiated = negotiateProtocol(parsed.data.protocolVersions);
|
|
15978
|
-
if (!negotiated.ok) {
|
|
15979
|
-
return {
|
|
15980
|
-
t: "hello_nack",
|
|
15981
|
-
reason: negotiated.reason,
|
|
15982
|
-
supported: negotiated.supported,
|
|
15983
|
-
message: negotiated.message
|
|
15984
|
-
};
|
|
15985
|
-
}
|
|
15986
16007
|
const key = credential.browserId;
|
|
15987
16008
|
const held = this.#sessions.get(key);
|
|
15988
16009
|
if (held?.streamActive) {
|
|
15989
|
-
|
|
16010
|
+
return {
|
|
16011
|
+
t: "hello_nack",
|
|
16012
|
+
reason: "session_active",
|
|
16013
|
+
supported: [],
|
|
16014
|
+
message: "This browser already has an active side-panel session."
|
|
16015
|
+
};
|
|
15990
16016
|
}
|
|
15991
16017
|
const session = {
|
|
15992
16018
|
// A counter, not a timestamp: a panel reload produces two handshakes
|
|
@@ -15996,28 +16022,17 @@ var Bridge = class {
|
|
|
15996
16022
|
protocolVersion: negotiated.version,
|
|
15997
16023
|
extensionVersion: parsed.data.extensionVersion
|
|
15998
16024
|
};
|
|
15999
|
-
const routingRequired = credential.kind === "claimed" && parsed.data.capabilities.includes(BROWSER_ROUTING_CAPABILITY);
|
|
16000
|
-
const fileRequestBound = parsed.data.capabilities.includes(
|
|
16001
|
-
LOCAL_FILE_REQUEST_CAPABILITY
|
|
16002
|
-
);
|
|
16003
16025
|
this.#installSession(key, session, {
|
|
16004
16026
|
tokenHash,
|
|
16005
16027
|
routingRequired,
|
|
16006
16028
|
fileRequestBound
|
|
16007
16029
|
});
|
|
16008
|
-
const limit = this.#deps.rateLimit ?? DEFAULT_RATE_LIMIT;
|
|
16009
|
-
this.#bucketTokens = limit.capacity;
|
|
16010
|
-
this.#bucketRefilledAt = (this.#deps.now ?? Date.now)();
|
|
16011
16030
|
return {
|
|
16012
16031
|
t: "hello_ack",
|
|
16013
16032
|
protocolVersion: negotiated.version,
|
|
16014
16033
|
serverVersion: this.#deps.serverVersion,
|
|
16015
16034
|
sessionId: session.sessionId,
|
|
16016
|
-
capabilities: [
|
|
16017
|
-
BRIDGE_AUTH_CAPABILITY,
|
|
16018
|
-
...routingRequired ? [BROWSER_ROUTING_CAPABILITY] : [],
|
|
16019
|
-
...fileRequestBound ? [LOCAL_FILE_REQUEST_CAPABILITY] : []
|
|
16020
|
-
]
|
|
16035
|
+
capabilities: [...REQUIRED_BROWSER_CAPABILITIES]
|
|
16021
16036
|
};
|
|
16022
16037
|
}
|
|
16023
16038
|
/**
|
|
@@ -16209,7 +16224,7 @@ var Bridge = class {
|
|
|
16209
16224
|
};
|
|
16210
16225
|
}
|
|
16211
16226
|
/**
|
|
16212
|
-
* Refill-then-take on the
|
|
16227
|
+
* Refill-then-take on the daemon's token bucket. The refill is computed
|
|
16213
16228
|
* lazily on each take, so there is no timer to leak and an injected clock
|
|
16214
16229
|
* keeps it testable without waiting real seconds.
|
|
16215
16230
|
*/
|
|
@@ -17137,13 +17152,6 @@ function createHttpBridge(opts) {
|
|
|
17137
17152
|
opts.bridge.disconnect(key);
|
|
17138
17153
|
if (wasPrimary) scheduleToolsDrop();
|
|
17139
17154
|
};
|
|
17140
|
-
opts.bridge.bindRetireSession((key, sessionId) => {
|
|
17141
|
-
const stream = streams.get(key);
|
|
17142
|
-
if (!stream || stream.sessionId !== sessionId) return;
|
|
17143
|
-
const wasPrimary = key === opts.bridge.sessionKey;
|
|
17144
|
-
removeStream(key)?.end();
|
|
17145
|
-
if (wasPrimary) scheduleToolsDrop();
|
|
17146
|
-
});
|
|
17147
17155
|
const server = createServer((req, res) => {
|
|
17148
17156
|
const url2 = new URL(req.url ?? "/", `http://${host}`);
|
|
17149
17157
|
const origin = req.headers.origin;
|
|
@@ -17286,9 +17294,16 @@ function createHttpBridge(opts) {
|
|
|
17286
17294
|
}
|
|
17287
17295
|
const action = b?.["action"];
|
|
17288
17296
|
if (action === "list") {
|
|
17297
|
+
const active = new Set(
|
|
17298
|
+
opts.bridge.connectedBrowsers().map((row) => row.id)
|
|
17299
|
+
);
|
|
17300
|
+
const browsers = (await registry2.list()).map((row) => ({
|
|
17301
|
+
...row,
|
|
17302
|
+
connected: row.browserId !== null && active.has(row.browserId)
|
|
17303
|
+
}));
|
|
17289
17304
|
json2(res, 200, {
|
|
17290
17305
|
ok: true,
|
|
17291
|
-
browsers
|
|
17306
|
+
browsers,
|
|
17292
17307
|
registryStatus: registry2.status()
|
|
17293
17308
|
});
|
|
17294
17309
|
return;
|
|
@@ -17854,24 +17869,54 @@ function matches(claim, handle) {
|
|
|
17854
17869
|
function createBrowserRegistry(opts) {
|
|
17855
17870
|
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
17856
17871
|
const revoked = /* @__PURE__ */ new Set();
|
|
17857
|
-
const
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
if (
|
|
17864
|
-
|
|
17872
|
+
const initial = readLedger(opts.path);
|
|
17873
|
+
const unreadable = initial.state === "unreadable" ? initial.reason : null;
|
|
17874
|
+
let rows = initial.state === "ok" ? initial.rows.map((row) => ({ ...row })) : [];
|
|
17875
|
+
let mutationTail = Promise.resolve();
|
|
17876
|
+
let pendingMutations = 0;
|
|
17877
|
+
const view = (source = rows) => {
|
|
17878
|
+
if (unreadable !== null) {
|
|
17879
|
+
throw new Error(`browser registry is unreadable: ${unreadable}`);
|
|
17880
|
+
}
|
|
17881
|
+
if (!opts.forbiddenTokenHash) return { rows: [...source], quarantined: [] };
|
|
17882
|
+
const quarantined = source.filter(
|
|
17865
17883
|
(row) => timingSafeEqual(row.tokenHash, opts.forbiddenTokenHash)
|
|
17866
17884
|
);
|
|
17867
17885
|
return {
|
|
17868
|
-
rows:
|
|
17886
|
+
rows: source.filter(
|
|
17869
17887
|
(row) => !timingSafeEqual(row.tokenHash, opts.forbiddenTokenHash)
|
|
17870
17888
|
),
|
|
17871
17889
|
quarantined
|
|
17872
17890
|
};
|
|
17873
17891
|
};
|
|
17874
|
-
const current = () =>
|
|
17892
|
+
const current = () => view().rows;
|
|
17893
|
+
const serialize = (work) => {
|
|
17894
|
+
pendingMutations += 1;
|
|
17895
|
+
const result = mutationTail.then(work, work);
|
|
17896
|
+
mutationTail = result.then(
|
|
17897
|
+
() => {
|
|
17898
|
+
pendingMutations -= 1;
|
|
17899
|
+
},
|
|
17900
|
+
() => {
|
|
17901
|
+
pendingMutations -= 1;
|
|
17902
|
+
}
|
|
17903
|
+
);
|
|
17904
|
+
return result;
|
|
17905
|
+
};
|
|
17906
|
+
const transact = (propose) => {
|
|
17907
|
+
if (unreadable !== null) {
|
|
17908
|
+
return Promise.reject(
|
|
17909
|
+
new Error(`browser registry is unreadable: ${unreadable}`)
|
|
17910
|
+
);
|
|
17911
|
+
}
|
|
17912
|
+
return serialize(async () => {
|
|
17913
|
+
const proposal = propose(rows.map((row) => ({ ...row })));
|
|
17914
|
+
await writeLedger(opts.path, proposal.next);
|
|
17915
|
+
rows = proposal.next;
|
|
17916
|
+
proposal.commit?.();
|
|
17917
|
+
return proposal.result;
|
|
17918
|
+
});
|
|
17919
|
+
};
|
|
17875
17920
|
return {
|
|
17876
17921
|
async add(label) {
|
|
17877
17922
|
const token = mintToken();
|
|
@@ -17881,8 +17926,10 @@ function createBrowserRegistry(opts) {
|
|
|
17881
17926
|
label,
|
|
17882
17927
|
createdAt: now().toISOString()
|
|
17883
17928
|
};
|
|
17884
|
-
|
|
17885
|
-
|
|
17929
|
+
return transact((snapshot) => ({
|
|
17930
|
+
next: [...snapshot, claim],
|
|
17931
|
+
result: { handle: handleOf(claim), token }
|
|
17932
|
+
}));
|
|
17886
17933
|
},
|
|
17887
17934
|
async list() {
|
|
17888
17935
|
return current().map((claim) => ({
|
|
@@ -17893,6 +17940,7 @@ function createBrowserRegistry(opts) {
|
|
|
17893
17940
|
}));
|
|
17894
17941
|
},
|
|
17895
17942
|
claim(browserId, tokenHash) {
|
|
17943
|
+
if (pendingMutations > 0) return false;
|
|
17896
17944
|
if (opts.claimed.has(browserId)) return false;
|
|
17897
17945
|
for (const held of opts.claimed.values()) {
|
|
17898
17946
|
if (timingSafeEqual(held, tokenHash)) return false;
|
|
@@ -17907,47 +17955,75 @@ function createBrowserRegistry(opts) {
|
|
|
17907
17955
|
(claim) => claim.browserId === null && timingSafeEqual(claim.tokenHash, tokenHash)
|
|
17908
17956
|
);
|
|
17909
17957
|
if (!row) return false;
|
|
17910
|
-
|
|
17958
|
+
const stored = rows.find((claim) => claim.tokenHash === row.tokenHash);
|
|
17959
|
+
if (!stored) return false;
|
|
17960
|
+
stored.browserId = browserId;
|
|
17911
17961
|
opts.claimed.set(browserId, row.tokenHash);
|
|
17912
|
-
|
|
17913
|
-
});
|
|
17962
|
+
opts.onClaim?.(browserId, stored.label);
|
|
17963
|
+
const snapshot = rows.map((entry) => ({ ...entry }));
|
|
17964
|
+
void serialize(async () => {
|
|
17965
|
+
try {
|
|
17966
|
+
await writeLedger(opts.path, snapshot);
|
|
17967
|
+
} catch (error51) {
|
|
17968
|
+
if (stored.browserId === browserId) stored.browserId = null;
|
|
17969
|
+
if (opts.claimed.get(browserId) === row.tokenHash) {
|
|
17970
|
+
opts.claimed.delete(browserId);
|
|
17971
|
+
opts.onRevoke?.(browserId);
|
|
17972
|
+
}
|
|
17973
|
+
throw error51;
|
|
17974
|
+
}
|
|
17975
|
+
}).catch(() => void 0);
|
|
17914
17976
|
return true;
|
|
17915
17977
|
},
|
|
17916
17978
|
async revoke(handle) {
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
if (!matches(claim, handle)) continue;
|
|
17923
|
-
revoked.add(claim.tokenHash);
|
|
17924
|
-
if (claim.browserId !== null) {
|
|
17925
|
-
opts.claimed.delete(claim.browserId);
|
|
17926
|
-
opts.onRevoke?.(claim.browserId);
|
|
17979
|
+
return transact((snapshot) => {
|
|
17980
|
+
const claims = view(snapshot).rows;
|
|
17981
|
+
const removed = claims.filter((claim) => matches(claim, handle));
|
|
17982
|
+
if (removed.length === 0) {
|
|
17983
|
+
return { next: snapshot, result: false };
|
|
17927
17984
|
}
|
|
17928
|
-
|
|
17929
|
-
|
|
17985
|
+
const removedHashes = new Set(removed.map((claim) => claim.tokenHash));
|
|
17986
|
+
return {
|
|
17987
|
+
next: snapshot.filter((claim) => !removedHashes.has(claim.tokenHash)),
|
|
17988
|
+
result: true,
|
|
17989
|
+
commit: () => {
|
|
17990
|
+
for (const claim of removed) {
|
|
17991
|
+
revoked.add(claim.tokenHash);
|
|
17992
|
+
if (claim.browserId !== null) {
|
|
17993
|
+
opts.claimed.delete(claim.browserId);
|
|
17994
|
+
opts.onRevoke?.(claim.browserId);
|
|
17995
|
+
}
|
|
17996
|
+
}
|
|
17997
|
+
}
|
|
17998
|
+
};
|
|
17999
|
+
});
|
|
17930
18000
|
},
|
|
17931
18001
|
async repair() {
|
|
17932
|
-
|
|
17933
|
-
|
|
17934
|
-
|
|
17935
|
-
|
|
18002
|
+
return transact((snapshot) => {
|
|
18003
|
+
const currentView = view(snapshot);
|
|
18004
|
+
const removed = currentView.quarantined.map(handleOf);
|
|
18005
|
+
const removedHashes = new Set(
|
|
18006
|
+
currentView.quarantined.map((row) => row.tokenHash)
|
|
18007
|
+
);
|
|
18008
|
+
return {
|
|
18009
|
+
next: snapshot.filter((row) => !removedHashes.has(row.tokenHash)),
|
|
18010
|
+
result: { removed }
|
|
18011
|
+
};
|
|
18012
|
+
});
|
|
17936
18013
|
},
|
|
17937
18014
|
status() {
|
|
17938
|
-
|
|
17939
|
-
if (read.state === "unreadable") {
|
|
18015
|
+
if (unreadable !== null) {
|
|
17940
18016
|
return {
|
|
17941
18017
|
state: "disabled",
|
|
17942
18018
|
error: "browser_registry_unreadable",
|
|
17943
|
-
detail:
|
|
18019
|
+
detail: unreadable
|
|
17944
18020
|
};
|
|
17945
18021
|
}
|
|
17946
|
-
if (
|
|
18022
|
+
if (opts.forbiddenTokenHash && ledgerOverlapsToken(rows, opts.forbiddenTokenHash)) {
|
|
17947
18023
|
return {
|
|
17948
18024
|
state: "degraded",
|
|
17949
18025
|
error: "browser_registry_root_authority_overlap",
|
|
17950
|
-
quarantinedHandles:
|
|
18026
|
+
quarantinedHandles: rows.filter(
|
|
17951
18027
|
(row) => timingSafeEqual(row.tokenHash, opts.forbiddenTokenHash)
|
|
17952
18028
|
).map(handleOf),
|
|
17953
18029
|
recovery: "browsers repair"
|
|
@@ -18016,20 +18092,7 @@ function runDaemon(env, deps = {}) {
|
|
|
18016
18092
|
claimedBrowsers,
|
|
18017
18093
|
browserLabels,
|
|
18018
18094
|
browserRegistryStatus: () => registry2.status(),
|
|
18019
|
-
claimBrowser: (browserId, tokenHash) =>
|
|
18020
|
-
const took = registry2.claim(browserId, tokenHash);
|
|
18021
|
-
if (took) {
|
|
18022
|
-
const now = readLedger(ledgerPath(deps.home));
|
|
18023
|
-
if (now.state === "ok") {
|
|
18024
|
-
for (const row of now.rows) {
|
|
18025
|
-
if (row.browserId === browserId) {
|
|
18026
|
-
browserLabels.set(browserId, row.label);
|
|
18027
|
-
}
|
|
18028
|
-
}
|
|
18029
|
-
}
|
|
18030
|
-
}
|
|
18031
|
-
return took;
|
|
18032
|
-
},
|
|
18095
|
+
claimBrowser: (browserId, tokenHash) => registry2.claim(browserId, tokenHash),
|
|
18033
18096
|
wasRevoked: (tokenHash) => registry2.wasRevoked(tokenHash),
|
|
18034
18097
|
log
|
|
18035
18098
|
});
|
|
@@ -18038,6 +18101,7 @@ function runDaemon(env, deps = {}) {
|
|
|
18038
18101
|
const registry2 = createBrowserRegistry({
|
|
18039
18102
|
path: ledgerPath(deps.home),
|
|
18040
18103
|
claimed: claimedBrowsers,
|
|
18104
|
+
onClaim: (browserId, label) => browserLabels.set(browserId, label),
|
|
18041
18105
|
forbiddenTokenHash: rootTokenHash,
|
|
18042
18106
|
onRevoke: (browserId) => http.disconnect(browserId)
|
|
18043
18107
|
});
|
|
@@ -1109,7 +1109,7 @@ async function removeSkills(io, detectedIds, slugs) {
|
|
|
1109
1109
|
var RESTART_NOTICE = "\uB9C8\uC9C0\uB9C9 \uD55C \uB2E8\uACC4: AI \uC571\uC744 \uC644\uC804\uD788 \uC885\uB8CC\uD588\uB2E4\uAC00 \uB2E4\uC2DC \uC2E4\uD589\uD574 \uC8FC\uC138\uC694.\n(Windows: \uC791\uC5C5 \uD45C\uC2DC\uC904 \uD2B8\uB808\uC774 \uC544\uC774\uCF58\uC5D0\uC11C \uC885\uB8CC)";
|
|
1110
1110
|
var NOTHING_CHANGED = "\uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC5B4\uC694.";
|
|
1111
1111
|
var UNINSTALL_DONE = "\uC815\uB9AC\uAC00 \uB05D\uB0AC\uC5B4\uC694.";
|
|
1112
|
-
var UNINSTALL_TOKEN_REMINDER = "\uC5F0\uACB0 \
|
|
1112
|
+
var UNINSTALL_TOKEN_REMINDER = "\uC774 \uBE0C\uB77C\uC6B0\uC800\uC758 \uB85C\uCEEC \uC5F0\uACB0 \uC815\uBCF4\uB3C4 \uC9C0\uC6B0\uB824\uBA74 \uB370\uC774\uD130\uB7A9\uD234\uC988 \uD328\uB110\uC5D0\uC11C '\uC774 \uBE0C\uB77C\uC6B0\uC800 \uC5F0\uACB0 \uB044\uAE30'\uB97C \uB20C\uB7EC \uC8FC\uC138\uC694. \uC6CC\uD06C\uBCA4\uCE58 \uB4F1\uB85D\uC740 \uBE0C\uB77C\uC6B0\uC800 \uBAA9\uB85D\uC5D0\uC11C \uBCC4\uB3C4\uB85C \uB0B4\uB9B4 \uC218 \uC788\uC5B4\uC694.";
|
|
1113
1113
|
var PERMISSION_DENIED_HINT = "\uD30C\uC77C \uAD8C\uD55C \uB54C\uBB38\uC5D0 \uC124\uC815\uC744 \uC4F8 \uC218 \uC5C6\uC5C8\uC5B4\uC694. \uD30C\uC77C \uAD8C\uD55C\uC744 \uD655\uC778\uD55C \uB4A4 \uAC19\uC740 \uBA85\uB839\uC5B4\uB97C \uB2E4\uC2DC \uC2E4\uD589\uD574 \uC8FC\uC138\uC694.";
|
|
1114
1114
|
var NO_HOSTS_DETECTED = "\uC5F0\uACB0\uD560 \uC218 \uC788\uB294 AI \uD504\uB85C\uADF8\uB7A8\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.";
|
|
1115
1115
|
var SUPPORTED_APPS_HEADER = "\uC9C0\uC6D0\uD558\uB294 \uD504\uB85C\uADF8\uB7A8\uACFC \uB2E4\uC6B4\uB85C\uB4DC \uC8FC\uC18C\uC608\uC694:";
|
package/dist/cli.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
dispatchCli,
|
|
4
4
|
runAdapter
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-65FDP6LF.js";
|
|
6
6
|
import {
|
|
7
7
|
runDaemon
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Q6SOGGKF.js";
|
|
9
9
|
import "./chunk-MLKGABMK.js";
|
|
10
10
|
|
|
11
11
|
// src/cli.ts
|
|
@@ -17,7 +17,7 @@ function log(message) {
|
|
|
17
17
|
`);
|
|
18
18
|
}
|
|
19
19
|
async function runInstaller(sub, argv) {
|
|
20
|
-
const { createNodeIo, runInstall, runUninstall } = await import("./dist-
|
|
20
|
+
const { createNodeIo, runInstall, runUninstall } = await import("./dist-63JYX33Z.js");
|
|
21
21
|
const opts = { version: VERSION };
|
|
22
22
|
for (let i = 0; i < argv.length; i += 1) {
|
|
23
23
|
const flag = argv[i];
|
|
@@ -62,8 +62,8 @@ async function main() {
|
|
|
62
62
|
// Loaded lazily, like the installer: the adapter path is what an MCP host
|
|
63
63
|
// spawns and must not pay for a command only an operator types.
|
|
64
64
|
browsers: async (argv) => {
|
|
65
|
-
const { runBrowsers } = await import("./browsers-
|
|
66
|
-
const { createNodeIo } = await import("./dist-
|
|
65
|
+
const { runBrowsers } = await import("./browsers-EMS5V4M4.js");
|
|
66
|
+
const { createNodeIo } = await import("./dist-63JYX33Z.js");
|
|
67
67
|
const io = createNodeIo();
|
|
68
68
|
const code = await runBrowsers(argv, {
|
|
69
69
|
env: process.env,
|
|
@@ -88,7 +88,7 @@ async function main() {
|
|
|
88
88
|
attachSkill,
|
|
89
89
|
detachSkill,
|
|
90
90
|
skillsPayloadRoot
|
|
91
|
-
} = await import("./dist-
|
|
91
|
+
} = await import("./dist-63JYX33Z.js");
|
|
92
92
|
const io = createNodeIo();
|
|
93
93
|
const root = skillsPayloadRoot();
|
|
94
94
|
const code = await runSkills(argv, {
|
package/dist/index.js
CHANGED