@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.md
CHANGED
|
@@ -47,7 +47,7 @@ pnpm dev:phone # AIT_TUNNEL=1 pnpm dev 와 동일
|
|
|
47
47
|
# 터미널에 QR 출력 → 폰 카메라로 스캔 → launcher PWA에서 자동 열림
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
`tunnel: { cdp: true }`를 켜면 같은 QR 한 번으로 화면 미리보기 + on-device CDP가 함께 열려 실기기 WebKit의 DOM·콘솔·예외를 MCP로 관측합니다 (`call_sdk`는 환경 2에서 mock — 실 SDK는 환경 3).
|
|
50
|
+
`tunnel: { cdp: true }`를 켜면 같은 QR 한 번으로 화면 미리보기 + on-device CDP가 함께 열려 실기기 WebKit의 DOM·콘솔·예외를 MCP로 관측합니다 (`call_sdk`는 환경 2에서 mock — 실 SDK는 환경 3). CDP를 쓰려면 디버깅 패키지 두 개를 추가로 설치하세요 — 아래 [디버깅 패키지](#디버깅-패키지-환경-23) 참고.
|
|
51
51
|
|
|
52
52
|
사전: 폰에 `https://devtools.aitc.dev/launcher/` 를 홈 화면에 한 번 추가. 상세: [`docs/scenarios/env-2.md`](./docs/scenarios/env-2.md)
|
|
53
53
|
|
|
@@ -55,10 +55,10 @@ pnpm dev:phone # AIT_TUNNEL=1 pnpm dev 와 동일
|
|
|
55
55
|
|
|
56
56
|
**환경 3 — intoss-private** (토스 WebView, HMR X, debug 전용)
|
|
57
57
|
|
|
58
|
-
실기기 토스 앱 WebView에서 dog-food 번들을 로드하고 MCP relay로 디버깅합니다.
|
|
58
|
+
실기기 토스 앱 WebView에서 dog-food 번들을 로드하고 MCP relay로 디버깅합니다. `@ait-co/debugger` 설치가 필요합니다 — 아래 [디버깅 패키지](#디버깅-패키지-환경-23) 참고.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
|
|
61
|
+
npx -y -p @ait-co/debugger debugger # MCP 서버 시작 → QR 출력 (devDep이면 pnpm exec debugger)
|
|
62
62
|
# ait build && ait deploy --scheme-only
|
|
63
63
|
# start_attach(scheme_url) 호출 한 번으로 QR 생성 + 폰 attach까지 — QR 스캔하면 토스 앱 로드 + relay attach
|
|
64
64
|
```
|
|
@@ -73,7 +73,7 @@ HMR 없음(토스 WebView cold-load만). 상세: [`docs/scenarios/env-3.md`](./d
|
|
|
73
73
|
|
|
74
74
|
```ts
|
|
75
75
|
// main.tsx (또는 미니앱 entry 최상단)
|
|
76
|
-
import '@ait-co/
|
|
76
|
+
import '@ait-co/debug-console/auto';
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
이 한 줄이 하는 일:
|
|
@@ -85,7 +85,9 @@ import '@ait-co/devtools/in-app/auto';
|
|
|
85
85
|
|
|
86
86
|
환경 3(intoss-private relay) 빌드는 relay QR deep-link가 `?debug=1&relay=<wss>` 파라미터를 실어 보내므로, 이 한 줄만 있으면 별도 게이트 코드가 필요 없습니다. 환경 2(PWA, `tunnel: { cdp: true }`)도 동일하게 동작합니다.
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
옛 경로 `@ait-co/devtools/in-app/auto`는 0.2.x에서도 계속 resolve되지만 inert한 no-op 스텁이며 1.0.0에서 제거됩니다 — import를 위 새 경로로 옮기세요.
|
|
89
|
+
|
|
90
|
+
> TOTP 인증이 필요한 dog-food 빌드는 빌드 define으로 `__DEBUG_TOTP_SECRET__`을 주입하고 `@ait-co/debug-console`을 직접 import해 `evaluateDebugGate({ verifyTotpCode })` + `maybeAttach()`를 사용하세요. `in-app/auto`는 TOTP verifier를 주입하지 않으므로 C3 레이어가 비활성화됩니다.
|
|
89
91
|
|
|
90
92
|
## 자주 겪는 문제 5가지
|
|
91
93
|
|
|
@@ -99,7 +101,7 @@ relay에 붙은 페이지가 없는 상태입니다. `start_attach` → QR 스
|
|
|
99
101
|
|
|
100
102
|
**"tunnel down" — 터널 응답 없음 또는 timeout**
|
|
101
103
|
|
|
102
|
-
cloudflared quick tunnel은 수 시간 후 drop될 수 있습니다. `
|
|
104
|
+
cloudflared quick tunnel은 수 시간 후 drop될 수 있습니다. `debugger` 프로세스를 재시작하면 새 tunnel URL이 발급됩니다. 재발급 후 QR을 다시 스캔하세요. (관련: [#290](https://github.com/apps-in-toss-community/devtools/issues/290))
|
|
103
105
|
|
|
104
106
|
**"page crash" — list_pages에 crashDetectedAt이 찍힘**
|
|
105
107
|
|
|
@@ -107,7 +109,7 @@ cloudflared quick tunnel은 수 시간 후 drop될 수 있습니다. `devtools-m
|
|
|
107
109
|
|
|
108
110
|
**"SDK 부재" — window.__sdkCall 미주입**
|
|
109
111
|
|
|
110
|
-
`call_sdk` 호출 시 `ok: false, error: "window.__sdkCall is not available"` 에러가 뜨면 SDK 브리지가 아직 설치되지 않은 상태입니다. 아래 "on-device 디버깅 한 줄 설정" 섹션을 참고해 `import '@ait-co/
|
|
112
|
+
`call_sdk` 호출 시 `ok: false, error: "window.__sdkCall is not available"` 에러가 뜨면 SDK 브리지가 아직 설치되지 않은 상태입니다. 아래 "on-device 디버깅 한 줄 설정" 섹션을 참고해 `import '@ait-co/debug-console/auto'`가 미니앱 entry에 추가돼 있는지 확인하세요. 환경 2(PWA)에서는 이 에러가 예상 결과입니다. (관련: [#285](https://github.com/apps-in-toss-community/devtools/issues/285))
|
|
111
113
|
|
|
112
114
|
**"QR 스캔했는데 인증 실패" — TOTP 만료**
|
|
113
115
|
|
|
@@ -138,6 +140,26 @@ devtools는 같은 코드에서 두 개의 npm dist-tag를 동시에 운영합
|
|
|
138
140
|
|
|
139
141
|
3.0이 정식(GA) 출시되면 stable `latest` peer가 3.0 라인으로 올라가고 beta 채널은 정리됩니다. devtools가 아직 mock하지 않은 API를 호출하면 런타임에 에러가 발생합니다 — 누락된 API는 [이슈](https://github.com/apps-in-toss-community/devtools/issues)로 알려주세요.
|
|
140
142
|
|
|
143
|
+
### 디버깅 패키지 (환경 2·3)
|
|
144
|
+
|
|
145
|
+
**환경 1(로컬 브라우저 + mock + 패널)만 쓴다면 위 설치가 전부입니다.** 아무것도 더 설치하지 않아도 됩니다.
|
|
146
|
+
|
|
147
|
+
on-device CDP 디버깅(환경 2의 `tunnel: { cdp: true }`, 환경 3의 relay attach)을 쓰려면 디버깅 패키지 두 개를 추가로 설치하세요:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm add -D @ait-co/debugger @ait-co/debug-console
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
| 패키지 | 역할 | 번들 반입 |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| [`@ait-co/debugger`](https://www.npmjs.com/package/@ait-co/debugger) | MCP 데몬 · 실기기 테스트 러너 · dev-bridge(환경 2 CDP relay + QR 대시보드) | 안 됨 — devDependency / `npx` 전용 |
|
|
156
|
+
| [`@ait-co/debug-console`](https://www.npmjs.com/package/@ait-co/debug-console) | on-device attach + 인앱 eruda 콘솔 | 됨 — debug 빌드에만 들어가는 유일한 패키지 |
|
|
157
|
+
|
|
158
|
+
두 패키지 모두 devtools의 **optional peer**입니다.
|
|
159
|
+
|
|
160
|
+
- `@ait-co/debugger`가 없으면 `tunnel: { cdp: true }`는 CDP 배선을 건너뛰고 일반 화면 미리보기 터널로 degrade하며, 터미널에 설치 안내를 한 번 출력합니다.
|
|
161
|
+
- `@ait-co/debug-console`이 없으면 unplugin이 in-app attach를 아예 주입하지 않습니다 — attach 코드가 번들에 구조적으로 들어갈 수 없다는 뜻이고, 이게 디버그 표면의 기술적 경계입니다.
|
|
162
|
+
|
|
141
163
|
## Reference consumer
|
|
142
164
|
|
|
143
165
|
[`sdk-example`](https://github.com/apps-in-toss-community/sdk-example)이 devtools의 reference consumer다. 모든 SDK API를 인터랙티브하게 실행해볼 수 있는 카탈로그 앱으로, 웹 데모는 <https://sdk-example.aitc.dev/>에서 바로 확인할 수 있다. 새 mock을 추가하면 sdk-example의 카드에서 그대로 동작하는 게 1차 sanity check. 단, 이 repo의 E2E suite는 sdk-example을 clone하지 않고 **내부 자기완결 fixture(`e2e/fixture/`)** 로 운영한다 — sdk-example이 깨져도 devtools CI는 영향받지 않는다.
|
|
@@ -280,7 +302,7 @@ aitDevtools.vite({ tunnel: { cdp: true } }); // 실기기 미리보기 + on-devi
|
|
|
280
302
|
|
|
281
303
|
## Production 빌드
|
|
282
304
|
|
|
283
|
-
기본적으로 devtools 플러그인은 **production 빌드에서 자동 비활성화**됩니다 (`NODE_ENV === 'production'`이면 alias 변환과 Panel 주입이 모두 스킵). 별도의 조건부 설정 없이도 안전합니다.
|
|
305
|
+
기본적으로 devtools 플러그인은 **production 빌드에서 자동 비활성화**됩니다 (`NODE_ENV === 'production'`이면 alias 변환과 Panel 주입이 모두 스킵). 별도의 조건부 설정 없이도 안전합니다. `@ait-co/devtools`는 devDependency이고 production 번들에 기여하는 바이트 수는 0입니다. CI가 실제 소비자 fixture를 빌드해 결과물을 grep하는 방식으로 이를 강제합니다.
|
|
284
306
|
|
|
285
307
|
스테이징 환경 등에서 production 빌드에서도 devtools를 사용하려면 `forceEnable` 옵션을 사용하세요:
|
|
286
308
|
|
|
@@ -391,9 +413,9 @@ launcher는 **PWA(홈 화면 앱)로 실행할 때만 동작**합니다. 일반
|
|
|
391
413
|
>
|
|
392
414
|
> `tunnel` 옵션은 Vite dev 모드에서만 동작합니다 — production 빌드는 `forceEnable`이어도 터널을 띄우지 않습니다. 다른 번들러(Webpack/Rspack 등)에서는 무시됩니다. 이 옵션을 켜면 `cloudflared` / `qrcode-terminal`가 동적 import로만 로드되므로, 끄면 번들 그래프에 들어오지 않습니다.
|
|
393
415
|
|
|
394
|
-
### 한 줄 셋업
|
|
416
|
+
### 한 줄 셋업
|
|
395
417
|
|
|
396
|
-
위 "프로젝트당 1회" 단계(vite.config 패치 + `onlyBuiltDependencies` + `dev:phone` 스크립트)는
|
|
418
|
+
위 "프로젝트당 1회" 단계(vite.config 패치 + `onlyBuiltDependencies` + `dev:phone` 스크립트)는 [`agent-plugin`](https://github.com/apps-in-toss-community/agent-plugin)의 `/ait:setup-phone-preview` 한 명령으로 자동화돼 있습니다. 이 README가 그 자동화의 명세서 역할을 하므로, 수동 셋업 단계가 줄어들어도 동작 모델 자체는 동일합니다.
|
|
397
419
|
|
|
398
420
|
## Device API 모드 시스템
|
|
399
421
|
|
|
@@ -632,6 +654,7 @@ __ait.update({ networkStatus: 'OFFLINE' });
|
|
|
632
654
|
__ait.patch('permissions', { camera: 'denied' });
|
|
633
655
|
__ait.patch('deviceModes', { location: 'web' });
|
|
634
656
|
__ait.patch('iap', { nextResult: 'USER_CANCELED' });
|
|
657
|
+
__ait.patch('failureModes', { loadAdMob: 'PLACEMENT_ID_FETCH_FAILED' }); // 실기기 광고 지면 조회 실패 재현
|
|
635
658
|
|
|
636
659
|
// 이벤트 트리거
|
|
637
660
|
__ait.trigger('backEvent');
|
|
@@ -746,6 +769,8 @@ unsubscribe(); // 구독 해제
|
|
|
746
769
|
| `TossAds.destroy/destroyAll` | no-op |
|
|
747
770
|
| `loadFullScreenAd` / `showFullScreenAd` | GoogleAdMob과 유사한 흐름 |
|
|
748
771
|
|
|
772
|
+
> 실패 다이얼(`failureModes.loadAdMob`, 패널 `forceNoFill`)을 설정하지 않으면 위 이벤트들은 매번 동일하게 발화합니다 — mock은 `adGroupId`를 판정에 쓰지 않고, 서버 측 지면(placement) 조회 단계를 모델링하지 않습니다. 실기기는 광고가 존재하기도 전에 지면 조회 자체가 실패해(예: `PLACEMENT_ID_FETCH_FAILED`) 즉시 거부될 수 있으므로, mock의 `loaded` 발화가 "실기기에서 광고가 실제로 나간다"는 신호는 아닙니다. 로컬에서 이 실패를 재현하려면: `__ait.patch('failureModes', { loadAdMob: 'PLACEMENT_ID_FETCH_FAILED' })`.
|
|
773
|
+
|
|
749
774
|
### 이벤트
|
|
750
775
|
|
|
751
776
|
| API | Mock 동작 |
|
|
@@ -853,6 +878,19 @@ it('Storage에 값을 저장하고 읽을 수 있다', async () => {
|
|
|
853
878
|
});
|
|
854
879
|
```
|
|
855
880
|
|
|
881
|
+
## 실기기 테스트 러너 (`debugger-test`)
|
|
882
|
+
|
|
883
|
+
위 "테스트에서의 활용"이 데스크톱 jsdom에서 mock을 검증하는 경로라면, 같은 스타일의 테스트를 **실기기 토스 앱 WebView(환경 3)에서 실 SDK로** 돌리는 러너는 `@ait-co/debugger`로 이동했습니다(#818) — bin도 `devtools-test`에서 `debugger-test`로 바뀌었습니다.
|
|
884
|
+
|
|
885
|
+
```bash
|
|
886
|
+
pnpm add -D @ait-co/debugger
|
|
887
|
+
pnpm exec debugger-test 'src/**/*.ait.test.ts' \
|
|
888
|
+
--scheme-url "intoss-private://my-mini-app?_deploymentId=<uuid>" \
|
|
889
|
+
--cell-sdk-line 3.x --cell-platform ios --report-dir .ait-report
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
전체 플래그·QR 스캔 절차·산출물 레퍼런스는 이제 `@ait-co/debugger` 패키지가 정본입니다 — `debugger-test --help`를 참고하세요. 미니앱 entry에 필요한 한 줄만 이 패키지 쪽에 남아 있습니다: `import '@ait-co/debug-console/auto'` ([위 섹션](#on-device-디버깅-한-줄-설정)).
|
|
893
|
+
|
|
856
894
|
## SDK 업데이트 대응
|
|
857
895
|
|
|
858
896
|
devtools는 [`@apps-in-toss/web-framework`](https://www.npmjs.com/package/@apps-in-toss/web-framework)를 추적하고, [`sdk-example`](https://github.com/apps-in-toss-community/sdk-example)은 원본 SDK와 devtools를 모두 추적한다. 즉 새 SDK 버전이 나오면 (1) devtools가 mock/타입 시그니처를 따라잡고 → (2) sdk-example이 양쪽 새 버전을 동시에 반영하는 흐름. devtools 단독 PR이 sdk-example을 깨뜨리면 양쪽을 함께 본다.
|
|
@@ -965,207 +1003,42 @@ Turbopack은 unplugin을 지원하지 않으므로, `next.config.js`에서 `reso
|
|
|
965
1003
|
import '@ait-co/devtools/panel';
|
|
966
1004
|
```
|
|
967
1005
|
|
|
968
|
-
### `devtools-mcp` — 이미 실행 중인 세션이 있을 때
|
|
969
|
-
|
|
970
|
-
두 번째 `devtools-mcp` 실행 시 "기존 debug-mode 세션이 이미 실행 중" 메시지가 stderr에 출력됩니다. 기존 PID와 wssUrl이 함께 표시됩니다.
|
|
971
|
-
|
|
972
|
-
회복 방법:
|
|
973
|
-
|
|
974
|
-
```bash
|
|
975
|
-
# 기존 세션을 직접 종료
|
|
976
|
-
kill <PID>
|
|
977
|
-
|
|
978
|
-
# 또는 --force 플래그로 기존 세션을 종료하고 takeover
|
|
979
|
-
npx @ait-co/devtools devtools-mcp --force
|
|
980
|
-
# local 모드라면:
|
|
981
|
-
npx @ait-co/devtools devtools-mcp --target=local --force
|
|
982
|
-
```
|
|
983
|
-
|
|
984
|
-
`--takeover`도 `--force`의 alias로 동일하게 동작합니다.
|
|
985
|
-
|
|
986
1006
|
## MCP Server
|
|
987
1007
|
|
|
988
|
-
|
|
989
|
-
통해 실행 중인 미니앱을 직접 관측할 수 있습니다. 단일 `devtools-mcp` bin이 두 모드를 제공합니다.
|
|
990
|
-
|
|
991
|
-
로컬 브라우저(환경 1)와 폰 토스 앱 WebView(환경 2·3)는 둘 다 CDP를 말하므로 모든 tool이 두 환경에서 동일하게 동작합니다 — 갈라지는 건 attach 전략(`--target=relay` vs `--target=local`)뿐입니다.
|
|
992
|
-
|
|
993
|
-
| 모드 + 타깃 | 호출 | 환경 변수 | 대상 | tool |
|
|
994
|
-
|---|---|---|---|---|
|
|
995
|
-
| `--target=mobile` (env 2) | `devtools-mcp` → `start_debug({mode:'relay-sandbox'})` | `AIT_RELAY_BASE_URL`, `AIT_TUNNEL_BASE_URL` | 실기기 Safari/WebKit PWA (외부 Chii relay + cloudflared 터널, 환경 2) | console/network/page + DOM/snapshot/screenshot |
|
|
996
|
-
| `--mode=debug --target=relay` (기본값, env 3) | `devtools-mcp` → `start_debug({mode: 'relay-staging'})` | — | 폰 안 dog-food 번들 (CDP/Chii relay + cloudflared 터널, 환경 3) | 동일 + `AIT.*` |
|
|
997
|
-
| `--mode=debug --target=local` (env 1) | `devtools-mcp --target=local` | `MCP_ENV=mock` (자동) | MCP가 직접 기동한 로컬 Chromium (CDP direct-attach, relay 불필요, 환경 1) | 동일 |
|
|
998
|
-
| `--mode=dev` | `devtools-mcp --mode=dev` | `MCP_ENV=mock` (자동) | 실행 중인 Vite dev server의 mock state (AIT.* 전용, CDP 없음) | `AIT.*` (+ `devtools_get_mock_state` alias) |
|
|
999
|
-
|
|
1000
|
-
`--target=local`은 `AIT_DEVTOOLS_URL`(기본 `http://localhost:5173`)을 열고 로컬 Chromium에 CDP direct-attach합니다 — relay나 터널이 필요하지 않습니다. `--mode=dev`는 Vite dev server의 mock-state HTTP endpoint를 읽으며 CDP tool은 제공하지 않습니다. 세션 내 환경 전환은 `start_debug(mode)` 한 번으로 처리됩니다: `relay-sandbox`(env 2 PWA), `relay-staging`(env 3 dogfood), `local-browser`(env 1).
|
|
1001
|
-
|
|
1002
|
-
#### 환경 2 (실기기 PWA CDP) — `--target=mobile`
|
|
1003
|
-
|
|
1004
|
-
토스 검수 없이 실기기 WebKit 엔진에서 CDP 디버깅이 가능한 모드입니다. [`tunnel:{cdp:true}`](#tunnel-옵션)를 켠 Vite dev server가 앱 HTTP 터널과 Chii relay 터널을 두 개 띄우고, MCP는 그 relay에 붙어 `start_attach` → launcher QR을 제공합니다.
|
|
1005
|
-
|
|
1006
|
-
**진입 절차:**
|
|
1007
|
-
|
|
1008
|
-
1. Vite dev server를 CDP 터널 모드로 기동:
|
|
1009
|
-
```bash
|
|
1010
|
-
AIT_TUNNEL_CDP=1 pnpm exec vite --config e2e/fixture/vite.config.ts
|
|
1011
|
-
```
|
|
1012
|
-
터미널 배너에 두 URL이 출력됩니다:
|
|
1013
|
-
- **앱 HTTP 터널** `https://<A>.trycloudflare.com` → `AIT_TUNNEL_BASE_URL`로 설정
|
|
1014
|
-
- **relay wss 터널** `wss://<B>.trycloudflare.com` → `AIT_RELAY_BASE_URL`의 `https://` 형으로 설정
|
|
1015
|
-
|
|
1016
|
-
2. MCP server를 mobile 모드로 기동 (별도 터미널):
|
|
1017
|
-
```json
|
|
1018
|
-
{
|
|
1019
|
-
"mcpServers": {
|
|
1020
|
-
"ait-debug": {
|
|
1021
|
-
"command": "npx",
|
|
1022
|
-
"args": ["-y", "@ait-co/devtools", "devtools-mcp"],
|
|
1023
|
-
"env": {
|
|
1024
|
-
"AIT_RELAY_BASE_URL": "https://<B>.trycloudflare.com",
|
|
1025
|
-
"AIT_TUNNEL_BASE_URL": "https://<A>.trycloudflare.com"
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
```
|
|
1031
|
-
|
|
1032
|
-
3. Claude Code 세션에서 진입:
|
|
1033
|
-
```
|
|
1034
|
-
start_debug({mode: 'relay-sandbox'})
|
|
1035
|
-
start_attach()
|
|
1036
|
-
```
|
|
1037
|
-
QR을 폰 카메라로 스캔하면 launcher PWA가 앱을 프레임에 열고 Chii target.js를 주입합니다.
|
|
1038
|
-
|
|
1039
|
-
4. `list_pages()` → 페이지 1개 확인. `take_screenshot()` 등 CDP tool을 사용합니다.
|
|
1040
|
-
|
|
1041
|
-
**env 2의 fidelity 경계**: SDK mock을 씁니다 (실 SDK 호출 불가) — `call_sdk`는 환경 2에서 mock을 칩니다. 실 SDK fidelity가 필요하면 환경 3으로 올라가세요. CDP는 실 WebKit 엔진 위에서 동작하므로 DOM·console·screenshot은 실기기 화면을 그대로 반영합니다.
|
|
1042
|
-
|
|
1043
|
-
**로컬 PC 검증**: `e2e/launcher-cdp.test.ts`가 node-side relay 기동(`startChiiRelay({port:0})`)과 launcher 파라미터 포워딩(Playwright)을 자동 검증합니다. browser-side Chii target.js 주입은 localhost 호스트 게이트(Layer B1)와 ws:// vs wss:// 제약으로 CI에서 검증 불가 — 위 수동 절차(실기기 trycloudflare.com 호스트)에서 완성됩니다.
|
|
1044
|
-
|
|
1045
|
-
### Debug 모드 (CDP via Chii)
|
|
1046
|
-
|
|
1047
|
-
실기기 relay 디버깅 루프(dog-food 빌드 → QR 스캔 → relay attach)의 단계별 절차와 복구 방법은 **[`docs/dogfood-relay-loop.md`](./docs/dogfood-relay-loop.md)** 를 참고하세요. crash가 발생한 경우 — `list_pages.crashDetectedAt`, iOS Console.app `.ips` 분석, redact 절차를 포함한 원인 추적 절차는 **[`docs/crash-triage.md`](./docs/crash-triage.md)** 를 참고하세요.
|
|
1048
|
-
|
|
1049
|
-
read-only tool만 노출합니다. 도구는 attach 상태에 따라 2단계로 등록됩니다 — attach 전에는 bootstrap
|
|
1050
|
-
도구(`start_attach`·`list_pages`)만 보이고, 릴레이/로컬 페이지가 attach되면 `notifications/tools/list_changed`로
|
|
1051
|
-
attach 의존 도구가 같은 세션에서 동적 등록됩니다(세션 재시작 불필요). 폰 attach 라운드트립은 fully wired
|
|
1052
|
-
상태이며 남은 것은 실기기 acceptance 한 번뿐입니다. tool 계층은 주입 가능한 CDP 연결 / AIT 소스를 mock해
|
|
1053
|
-
CI에서 검증됩니다.
|
|
1054
|
-
|
|
1055
|
-
`devtools-mcp`를 stdio로 실행하면 로컬 Chii 릴레이를 OS가 할당한 포트에 띄우고 cloudflared quick
|
|
1056
|
-
tunnel로 공개 `wss://*.trycloudflare.com` URL을 발급한 뒤 QR을 터미널에 출력합니다(시크릿/인증
|
|
1057
|
-
코드는 출력하지 않습니다). 폰이 dog-food 진입 시 in-app attach UI가 그 URL로 릴레이에 붙으면,
|
|
1058
|
-
에이전트가 `chrome-devtools-mcp` 호환 tool로 console/network/page 상태를 read합니다. 사람이 폰을
|
|
1059
|
-
지켜볼 필요 없이 회귀를 단독 진단하는 것이 목표입니다.
|
|
1060
|
-
|
|
1061
|
-
환경 3 (intoss-private relay) — `devtools-mcp`를 그대로 기동한 뒤 `start_debug(mode)`로 진입합니다:
|
|
1008
|
+
MCP 표면(데몬 · attach · CDP tool)은 `@ait-co/debugger`로 이동했습니다(#818). 에이전트 등록도 이제 devtools가 아니라 debugger를 가리킵니다:
|
|
1062
1009
|
|
|
1063
1010
|
```json
|
|
1064
1011
|
{
|
|
1065
1012
|
"mcpServers": {
|
|
1066
1013
|
"ait-debug": {
|
|
1067
|
-
"command": "
|
|
1068
|
-
"args": ["
|
|
1014
|
+
"command": "npx",
|
|
1015
|
+
"args": ["-y", "-p", "@ait-co/debugger", "debugger"]
|
|
1069
1016
|
}
|
|
1070
1017
|
}
|
|
1071
1018
|
}
|
|
1072
1019
|
```
|
|
1073
1020
|
|
|
1074
|
-
- 환경 3
|
|
1075
|
-
**세션 내 환경 전환은 `start_debug(mode)`가 단일 진입 경로**입니다.
|
|
1076
|
-
|
|
1077
|
-
| Tool | CDP / AIT 백킹 | 설명 |
|
|
1078
|
-
|---|---|---|
|
|
1079
|
-
| `list_console_messages` | `Runtime.consoleAPICalled` | 최근 console.log/warn/error 메시지 (level, text, timestamp, args) |
|
|
1080
|
-
| `list_network_requests` | `Network.requestWillBeSent` + `responseReceived` | 최근 XHR/fetch 요청 (url, method, status, timing) |
|
|
1081
|
-
| `list_pages` | Chii 릴레이 target 목록 | attach된 페이지 + tunnel 상태 + wss URL |
|
|
1082
|
-
| `start_attach` | (순수 합성 + attach 대기) | `ait deploy --scheme-only` URL에 `debug=1`+릴레이 URL을 끼워 self-attach deep-link를 합성하고 QR을 출력한 뒤, 폰이 attach될 때까지 같은 호출 안에서 대기한다(QR 생성·attach가 한 호출). `mode`로 세션 환경을 함께 전환할 수 있고, 대기 중 TOTP 코드를 자동 재발행한다. 환경 2·3 진입 도구(bootstrap) — `list_pages` 선행 불필요 |
|
|
1083
|
-
| `get_dom_document` | `DOM.getDocument` | DOM 트리 read (구조/레이아웃 회귀 진단) |
|
|
1084
|
-
| `take_snapshot` | `DOMSnapshot.captureSnapshot` | 페이지 스냅샷 (documents + interned strings, 시각 회귀 진단) |
|
|
1085
|
-
| `take_screenshot` | `Page.captureScreenshot` | 페이지 PNG 스크린샷 (MCP image content block 반환) |
|
|
1086
|
-
| `measure_safe_area` | `Runtime.evaluate` | attach된 페이지에서 safe-area 프로브 실행 → 정규화된 safe-area inset·뷰포트 geometry·DPR·User-Agent 반환. read-only. relay 세션(폰 attach)에서 viewport preset을 extrapolated/placeholder→measured로 승급할 ground truth 수집용. attach 필요 (`list_pages` 먼저) |
|
|
1087
|
-
| `evaluate` | `Runtime.evaluate` | attach된 페이지에서 임의 JS 표현식 평가(returnByValue) → 결과 반환. **read-only 아님** — 표현식이 부작용(DOM 변경·SDK 호출·상태 변경)을 일으킬 수 있음. attach 필요 |
|
|
1088
|
-
| `call_sdk` | `window.__sdkCall` 브리지 (`Runtime.evaluate` 경유) | dog-food SDK 메서드를 `window.__sdkCall` 브리지로 호출 (`@apps-in-toss/web-framework`가 `__DEBUG_BUILD__` 번들에서만 export). **read-only 아님** — SDK 호출은 부작용(내비게이션·결제·권한 등). 환경 3(실기기 relay)에선 실 SDK, 환경 1(로컬 mock)에선 mock SDK. 환경 2(PWA)는 SDK 미주입으로 사용 불가. attach 필요. `{ok,value}` / `{ok,error}` 반환 |
|
|
1089
|
-
| `AIT.getSdkCallHistory` | AIT 도메인 | SDK 호출 trace (method, args, result/error, timestamp) |
|
|
1090
|
-
| `AIT.getMockState` | AIT 도메인 | mock state 스냅샷 (`window.__ait`) |
|
|
1091
|
-
| `AIT.getOperationalEnvironment` | AIT 도메인 | `getOperationalEnvironment()` + SDK 버전 |
|
|
1092
|
-
|
|
1093
|
-
`AIT.*`는 raw CDP가 못 잡는 영역으로, 같은 MCP server가 CDP와 함께 forward합니다. debug 모드에서는
|
|
1094
|
-
in-app 측이 Chii 채널로 응답합니다.
|
|
1095
|
-
|
|
1096
|
-
### Dev 모드 (mock state)
|
|
1097
|
-
|
|
1098
|
-
`devtools-mcp --mode=dev`는 실행 중인 브라우저의 mock state를 읽습니다. debug 모드와 같은 `AIT.*`
|
|
1099
|
-
tool surface를 공유합니다.
|
|
1100
|
-
|
|
1101
|
-
#### 구조
|
|
1102
|
-
|
|
1103
|
-
```
|
|
1104
|
-
브라우저 (aitState)
|
|
1105
|
-
└─ POST /api/ait-devtools/state (panel이 state 변경 시 자동 push)
|
|
1106
|
-
└─ Vite dev server (unplugin mcp: true 로 등록)
|
|
1107
|
-
└─ GET /api/ait-devtools/state
|
|
1108
|
-
└─ MCP stdio server (dist/mcp/server.js)
|
|
1109
|
-
└─ AI 에이전트 (AIT.getMockState tool)
|
|
1110
|
-
```
|
|
1111
|
-
|
|
1112
|
-
#### 설정
|
|
1113
|
-
|
|
1114
|
-
**1. Vite 플러그인에 `mcp: true` 추가**
|
|
1115
|
-
|
|
1116
|
-
```ts
|
|
1117
|
-
// vite.config.ts
|
|
1118
|
-
import aitDevtools from '@ait-co/devtools/unplugin';
|
|
1119
|
-
|
|
1120
|
-
export default {
|
|
1121
|
-
plugins: [aitDevtools.vite({ mcp: true })],
|
|
1122
|
-
};
|
|
1123
|
-
```
|
|
1124
|
-
|
|
1125
|
-
**2. MCP 클라이언트 설정 (예: Claude Code `.claude/settings.json`)**
|
|
1126
|
-
|
|
1127
|
-
```json
|
|
1128
|
-
{
|
|
1129
|
-
"mcpServers": {
|
|
1130
|
-
"ait-devtools": {
|
|
1131
|
-
"command": "pnpm",
|
|
1132
|
-
"args": ["exec", "devtools-mcp", "--mode=dev"],
|
|
1133
|
-
"env": {
|
|
1134
|
-
"AIT_DEVTOOLS_URL": "http://localhost:5173"
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
```
|
|
1140
|
-
|
|
1141
|
-
`AIT_DEVTOOLS_URL`은 기본값이 `http://localhost:5173`이므로 기본 포트를 쓰면 생략 가능합니다.
|
|
1142
|
-
|
|
1143
|
-
**3. 앱을 브라우저에서 열고, AI 에이전트에서 tool 호출**
|
|
1144
|
-
|
|
1145
|
-
```
|
|
1146
|
-
> AIT.getMockState
|
|
1147
|
-
```
|
|
1148
|
-
|
|
1149
|
-
현재 mock state 전체(권한, 위치, 인증, 네트워크, IAP 등)를 JSON으로 반환합니다.
|
|
1150
|
-
|
|
1151
|
-
| Tool | 설명 |
|
|
1152
|
-
|---|---|
|
|
1153
|
-
| `AIT.getMockState` | 현재 `AitDevtoolsState` 스냅샷 반환 (read-only) |
|
|
1154
|
-
| `AIT.getOperationalEnvironment` | mock state의 `environment` + `appVersion` 기반 환경/버전 |
|
|
1155
|
-
| `AIT.getSdkCallHistory` | dev 모드에서는 빈 목록 (HTTP endpoint가 trace를 기록하지 않음) |
|
|
1156
|
-
| `devtools_get_mock_state` | `AIT.getMockState`의 하위호환 alias (신규 설정은 `AIT.getMockState` 권장) |
|
|
1021
|
+
이 서버가 주는 것: 로컬 브라우저(환경 1)·PWA(환경 2)·intoss-private WebView(환경 3)에서 실행 중인 미니앱을 CDP로 관측 — console, network, DOM, snapshot, screenshot — 그리고 환경 2·3 on-device 진입용 `start_attach`. 전체 tool 목록·모드/타깃 매트릭스·환경별 설정은 [`@ait-co/debugger`](https://www.npmjs.com/package/@ait-co/debugger) 패키지 문서가 정본입니다.
|
|
1157
1022
|
|
|
1158
1023
|
## 패키지 Export 구조
|
|
1159
1024
|
|
|
1025
|
+
이 패키지가 실제로 출하하는 진입점입니다:
|
|
1026
|
+
|
|
1160
1027
|
| Import path | 용도 |
|
|
1161
1028
|
|---|---|
|
|
1162
|
-
| `@ait-co/devtools`
|
|
1029
|
+
| `@ait-co/devtools` (= `/mock`) | 번들러 alias 대상, 모든 mock export |
|
|
1163
1030
|
| `@ait-co/devtools/panel` | Floating DevTools Panel (import 시 자동 마운트) |
|
|
1164
1031
|
| `@ait-co/devtools/unplugin` | 번들러 플러그인 (.vite, .webpack, .rspack, .esbuild, .rollup) |
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
|
1032
|
+
|
|
1033
|
+
아래는 **전환 스텁**입니다 — 0.2.x에만 존재하고 1.0.0에서 제거됩니다(#818). 새 패키지로 마이그레이션하세요.
|
|
1034
|
+
|
|
1035
|
+
| Import path | 이동처 | import 시 |
|
|
1036
|
+
|---|---|---|
|
|
1037
|
+
| `@ait-co/devtools/mcp/server` | `@ait-co/debugger/mcp/server` | throw |
|
|
1038
|
+
| `@ait-co/devtools/mcp/cli` | `@ait-co/debugger/mcp/cli` | throw |
|
|
1039
|
+
| `@ait-co/devtools/test-runner` | `@ait-co/debugger/test-runner` | throw |
|
|
1040
|
+
| `@ait-co/devtools/in-app` | `@ait-co/debug-console` | no-op + `console.error` 1회 |
|
|
1041
|
+
| `@ait-co/devtools/in-app/auto` | `@ait-co/debug-console/auto` | no-op + `console.error` 1회 |
|
|
1169
1042
|
|
|
1170
1043
|
## 라이센스
|
|
1171
1044
|
|
package/dist/in-app/auto.d.ts
CHANGED
|
@@ -1,138 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @ait-co/devtools/in-app/auto — self-gating side-effect entry.
|
|
4
|
-
*
|
|
5
|
-
* Consumers add a single line to their mini-app entry:
|
|
6
|
-
*
|
|
7
|
-
* import '@ait-co/devtools/in-app/auto';
|
|
8
|
-
*
|
|
9
|
-
* The entry self-gates: if none of the debug activation signals are present
|
|
10
|
-
* (no `?debug=1`, no `?relay=`, and not a DEV build), it does nothing. The
|
|
11
|
-
* imported chunk stays dormant and `window.__sdk` / `window.__sdkCall` are
|
|
12
|
-
* never installed on a normal production load.
|
|
13
|
-
*
|
|
14
|
-
* DEPRECATED for builds that require debug code to be PHYSICALLY ABSENT from
|
|
15
|
-
* the release bundle. This entry is a RUNTIME self-gate, not a build-time one:
|
|
16
|
-
* the imported chunk (Chii target.js injection, the SDK bridge, and the eruda
|
|
17
|
-
* console it pulls in via `maybeAttach()`) stays in the production bundle as a
|
|
18
|
-
* dormant chunk and is only kept asleep at runtime. If your threat model needs
|
|
19
|
-
* "zero bytes of debug surface in release" (no dormant chunk to extract or
|
|
20
|
-
* re-enable), do NOT use this entry. Instead guard the call site yourself:
|
|
21
|
-
*
|
|
22
|
-
* if (__DEBUG_BUILD__) {
|
|
23
|
-
* import('@ait-co/devtools/in-app').then((m) => m.maybeAttach());
|
|
24
|
-
* }
|
|
25
|
-
*
|
|
26
|
-
* with `define: { __DEBUG_BUILD__: 'false' }` in your release build — the
|
|
27
|
-
* bundler then dead-code-eliminates the whole `@ait-co/devtools/in-app` graph
|
|
28
|
-
* (verified on Vite 8/rolldown). This entry stays for the convenience case
|
|
29
|
-
* where a dormant chunk gated at runtime is acceptable.
|
|
30
|
-
*
|
|
31
|
-
* When the gate passes it:
|
|
32
|
-
* 1. Calls `maybeAttach()` — runs the full Layer B/C gate (host allowlist,
|
|
33
|
-
* opt-in params, relay URL, TOTP) and injects the Chii `target.js` script.
|
|
34
|
-
* Gate semantics are NOT changed — this is a thin self-gate wrapper.
|
|
35
|
-
* 2. Installs the SDK bridge (`window.__sdk` / `window.__sdkCall`) so an AI
|
|
36
|
-
* agent can drive any SDK API over the CDP relay without hand-synthesising
|
|
37
|
-
* the Granite/ReactNative bridge envelope. SDK access uses a dynamic
|
|
38
|
-
* import of `@apps-in-toss/web-framework` — the peer is optional, so if
|
|
39
|
-
* the SDK is not installed the bridge install is silently skipped
|
|
40
|
-
* (fail-silent). The namespace mirror pattern (iterate `Object.keys`) is
|
|
41
|
-
* SDK version-neutral: 2.x and 3.x are both covered without any static
|
|
42
|
-
* import that would couple the entry to a specific SDK line.
|
|
43
|
-
*
|
|
44
|
-
* SECRET-HANDLING: no secret, TOTP code, relay URL, or host value is ever
|
|
45
|
-
* logged or surfaced beyond the reason enum in `maybeAttach()`.
|
|
46
|
-
*
|
|
47
|
-
* Layer A (build-time DCE) is NOT enforced here — this entry IS the
|
|
48
|
-
* consumer-facing alternative to `if (__DEBUG_BUILD__) { … }`. The self-gate
|
|
49
|
-
* below performs the same dormancy guarantee via a URL param check, which is
|
|
50
|
-
* safe in a side-effect import context (the gate runs at module evaluation
|
|
51
|
-
* time, before any React tree mounts). Consumers who already manage their own
|
|
52
|
-
* `__DEBUG_BUILD__` guard can keep using `@ait-co/devtools/in-app` directly.
|
|
53
|
-
*
|
|
54
|
-
* DEV detection uses two complementary signals:
|
|
55
|
-
* 1. `import.meta.env.DEV` — resolved by the consumer's bundler at their
|
|
56
|
-
* build time (Vite/Webpack/Rspack inject the value via top-level source
|
|
57
|
-
* transforms). Works when the consumer's source code (not node_modules)
|
|
58
|
-
* is processed — same pattern used by the polyfill's `auto` entry.
|
|
59
|
-
* 2. `process.env.NODE_ENV === 'development'` — resolved by the consumer's
|
|
60
|
-
* bundler via esbuild `define` (Vite dep-prebundle) or DefinePlugin
|
|
61
|
-
* (webpack/Rspack). This token IS substituted in dep code inside
|
|
62
|
-
* node_modules (how React's own dev/prod branching works), fixing the
|
|
63
|
-
* env-1 regression where signal (1) was never injected into dep code
|
|
64
|
-
* (sdk-example#180 / issue #520).
|
|
65
|
-
* IMPORTANT: the `process.env.NODE_ENV` token must be written verbatim
|
|
66
|
-
* — bundler define substitution is a textual token match. A `typeof
|
|
67
|
-
* process` guard would survive substitution as-is and always evaluate to
|
|
68
|
-
* `false` in a browser, killing the comparison. Instead we rely on
|
|
69
|
-
* try/catch: if `process` is not defined (raw ESM in a browser without
|
|
70
|
-
* bundler substitution) a ReferenceError is caught → fail-closed (dormant).
|
|
71
|
-
*/
|
|
72
|
-
declare global {
|
|
73
|
-
interface Window {
|
|
74
|
-
/**
|
|
75
|
-
* Entire `@apps-in-toss/web-framework` export namespace mirrored onto a
|
|
76
|
-
* plain writable object. Installed by the auto entry when `?debug=1` /
|
|
77
|
-
* `?relay=` is present in the URL, or in DEV builds.
|
|
78
|
-
*
|
|
79
|
-
* Lets an AI agent call any SDK API over a CDP relay without
|
|
80
|
-
* hand-synthesising the Granite/ReactNative bridge envelope:
|
|
81
|
-
* `window.__sdk.setDeviceOrientation({ type: 'landscape' })`
|
|
82
|
-
*/
|
|
83
|
-
__sdk?: Record<string, unknown>;
|
|
84
|
-
/**
|
|
85
|
-
* Safe call wrapper for `window.__sdk`. Returns a JSON-serialisable
|
|
86
|
-
* `{ ok: true, value }` or `{ ok: false, error }` tuple even for
|
|
87
|
-
* throwing/async SDK functions — ideal for `Runtime.evaluate` results.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* window.__sdkCall('setDeviceOrientation', { type: 'landscape' })
|
|
91
|
-
*/
|
|
92
|
-
__sdkCall?: (name: string, ...args: unknown[]) => Promise<{
|
|
93
|
-
ok: boolean;
|
|
94
|
-
value?: unknown;
|
|
95
|
-
error?: string;
|
|
96
|
-
}>;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Detects whether the current build is a DEV build by consulting two signals.
|
|
101
|
-
*
|
|
102
|
-
* Signal A — `import.meta.env.DEV`:
|
|
103
|
-
* Substituted by Vite/Webpack/Rspack in the consumer's own source files.
|
|
104
|
-
* NOT substituted in node_modules dep code (esbuild prebundle does not
|
|
105
|
-
* apply Vite's define pass to deps) — this was the root cause of #520.
|
|
106
|
-
*
|
|
107
|
-
* Signal B — `process.env.NODE_ENV === 'development'`:
|
|
108
|
-
* Substituted by esbuild's dep-prebundle define pass (Vite) and by
|
|
109
|
-
* DefinePlugin (webpack/Rspack) even inside node_modules. This is how
|
|
110
|
-
* React itself gates its dev-only code paths. Writing the token verbatim
|
|
111
|
-
* ensures textual substitution works; a `typeof process` guard would not
|
|
112
|
-
* be substituted and would evaluate to `'undefined'` in the browser,
|
|
113
|
-
* killing the comparison. A try/catch catches the ReferenceError when
|
|
114
|
-
* `process` is genuinely absent (raw ESM without bundler, e.g. direct
|
|
115
|
-
* browser import or test runners that leave identifiers in place) →
|
|
116
|
-
* fail-closed (dormant).
|
|
117
|
-
*
|
|
118
|
-
* Exported for unit tests — pass an explicit `isDev` override to bypass
|
|
119
|
-
* the environment detection in controlled test scenarios.
|
|
120
|
-
*/
|
|
121
|
-
declare function detectDevSignal(): boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Pure predicate for the self-gate. Exported for unit tests.
|
|
124
|
-
*
|
|
125
|
-
* @param isDev - Whether the consumer's bundler signals a DEV build.
|
|
126
|
-
* Default: calls `detectDevSignal()` which consults both
|
|
127
|
-
* `import.meta.env.DEV` (consumer source pass) and
|
|
128
|
-
* `process.env.NODE_ENV === 'development'` (dep prebundle pass, fixing
|
|
129
|
-
* the env-1 regression in issue #520).
|
|
130
|
-
* Pass an explicit value in tests to control the DEV signal without
|
|
131
|
-
* depending on the Vite/vitest build environment.
|
|
132
|
-
* @param searchStr - URL search string to inspect. Defaults to
|
|
133
|
-
* `window.location.search` when called in a browser context.
|
|
134
|
-
*/
|
|
135
|
-
declare function shouldActivate(isDev?: boolean, searchStr?: string): boolean;
|
|
136
|
-
//#endregion
|
|
137
|
-
export { detectDevSignal, shouldActivate };
|
|
138
|
-
//# sourceMappingURL=auto.d.ts.map
|
|
1
|
+
export { };
|