@ait-co/devtools 0.1.77 → 0.1.78
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 +2 -2
- package/README.md +6 -6
- package/dist/deeplink-B-94XmWA.js.map +1 -1
- package/dist/deeplink-BLU2_hg6.cjs.map +1 -1
- package/dist/deeplink-CU6opogq.cjs.map +1 -1
- package/dist/deeplink-CYqDwVYs.js.map +1 -1
- package/dist/mcp/cli.js +34 -34
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.js +6 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/panel/index.js +8 -8
- package/dist/panel/index.js.map +1 -1
- package/dist/{qr-http-server-CDO6o2nr.js → qr-http-server-BQhf6N3z.js} +9 -9
- package/dist/qr-http-server-BQhf6N3z.js.map +1 -0
- package/dist/{qr-http-server-jMC1nVqY.cjs → qr-http-server-CC2d-Tc3.cjs} +9 -9
- package/dist/qr-http-server-CC2d-Tc3.cjs.map +1 -0
- package/dist/{qr-http-server-DznDIcJF.js → qr-http-server-CRK_XlW8.js} +9 -9
- package/dist/qr-http-server-CRK_XlW8.js.map +1 -0
- package/dist/{qr-http-server-D0v9ooAD.cjs → qr-http-server-CTX8GtQV.cjs} +9 -9
- package/dist/qr-http-server-CTX8GtQV.cjs.map +1 -0
- package/dist/{relay-secret-store-D-W-WaSx.js → relay-secret-store-6pPzLkUO.js} +2 -2
- package/dist/{relay-secret-store-D-W-WaSx.js.map → relay-secret-store-6pPzLkUO.js.map} +1 -1
- package/dist/{relay-secret-store-BFOEhsLO.cjs → relay-secret-store-CsCOfpWt.cjs} +2 -2
- package/dist/{relay-secret-store-BFOEhsLO.cjs.map → relay-secret-store-CsCOfpWt.cjs.map} +1 -1
- package/dist/{relay-secret-store-C_LUxvAp.js → relay-secret-store-J0SUUXjH.js} +2 -2
- package/dist/{relay-secret-store-C_LUxvAp.js.map → relay-secret-store-J0SUUXjH.js.map} +1 -1
- package/dist/{relay-url-store-DjKJJZ0d.js → relay-url-store-B_wrNe5A.js} +2 -2
- package/dist/{relay-url-store-DjKJJZ0d.js.map → relay-url-store-B_wrNe5A.js.map} +1 -1
- package/dist/{relay-url-store-DAh5KiJi.js → relay-url-store-CV8nScsn.js} +2 -2
- package/dist/{relay-url-store-DAh5KiJi.js.map → relay-url-store-CV8nScsn.js.map} +1 -1
- package/dist/{relay-url-store-2sy_l2bf.cjs → relay-url-store-Cx_SqWtl.cjs} +2 -2
- package/dist/{relay-url-store-2sy_l2bf.cjs.map → relay-url-store-Cx_SqWtl.cjs.map} +1 -1
- package/dist/totp-BcBNRoDD.js +3 -0
- package/dist/{totp-BxtxuEt4.js → totp-BmKSPb5d.js} +2 -2
- package/dist/{totp-D9rndqg_.cjs.map → totp-BmKSPb5d.js.map} +1 -1
- package/dist/{totp-D9rndqg_.cjs → totp-BwDZ6dUT.cjs} +2 -2
- package/dist/totp-BwDZ6dUT.cjs.map +1 -0
- package/dist/{totp-D4iTMA9U.cjs → totp-CNw0w89F.cjs} +3 -3
- package/dist/totp-CNw0w89F.cjs.map +1 -0
- package/dist/{totp-DbEfKQRi.js → totp-DYdP9N3o.js} +3 -3
- package/dist/totp-DYdP9N3o.js.map +1 -0
- package/dist/{totp-BfVk8gQe.js → totp-Xq3ACwkm.js} +3 -3
- package/dist/totp-Xq3ACwkm.js.map +1 -0
- package/dist/{tunnel-D7f-0enB.cjs → tunnel-CbtLkErI.cjs} +3 -3
- package/dist/{tunnel-D7f-0enB.cjs.map → tunnel-CbtLkErI.cjs.map} +1 -1
- package/dist/{tunnel-km3KkZrF.js → tunnel-vIjpD9wn.js} +3 -3
- package/dist/{tunnel-km3KkZrF.js.map → tunnel-vIjpD9wn.js.map} +1 -1
- package/dist/unplugin/index.cjs +4 -4
- package/dist/unplugin/index.js +4 -4
- package/dist/unplugin/tunnel.cjs +2 -2
- package/dist/unplugin/tunnel.js +2 -2
- package/package.json +1 -1
- package/dist/qr-http-server-CDO6o2nr.js.map +0 -1
- package/dist/qr-http-server-D0v9ooAD.cjs.map +0 -1
- package/dist/qr-http-server-DznDIcJF.js.map +0 -1
- package/dist/qr-http-server-jMC1nVqY.cjs.map +0 -1
- package/dist/totp-BfVk8gQe.js.map +0 -1
- package/dist/totp-BxtxuEt4.js.map +0 -1
- package/dist/totp-D4iTMA9U.cjs.map +0 -1
- package/dist/totp-D8f6qAEu.js +0 -3
- package/dist/totp-DbEfKQRi.js.map +0 -1
package/dist/mcp/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as generateTotp, n as assertRelayAuthConfigured, r as buildRelayVerifyAuth } from "../totp-
|
|
3
|
-
import { t as loadRelaySecretReadOnly } from "../relay-secret-store-
|
|
2
|
+
import { i as generateTotp, n as assertRelayAuthConfigured, r as buildRelayVerifyAuth } from "../totp-Xq3ACwkm.js";
|
|
3
|
+
import { t as loadRelaySecretReadOnly } from "../relay-secret-store-J0SUUXjH.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { argv } from "node:process";
|
|
@@ -1051,10 +1051,10 @@ function buildLauncherAttachUrl(tunnelUrl, wssUrl, totpCode, opts) {
|
|
|
1051
1051
|
return url;
|
|
1052
1052
|
}
|
|
1053
1053
|
/**
|
|
1054
|
-
* Build a self-attaching
|
|
1054
|
+
* Build a self-attaching dog-food deep-link.
|
|
1055
1055
|
*
|
|
1056
1056
|
* `ait deploy --scheme-only` prints an `intoss-private://…?_deploymentId=<uuid>`
|
|
1057
|
-
* URL that opens a
|
|
1057
|
+
* URL that opens a dog-food bundle on a phone. The in-app debug gate
|
|
1058
1058
|
* (`src/in-app/gate.ts`) auto-attaches when the entry URL also carries
|
|
1059
1059
|
* `debug=1` and `relay=<wss-url>`. This helper splices those params (plus
|
|
1060
1060
|
* `at=<code>` when TOTP is enabled) into the scheme URL; rendering the result
|
|
@@ -1440,7 +1440,7 @@ function toLegacyEnv(env) {
|
|
|
1440
1440
|
*
|
|
1441
1441
|
* `relayOrigin` is the booted-family discriminator (NOT sniffed from the URL)
|
|
1442
1442
|
* that distinguishes the env-2 external-PWA relay (`relay-mobile`) from the
|
|
1443
|
-
* intoss-private
|
|
1443
|
+
* intoss-private dog-food relay (`relay-dev`); both are `kind: 'relay'`.
|
|
1444
1444
|
*
|
|
1445
1445
|
* Pure — used at every output boundary (envelope `meta.env`, `get_debug_status`,
|
|
1446
1446
|
* `measure_safe_area` provenance) so the surface never sniffs a URL again.
|
|
@@ -1521,7 +1521,7 @@ function tunnelDownError() {
|
|
|
1521
1521
|
* enableDomains()가 "No mini-app page attached" 에러를 던질 때.
|
|
1522
1522
|
*/
|
|
1523
1523
|
function pageMissingError(toolName) {
|
|
1524
|
-
return mcpError(`${toolName ? `${toolName}: ` : ""}페이지가 attach 안 됨.
|
|
1524
|
+
return mcpError(`${toolName ? `${toolName}: ` : ""}페이지가 attach 안 됨. dog-food 번들 배포 후 build_attach_url을 호출해 QR을 생성하세요: \`ait deploy --scheme-only\` → \`build_attach_url(scheme_url)\` → QR 스캔.`);
|
|
1525
1525
|
}
|
|
1526
1526
|
/**
|
|
1527
1527
|
* 상태 3: page crash — 연결됐던 페이지가 crash/destroy됐다.
|
|
@@ -1537,7 +1537,7 @@ function pageCrashError(toolName) {
|
|
|
1537
1537
|
*
|
|
1538
1538
|
* call_sdk 호출 시 브리지가 없을 때. 같은 "브리지 부재"라도 다음 행동은
|
|
1539
1539
|
* connection 종류에 따라 정반대다 (issue #360):
|
|
1540
|
-
* - relay(`--target` 없는 intoss / env-2):
|
|
1540
|
+
* - relay(`--target` 없는 intoss / env-2): dog-food 빌드가 아니다 → dog-food
|
|
1541
1541
|
* 채널로 재배포 후 QR 재스캔.
|
|
1542
1542
|
* - local(`--target=local`, env 1 로컬 브라우저): 재배포가 아니라 dev 서버를
|
|
1543
1543
|
* `pnpm dev`로 띄웠는지 + unplugin alias가 `@apps-in-toss/web-framework`를
|
|
@@ -1549,7 +1549,7 @@ function pageCrashError(toolName) {
|
|
|
1549
1549
|
function sdkAbsentError(toolName, isLocal = false) {
|
|
1550
1550
|
const prefix = toolName ? `${toolName}: ` : "";
|
|
1551
1551
|
if (isLocal) return mcpError(`${prefix}window.__sdkCall이 주입되지 않았습니다 (로컬 dev 브리지 부재). sdk-example을 \`pnpm dev\`로 띄웠는지, 그리고 unplugin alias가 \`@apps-in-toss/web-framework\`를 devtools mock으로 resolve하는지 확인하세요. dev 빌드(\`import.meta.env.DEV\`)면 \`window.__sdkCall\`이 자동 설치됩니다.`);
|
|
1552
|
-
return mcpError(`${prefix}window.__sdkCall이 주입되지 않았습니다 (
|
|
1552
|
+
return mcpError(`${prefix}window.__sdkCall이 주입되지 않았습니다 (dog-food 빌드가 아닙니다). dog-food 채널(intoss-private)로 재배포 후 QR을 다시 스캔하세요: \`ait build && aitcc app deploy\`.`);
|
|
1553
1553
|
}
|
|
1554
1554
|
/**
|
|
1555
1555
|
* relay-live 환경에서 side-effect 도구(`call_sdk`, `evaluate`)를 `confirm: true`
|
|
@@ -1564,7 +1564,7 @@ function liveGuardError(toolName) {
|
|
|
1564
1564
|
|
|
1565
1565
|
다음 중 하나를 선택하세요:
|
|
1566
1566
|
1. \`confirm: true\` 인자를 추가해 재호출: ${toolName}(…, confirm: true)\n 2. 읽기 전용 도구(list_pages, list_console_messages, take_screenshot 등)를 사용하세요.
|
|
1567
|
-
3.
|
|
1567
|
+
3. dog-food 빌드(relay-dev 환경)에서 먼저 검증 후 live에 적용하세요.
|
|
1568
1568
|
|
|
1569
1569
|
live-guard: MCP_ENV=relay-live + confirm: true missing`);
|
|
1570
1570
|
}
|
|
@@ -2117,15 +2117,15 @@ const en = {
|
|
|
2117
2117
|
"attach.steps.section": "How to scan",
|
|
2118
2118
|
"attach.faq.section": "Troubleshooting checklist",
|
|
2119
2119
|
"attach.url.section": "URL (fallback)",
|
|
2120
|
-
"attach.mode.sandbox": "
|
|
2121
|
-
"attach.mode.intossDev": "
|
|
2122
|
-
"attach.mode.intossLive": "
|
|
2120
|
+
"attach.mode.sandbox": "env 2 — AITC Sandbox App (PWA)",
|
|
2121
|
+
"attach.mode.intossDev": "env 3 — intoss-private relay dev",
|
|
2122
|
+
"attach.mode.intossLive": "env 4 — intoss live relay debug",
|
|
2123
2123
|
"attach.sandbox.step1": "Launch the launcher PWA icon on your home screen (if the Safari address bar is visible, it is not standalone).",
|
|
2124
2124
|
"attach.sandbox.step2": "Scan this QR code with <strong>\"Scan QR with camera\"</strong> inside the launcher.",
|
|
2125
2125
|
"attach.sandbox.step3": "The mini-app opens fullscreen and the debug session attaches automatically.",
|
|
2126
2126
|
"attach.sandbox.faq.notInstalled": "<strong>Launcher is not installed</strong> — open <code>devtools.aitc.dev/launcher/</code> once and add it to your home screen",
|
|
2127
2127
|
"attach.sandbox.faq.cameraApp": "<strong>Scanning with the camera app opens a Safari tab (bottom tab bar visible)</strong> — relaunch from the launcher icon and use the in-app scanner",
|
|
2128
|
-
"attach.sandbox.faq.totp": "<strong>QR expired (TOTP ~3 min)</strong> — scan a fresh QR code",
|
|
2128
|
+
"attach.sandbox.faq.totp": "<strong>QR expired (TOTP — 30-second step, ±6 steps (~3 min) accepted)</strong> — scan a fresh QR code",
|
|
2129
2129
|
"attach.sandbox.faq.chii": "<strong>Chii injection failure / console is empty</strong> — verify the mini-app bundle has an <code>in-app</code> debug import",
|
|
2130
2130
|
"attach.intoss.step1": "Open the Toss app.",
|
|
2131
2131
|
"attach.intoss.step2": "Scan the QR code with your phone camera app.",
|
|
@@ -2369,7 +2369,7 @@ const tables = {
|
|
|
2369
2369
|
"attach.steps.section": "스캔 절차",
|
|
2370
2370
|
"attach.faq.section": "진단 체크리스트",
|
|
2371
2371
|
"attach.url.section": "URL (fallback)",
|
|
2372
|
-
"attach.mode.sandbox": "환경 2 — AITC Sandbox PWA",
|
|
2372
|
+
"attach.mode.sandbox": "환경 2 — AITC Sandbox App (PWA)",
|
|
2373
2373
|
"attach.mode.intossDev": "환경 3 — intoss-private relay dev",
|
|
2374
2374
|
"attach.mode.intossLive": "환경 4 — intoss live relay debug",
|
|
2375
2375
|
"attach.sandbox.step1": "홈 화면의 launcher PWA 아이콘으로 실행하세요 (Safari 주소창이 보이면 standalone이 아닙니다).",
|
|
@@ -2377,7 +2377,7 @@ const tables = {
|
|
|
2377
2377
|
"attach.sandbox.step3": "미니앱이 풀스크린으로 열리고 디버그 세션이 자동으로 attach됩니다.",
|
|
2378
2378
|
"attach.sandbox.faq.notInstalled": "<strong>launcher가 설치돼 있지 않은 경우</strong> — <code>devtools.aitc.dev/launcher/</code>를 한 번 열어 홈 화면에 추가하세요",
|
|
2379
2379
|
"attach.sandbox.faq.cameraApp": "<strong>카메라 앱으로 스캔하면 Safari 탭으로 열립니다 (하단 탭 바 노출)</strong> — launcher 아이콘으로 다시 실행해 인앱 스캔을 사용하세요",
|
|
2380
|
-
"attach.sandbox.faq.totp": "<strong>QR이 만료된 경우 (TOTP ~3분)</strong> — 새 QR을 다시 스캔하세요",
|
|
2380
|
+
"attach.sandbox.faq.totp": "<strong>QR이 만료된 경우 (TOTP — 코드 1개는 30초 창, 만료 후 ~3분(±6 step) 이내 소급 허용)</strong> — 새 QR을 다시 스캔하세요",
|
|
2381
2381
|
"attach.sandbox.faq.chii": "<strong>Chii 주입 실패 / 콘솔이 비어 있는 경우</strong> — 미니앱 번들에 <code>in-app</code> debug import가 있는지 확인",
|
|
2382
2382
|
"attach.intoss.step1": "토스 앱을 실행하세요.",
|
|
2383
2383
|
"attach.intoss.step2": "폰 카메라 앱으로 QR 코드를 스캔하세요.",
|
|
@@ -2567,7 +2567,7 @@ hr { border: none; border-top: 1px solid #21262d; width: 100%; margin: 0.5rem 0;
|
|
|
2567
2567
|
.lang-switcher { display: flex; gap: 0.5rem; font-size: 0.75rem; }
|
|
2568
2568
|
.lang-switcher a { color: #58a6ff; text-decoration: none; opacity: 0.6; }
|
|
2569
2569
|
.lang-switcher a.active { font-weight: 700; text-decoration: underline; opacity: 1; }
|
|
2570
|
-
</style></head><body><h1>AIT 디버그 세션 — QR 스캔</h1>__MODE_LABEL____LANG_SWITCHER__<div id="attach-section"><img class="qr" src="__QR_DATA_URL__" alt="attach QR"/></div><section><h2>스캔 절차</h2><ol><li>홈 화면의 launcher PWA 아이콘으로 실행하세요 (Safari 주소창이 보이면 standalone이 아닙니다).</li><li>launcher 안의 <strong>"QR 카메라로 스캔"</strong>으로 이 QR 코드를 스캔하세요.</li><li>미니앱이 풀스크린으로 열리고 디버그 세션이 자동으로 attach됩니다.</li></ol></section><hr/><section><h2>진단 체크리스트</h2><ul><li><strong>launcher가 설치돼 있지 않은 경우</strong> — <code>devtools.aitc.dev/launcher/</code>를 한 번 열어 홈 화면에 추가하세요</li><li><strong>카메라 앱으로 스캔하면 Safari 탭으로 열립니다 (하단 탭 바 노출)</strong> — launcher 아이콘으로 다시 실행해 인앱 스캔을 사용하세요</li><li><strong>QR이 만료된 경우 (TOTP ~3분)</strong> — 새 QR을 다시 스캔하세요</li><li><strong>Chii 주입 실패 / 콘솔이 비어 있는 경우</strong> — 미니앱 번들에 <code>in-app</code> debug import가 있는지 확인</li></ul></section><hr/><section id="url-section"><h2>URL (fallback)</h2><div class="url-row"><p class="url-box" id="url-box">__SAFE_ATTACH_URL__</p><button class="copy-btn" id="copy-btn" type="button" aria-label="복사">복사</button></div></section></body></html>`;
|
|
2570
|
+
</style></head><body><h1>AIT 디버그 세션 — QR 스캔</h1>__MODE_LABEL____LANG_SWITCHER__<div id="attach-section"><img class="qr" src="__QR_DATA_URL__" alt="attach QR"/></div><section><h2>스캔 절차</h2><ol><li>홈 화면의 launcher PWA 아이콘으로 실행하세요 (Safari 주소창이 보이면 standalone이 아닙니다).</li><li>launcher 안의 <strong>"QR 카메라로 스캔"</strong>으로 이 QR 코드를 스캔하세요.</li><li>미니앱이 풀스크린으로 열리고 디버그 세션이 자동으로 attach됩니다.</li></ol></section><hr/><section><h2>진단 체크리스트</h2><ul><li><strong>launcher가 설치돼 있지 않은 경우</strong> — <code>devtools.aitc.dev/launcher/</code>를 한 번 열어 홈 화면에 추가하세요</li><li><strong>카메라 앱으로 스캔하면 Safari 탭으로 열립니다 (하단 탭 바 노출)</strong> — launcher 아이콘으로 다시 실행해 인앱 스캔을 사용하세요</li><li><strong>QR이 만료된 경우 (TOTP — 코드 1개는 30초 창, 만료 후 ~3분(±6 step) 이내 소급 허용)</strong> — 새 QR을 다시 스캔하세요</li><li><strong>Chii 주입 실패 / 콘솔이 비어 있는 경우</strong> — 미니앱 번들에 <code>in-app</code> debug import가 있는지 확인</li></ul></section><hr/><section id="url-section"><h2>URL (fallback)</h2><div class="url-row"><p class="url-box" id="url-box">__SAFE_ATTACH_URL__</p><button class="copy-btn" id="copy-btn" type="button" aria-label="복사">복사</button></div></section></body></html>`;
|
|
2571
2571
|
const attachChromeHtmlKoIntoss = `<!DOCTYPE html>
|
|
2572
2572
|
<html lang="ko"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="__QR_DATA_URL__"/><title>AIT 디버그 세션 — QR 스캔</title><style>
|
|
2573
2573
|
*, *::before, *::after { box-sizing: border-box; }
|
|
@@ -2727,7 +2727,7 @@ hr { border: none; border-top: 1px solid #21262d; width: 100%; margin: 0.5rem 0;
|
|
|
2727
2727
|
.lang-switcher { display: flex; gap: 0.5rem; font-size: 0.75rem; }
|
|
2728
2728
|
.lang-switcher a { color: #58a6ff; text-decoration: none; opacity: 0.6; }
|
|
2729
2729
|
.lang-switcher a.active { font-weight: 700; text-decoration: underline; opacity: 1; }
|
|
2730
|
-
</style></head><body><h1>AIT Debug Session — QR Scan</h1>__MODE_LABEL____LANG_SWITCHER__<div id="attach-section"><img class="qr" src="__QR_DATA_URL__" alt="attach QR"/></div><section><h2>How to scan</h2><ol><li>Launch the launcher PWA icon on your home screen (if the Safari address bar is visible, it is not standalone).</li><li>Scan this QR code with <strong>"Scan QR with camera"</strong> inside the launcher.</li><li>The mini-app opens fullscreen and the debug session attaches automatically.</li></ol></section><hr/><section><h2>Troubleshooting checklist</h2><ul><li><strong>Launcher is not installed</strong> — open <code>devtools.aitc.dev/launcher/</code> once and add it to your home screen</li><li><strong>Scanning with the camera app opens a Safari tab (bottom tab bar visible)</strong> — relaunch from the launcher icon and use the in-app scanner</li><li><strong>QR expired (TOTP ~3 min)</strong> — scan a fresh QR code</li><li><strong>Chii injection failure / console is empty</strong> — verify the mini-app bundle has an <code>in-app</code> debug import</li></ul></section><hr/><section id="url-section"><h2>URL (fallback)</h2><div class="url-row"><p class="url-box" id="url-box">__SAFE_ATTACH_URL__</p><button class="copy-btn" id="copy-btn" type="button" aria-label="Copy">Copy</button></div></section></body></html>`;
|
|
2730
|
+
</style></head><body><h1>AIT Debug Session — QR Scan</h1>__MODE_LABEL____LANG_SWITCHER__<div id="attach-section"><img class="qr" src="__QR_DATA_URL__" alt="attach QR"/></div><section><h2>How to scan</h2><ol><li>Launch the launcher PWA icon on your home screen (if the Safari address bar is visible, it is not standalone).</li><li>Scan this QR code with <strong>"Scan QR with camera"</strong> inside the launcher.</li><li>The mini-app opens fullscreen and the debug session attaches automatically.</li></ol></section><hr/><section><h2>Troubleshooting checklist</h2><ul><li><strong>Launcher is not installed</strong> — open <code>devtools.aitc.dev/launcher/</code> once and add it to your home screen</li><li><strong>Scanning with the camera app opens a Safari tab (bottom tab bar visible)</strong> — relaunch from the launcher icon and use the in-app scanner</li><li><strong>QR expired (TOTP — 30-second step, ±6 steps (~3 min) accepted)</strong> — scan a fresh QR code</li><li><strong>Chii injection failure / console is empty</strong> — verify the mini-app bundle has an <code>in-app</code> debug import</li></ul></section><hr/><section id="url-section"><h2>URL (fallback)</h2><div class="url-row"><p class="url-box" id="url-box">__SAFE_ATTACH_URL__</p><button class="copy-btn" id="copy-btn" type="button" aria-label="Copy">Copy</button></div></section></body></html>`;
|
|
2731
2731
|
const attachChromeHtmlEnIntoss = `<!DOCTYPE html>
|
|
2732
2732
|
<html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="__QR_DATA_URL__"/><title>AIT Debug Session — QR Scan</title><style>
|
|
2733
2733
|
*, *::before, *::after { box-sizing: border-box; }
|
|
@@ -3646,7 +3646,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3646
3646
|
},
|
|
3647
3647
|
{
|
|
3648
3648
|
name: "build_attach_url",
|
|
3649
|
-
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
|
|
3649
|
+
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. When open_in_browser=true (default), saves the QR as a PNG and opens it in the OS default browser — only works when the MCP server runs on a local GUI machine (not headless/remote containers). \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.",
|
|
3650
3650
|
inputSchema: {
|
|
3651
3651
|
type: "object",
|
|
3652
3652
|
properties: {
|
|
@@ -3703,7 +3703,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3703
3703
|
},
|
|
3704
3704
|
{
|
|
3705
3705
|
name: "measure_safe_area",
|
|
3706
|
-
description: "Runs a safe-area probe on the attached mini-app page via Runtime.evaluate and returns normalized safe-area insets, viewport geometry, device pixel ratio, and User-Agent. Read-only — does not modify page state. Tier C per RFC #277: the same Runtime.evaluate probe runs in both `mock` (devtools panel page with window.__ait state) and `relay` (real-device WebView with window.__sdk). The result includes a `source: \"mock\" | \"relay-dev\" | \"relay-live\"` field so consumers can identify provenance without inspecting payload values. Use in a relay session (phone attached) to get ground-truth values for upgrading a viewport preset from extrapolated/placeholder to measured. Requires a page to be attached — call list_pages first.",
|
|
3706
|
+
description: "Runs a safe-area probe on the attached mini-app page via Runtime.evaluate and returns normalized safe-area insets, viewport geometry, device pixel ratio, and User-Agent. Read-only — does not modify page state. Tier C per RFC #277: the same Runtime.evaluate probe runs in both `mock` (devtools panel page with window.__ait state) and `relay` (real-device WebView with window.__sdk). The result includes a `source: \"mock\" | \"relay-dev\" | \"relay-live\" | \"relay-mobile\"` field so consumers can identify provenance without inspecting payload values. (`relay-mobile` = env 2 real-device PWA over an external relay; `relay-dev` = env 3 dog-food WebView; `relay-live` = env 4 production WebView.) Use in a relay session (phone attached) to get ground-truth values for upgrading a viewport preset from extrapolated/placeholder to measured. Requires a page to be attached — call list_pages first.",
|
|
3707
3707
|
inputSchema: {
|
|
3708
3708
|
type: "object",
|
|
3709
3709
|
properties: {},
|
|
@@ -3745,7 +3745,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3745
3745
|
},
|
|
3746
3746
|
{
|
|
3747
3747
|
name: "call_sdk",
|
|
3748
|
-
description: "Calls a
|
|
3748
|
+
description: "Calls a dog-food SDK method via the window.__sdkCall bridge (exported by @apps-in-toss/web-framework only in __DEBUG_BUILD__ bundles). NOT read-only — SDK calls have side effects (navigation, payments, permissions, etc.). On env 3/4 (real device relay) this hits the real SDK; on env 1 (local mock) and env 2 (PWA relay — real WebKit, mock SDK) it hits the mock SDK. Requires the relay to be attached — call list_pages first. Returns {ok: true, value} on success or {ok: false, error} on failure. If a Runtime.exceptionThrown event was observed within [callStart-50ms, callEnd+200ms], the result also includes `recentException` for crash triage. Returns a clear error if window.__sdkCall is not available — on relay (env 3/4) that means a non-dog-food bundle (redeploy via `ait build && aitcc app deploy`); on local (--target=local, env 1) it means the dev bridge is not installed (start the dev server with `pnpm dev`).\n\nSECURITY: method name, args, and result value are not redacted — never include secrets.\n\nLIVE guard: when running against a live/production relay (relay-live env, MCP_ENV=relay-live), this tool requires `confirm: true` to acknowledge that the SDK call may affect real users. Without it the call is rejected with a structured error. mock and relay-dev sessions are unaffected.\n\nIMPORTANT — 인자 시그니처 (잘못된 인자로 호출하면 토스 앱 crash 위험):\n setDeviceOrientation: call_sdk(\"setDeviceOrientation\", [{ type: \"landscape\" }]) // NOT \"landscape\"\n setIosSwipeGestureEnabled: call_sdk(\"setIosSwipeGestureEnabled\", [{ isEnabled: false }])\n setSecureScreen: call_sdk(\"setSecureScreen\", [{ enabled: true }])\n setScreenAwakeMode: call_sdk(\"setScreenAwakeMode\", [{ enabled: true }])\n getOperationalEnvironment: call_sdk(\"getOperationalEnvironment\", [])\n getPlatformOS: call_sdk(\"getPlatformOS\", [])\n getDeviceId: call_sdk(\"getDeviceId\", [])\n getLocale: call_sdk(\"getLocale\", [])\n getNetworkStatus: call_sdk(\"getNetworkStatus\", [])\n getSchemeUri: call_sdk(\"getSchemeUri\", [])\n requestReview: call_sdk(\"requestReview\", [])\n closeView: call_sdk(\"closeView\", [])",
|
|
3749
3749
|
inputSchema: {
|
|
3750
3750
|
type: "object",
|
|
3751
3751
|
properties: {
|
|
@@ -3799,7 +3799,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3799
3799
|
},
|
|
3800
3800
|
{
|
|
3801
3801
|
name: "start_debug",
|
|
3802
|
-
description: "Switches the active debug environment in-place (issue #348) — no Claude Code restart and no MCP re-handshake. One daemon holds both a local (env 1, mock SDK in a Chromium) and a relay (env 3/4, real-device Toss WebView over the Chii relay + cloudflared tunnel) connection at once; this tool flips which one every other tool reads from, lazily booting the requested family's infra on first use and keeping the inactive one warm so an existing attach survives the switch. After switching it emits notifications/tools/list_changed — call tools/list again to see the updated tool surface for the new environment.\n\nmodes:\n local-browser — env 1: desktop Chromium with the
|
|
3802
|
+
description: "Switches the active debug environment in-place (issue #348) — no Claude Code restart and no MCP re-handshake. One daemon holds both a local (env 1, mock SDK in a Chromium) and a relay (env 3/4, real-device Toss WebView over the Chii relay + cloudflared tunnel) connection at once; this tool flips which one every other tool reads from, lazily booting the requested family's infra on first use and keeping the inactive one warm so an existing attach survives the switch. After switching it emits notifications/tools/list_changed — call tools/list again to see the updated tool surface for the new environment.\n\nmodes:\n local-browser — env 1: desktop Chromium with the mock SDK and a local CDP attach. Side-effect tools (call_sdk/evaluate) run unguarded against the mock; nothing touches a real device or real users. No prerequisites — the default, always-available environment for state/contract and visual-layout work.\n relay-sandbox — env 2: a real-device PWA (real WebKit engine, mock SDK) over an external Chii relay. CDP covers real-device WebKit DOM, console, exceptions, and safe-area observation; call_sdk still hits the mock (SDK fidelity needs relay-staging). liveIntent off — dev-intent, LIVE guard inactive, side-effect tools run unguarded against the mock. Only the dual-connection daemon can enter relay-sandbox in-place; a single-connection session rejects it with \"동적 전환할 수 없습니다 … relay-sandbox 모드로 재시작하세요\" — follow that hint and restart the MCP server in relay-sandbox mode rather than retrying. Prerequisites: both AIT_RELAY_BASE_URL (the relay base the unplugin emits when started with tunnel:{cdp:true}, used for the CDP attach) and AIT_TUNNEL_BASE_URL (the dev-server tunnel host, required by build_attach_url to render the launcher QR) must be set before the MCP server starts — the unplugin does not auto-forward either; set them explicitly. Both carry relay/tunnel hosts (secret-class) — keep them out of logs.\n relay-staging — env 3: a real-device Toss WebView dog-food build with the REAL SDK over the intoss-private relay. The first environment where call_sdk exercises the genuine native bridge. Side-effect tools run unguarded (dog-food, not released to real users). Prerequisite: a dog-food candidate bundle built with `RELEASE_CHANNEL=dogfood ait build`, then uploaded with `ait deploy` (add `--scheme-only` to print the resulting intoss-private://…?_deploymentId=… deep-link); open that deep-link/QR on the device to cold-load the bundle with the relay injected. Unlike env 2, env 3 is NOT a dev-server tunnel — it is a deployed bundle reached via the intoss-private scheme, so `pnpm dev` plays no part here.\n relay-live — env 4: the REVIEW-PASSED, released production runtime with the REAL SDK over the intoss relay — real end users are on the other side. Read-only debugging is the intent: the LIVE guard is armed, so call_sdk/evaluate require confirm:true per call, and ENTERING relay-live ALSO requires confirm:true on this call. Use it only to observe a shipped regression; verify fixes in relay-staging first.\n\nSwitching back to local-browser automatically disarms the LIVE guard.\n\nFor a relay mode (relay-sandbox/relay-staging/relay-live), also pass projectRoot — the absolute mini-app project root — so the daemon can read the relay auth secret from <projectRoot>/.ait_relay (read-only; the daemon never mints it). Omit it for local-browser.",
|
|
3803
3803
|
inputSchema: {
|
|
3804
3804
|
type: "object",
|
|
3805
3805
|
properties: {
|
|
@@ -3828,7 +3828,7 @@ const DEBUG_TOOL_DEFINITIONS = [
|
|
|
3828
3828
|
},
|
|
3829
3829
|
{
|
|
3830
3830
|
name: "get_debug_status",
|
|
3831
|
-
description: "Reports the current debug session state — which environment/mode is active, whether a page is attached, and a full diagnostic snapshot — in one call. Use this any time to answer \"what mode am I in right now?\" or \"why is this not working?\" without chaining tools. Fields: mcpVersion (MCP SDK version), devtoolsVersion (@ait-co/devtools package version), tunnel (up/wssUrl/pid/startedAt), pages (list_pages result + lastSeenAt stats), lastAttachAt, lastDetachAt, recentErrors (last N server-side errors, PII/secret redacted), authRejects ({count, lastAt} — relay TOTP 401 rejections, secret-free; count > 0 with empty pages means the phone reached the relay but its code was rejected), environment (kind: mock|relay-dev|relay-live|relay-mobile, env: mock|relay backward-compat, reason, liveGuardActive: true when relay-live LIVE guard is active), serverLockHolder (pid + startedAt from the lock file, or null), nextRecommendedAction ({tool, reason} or null — the single next tool to call; in local-target mode tunnel.up=false is normal so \"restart\" is never recommended). All fields are nullable — missing data is null, not an error. debug-mode only — dev-mode (--mode=dev) does not support relay diagnostics. Tier C (both mock and relay).",
|
|
3831
|
+
description: "Reports the current debug session state — which environment/mode is active, whether a page is attached, and a full diagnostic snapshot — in one call. Use this any time to answer \"what mode am I in right now?\" or \"why is this not working?\" without chaining tools. Fields: mcpVersion (MCP SDK version), devtoolsVersion (@ait-co/devtools package version), tunnel (up/wssUrl/pid/startedAt), pages (list_pages result + lastSeenAt stats), lastAttachAt, lastDetachAt, recentErrors (last N server-side errors, PII/secret redacted), authRejects ({count, lastAt} — relay TOTP 401 rejections, secret-free; count > 0 with empty pages means the phone reached the relay but its code was rejected), environment (kind: mock|relay-dev|relay-live|relay-mobile, env: mock|relay backward-compat, reason, liveGuardActive: true when relay-live LIVE guard is active; start_debug mode→kind mapping: relay-sandbox→relay-mobile, relay-staging→relay-dev, relay-live→relay-live, local-browser→mock), serverLockHolder (pid + startedAt from the lock file, or null), nextRecommendedAction ({tool, reason} or null — the single next tool to call; in local-target mode tunnel.up=false is normal so \"restart\" is never recommended). All fields are nullable — missing data is null, not an error. debug-mode only — dev-mode (--mode=dev) does not support relay diagnostics. Tier C (both mock and relay).",
|
|
3832
3832
|
inputSchema: {
|
|
3833
3833
|
type: "object",
|
|
3834
3834
|
properties: { recent_errors_limit: {
|
|
@@ -3993,7 +3993,7 @@ function listPages(connection, tunnel) {
|
|
|
3993
3993
|
};
|
|
3994
3994
|
}
|
|
3995
3995
|
/**
|
|
3996
|
-
* Builds a self-attaching
|
|
3996
|
+
* Builds a self-attaching dog-food deep-link from an `ait deploy --scheme-only`
|
|
3997
3997
|
* URL plus this session's live relay. Throws if the tunnel is not up yet (no
|
|
3998
3998
|
* relay URL to splice in) — the caller surfaces that as a tool error.
|
|
3999
3999
|
*
|
|
@@ -4232,8 +4232,8 @@ async function takeScreenshot(connection) {
|
|
|
4232
4232
|
* those CSS env vars, then `getComputedStyle`.
|
|
4233
4233
|
* 2. SDK insets via a priority chain so the SAME probe works on both relay
|
|
4234
4234
|
* (real device) and mock (devtools panel page):
|
|
4235
|
-
* a. `window.__sdk.SafeAreaInsets.get()` —
|
|
4236
|
-
* b. `window.__sdk.getSafeAreaInsets()` —
|
|
4235
|
+
* a. `window.__sdk.SafeAreaInsets.get()` — dog-food bundle on real device.
|
|
4236
|
+
* b. `window.__sdk.getSafeAreaInsets()` — dog-food bundle (deprecated).
|
|
4237
4237
|
* c. `window.__ait.state.safeAreaInsets` — devtools mock state (mock env).
|
|
4238
4238
|
* The probe records `sdkInsetsSource` = `'window.__sdk'` | `'window.__ait'`
|
|
4239
4239
|
* | `null`. If all paths fail the result carries `sdkInsetsError`.
|
|
@@ -4437,13 +4437,13 @@ async function evaluate(connection, expression) {
|
|
|
4437
4437
|
*
|
|
4438
4438
|
* Name and args are embedded via `JSON.stringify` so they are safely escaped.
|
|
4439
4439
|
* The expression checks for `window.__sdkCall` and returns a clear error if
|
|
4440
|
-
* it is absent (non-
|
|
4440
|
+
* it is absent (non-dog-food bundle).
|
|
4441
4441
|
*
|
|
4442
4442
|
* SECRET-HANDLING: the expression is built here and MUST NOT be written to
|
|
4443
4443
|
* any log or stderr by the caller.
|
|
4444
4444
|
*/
|
|
4445
4445
|
function buildCallSdkExpression(name, args) {
|
|
4446
|
-
return `(async () => { if (typeof window.__sdkCall !== 'function') { return JSON.stringify({ok:false,error:'sdk-absent: window.__sdkCall이 주입되지 않았습니다 (
|
|
4446
|
+
return `(async () => { if (typeof window.__sdkCall !== 'function') { return JSON.stringify({ok:false,error:'sdk-absent: window.__sdkCall이 주입되지 않았습니다 (dog-food 빌드가 아닙니다). dog-food 채널로 재배포하세요.'}); } try { const r = await window.__sdkCall(${JSON.stringify(name)}, ...${JSON.stringify(args)}); return JSON.stringify({ok:true,value:r}); } catch(e) { return JSON.stringify({ok:false,error:String(e && e.message || e)}); }})()`;
|
|
4447
4447
|
}
|
|
4448
4448
|
/**
|
|
4449
4449
|
* Parses the JSON envelope string returned by the `call_sdk` expression.
|
|
@@ -4490,7 +4490,7 @@ function findRecentException(connection, windowStart, windowEnd) {
|
|
|
4490
4490
|
}
|
|
4491
4491
|
}
|
|
4492
4492
|
/**
|
|
4493
|
-
* Calls a
|
|
4493
|
+
* Calls a dog-food SDK method via `window.__sdkCall` on the attached page.
|
|
4494
4494
|
* NOT read-only — SDK calls may have side effects.
|
|
4495
4495
|
*
|
|
4496
4496
|
* On env 3/4 (toss WebView relay) this hits the real SDK. On env 1 (local
|
|
@@ -4660,7 +4660,7 @@ async function readMcpSdkVersion() {
|
|
|
4660
4660
|
* some test environments that skip the build step).
|
|
4661
4661
|
*/
|
|
4662
4662
|
function readDevtoolsVersion() {
|
|
4663
|
-
return "0.1.
|
|
4663
|
+
return "0.1.78";
|
|
4664
4664
|
}
|
|
4665
4665
|
/**
|
|
4666
4666
|
* Derives the next recommended action from a completed diagnostics snapshot.
|
|
@@ -4905,7 +4905,7 @@ async function renderAttachBanner(input) {
|
|
|
4905
4905
|
authNote,
|
|
4906
4906
|
"",
|
|
4907
4907
|
" Use build_attach_url to generate a deep link with the current TOTP code.",
|
|
4908
|
-
" Scan the QR to locate the relay (open the
|
|
4908
|
+
" Scan the QR to locate the relay (open the dog-food URL separately with",
|
|
4909
4909
|
" ?debug=1&relay=<wss>&at=<code> or use the build_attach_url tool):",
|
|
4910
4910
|
"",
|
|
4911
4911
|
qr
|
|
@@ -5164,7 +5164,7 @@ function createDebugServer(deps) {
|
|
|
5164
5164
|
const collector = collectorDep ?? new InMemoryDiagnosticsCollector();
|
|
5165
5165
|
const server = new Server({
|
|
5166
5166
|
name: "ait-debug",
|
|
5167
|
-
version: "0.1.
|
|
5167
|
+
version: "0.1.78"
|
|
5168
5168
|
}, { capabilities: { tools: { listChanged: true } } });
|
|
5169
5169
|
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
5170
5170
|
const conn = router.active;
|
|
@@ -5243,7 +5243,7 @@ function createDebugServer(deps) {
|
|
|
5243
5243
|
const buildProjectRoot = typeof rawBuildProjectRoot === "string" ? rawBuildProjectRoot : void 0;
|
|
5244
5244
|
let tunnelHttpUrl = process.env.AIT_TUNNEL_BASE_URL?.trim() ?? "";
|
|
5245
5245
|
if (tunnelHttpUrl === "" && buildProjectRoot !== void 0) {
|
|
5246
|
-
const { readRelayUrls } = await import("../relay-url-store-
|
|
5246
|
+
const { readRelayUrls } = await import("../relay-url-store-B_wrNe5A.js");
|
|
5247
5247
|
tunnelHttpUrl = (await readRelayUrls({ projectRoot: buildProjectRoot }))?.tunnelBaseUrl ?? "";
|
|
5248
5248
|
}
|
|
5249
5249
|
if (tunnelHttpUrl === "") return mcpError("build_attach_url(mobile): AIT_TUNNEL_BASE_URL이 설정되지 않았습니다. dev 서버가 tunnel:{cdp:true}로 기동 중이면 .ait_urls 파일이 자동 생성돼 있어야 합니다. 자동 발견이 되지 않을 경우 앱 HTTP 터널 URL을 AIT_TUNNEL_BASE_URL 환경변수로 직접 전달하세요.");
|
|
@@ -6022,7 +6022,7 @@ async function readMobileRelayBaseUrl(env = process.env, projectRoot) {
|
|
|
6022
6022
|
const envValue = typeof raw === "string" ? raw.trim() : "";
|
|
6023
6023
|
if (envValue !== "") return envValue;
|
|
6024
6024
|
if (projectRoot !== void 0) {
|
|
6025
|
-
const { readRelayUrls } = await import("../relay-url-store-
|
|
6025
|
+
const { readRelayUrls } = await import("../relay-url-store-B_wrNe5A.js");
|
|
6026
6026
|
const stored = await readRelayUrls({ projectRoot });
|
|
6027
6027
|
if (stored?.relayBaseUrl !== void 0) return stored.relayBaseUrl;
|
|
6028
6028
|
}
|
|
@@ -7105,7 +7105,7 @@ function createDevServer(deps = {}) {
|
|
|
7105
7105
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
7106
7106
|
const server = new Server({
|
|
7107
7107
|
name: "ait-devtools",
|
|
7108
|
-
version: "0.1.
|
|
7108
|
+
version: "0.1.78"
|
|
7109
7109
|
}, { capabilities: { tools: {} } });
|
|
7110
7110
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
7111
7111
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|