@ait-co/devtools 0.1.84 → 0.1.85
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 +1 -1
- package/README.md +1 -1
- package/dist/mcp/cli.js +12 -21
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +2 -10
- package/dist/mcp/server.js.map +1 -1
- package/dist/panel/index.js +2 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -106,7 +106,7 @@ For environments 3 and 4 (intoss-private relay), the relay QR deep-link carries
|
|
|
106
106
|
|
|
107
107
|
**"QR window doesn't open"**
|
|
108
108
|
|
|
109
|
-
Either `build_attach_url` wasn't called first, or
|
|
109
|
+
Either `build_attach_url` wasn't called first, or the MCP server is running in a headless environment where no browser can be opened. The tool result always includes a text QR — scan it directly with your phone camera. On a local GUI machine, the dashboard opens automatically in the browser.
|
|
110
110
|
|
|
111
111
|
**"Page not attached" — list_pages returns an empty array**
|
|
112
112
|
|
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ import '@ait-co/devtools/in-app/auto';
|
|
|
106
106
|
|
|
107
107
|
**"QR 창이 안 열림"**
|
|
108
108
|
|
|
109
|
-
`build_attach_url`을 먼저 호출하지 않았거나, GUI 없는 headless
|
|
109
|
+
`build_attach_url`을 먼저 호출하지 않았거나, GUI 없는 headless 환경이라 대시보드를 열 수 없는 경우입니다. 도구 결과에 텍스트 QR이 출력되므로 폰 카메라로 직접 스캔하세요. 로컬 GUI 환경에서는 대시보드가 자동으로 브라우저에 열립니다.
|
|
110
110
|
|
|
111
111
|
**"page 미attach" — list_pages가 빈 배열 반환**
|
|
112
112
|
|
package/dist/mcp/cli.js
CHANGED
|
@@ -3761,7 +3761,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3761
3761
|
},
|
|
3762
3762
|
{
|
|
3763
3763
|
name: "build_attach_url",
|
|
3764
|
-
description: "The tool result already shows the QR to the user directly (Claude Code renders MCP tool output to the user's screen; they press Ctrl+O to expand if it's collapsed). Do NOT re-print or re-render the QR in your reply — that just wastes output tokens. Simply tell the user to scan the QR shown in this tool's output with their phone camera. Builds a self-attaching deep-link for the active relay environment and returns a QR code. Scan the QR with the phone camera to open the mini-app and attach it to this debug session (QR is the single entry path — no USB cable or platform CLI needed). Call list_pages first to confirm the relay/tunnel is up. If the tunnel is not up, restart: `npx @ait-co/devtools devtools-mcp`.\n\nEnvironment-specific behaviour:\n • env 3 / relay-staging (start_debug mode=\"relay-staging\"): requires scheme_url — the intoss-private://…?_deploymentId=<uuid> URL from `ait deploy --scheme-only`. Splices debug=1 + relay URL into the scheme URL to produce a self-attach deep-link.\n • env 2 / relay-sandbox (start_debug mode=\"relay-sandbox\"): scheme_url is NOT used. Instead, reads AIT_TUNNEL_BASE_URL (the https://*.trycloudflare.com app tunnel from `tunnel:{cdp:true}`) and builds a launcher PWA deep-link (https://devtools.aitc.dev/launcher/?url=…&debug=1&relay=…). When projectRoot is given, the app name from <projectRoot>/package.json is automatically added as name= so the launcher partner bar shows it. Scan the QR with the phone to open the launcher, which frames the tunnel URL and attaches CDP.\n\nSet wait_for_attach=true to block until a page attaches (polls up to 30 s). On timeout, call build_attach_url again to resume polling.
|
|
3764
|
+
description: "The tool result already shows the QR to the user directly (Claude Code renders MCP tool output to the user's screen; they press Ctrl+O to expand if it's collapsed). Do NOT re-print or re-render the QR in your reply — that just wastes output tokens. Simply tell the user to scan the QR shown in this tool's output with their phone camera. Builds a self-attaching deep-link for the active relay environment and returns a QR code. Scan the QR with the phone camera to open the mini-app and attach it to this debug session (QR is the single entry path — no USB cable or platform CLI needed). Call list_pages first to confirm the relay/tunnel is up. If the tunnel is not up, restart: `npx @ait-co/devtools devtools-mcp`.\n\nEnvironment-specific behaviour:\n • env 3 / relay-staging (start_debug mode=\"relay-staging\"): requires scheme_url — the intoss-private://…?_deploymentId=<uuid> URL from `ait deploy --scheme-only`. Splices debug=1 + relay URL into the scheme URL to produce a self-attach deep-link.\n • env 2 / relay-sandbox (start_debug mode=\"relay-sandbox\"): scheme_url is NOT used. Instead, reads AIT_TUNNEL_BASE_URL (the https://*.trycloudflare.com app tunnel from `tunnel:{cdp:true}`) and builds a launcher PWA deep-link (https://devtools.aitc.dev/launcher/?url=…&debug=1&relay=…). When projectRoot is given, the app name from <projectRoot>/package.json is automatically added as name= so the launcher partner bar shows it. Scan the QR with the phone to open the launcher, which frames the tunnel URL and attaches CDP.\n\nSet wait_for_attach=true to block until a page attaches (polls up to 30 s). On timeout, call build_attach_url again to resume polling. The server automatically opens the QR dashboard in the OS default browser when running on a local GUI machine — headless/remote environments fall back to the text QR in the tool output.\n\nTOTP auth: when AIT_DEBUG_TOTP_SECRET is set on the MCP server, the returned attachUrl automatically includes the current one-time code (at=<code>). The code is valid for ~3 minutes (the relay gate accepts ±6 TOTP steps = 180–210 s of backwards acceptance). The response includes a `totp` field with `expiresAt` (ISO timestamp, ~3 min from issuance). If the phone scan happens after expiresAt, the relay will reject the code — just call build_attach_url again to get a fresh URL. Without AIT_DEBUG_TOTP_SECRET, the attachUrl has no expiry.\n\nselfdebug (env 2 / relay-sandbox only): pass selfdebug=true to add &selfdebug=1 to the launcher deep-link. The launcher PWA then registers its own document as the CDP target instead of the framed mini-app. SINGLE-ATTACH MODEL: attaching the launcher self-target evicts any currently-attached mini-app target — use this mode exclusively for diagnosing the launcher document itself (DOM, safe-area, console). Not applicable in env 3/4 (relay-staging/relay-live) — passing selfdebug=true there returns an error.",
|
|
3765
3765
|
inputSchema: {
|
|
3766
3766
|
type: "object",
|
|
3767
3767
|
properties: {
|
|
@@ -3773,10 +3773,6 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3773
3773
|
type: "boolean",
|
|
3774
3774
|
description: "If true, block after returning the QR until a page attaches to the relay (polls listTargets ~1 s interval, timeout 30 s). On attach, the response includes the attached page list. On timeout, call build_attach_url again to resume polling."
|
|
3775
3775
|
},
|
|
3776
|
-
open_in_browser: {
|
|
3777
|
-
type: "boolean",
|
|
3778
|
-
description: "If true (default), render the QR as a PNG and open it in the OS default browser. Only works when the MCP server is running on a local GUI machine — headless or remote container environments should set this to false to use the text QR fallback."
|
|
3779
|
-
},
|
|
3780
3776
|
projectRoot: {
|
|
3781
3777
|
type: "string",
|
|
3782
3778
|
description: "Absolute path to the mini-app project root (the directory containing its package.json and .ait_urls). When AIT_TUNNEL_BASE_URL is unset (env 2 / relay-mobile only), the daemon reads the app tunnel URL from <projectRoot>/.ait_urls written by the dev server (tunnel:{cdp:true}). Pass this because the daemon's own cwd is fixed at launch. Omit when AIT_TUNNEL_BASE_URL is set explicitly."
|
|
@@ -4779,7 +4775,7 @@ async function readMcpSdkVersion() {
|
|
|
4779
4775
|
* some test environments that skip the build step).
|
|
4780
4776
|
*/
|
|
4781
4777
|
function readDevtoolsVersion() {
|
|
4782
|
-
return "0.1.
|
|
4778
|
+
return "0.1.85";
|
|
4783
4779
|
}
|
|
4784
4780
|
/**
|
|
4785
4781
|
* Derives the next recommended action from a completed diagnostics snapshot.
|
|
@@ -5283,7 +5279,7 @@ function createDebugServer(deps) {
|
|
|
5283
5279
|
const collector = collectorDep ?? new InMemoryDiagnosticsCollector();
|
|
5284
5280
|
const server = new Server({
|
|
5285
5281
|
name: "ait-debug",
|
|
5286
|
-
version: "0.1.
|
|
5282
|
+
version: "0.1.85"
|
|
5287
5283
|
}, { capabilities: { tools: { listChanged: true } } });
|
|
5288
5284
|
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
5289
5285
|
const conn = router.active;
|
|
@@ -5356,7 +5352,6 @@ function createDebugServer(deps) {
|
|
|
5356
5352
|
}
|
|
5357
5353
|
if (name === "build_attach_url") {
|
|
5358
5354
|
const waitForAttach = request.params.arguments?.wait_for_attach === true;
|
|
5359
|
-
const openInBrowser = request.params.arguments?.open_in_browser !== false;
|
|
5360
5355
|
const selfdebug = request.params.arguments?.selfdebug === true;
|
|
5361
5356
|
if (selfdebug && env !== "relay-mobile") return mcpError("build_attach_url: selfdebug=true는 env 2 / relay-sandbox 전용 기능입니다. 현재 환경(env 3/4)에서는 launcher가 없어 self-target 모드를 지원하지 않습니다. launcher self-target이 필요하다면 relay-sandbox 모드로 재시작하세요.");
|
|
5362
5357
|
if (env === "relay-mobile") {
|
|
@@ -5414,8 +5409,8 @@ function createDebugServer(deps) {
|
|
|
5414
5409
|
const header = "This tool result is shown to the user directly — do NOT re-print the QR below in your reply (it wastes output tokens). Just tell the user to scan the QR in this output (Ctrl+O to expand if collapsed).";
|
|
5415
5410
|
const warningPrefix = "";
|
|
5416
5411
|
const guiAvailable = canOpenBrowser();
|
|
5417
|
-
if (
|
|
5418
|
-
const headlessNote = "
|
|
5412
|
+
if (!guiAvailable) {
|
|
5413
|
+
const headlessNote = "GUI 환경이 감지되지 않았습니다 (headless/remote 환경). 텍스트 QR을 폰 카메라로 스캔하거나, 로컬 GUI 환경에서 실행하세요.\n\n";
|
|
5419
5414
|
const qrHeadless = await renderQr(attachUrl);
|
|
5420
5415
|
const headlessText = `${warningPrefix}${headlessNote}${header}\n${JSON.stringify({
|
|
5421
5416
|
attachUrl,
|
|
@@ -5445,7 +5440,7 @@ function createDebugServer(deps) {
|
|
|
5445
5440
|
text: `${headlessText}\n\n${JSON.stringify(pagesResultHl, null, 2)}`
|
|
5446
5441
|
}] };
|
|
5447
5442
|
}
|
|
5448
|
-
if (
|
|
5443
|
+
if (guiAvailable && qrHttpServer) {
|
|
5449
5444
|
const browserResult = await openQrInBrowser(qrHttpServer.buildAttachPageUrl(attachUrl), `http://127.0.0.1:${qrHttpServer.port}/qr.png?u=${encodeURIComponent(attachUrl)}`);
|
|
5450
5445
|
if (browserResult.opened) {
|
|
5451
5446
|
const retriedNote = browserResult.retried ? " (1회 retry 후 성공)" : "";
|
|
@@ -5490,7 +5485,7 @@ function createDebugServer(deps) {
|
|
|
5490
5485
|
...browserResult.stderrSummary ? { stderrSummary: browserResult.stderrSummary } : {}
|
|
5491
5486
|
};
|
|
5492
5487
|
const stderrNote = browserResult.stderrSummary ? `\nstderr: ${browserResult.stderrSummary}` : "";
|
|
5493
|
-
const fallbackNote =
|
|
5488
|
+
const fallbackNote = `브라우저 자동 열기에 실패했습니다. 다음 URL을 직접 브라우저에서 여세요:\n${browserResult.httpUrl}\n또는 PNG로 받기: ${browserResult.pngUrl}` + stderrNote + "\n\n";
|
|
5494
5489
|
const qr = await renderQr(attachUrl);
|
|
5495
5490
|
const baseText = `${warningPrefix}${fallbackNote}${header}\n${JSON.stringify({
|
|
5496
5491
|
attachUrl,
|
|
@@ -5585,8 +5580,8 @@ function createDebugServer(deps) {
|
|
|
5585
5580
|
const warningPrefix = authorityWarning ? `⚠️ scheme_url 경고: ${authorityWarning}\n\n` : "";
|
|
5586
5581
|
const header = "This tool result is shown to the user directly — do NOT re-print the QR below in your reply (it wastes output tokens). Just tell the user to scan the QR in this output (Ctrl+O to expand if collapsed).";
|
|
5587
5582
|
const guiAvailable = canOpenBrowser();
|
|
5588
|
-
if (
|
|
5589
|
-
const headlessNote = "
|
|
5583
|
+
if (!guiAvailable) {
|
|
5584
|
+
const headlessNote = "GUI 환경이 감지되지 않았습니다 (headless/remote 환경). 텍스트 QR을 폰 카메라로 스캔하거나, 로컬 GUI 환경에서 실행하세요.\n\n";
|
|
5590
5585
|
const qrHeadless = await renderQr(attachUrl);
|
|
5591
5586
|
const headlessText = `${warningPrefix}${headlessNote}${header}\n${JSON.stringify({
|
|
5592
5587
|
attachUrl,
|
|
@@ -5616,7 +5611,7 @@ function createDebugServer(deps) {
|
|
|
5616
5611
|
text: `${headlessText}\n\n${JSON.stringify(pagesResultHl, null, 2)}`
|
|
5617
5612
|
}] };
|
|
5618
5613
|
}
|
|
5619
|
-
if (
|
|
5614
|
+
if (guiAvailable && qrHttpServer) {
|
|
5620
5615
|
const browserResult = await openQrInBrowser(qrHttpServer.buildAttachPageUrl(attachUrl), `http://127.0.0.1:${qrHttpServer.port}/qr.png?u=${encodeURIComponent(attachUrl)}`);
|
|
5621
5616
|
if (browserResult.opened) {
|
|
5622
5617
|
const retriedNote = browserResult.retried ? " (1회 retry 후 성공)" : "";
|
|
@@ -5661,7 +5656,7 @@ function createDebugServer(deps) {
|
|
|
5661
5656
|
...browserResult.stderrSummary ? { stderrSummary: browserResult.stderrSummary } : {}
|
|
5662
5657
|
};
|
|
5663
5658
|
const stderrNote = browserResult.stderrSummary ? `\nstderr: ${browserResult.stderrSummary}` : "";
|
|
5664
|
-
const fallbackNote =
|
|
5659
|
+
const fallbackNote = `브라우저 자동 열기에 실패했습니다. 다음 URL을 직접 브라우저에서 여세요:
|
|
5665
5660
|
${browserResult.httpUrl}\n또는 PNG로 받기: ${browserResult.pngUrl}` + stderrNote + "\n\n";
|
|
5666
5661
|
const qr = await renderQr(attachUrl);
|
|
5667
5662
|
const baseText = `${warningPrefix}${fallbackNote}${header}\n${JSON.stringify({
|
|
@@ -7117,10 +7112,6 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
7117
7112
|
wait_for_attach: {
|
|
7118
7113
|
type: "boolean",
|
|
7119
7114
|
description: "If true, block until a page attaches."
|
|
7120
|
-
},
|
|
7121
|
-
open_in_browser: {
|
|
7122
|
-
type: "boolean",
|
|
7123
|
-
description: "If true (default), open the QR PNG in the OS browser."
|
|
7124
7115
|
}
|
|
7125
7116
|
},
|
|
7126
7117
|
required: ["scheme_url"]
|
|
@@ -7331,7 +7322,7 @@ function createDevServer(deps = {}) {
|
|
|
7331
7322
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
7332
7323
|
const server = new Server({
|
|
7333
7324
|
name: "ait-devtools",
|
|
7334
|
-
version: "0.1.
|
|
7325
|
+
version: "0.1.85"
|
|
7335
7326
|
}, { capabilities: { tools: {} } });
|
|
7336
7327
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
7337
7328
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|