@ait-co/devtools 0.1.143 → 0.2.0
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 +65 -163
- package/README.md +65 -192
- package/dist/in-app/auto.d.ts +1 -138
- package/dist/in-app/auto.js +28 -1102
- package/dist/in-app/auto.js.map +1 -1
- package/dist/in-app/index.d.ts +38 -547
- package/dist/in-app/index.d.ts.map +1 -1
- package/dist/in-app/index.js +62 -939
- package/dist/in-app/index.js.map +1 -1
- package/dist/mcp/cli.d.ts +1 -54
- package/dist/mcp/cli.js +33 -9720
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -88
- package/dist/mcp/server.js +36 -1076
- package/dist/mcp/server.js.map +1 -1
- package/dist/mock/index.d.ts +19 -20
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js.map +1 -1
- package/dist/optional-peers-CDEFhlhJ.cjs +131 -0
- package/dist/optional-peers-CDEFhlhJ.cjs.map +1 -0
- package/dist/optional-peers-FdVbUJst.js +96 -0
- package/dist/optional-peers-FdVbUJst.js.map +1 -0
- package/dist/panel/index.js +1 -103
- package/dist/panel/index.js.map +1 -1
- package/dist/relay-url-store-CPZAn-T5.js +107 -0
- package/dist/relay-url-store-CPZAn-T5.js.map +1 -0
- package/dist/relay-url-store-DLjlvMSA.cjs +108 -0
- package/dist/relay-url-store-DLjlvMSA.cjs.map +1 -0
- package/dist/stubs/bin-devtools-mcp.js +58 -0
- package/dist/stubs/bin-devtools-mcp.js.map +1 -0
- package/dist/stubs/bin-devtools-test.d.ts +2 -0
- package/dist/stubs/bin-devtools-test.js +55 -0
- package/dist/stubs/bin-devtools-test.js.map +1 -0
- package/dist/test-runner/config.d.ts +1 -231
- package/dist/test-runner/config.js +41 -45
- package/dist/test-runner/config.js.map +1 -1
- package/dist/{tunnel-BVSMXctM.cjs → tunnel-BKZkOyQp.cjs} +27 -75
- package/dist/tunnel-BKZkOyQp.cjs.map +1 -0
- package/dist/{tunnel-D7xkimBu.js → tunnel-CqSCIrdU.js} +27 -75
- package/dist/tunnel-CqSCIrdU.js.map +1 -0
- package/dist/unplugin/index.cjs +17 -30
- package/dist/unplugin/index.cjs.map +1 -1
- package/dist/unplugin/index.d.cts +34 -5
- package/dist/unplugin/index.d.cts.map +1 -1
- package/dist/unplugin/index.d.ts +35 -6
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +17 -30
- package/dist/unplugin/index.js.map +1 -1
- package/dist/unplugin/tunnel.cjs +61 -74
- package/dist/unplugin/tunnel.cjs.map +1 -1
- package/dist/unplugin/tunnel.d.cts +22 -16
- package/dist/unplugin/tunnel.d.cts.map +1 -1
- package/dist/unplugin/tunnel.d.ts +22 -16
- package/dist/unplugin/tunnel.d.ts.map +1 -1
- package/dist/unplugin/tunnel.js +61 -74
- package/dist/unplugin/tunnel.js.map +1 -1
- package/package.json +17 -22
- package/dist/attach-orchestrator-0F0m_UqQ.js +0 -1845
- package/dist/attach-orchestrator-0F0m_UqQ.js.map +0 -1
- package/dist/attach-orchestrator-D65KxFy_.js +0 -1831
- package/dist/attach-orchestrator-D65KxFy_.js.map +0 -1
- package/dist/attach-orchestrator-DL3NQ9ca.js +0 -1846
- package/dist/attach-orchestrator-DL3NQ9ca.js.map +0 -1
- package/dist/bundle-C796JIwG.d.ts +0 -159
- package/dist/bundle-C796JIwG.d.ts.map +0 -1
- package/dist/capture-DsP525OZ.d.ts +0 -58
- package/dist/capture-DsP525OZ.d.ts.map +0 -1
- package/dist/cdp-connection-rP1WdnH5.d.ts +0 -287
- package/dist/cdp-connection-rP1WdnH5.d.ts.map +0 -1
- package/dist/cell-BaLvusOl.js +0 -68
- package/dist/cell-BaLvusOl.js.map +0 -1
- package/dist/cell-CBUS3-nT.js +0 -274
- package/dist/cell-CBUS3-nT.js.map +0 -1
- package/dist/cell-EBKKpAAT.js +0 -307
- package/dist/cell-EBKKpAAT.js.map +0 -1
- package/dist/chii-relay-BZ3HqWL5.js +0 -304
- package/dist/chii-relay-BZ3HqWL5.js.map +0 -1
- package/dist/chii-relay-D7eK2acz.cjs +0 -304
- package/dist/chii-relay-D7eK2acz.cjs.map +0 -1
- package/dist/debug-server-B3ABDrRI.js +0 -456
- package/dist/debug-server-B3ABDrRI.js.map +0 -1
- package/dist/debug-server-BWhwrVXa.js +0 -1158
- package/dist/debug-server-BWhwrVXa.js.map +0 -1
- package/dist/debug-server-CfQNxxGW.js +0 -600
- package/dist/debug-server-CfQNxxGW.js.map +0 -1
- package/dist/deeplink-B5-Hxu0Q.js +0 -62
- package/dist/deeplink-B5-Hxu0Q.js.map +0 -1
- package/dist/deeplink-BpO9qc-D.js +0 -62
- package/dist/deeplink-BpO9qc-D.js.map +0 -1
- package/dist/deeplink-BzdbA1gV.cjs +0 -62
- package/dist/deeplink-BzdbA1gV.cjs.map +0 -1
- package/dist/deeplink-DCScMYcp.cjs +0 -62
- package/dist/deeplink-DCScMYcp.cjs.map +0 -1
- package/dist/devtools-opener-3Drge_RJ.js +0 -75
- package/dist/devtools-opener-3Drge_RJ.js.map +0 -1
- package/dist/devtools-opener-B8nxrxqu.js +0 -71
- package/dist/devtools-opener-B8nxrxqu.js.map +0 -1
- package/dist/devtools-opener-BDY0w3_0.cjs +0 -68
- package/dist/devtools-opener-BDY0w3_0.cjs.map +0 -1
- package/dist/devtools-opener-BTl5A6Cd.js +0 -71
- package/dist/devtools-opener-BTl5A6Cd.js.map +0 -1
- package/dist/devtools-opener-CJpEsXXQ.js +0 -76
- package/dist/devtools-opener-CJpEsXXQ.js.map +0 -1
- package/dist/devtools-opener-CxtryS8c.js +0 -75
- package/dist/devtools-opener-CxtryS8c.js.map +0 -1
- package/dist/devtools-opener-iv1OwfJN.cjs +0 -68
- package/dist/devtools-opener-iv1OwfJN.cjs.map +0 -1
- package/dist/in-app/auto.d.ts.map +0 -1
- package/dist/mcp/cli.d.ts.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/pool-DcaaOwUq.d.ts +0 -14761
- package/dist/pool-DcaaOwUq.d.ts.map +0 -1
- package/dist/qr-http-server--gl2-WKc.cjs +0 -1644
- package/dist/qr-http-server--gl2-WKc.cjs.map +0 -1
- package/dist/qr-http-server-Bb7lMeqi.js +0 -1644
- package/dist/qr-http-server-Bb7lMeqi.js.map +0 -1
- package/dist/qr-http-server-C_lqOrgc.js +0 -1644
- package/dist/qr-http-server-C_lqOrgc.js.map +0 -1
- package/dist/qr-http-server-CopuMbub.js +0 -1644
- package/dist/qr-http-server-CopuMbub.js.map +0 -1
- package/dist/qr-http-server-D-Off6K1.cjs +0 -1644
- package/dist/qr-http-server-D-Off6K1.cjs.map +0 -1
- package/dist/qr-http-server-DrbIVDjO.js +0 -1645
- package/dist/qr-http-server-DrbIVDjO.js.map +0 -1
- package/dist/qr-http-server-n1twN18z.js +0 -1644
- package/dist/qr-http-server-n1twN18z.js.map +0 -1
- package/dist/relay-factory-N9QobQxG.js +0 -206
- package/dist/relay-factory-N9QobQxG.js.map +0 -1
- package/dist/relay-secret-store-BPhN1upr.js +0 -240
- package/dist/relay-secret-store-BPhN1upr.js.map +0 -1
- package/dist/relay-secret-store-Bmyleu0A.js +0 -154
- package/dist/relay-secret-store-Bmyleu0A.js.map +0 -1
- package/dist/relay-secret-store-CQenfcSL.js +0 -154
- package/dist/relay-secret-store-CQenfcSL.js.map +0 -1
- package/dist/relay-secret-store-DKxs7zwq.js +0 -153
- package/dist/relay-secret-store-DKxs7zwq.js.map +0 -1
- package/dist/relay-secret-store-DWKdV-eY.cjs +0 -241
- package/dist/relay-secret-store-DWKdV-eY.cjs.map +0 -1
- package/dist/relay-secret-store-WJ8EGkIl.js +0 -153
- package/dist/relay-secret-store-WJ8EGkIl.js.map +0 -1
- package/dist/relay-url-store-1FGuSYAn.cjs +0 -115
- package/dist/relay-url-store-1FGuSYAn.cjs.map +0 -1
- package/dist/relay-url-store-BR2XodiO.js +0 -123
- package/dist/relay-url-store-BR2XodiO.js.map +0 -1
- package/dist/relay-url-store-Bskcyeg8.js +0 -114
- package/dist/relay-url-store-Bskcyeg8.js.map +0 -1
- package/dist/relay-url-store-CH63fVCm.js +0 -122
- package/dist/relay-url-store-CH63fVCm.js.map +0 -1
- package/dist/relay-url-store-DaY1QPes.js +0 -123
- package/dist/relay-url-store-DaY1QPes.js.map +0 -1
- package/dist/relay-url-store-xmUuTjXA.js +0 -122
- package/dist/relay-url-store-xmUuTjXA.js.map +0 -1
- package/dist/relay-worker-B5HKkGUY.js +0 -832
- package/dist/relay-worker-B5HKkGUY.js.map +0 -1
- package/dist/relay-worker-YdlpZQl9.d.ts +0 -214
- package/dist/relay-worker-YdlpZQl9.d.ts.map +0 -1
- package/dist/rolldown-runtime-DGkTqVfb.js +0 -15
- package/dist/rolldown-runtime-DUslC3ob.js +0 -14
- package/dist/runtime-kn9DxOeg.d.ts +0 -249
- package/dist/runtime-kn9DxOeg.d.ts.map +0 -1
- package/dist/test-runner/bin.js +0 -2584
- package/dist/test-runner/bin.js.map +0 -1
- package/dist/test-runner/bridge-stub.d.ts +0 -125
- package/dist/test-runner/bridge-stub.d.ts.map +0 -1
- package/dist/test-runner/bridge-stub.js +0 -92
- package/dist/test-runner/bridge-stub.js.map +0 -1
- package/dist/test-runner/bundle.d.ts +0 -2
- package/dist/test-runner/bundle.js +0 -439
- package/dist/test-runner/bundle.js.map +0 -1
- package/dist/test-runner/capture.d.ts +0 -2
- package/dist/test-runner/capture.js +0 -44
- package/dist/test-runner/capture.js.map +0 -1
- package/dist/test-runner/config.d.ts.map +0 -1
- package/dist/test-runner/method-pace.d.ts +0 -82
- package/dist/test-runner/method-pace.d.ts.map +0 -1
- package/dist/test-runner/method-pace.js +0 -120
- package/dist/test-runner/method-pace.js.map +0 -1
- package/dist/test-runner/pool.d.ts +0 -2
- package/dist/test-runner/pool.js +0 -136
- package/dist/test-runner/pool.js.map +0 -1
- package/dist/test-runner/relay-factory.d.ts +0 -11245
- package/dist/test-runner/relay-factory.d.ts.map +0 -1
- package/dist/test-runner/relay-factory.js +0 -206
- package/dist/test-runner/relay-factory.js.map +0 -1
- package/dist/test-runner/relay-worker.d.ts +0 -2
- package/dist/test-runner/relay-worker.js +0 -2
- package/dist/test-runner/report.d.ts +0 -163
- package/dist/test-runner/report.d.ts.map +0 -1
- package/dist/test-runner/report.js +0 -198
- package/dist/test-runner/report.js.map +0 -1
- package/dist/test-runner/rpc.d.ts +0 -56
- package/dist/test-runner/rpc.d.ts.map +0 -1
- package/dist/test-runner/rpc.js +0 -98
- package/dist/test-runner/rpc.js.map +0 -1
- package/dist/test-runner/runtime.d.ts +0 -2
- package/dist/test-runner/runtime.js +0 -659
- package/dist/test-runner/runtime.js.map +0 -1
- package/dist/test-runner/task-graph.d.ts +0 -38
- package/dist/test-runner/task-graph.d.ts.map +0 -1
- package/dist/test-runner/task-graph.js +0 -182
- package/dist/test-runner/task-graph.js.map +0 -1
- package/dist/throttle-DKKzX1qC.js +0 -59
- package/dist/throttle-DKKzX1qC.js.map +0 -1
- package/dist/totp-95OAa20j.js +0 -64
- package/dist/totp-95OAa20j.js.map +0 -1
- package/dist/totp-BjtoQNfu.cjs +0 -64
- package/dist/totp-BjtoQNfu.cjs.map +0 -1
- package/dist/totp-CZLLKfOC.js +0 -200
- package/dist/totp-CZLLKfOC.js.map +0 -1
- package/dist/totp-DAxys-r0.js +0 -199
- package/dist/totp-DAxys-r0.js.map +0 -1
- package/dist/totp-DIbrZtI7.js +0 -189
- package/dist/totp-DIbrZtI7.js.map +0 -1
- package/dist/totp-Df252ZdA.cjs +0 -192
- package/dist/totp-Df252ZdA.cjs.map +0 -1
- package/dist/totp-DfekTBk3.js +0 -211
- package/dist/totp-DfekTBk3.js.map +0 -1
- package/dist/totp-Dwft0Kz7.js +0 -3
- package/dist/totp-WY6l0ysP.js +0 -190
- package/dist/totp-WY6l0ysP.js.map +0 -1
- package/dist/tunnel-BVSMXctM.cjs.map +0 -1
- package/dist/tunnel-D7xkimBu.js.map +0 -1
- /package/dist/{test-runner/bin.d.ts → stubs/bin-devtools-mcp.d.ts} +0 -0
package/README.en.md
CHANGED
|
@@ -47,7 +47,7 @@ pnpm dev:phone # same as AIT_TUNNEL=1 pnpm dev
|
|
|
47
47
|
# QR appears in the terminal → scan with your phone camera → opens in the launcher PWA
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
With `tunnel: { cdp: true }`, a single QR scan opens both the screen preview and on-device CDP — inspect the real WebKit DOM, console, and exceptions from your MCP host (`call_sdk` still hits the mock on environment 2; the real SDK lives on environment 3).
|
|
50
|
+
With `tunnel: { cdp: true }`, a single QR scan opens both the screen preview and on-device CDP — inspect the real WebKit DOM, console, and exceptions from your MCP host (`call_sdk` still hits the mock on environment 2; the real SDK lives on environment 3). CDP needs two extra packages — see [Debugging packages](#debugging-packages-environments-2-and-3) below.
|
|
51
51
|
|
|
52
52
|
One-time prerequisite: add `https://devtools.aitc.dev/launcher/` to your phone's home screen. Details: [`docs/scenarios/env-2.md`](./docs/scenarios/env-2.md)
|
|
53
53
|
|
|
@@ -55,10 +55,10 @@ One-time prerequisite: add `https://devtools.aitc.dev/launcher/` to your phone's
|
|
|
55
55
|
|
|
56
56
|
**Environment 3 — intoss-private** (Toss WebView, HMR off, debug only)
|
|
57
57
|
|
|
58
|
-
Load a dog-food bundle in the real Toss app WebView and debug it via the MCP relay.
|
|
58
|
+
Load a dog-food bundle in the real Toss app WebView and debug it via the MCP relay. Requires `@ait-co/debugger` — see [Debugging packages](#debugging-packages-environments-2-and-3) below.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
|
|
61
|
+
npx -y -p @ait-co/debugger debugger # start MCP server → QR printed in terminal (or `pnpm exec debugger` if it's a devDependency)
|
|
62
62
|
# ait build && ait deploy --scheme-only
|
|
63
63
|
# one start_attach(scheme_url) call generates the QR and waits for the phone to attach — scan it and the Toss app loads the bundle + relay attaches
|
|
64
64
|
```
|
|
@@ -73,7 +73,7 @@ To enable on-device CDP debugging in environments 2 and 3, add **one line** to y
|
|
|
73
73
|
|
|
74
74
|
```ts
|
|
75
75
|
// main.tsx (or the top of your mini-app entry)
|
|
76
|
-
import '@ait-co/
|
|
76
|
+
import '@ait-co/debug-console/auto';
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
What this single line does:
|
|
@@ -85,7 +85,9 @@ What this single line does:
|
|
|
85
85
|
|
|
86
86
|
For environment 3 (intoss-private relay), the relay QR deep-link carries `?debug=1&relay=<wss>` query params, so this one line is all the wiring you need. Environment 2 (PWA, `tunnel: { cdp: true }`) works the same way.
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
The old `@ait-co/devtools/in-app/auto` path still resolves in 0.2.x as an inert no-op stub and is removed in 1.0.0 — migrate the import to the path above.
|
|
89
|
+
|
|
90
|
+
> For dog-food builds with TOTP authentication, inject `__DEBUG_TOTP_SECRET__` via your build define and use `@ait-co/debug-console` directly with `evaluateDebugGate({ verifyTotpCode })` + `maybeAttach()`. `in-app/auto` does not inject a TOTP verifier, so Layer C3 is disabled.
|
|
89
91
|
|
|
90
92
|
## Five common problems
|
|
91
93
|
|
|
@@ -99,7 +101,7 @@ No page has joined the relay yet. Re-enter via `start_attach` → QR scan on you
|
|
|
99
101
|
|
|
100
102
|
**"Tunnel down" — no response or timeout**
|
|
101
103
|
|
|
102
|
-
A cloudflared quick tunnel can drop after a few hours. Restart the `
|
|
104
|
+
A cloudflared quick tunnel can drop after a few hours. Restart the `debugger` process to get a new tunnel URL, then scan the new QR. (Related: [#290](https://github.com/apps-in-toss-community/devtools/issues/290))
|
|
103
105
|
|
|
104
106
|
**"Page crash" — list_pages shows a non-null crashDetectedAt**
|
|
105
107
|
|
|
@@ -107,7 +109,7 @@ The page on the phone died (OOM, JS exception, or native bridge crash). Relaunch
|
|
|
107
109
|
|
|
108
110
|
**"SDK not available" — window.__sdkCall not injected**
|
|
109
111
|
|
|
110
|
-
When `call_sdk` returns `ok: false, error: "window.__sdkCall is not available"`, the SDK bridge has not been installed. Check that `import '@ait-co/
|
|
112
|
+
When `call_sdk` returns `ok: false, error: "window.__sdkCall is not available"`, the SDK bridge has not been installed. Check that `import '@ait-co/debug-console/auto'` is present at the top of your mini-app entry — see the "On-device debugging in one line" section above. This error is the expected result in environment 2 (PWA). (Related: [#285](https://github.com/apps-in-toss-community/devtools/issues/285))
|
|
111
113
|
|
|
112
114
|
**"QR scanned but auth rejected" — TOTP code expired**
|
|
113
115
|
|
|
@@ -138,6 +140,26 @@ devtools runs two npm dist-tags off the same code at once. Pick the channel that
|
|
|
138
140
|
|
|
139
141
|
When 3.0 ships GA, the stable `latest` peer moves up to the 3.0 line and the beta channel is retired. Calling an API that devtools has not yet mocked will throw a runtime error — please [file an issue](https://github.com/apps-in-toss-community/devtools/issues) for missing APIs.
|
|
140
142
|
|
|
143
|
+
### Debugging packages (environments 2 and 3)
|
|
144
|
+
|
|
145
|
+
**If you only use environment 1 (local browser + mock + panel), the install above is all you need.** Nothing else to add.
|
|
146
|
+
|
|
147
|
+
For on-device CDP debugging — `tunnel: { cdp: true }` on environment 2, or relay attach on environment 3 — install the two debugging packages as well:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm add -D @ait-co/debugger @ait-co/debug-console
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
| Package | Role | Can enter a bundle |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| [`@ait-co/debugger`](https://www.npmjs.com/package/@ait-co/debugger) | MCP daemon · real-device test runner · dev-bridge (environment 2 CDP relay + QR dashboard) | No — devDependency / `npx` only |
|
|
156
|
+
| [`@ait-co/debug-console`](https://www.npmjs.com/package/@ait-co/debug-console) | On-device attach + in-app eruda console | Yes — the only one that enters a debug build |
|
|
157
|
+
|
|
158
|
+
Both are **optional peers** of devtools.
|
|
159
|
+
|
|
160
|
+
- Without `@ait-co/debugger`, `tunnel: { cdp: true }` skips the CDP wiring, degrades to the plain screen-preview tunnel, and prints the install hint once.
|
|
161
|
+
- Without `@ait-co/debug-console`, the unplugin injects no in-app attach at all — the attach code cannot structurally enter your bundle, which is the technical boundary of the debug surface.
|
|
162
|
+
|
|
141
163
|
## Reference consumer
|
|
142
164
|
|
|
143
165
|
[`sdk-example`](https://github.com/apps-in-toss-community/sdk-example) is the reference consumer of devtools. It's a catalog app where every SDK API can be run interactively, and the web demo is live at <https://sdk-example.aitc.dev/>. When you add a new mock, confirming that it works on the sdk-example card is the first sanity check. That said, this repo's E2E suite runs against an **internal self-contained fixture (`e2e/fixture/`)** without cloning sdk-example — so a broken sdk-example won't affect devtools CI.
|
|
@@ -280,7 +302,7 @@ aitDevtools.vite({ tunnel: { cdp: true } }); // real-device preview + on-device
|
|
|
280
302
|
|
|
281
303
|
## Production builds
|
|
282
304
|
|
|
283
|
-
By default, the devtools plugin **automatically disables itself in production** (`NODE_ENV === 'production'` causes both the alias transform and the Panel injection to be skipped). No conditional configuration is needed to keep it safe.
|
|
305
|
+
By default, the devtools plugin **automatically disables itself in production** (`NODE_ENV === 'production'` causes both the alias transform and the Panel injection to be skipped). No conditional configuration is needed to keep it safe. `@ait-co/devtools` is a devDependency, and its contribution to a production bundle is zero bytes. CI enforces this by building a real consumer fixture and grepping the output.
|
|
284
306
|
|
|
285
307
|
To use devtools in a production build — for example in a staging environment — use the `forceEnable` option:
|
|
286
308
|
|
|
@@ -391,9 +413,9 @@ The launcher **only works when launched as an installed PWA from the home screen
|
|
|
391
413
|
>
|
|
392
414
|
> The `tunnel` option only works in Vite dev mode — no tunnel is started for production builds, even with `forceEnable`. It is silently ignored for other bundlers (Webpack/Rspack, etc.). When the option is enabled, `cloudflared` and `qrcode-terminal` are loaded via dynamic import only, so they do not appear in the bundle graph when the option is off.
|
|
393
415
|
|
|
394
|
-
### One-line setup
|
|
416
|
+
### One-line setup
|
|
395
417
|
|
|
396
|
-
The per-project steps above (vite.config patch + `onlyBuiltDependencies` + `dev:phone` script) are
|
|
418
|
+
The per-project steps above (vite.config patch + `onlyBuiltDependencies` + `dev:phone` script) are automated by a single [`agent-plugin`](https://github.com/apps-in-toss-community/agent-plugin) command, `/ait:setup-phone-preview`. Since this README serves as the spec for that automation, the manual steps stay documented here alongside it.
|
|
397
419
|
|
|
398
420
|
## Device API mode system
|
|
399
421
|
|
|
@@ -621,6 +643,7 @@ __ait.update({ networkStatus: 'OFFLINE' });
|
|
|
621
643
|
__ait.patch('permissions', { camera: 'denied' });
|
|
622
644
|
__ait.patch('deviceModes', { location: 'web' });
|
|
623
645
|
__ait.patch('iap', { nextResult: 'USER_CANCELED' });
|
|
646
|
+
__ait.patch('failureModes', { loadAdMob: 'PLACEMENT_ID_FETCH_FAILED' }); // reproduce a real-device ad placement lookup failure
|
|
624
647
|
|
|
625
648
|
// Trigger events
|
|
626
649
|
__ait.trigger('backEvent');
|
|
@@ -735,6 +758,8 @@ unsubscribe(); // unsubscribe
|
|
|
735
758
|
| `TossAds.destroy/destroyAll` | No-op |
|
|
736
759
|
| `loadFullScreenAd` / `showFullScreenAd` | Similar flow to GoogleAdMob |
|
|
737
760
|
|
|
761
|
+
> Unless a failure dial is set (`failureModes.loadAdMob`, panel `forceNoFill`), the events above fire the same way every time — the mock does not use `adGroupId` to decide the outcome, and it does not model a server-side placement-resolution step. A real device can fail placement lookup itself before any ad exists (e.g. `PLACEMENT_ID_FETCH_FAILED`) and reject immediately, so a mock `loaded` event is not a signal that an ad will actually serve on a real device. To reproduce this failure locally: `__ait.patch('failureModes', { loadAdMob: 'PLACEMENT_ID_FETCH_FAILED' })`.
|
|
762
|
+
|
|
738
763
|
### Events
|
|
739
764
|
|
|
740
765
|
| API | Mock behavior |
|
|
@@ -842,6 +867,19 @@ it('can write and read from Storage', async () => {
|
|
|
842
867
|
});
|
|
843
868
|
```
|
|
844
869
|
|
|
870
|
+
## On-device test runner (`debugger-test`)
|
|
871
|
+
|
|
872
|
+
"Using in tests" above verifies mocks in desktop jsdom. The runner that runs the same style of tests **against the real SDK inside the Toss app WebView on a real phone (environment 3)** moved to `@ait-co/debugger` (#818) — the bin is now `debugger-test`, renamed from `devtools-test`.
|
|
873
|
+
|
|
874
|
+
```bash
|
|
875
|
+
pnpm add -D @ait-co/debugger
|
|
876
|
+
pnpm exec debugger-test 'src/**/*.ait.test.ts' \
|
|
877
|
+
--scheme-url "intoss-private://my-mini-app?_deploymentId=<uuid>" \
|
|
878
|
+
--cell-sdk-line 3.x --cell-platform ios --report-dir .ait-report
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
The full flag reference, QR-scan procedure, and artifact layout are now documented in `@ait-co/debugger` — see `debugger-test --help`. The one line this package still owns is the mini-app entry point: `import '@ait-co/debug-console/auto'` ([section above](#on-device-debugging-in-one-line)).
|
|
882
|
+
|
|
845
883
|
## SDK update tracking
|
|
846
884
|
|
|
847
885
|
devtools tracks [`@apps-in-toss/web-framework`](https://www.npmjs.com/package/@apps-in-toss/web-framework), and [`sdk-example`](https://github.com/apps-in-toss-community/sdk-example) tracks both the original SDK and devtools. When a new SDK version is released, the flow is: (1) devtools catches up on mock/type signatures → (2) sdk-example incorporates both new versions together. If a devtools-only PR breaks sdk-example, both are addressed together.
|
|
@@ -956,176 +994,40 @@ import '@ait-co/devtools/panel';
|
|
|
956
994
|
|
|
957
995
|
## MCP Server
|
|
958
996
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
A local browser (env 1) and a phone Toss WebView (env 2/3) both speak CDP, so every tool works identically in both environments — the only difference is the attach strategy (`--target=relay` vs `--target=local`).
|
|
962
|
-
|
|
963
|
-
| Mode + target | Invocation | Env vars | Target | Tools |
|
|
964
|
-
|---|---|---|---|---|
|
|
965
|
-
| `--target=mobile` (env 2) | `devtools-mcp` → `start_debug({mode:'relay-sandbox'})` | `AIT_RELAY_BASE_URL`, `AIT_TUNNEL_BASE_URL` | Real-device Safari/WebKit PWA (external Chii relay + cloudflared tunnel, env 2) | console/network/page + DOM/snapshot/screenshot |
|
|
966
|
-
| `--mode=debug --target=relay` (default, env 3) | `devtools-mcp` → `start_debug({mode: 'relay-staging'})` | — | Dog-food bundle on a phone (CDP/Chii relay + cloudflared tunnel, env 3) | same + `AIT.*` |
|
|
967
|
-
| `--mode=debug --target=local` (env 1) | `devtools-mcp --target=local` | `MCP_ENV=mock` (auto) | Local Chromium launched by the MCP server (CDP direct-attach, no relay needed, env 1) | same |
|
|
968
|
-
| `--mode=dev` | `devtools-mcp --mode=dev` | `MCP_ENV=mock` (auto) | Mock state from a running Vite dev server (AIT.* only, no CDP) | `AIT.*` (+ `devtools_get_mock_state` alias) |
|
|
969
|
-
|
|
970
|
-
`--target=local` opens `AIT_DEVTOOLS_URL` (default `http://localhost:5173`) and attaches directly to a local Chromium — no relay or tunnel required. `--mode=dev` reads the mock-state HTTP endpoint of the Vite dev server and does not provide CDP tools. Switch environments in-session with `start_debug(mode)`: `relay-sandbox` (env 2 PWA), `relay-staging` (env 3 dogfood), `local-browser` (env 1).
|
|
971
|
-
|
|
972
|
-
#### Environment 2 (real-device PWA CDP) — `--target=mobile`
|
|
973
|
-
|
|
974
|
-
Debug on a real phone using Safari/WebKit without Toss review. The Vite dev server with [`tunnel:{cdp:true}`](#tunnel-option) brings up both an app HTTP tunnel and a Chii relay tunnel. The MCP server attaches to that relay and provides `start_attach` → launcher QR.
|
|
975
|
-
|
|
976
|
-
**Setup procedure:**
|
|
977
|
-
|
|
978
|
-
1. Start the Vite dev server in CDP tunnel mode:
|
|
979
|
-
```bash
|
|
980
|
-
AIT_TUNNEL_CDP=1 pnpm exec vite --config e2e/fixture/vite.config.ts
|
|
981
|
-
```
|
|
982
|
-
The terminal banner prints two URLs:
|
|
983
|
-
- **App HTTP tunnel** `https://<A>.trycloudflare.com` → set as `AIT_TUNNEL_BASE_URL`
|
|
984
|
-
- **Relay wss tunnel** `wss://<B>.trycloudflare.com` → set `AIT_RELAY_BASE_URL` to its `https://` form
|
|
985
|
-
|
|
986
|
-
2. Start the MCP server in mobile mode (separate terminal):
|
|
987
|
-
```json
|
|
988
|
-
{
|
|
989
|
-
"mcpServers": {
|
|
990
|
-
"ait-debug": {
|
|
991
|
-
"command": "npx",
|
|
992
|
-
"args": ["-y", "@ait-co/devtools", "devtools-mcp"],
|
|
993
|
-
"env": {
|
|
994
|
-
"AIT_RELAY_BASE_URL": "https://<B>.trycloudflare.com",
|
|
995
|
-
"AIT_TUNNEL_BASE_URL": "https://<A>.trycloudflare.com"
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
3. In a Claude Code session:
|
|
1003
|
-
```
|
|
1004
|
-
start_debug({mode: 'relay-sandbox'})
|
|
1005
|
-
start_attach()
|
|
1006
|
-
```
|
|
1007
|
-
Scan the QR with your phone camera. The launcher PWA opens the app in a frame and injects Chii target.js.
|
|
1008
|
-
|
|
1009
|
-
4. `list_pages()` → expect one page. Use `take_screenshot()` and other CDP tools.
|
|
1010
|
-
|
|
1011
|
-
**Env 2 fidelity boundary**: uses the mock SDK (`call_sdk` hits the mock). For real SDK fidelity, move to env 3. CDP runs on the real WebKit engine, so DOM, console, and screenshot reflect the real device screen.
|
|
1012
|
-
|
|
1013
|
-
**Local-PC verification**: `e2e/launcher-cdp.test.ts` automates node-side relay startup (`startChiiRelay({port:0})`) and launcher param forwarding (Playwright). Browser-side Chii target.js injection is not automated in CI due to the localhost host gate (Layer B1) and ws:// vs wss:// constraints — completed by the manual procedure above on a real device with a trycloudflare.com hostname.
|
|
1014
|
-
|
|
1015
|
-
### Debug mode (CDP via Chii)
|
|
1016
|
-
|
|
1017
|
-
For a step-by-step walkthrough of the on-device relay debug loop (dog-food build → QR scan → relay attach) including common failure recovery, see **[`docs/dogfood-relay-loop.md`](./docs/dogfood-relay-loop.md)** (Korean). For crash triage — `list_pages.crashDetectedAt`, iOS Console.app `.ips` analysis, and the redact procedure — see **[`docs/crash-triage.md`](./docs/crash-triage.md)** (Korean).
|
|
1018
|
-
|
|
1019
|
-
Read-only tools only. Tools are registered in two tiers based on attach state — before attach, only the bootstrap tools (`start_attach`, `list_pages`) are visible; once a relay/local page attaches, the attach-dependent tools are registered dynamically in the same session via `notifications/tools/list_changed` (no session restart needed). The phone attach roundtrip is fully wired; all that remains is a single on-device acceptance run. The tool layer is CI-verified via a mockable injectable CDP connection / AIT source.
|
|
1020
|
-
|
|
1021
|
-
Running `devtools-mcp` as a stdio server starts a local Chii relay on an OS-assigned port and opens a cloudflared quick tunnel, printing a public `wss://*.trycloudflare.com` URL and a QR code in the terminal (secrets/auth codes are never printed). When the phone enters the dog-food entry point, the in-app attach UI connects to the relay with that URL, and the agent reads console/network/page state via `chrome-devtools-mcp`-compatible tools — diagnosing regressions without anyone watching the phone.
|
|
1022
|
-
|
|
1023
|
-
Environment 3 (intoss-private relay) — start `devtools-mcp` as-is, then enter via `start_debug(mode)`:
|
|
997
|
+
The MCP surface (daemon, attach, CDP tools) moved to `@ait-co/debugger` (#818). Point your agent's registration at debugger, not devtools:
|
|
1024
998
|
|
|
1025
999
|
```json
|
|
1026
1000
|
{
|
|
1027
1001
|
"mcpServers": {
|
|
1028
1002
|
"ait-debug": {
|
|
1029
|
-
"command": "
|
|
1030
|
-
"args": ["
|
|
1003
|
+
"command": "npx",
|
|
1004
|
+
"args": ["-y", "-p", "@ait-co/debugger", "debugger"]
|
|
1031
1005
|
}
|
|
1032
1006
|
}
|
|
1033
1007
|
}
|
|
1034
1008
|
```
|
|
1035
1009
|
|
|
1036
|
-
-
|
|
1037
|
-
**`start_debug(mode)` is the single in-session entry path.**
|
|
1038
|
-
|
|
1039
|
-
| Tool | CDP / AIT backing | Description |
|
|
1040
|
-
|---|---|---|
|
|
1041
|
-
| `list_console_messages` | `Runtime.consoleAPICalled` | Recent console.log/warn/error messages (level, text, timestamp, args) |
|
|
1042
|
-
| `list_network_requests` | `Network.requestWillBeSent` + `responseReceived` | Recent XHR/fetch requests (url, method, status, timing) |
|
|
1043
|
-
| `list_pages` | Chii relay target list | Attached pages + tunnel status + wss URL |
|
|
1044
|
-
| `start_attach` | (pure synthesis + attach wait) | Splices `debug=1` + the relay URL into an `ait deploy --scheme-only` URL, prints a QR, then waits in the same call until the phone attaches (QR generation and attach in one call). A `mode` arg can switch the session environment too, and the TOTP code is re-minted automatically during the wait. Entry tool for env 2 and 3 (bootstrap) — no `list_pages` needed first |
|
|
1045
|
-
| `get_dom_document` | `DOM.getDocument` | DOM tree read (structural/layout regression diagnosis) |
|
|
1046
|
-
| `take_snapshot` | `DOMSnapshot.captureSnapshot` | Page snapshot (documents + interned strings, visual regression) |
|
|
1047
|
-
| `take_screenshot` | `Page.captureScreenshot` | Page PNG screenshot (returned as an MCP image content block) |
|
|
1048
|
-
| `measure_safe_area` | `Runtime.evaluate` | Runs a safe-area probe on the attached page → returns normalized safe-area insets, viewport geometry, DPR, and User-Agent. Read-only. Use in a relay session to get ground-truth values for upgrading a viewport preset from extrapolated/placeholder to measured. Requires attach (`list_pages` first) |
|
|
1049
|
-
| `evaluate` | `Runtime.evaluate` | Evaluates an arbitrary JS expression on the attached page (returnByValue) and returns the result. **Not read-only** — the expression can have side effects (DOM mutations, SDK calls, state changes). Requires attach |
|
|
1050
|
-
| `call_sdk` | `window.__sdkCall` bridge (via `Runtime.evaluate`) | Calls a dog-food SDK method via the `window.__sdkCall` bridge (exported by `@apps-in-toss/web-framework` in `__DEBUG_BUILD__` bundles only). **Not read-only** — SDK calls have side effects (navigation, payments, permissions, etc.). Hits the real SDK on env 3, mock SDK on env 1. Env 2 (PWA) does not inject the SDK — not available there. Requires attach. Returns `{ok,value}` / `{ok,error}` |
|
|
1051
|
-
| `AIT.getSdkCallHistory` | AIT domain | SDK call trace (method, args, result/error, timestamp) |
|
|
1052
|
-
| `AIT.getMockState` | AIT domain | Mock state snapshot (`window.__ait`) |
|
|
1053
|
-
| `AIT.getOperationalEnvironment` | AIT domain | `getOperationalEnvironment()` + SDK version |
|
|
1054
|
-
|
|
1055
|
-
`AIT.*` covers what raw CDP cannot; the same MCP server forwards it alongside CDP. In debug mode the in-app side answers over the Chii channel.
|
|
1056
|
-
|
|
1057
|
-
### Dev mode (mock state)
|
|
1058
|
-
|
|
1059
|
-
`devtools-mcp --mode=dev` reads the mock state from a running browser. It shares the same `AIT.*` tool surface as debug mode.
|
|
1060
|
-
|
|
1061
|
-
#### Architecture
|
|
1062
|
-
|
|
1063
|
-
```
|
|
1064
|
-
Browser (aitState)
|
|
1065
|
-
└─ POST /api/ait-devtools/state (auto-pushed by the panel on every state change)
|
|
1066
|
-
└─ Vite dev server (unplugin with mcp: true)
|
|
1067
|
-
└─ GET /api/ait-devtools/state
|
|
1068
|
-
└─ MCP stdio server (dist/mcp/server.js)
|
|
1069
|
-
└─ AI agent (AIT.getMockState tool)
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
#### Setup
|
|
1073
|
-
|
|
1074
|
-
**1. Add `mcp: true` to the Vite plugin**
|
|
1075
|
-
|
|
1076
|
-
```ts
|
|
1077
|
-
// vite.config.ts
|
|
1078
|
-
import aitDevtools from '@ait-co/devtools/unplugin';
|
|
1079
|
-
|
|
1080
|
-
export default {
|
|
1081
|
-
plugins: [aitDevtools.vite({ mcp: true })],
|
|
1082
|
-
};
|
|
1083
|
-
```
|
|
1084
|
-
|
|
1085
|
-
**2. Configure your MCP client (e.g. Claude Code `.claude/settings.json`)**
|
|
1086
|
-
|
|
1087
|
-
```json
|
|
1088
|
-
{
|
|
1089
|
-
"mcpServers": {
|
|
1090
|
-
"ait-devtools": {
|
|
1091
|
-
"command": "pnpm",
|
|
1092
|
-
"args": ["exec", "devtools-mcp", "--mode=dev"],
|
|
1093
|
-
"env": {
|
|
1094
|
-
"AIT_DEVTOOLS_URL": "http://localhost:5173"
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
```
|
|
1100
|
-
|
|
1101
|
-
`AIT_DEVTOOLS_URL` defaults to `http://localhost:5173` — you can omit it if you're using the default port.
|
|
1102
|
-
|
|
1103
|
-
**3. Open the app in your browser, then call the tool from your AI agent**
|
|
1104
|
-
|
|
1105
|
-
```
|
|
1106
|
-
> AIT.getMockState
|
|
1107
|
-
```
|
|
1108
|
-
|
|
1109
|
-
Returns the full current mock state (permissions, location, auth, network, IAP, etc.) as JSON.
|
|
1110
|
-
|
|
1111
|
-
| Tool | Description |
|
|
1112
|
-
|---|---|
|
|
1113
|
-
| `AIT.getMockState` | Returns the current `AitDevtoolsState` snapshot (read-only) |
|
|
1114
|
-
| `AIT.getOperationalEnvironment` | Environment + version derived from the mock state's `environment` + `appVersion` |
|
|
1115
|
-
| `AIT.getSdkCallHistory` | Empty in dev mode (the HTTP endpoint records no trace) |
|
|
1116
|
-
| `devtools_get_mock_state` | Backward-compatible alias of `AIT.getMockState` (prefer `AIT.getMockState` in new configs) |
|
|
1010
|
+
What this gives you: CDP observation of a running mini-app across environments 1 (local browser), 2 (PWA), and 3 (intoss-private WebView) — console, network, DOM, snapshot, screenshot — plus `start_attach` for on-device entry in environments 2/3. The full tool list, mode/target matrix, and per-environment config live in the [`@ait-co/debugger`](https://www.npmjs.com/package/@ait-co/debugger) package docs.
|
|
1117
1011
|
|
|
1118
1012
|
## Package export structure
|
|
1119
1013
|
|
|
1014
|
+
The entry points this package actually ships:
|
|
1015
|
+
|
|
1120
1016
|
| Import path | Purpose |
|
|
1121
1017
|
|---|---|
|
|
1122
|
-
| `@ait-co/devtools`
|
|
1018
|
+
| `@ait-co/devtools` (= `/mock`) | Bundler alias target, all mock exports |
|
|
1123
1019
|
| `@ait-co/devtools/panel` | Floating DevTools Panel (auto-mounts on import) |
|
|
1124
1020
|
| `@ait-co/devtools/unplugin` | Bundler plugin (.vite, .webpack, .rspack, .esbuild, .rollup) |
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
|
1021
|
+
|
|
1022
|
+
Everything below is a **transition stub** — it exists only in 0.2.x and is removed in 1.0.0 (#818). Migrate to the new package.
|
|
1023
|
+
|
|
1024
|
+
| Import path | New home | On import |
|
|
1025
|
+
|---|---|---|
|
|
1026
|
+
| `@ait-co/devtools/mcp/server` | `@ait-co/debugger/mcp/server` | throws |
|
|
1027
|
+
| `@ait-co/devtools/mcp/cli` | `@ait-co/debugger/mcp/cli` | throws |
|
|
1028
|
+
| `@ait-co/devtools/test-runner` | `@ait-co/debugger/test-runner` | throws |
|
|
1029
|
+
| `@ait-co/devtools/in-app` | `@ait-co/debug-console` | no-op + one `console.error` |
|
|
1030
|
+
| `@ait-co/devtools/in-app/auto` | `@ait-co/debug-console/auto` | no-op + one `console.error` |
|
|
1129
1031
|
|
|
1130
1032
|
## License
|
|
1131
1033
|
|