@ait-co/devtools 0.1.85 → 0.1.87
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/dist/mcp/cli.js +48 -26
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +12 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/panel/index.js +4 -2
- package/dist/panel/index.js.map +1 -1
- package/dist/{qr-http-server-BvAtX9Lc.cjs → qr-http-server-BfO-vZEB.cjs} +3 -1
- package/dist/qr-http-server-BfO-vZEB.cjs.map +1 -0
- package/dist/{qr-http-server-Buorblrx.js → qr-http-server-CkO-CLxK.js} +3 -1
- package/dist/qr-http-server-CkO-CLxK.js.map +1 -0
- package/dist/{qr-http-server-CAUyOrCm.cjs → qr-http-server-CqabMUSq.cjs} +3 -1
- package/dist/qr-http-server-CqabMUSq.cjs.map +1 -0
- package/dist/{qr-http-server-BxjrJr9t.js → qr-http-server-aYAg1bKl.js} +3 -1
- package/dist/qr-http-server-aYAg1bKl.js.map +1 -0
- package/dist/{tunnel-DPwJBn1u.js → tunnel-BC7bu3O9.js} +2 -2
- package/dist/{tunnel-DPwJBn1u.js.map → tunnel-BC7bu3O9.js.map} +1 -1
- package/dist/{tunnel-CfT31xho.cjs → tunnel-DwmbHIBp.cjs} +2 -2
- package/dist/{tunnel-CfT31xho.cjs.map → tunnel-DwmbHIBp.cjs.map} +1 -1
- package/dist/unplugin/index.cjs +1 -1
- package/dist/unplugin/index.js +1 -1
- package/dist/unplugin/tunnel.cjs +1 -1
- package/dist/unplugin/tunnel.js +1 -1
- package/package.json +1 -1
- package/dist/qr-http-server-Buorblrx.js.map +0 -1
- package/dist/qr-http-server-BvAtX9Lc.cjs.map +0 -1
- package/dist/qr-http-server-BxjrJr9t.js.map +0 -1
- package/dist/qr-http-server-CAUyOrCm.cjs.map +0 -1
package/dist/mcp/cli.js
CHANGED
|
@@ -2188,6 +2188,7 @@ const en = {
|
|
|
2188
2188
|
"launcher.diagYes": "yes",
|
|
2189
2189
|
"launcher.diagNo": "no",
|
|
2190
2190
|
"launcher.letterboxDetected": "Letterbox correction +{pt}pt applied — using full screen height.",
|
|
2191
|
+
"launcher.letterboxClipped": "An iOS viewport bug makes the bottom {pt}pt unusable — rotating to landscape and back to portrait may recover it.",
|
|
2191
2192
|
"launcher.navbar.defaultTitle": "Mini App",
|
|
2192
2193
|
"launcher.navbar.back": "Back",
|
|
2193
2194
|
"launcher.navbar.menu": "Menu",
|
|
@@ -2442,6 +2443,7 @@ const tables = {
|
|
|
2442
2443
|
"launcher.diagYes": "예",
|
|
2443
2444
|
"launcher.diagNo": "아니요",
|
|
2444
2445
|
"launcher.letterboxDetected": "letterbox 보정 +{pt}pt 적용됨 — 화면 전체를 사용합니다.",
|
|
2446
|
+
"launcher.letterboxClipped": "iOS 뷰포트 버그로 화면 아래 {pt}pt를 쓸 수 없습니다 — 기기를 가로로 돌렸다 세로로 돌리면 복구될 수 있어요.",
|
|
2445
2447
|
"launcher.navbar.defaultTitle": "미니앱",
|
|
2446
2448
|
"launcher.navbar.back": "뒤로가기",
|
|
2447
2449
|
"launcher.navbar.menu": "메뉴",
|
|
@@ -3761,7 +3763,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3761
3763
|
},
|
|
3762
3764
|
{
|
|
3763
3765
|
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 (
|
|
3766
|
+
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 (default 60 s, adjustable via wait_timeout_seconds). 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
3767
|
inputSchema: {
|
|
3766
3768
|
type: "object",
|
|
3767
3769
|
properties: {
|
|
@@ -3771,7 +3773,11 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3771
3773
|
},
|
|
3772
3774
|
wait_for_attach: {
|
|
3773
3775
|
type: "boolean",
|
|
3774
|
-
description: "If true, block after returning the QR until a page attaches to the relay (polls listTargets ~1 s interval,
|
|
3776
|
+
description: "If true, block after returning the QR until a page attaches to the relay (polls listTargets ~1 s interval, default 60 s). On attach, the response includes the attached page list. On timeout, call build_attach_url again to resume polling."
|
|
3777
|
+
},
|
|
3778
|
+
wait_timeout_seconds: {
|
|
3779
|
+
type: "number",
|
|
3780
|
+
description: "Maximum seconds to wait when wait_for_attach=true (default 60, range 1–600). Values outside the range or invalid inputs (0, negative, NaN) fall back to the default silently. Only meaningful when wait_for_attach=true."
|
|
3775
3781
|
},
|
|
3776
3782
|
projectRoot: {
|
|
3777
3783
|
type: "string",
|
|
@@ -4775,7 +4781,7 @@ async function readMcpSdkVersion() {
|
|
|
4775
4781
|
* some test environments that skip the build step).
|
|
4776
4782
|
*/
|
|
4777
4783
|
function readDevtoolsVersion() {
|
|
4778
|
-
return "0.1.
|
|
4784
|
+
return "0.1.87";
|
|
4779
4785
|
}
|
|
4780
4786
|
/**
|
|
4781
4787
|
* Derives the next recommended action from a completed diagnostics snapshot.
|
|
@@ -4851,9 +4857,14 @@ async function getDiagnostics(input) {
|
|
|
4851
4857
|
reissueAttempts: tunnel.reissueAttempts ?? 0
|
|
4852
4858
|
};
|
|
4853
4859
|
let pages = null;
|
|
4854
|
-
if (connection !== void 0)
|
|
4855
|
-
|
|
4856
|
-
|
|
4860
|
+
if (connection !== void 0) {
|
|
4861
|
+
try {
|
|
4862
|
+
await connection.refreshTargets?.();
|
|
4863
|
+
} catch {}
|
|
4864
|
+
try {
|
|
4865
|
+
pages = listPages(connection, tunnel);
|
|
4866
|
+
} catch {}
|
|
4867
|
+
}
|
|
4857
4868
|
const limit = Math.min(Math.max(1, recentErrorsLimit), 50);
|
|
4858
4869
|
const recentErrors = collector.getRecentErrors(limit);
|
|
4859
4870
|
const authRejects = collector.getAuthRejects();
|
|
@@ -5271,7 +5282,7 @@ function waitForAttachWithEvents(connection, filterFn, timeoutMs, pollIntervalMs
|
|
|
5271
5282
|
* naturally via `enableDomains`). The tier only controls visibility.
|
|
5272
5283
|
*/
|
|
5273
5284
|
function createDebugServer(deps) {
|
|
5274
|
-
const { connection, router: routerDep, aitSource, getTunnelStatus, waitForAttachTimeoutMs =
|
|
5285
|
+
const { connection, router: routerDep, aitSource, getTunnelStatus, waitForAttachTimeoutMs = 6e4, qrHttpServer, getEnvironment: getEnvDep, getEnvironmentReason: getEnvReasonDep, diagnosticsCollector: collectorDep, totpSecret, onAttachUrlBuilt } = deps;
|
|
5275
5286
|
const getTotpSecret = deps.getTotpSecret ?? (() => totpSecret);
|
|
5276
5287
|
const router = routerDep ?? makeSingleConnectionRouter(connection);
|
|
5277
5288
|
const resolveEnvironment = getEnvDep ?? (() => deriveEnvironment(router.active.kind, getLiveIntent(), router.activeRelayOrigin));
|
|
@@ -5279,7 +5290,7 @@ function createDebugServer(deps) {
|
|
|
5279
5290
|
const collector = collectorDep ?? new InMemoryDiagnosticsCollector();
|
|
5280
5291
|
const server = new Server({
|
|
5281
5292
|
name: "ait-debug",
|
|
5282
|
-
version: "0.1.
|
|
5293
|
+
version: "0.1.87"
|
|
5283
5294
|
}, { capabilities: { tools: { listChanged: true } } });
|
|
5284
5295
|
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
5285
5296
|
const conn = router.active;
|
|
@@ -5353,6 +5364,13 @@ function createDebugServer(deps) {
|
|
|
5353
5364
|
if (name === "build_attach_url") {
|
|
5354
5365
|
const waitForAttach = request.params.arguments?.wait_for_attach === true;
|
|
5355
5366
|
const selfdebug = request.params.arguments?.selfdebug === true;
|
|
5367
|
+
const rawWaitTimeout = request.params.arguments?.wait_timeout_seconds;
|
|
5368
|
+
const callTimeoutMs = (() => {
|
|
5369
|
+
if (typeof rawWaitTimeout !== "number" || !Number.isFinite(rawWaitTimeout)) return waitForAttachTimeoutMs;
|
|
5370
|
+
const clamped = Math.max(1, Math.min(600, rawWaitTimeout));
|
|
5371
|
+
if (rawWaitTimeout <= 0) return waitForAttachTimeoutMs;
|
|
5372
|
+
return Math.round(clamped) * 1e3;
|
|
5373
|
+
})();
|
|
5356
5374
|
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 모드로 재시작하세요.");
|
|
5357
5375
|
if (env === "relay-mobile") {
|
|
5358
5376
|
const rawBuildProjectRoot = request.params.arguments?.projectRoot;
|
|
@@ -5423,13 +5441,13 @@ function createDebugServer(deps) {
|
|
|
5423
5441
|
}] };
|
|
5424
5442
|
let attachedPagesHl = [];
|
|
5425
5443
|
try {
|
|
5426
|
-
attachedPagesHl = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5444
|
+
attachedPagesHl = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5427
5445
|
} catch {
|
|
5428
5446
|
attachedPagesHl = conn.listTargets();
|
|
5429
5447
|
return {
|
|
5430
5448
|
content: [{
|
|
5431
5449
|
type: "text",
|
|
5432
|
-
text: buildTimeoutError(headlessText,
|
|
5450
|
+
text: buildTimeoutError(headlessText, callTimeoutMs / 1e3, attachedPagesHl)
|
|
5433
5451
|
}],
|
|
5434
5452
|
isError: true
|
|
5435
5453
|
};
|
|
@@ -5460,13 +5478,13 @@ function createDebugServer(deps) {
|
|
|
5460
5478
|
}] };
|
|
5461
5479
|
let attachedPages = [];
|
|
5462
5480
|
try {
|
|
5463
|
-
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5481
|
+
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5464
5482
|
} catch {
|
|
5465
5483
|
attachedPages = conn.listTargets();
|
|
5466
5484
|
return {
|
|
5467
5485
|
content: [{
|
|
5468
5486
|
type: "text",
|
|
5469
|
-
text: buildTimeoutError(shortText,
|
|
5487
|
+
text: buildTimeoutError(shortText, callTimeoutMs / 1e3, attachedPages)
|
|
5470
5488
|
}],
|
|
5471
5489
|
isError: true
|
|
5472
5490
|
};
|
|
@@ -5499,13 +5517,13 @@ function createDebugServer(deps) {
|
|
|
5499
5517
|
}] };
|
|
5500
5518
|
let attachedPagesFb = [];
|
|
5501
5519
|
try {
|
|
5502
|
-
attachedPagesFb = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5520
|
+
attachedPagesFb = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5503
5521
|
} catch {
|
|
5504
5522
|
attachedPagesFb = conn.listTargets();
|
|
5505
5523
|
return {
|
|
5506
5524
|
content: [{
|
|
5507
5525
|
type: "text",
|
|
5508
|
-
text: buildTimeoutError(baseText,
|
|
5526
|
+
text: buildTimeoutError(baseText, callTimeoutMs / 1e3, attachedPagesFb)
|
|
5509
5527
|
}],
|
|
5510
5528
|
isError: true
|
|
5511
5529
|
};
|
|
@@ -5528,13 +5546,13 @@ function createDebugServer(deps) {
|
|
|
5528
5546
|
}] };
|
|
5529
5547
|
let attachedPages = [];
|
|
5530
5548
|
try {
|
|
5531
|
-
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5549
|
+
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5532
5550
|
} catch {
|
|
5533
5551
|
attachedPages = conn.listTargets();
|
|
5534
5552
|
return {
|
|
5535
5553
|
content: [{
|
|
5536
5554
|
type: "text",
|
|
5537
|
-
text: buildTimeoutError(baseText,
|
|
5555
|
+
text: buildTimeoutError(baseText, callTimeoutMs / 1e3, attachedPages)
|
|
5538
5556
|
}],
|
|
5539
5557
|
isError: true
|
|
5540
5558
|
};
|
|
@@ -5594,13 +5612,13 @@ function createDebugServer(deps) {
|
|
|
5594
5612
|
}] };
|
|
5595
5613
|
let attachedPagesHl = [];
|
|
5596
5614
|
try {
|
|
5597
|
-
attachedPagesHl = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5615
|
+
attachedPagesHl = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5598
5616
|
} catch {
|
|
5599
5617
|
attachedPagesHl = conn.listTargets();
|
|
5600
5618
|
return {
|
|
5601
5619
|
content: [{
|
|
5602
5620
|
type: "text",
|
|
5603
|
-
text: buildTimeoutError(headlessText,
|
|
5621
|
+
text: buildTimeoutError(headlessText, callTimeoutMs / 1e3, attachedPagesHl)
|
|
5604
5622
|
}],
|
|
5605
5623
|
isError: true
|
|
5606
5624
|
};
|
|
@@ -5631,13 +5649,13 @@ function createDebugServer(deps) {
|
|
|
5631
5649
|
}] };
|
|
5632
5650
|
let attachedPages = [];
|
|
5633
5651
|
try {
|
|
5634
|
-
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5652
|
+
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5635
5653
|
} catch {
|
|
5636
5654
|
attachedPages = conn.listTargets();
|
|
5637
5655
|
return {
|
|
5638
5656
|
content: [{
|
|
5639
5657
|
type: "text",
|
|
5640
|
-
text: buildTimeoutError(shortText,
|
|
5658
|
+
text: buildTimeoutError(shortText, callTimeoutMs / 1e3, attachedPages)
|
|
5641
5659
|
}],
|
|
5642
5660
|
isError: true
|
|
5643
5661
|
};
|
|
@@ -5671,13 +5689,13 @@ ${browserResult.httpUrl}\n또는 PNG로 받기: ${browserResult.pngUrl}` + stder
|
|
|
5671
5689
|
}] };
|
|
5672
5690
|
let attachedPagesFb = [];
|
|
5673
5691
|
try {
|
|
5674
|
-
attachedPagesFb = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5692
|
+
attachedPagesFb = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5675
5693
|
} catch {
|
|
5676
5694
|
attachedPagesFb = conn.listTargets();
|
|
5677
5695
|
return {
|
|
5678
5696
|
content: [{
|
|
5679
5697
|
type: "text",
|
|
5680
|
-
text: buildTimeoutError(baseText,
|
|
5698
|
+
text: buildTimeoutError(baseText, callTimeoutMs / 1e3, attachedPagesFb)
|
|
5681
5699
|
}],
|
|
5682
5700
|
isError: true
|
|
5683
5701
|
};
|
|
@@ -5700,13 +5718,13 @@ ${browserResult.httpUrl}\n또는 PNG로 받기: ${browserResult.pngUrl}` + stder
|
|
|
5700
5718
|
}] };
|
|
5701
5719
|
let attachedPages = [];
|
|
5702
5720
|
try {
|
|
5703
|
-
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage,
|
|
5721
|
+
attachedPages = await waitForAttachWithEvents(conn, isMatchingPage, callTimeoutMs);
|
|
5704
5722
|
} catch {
|
|
5705
5723
|
attachedPages = conn.listTargets();
|
|
5706
5724
|
return {
|
|
5707
5725
|
content: [{
|
|
5708
5726
|
type: "text",
|
|
5709
|
-
text: buildTimeoutError(baseText,
|
|
5727
|
+
text: buildTimeoutError(baseText, callTimeoutMs / 1e3, attachedPages)
|
|
5710
5728
|
}],
|
|
5711
5729
|
isError: true
|
|
5712
5730
|
};
|
|
@@ -7111,7 +7129,11 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
7111
7129
|
},
|
|
7112
7130
|
wait_for_attach: {
|
|
7113
7131
|
type: "boolean",
|
|
7114
|
-
description: "If true, block until a page attaches."
|
|
7132
|
+
description: "If true, block until a page attaches (default 60 s)."
|
|
7133
|
+
},
|
|
7134
|
+
wait_timeout_seconds: {
|
|
7135
|
+
type: "number",
|
|
7136
|
+
description: "Maximum seconds to wait when wait_for_attach=true (default 60, range 1–600). Invalid inputs fall back to default."
|
|
7115
7137
|
}
|
|
7116
7138
|
},
|
|
7117
7139
|
required: ["scheme_url"]
|
|
@@ -7322,7 +7344,7 @@ function createDevServer(deps = {}) {
|
|
|
7322
7344
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
7323
7345
|
const server = new Server({
|
|
7324
7346
|
name: "ait-devtools",
|
|
7325
|
-
version: "0.1.
|
|
7347
|
+
version: "0.1.87"
|
|
7326
7348
|
}, { capabilities: { tools: {} } });
|
|
7327
7349
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
7328
7350
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|