@ait-co/devtools 0.1.140 → 0.1.142
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 +4 -4
- package/README.md +4 -4
- package/dist/{attach-orchestrator-BG8TGJOZ.js → attach-orchestrator-0F0m_UqQ.js} +71 -9
- package/dist/{attach-orchestrator-BG8TGJOZ.js.map → attach-orchestrator-0F0m_UqQ.js.map} +1 -1
- package/dist/{attach-orchestrator-6kz_ZdWL.js → attach-orchestrator-D65KxFy_.js} +71 -9
- package/dist/{attach-orchestrator-6kz_ZdWL.js.map → attach-orchestrator-D65KxFy_.js.map} +1 -1
- package/dist/{attach-orchestrator-BEiz3wAx.js → attach-orchestrator-DL3NQ9ca.js} +71 -9
- package/dist/{attach-orchestrator-BEiz3wAx.js.map → attach-orchestrator-DL3NQ9ca.js.map} +1 -1
- package/dist/{cell-BMlFh08P.js → cell-BaLvusOl.js} +2 -2
- package/dist/{cell-BMlFh08P.js.map → cell-BaLvusOl.js.map} +1 -1
- package/dist/{cell-Dtgtusog.js → cell-CBUS3-nT.js} +2 -2
- package/dist/{cell-Dtgtusog.js.map → cell-CBUS3-nT.js.map} +1 -1
- package/dist/{cell-KsRXFdDs.js → cell-EBKKpAAT.js} +2 -2
- package/dist/{cell-KsRXFdDs.js.map → cell-EBKKpAAT.js.map} +1 -1
- package/dist/{debug-server-DWat7d-9.js → debug-server-B3ABDrRI.js} +4 -4
- package/dist/{debug-server-DWat7d-9.js.map → debug-server-B3ABDrRI.js.map} +1 -1
- package/dist/{debug-server-6c22qSWa.js → debug-server-BWhwrVXa.js} +4 -4
- package/dist/{debug-server-6c22qSWa.js.map → debug-server-BWhwrVXa.js.map} +1 -1
- package/dist/{debug-server-BQHbaKPT.js → debug-server-CfQNxxGW.js} +6 -6
- package/dist/{debug-server-BQHbaKPT.js.map → debug-server-CfQNxxGW.js.map} +1 -1
- package/dist/in-app/auto.js +299 -3
- package/dist/in-app/auto.js.map +1 -1
- package/dist/in-app/index.d.ts +161 -14
- package/dist/in-app/index.d.ts.map +1 -1
- package/dist/in-app/index.js +300 -4
- package/dist/in-app/index.js.map +1 -1
- package/dist/mcp/cli.js +82 -16
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mock/index.d.ts +174 -97
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +78 -14
- package/dist/mock/index.js.map +1 -1
- package/dist/panel/index.js +7 -23
- package/dist/panel/index.js.map +1 -1
- package/dist/{qr-http-server-Cz1mA07b.cjs → qr-http-server--gl2-WKc.cjs} +9 -5
- package/dist/qr-http-server--gl2-WKc.cjs.map +1 -0
- package/dist/{qr-http-server-D4rGz8M7.js → qr-http-server-Bb7lMeqi.js} +9 -5
- package/dist/qr-http-server-Bb7lMeqi.js.map +1 -0
- package/dist/{qr-http-server-D1hpoyBF.js → qr-http-server-C_lqOrgc.js} +9 -5
- package/dist/qr-http-server-C_lqOrgc.js.map +1 -0
- package/dist/{qr-http-server-CTLdclg_.js → qr-http-server-CopuMbub.js} +9 -5
- package/dist/qr-http-server-CopuMbub.js.map +1 -0
- package/dist/{qr-http-server-D16Lq2ag.cjs → qr-http-server-D-Off6K1.cjs} +9 -5
- package/dist/qr-http-server-D-Off6K1.cjs.map +1 -0
- package/dist/{qr-http-server-DIjCV7h_.js → qr-http-server-DrbIVDjO.js} +9 -5
- package/dist/qr-http-server-DrbIVDjO.js.map +1 -0
- package/dist/qr-http-server-n1twN18z.js +1644 -0
- package/dist/qr-http-server-n1twN18z.js.map +1 -0
- package/dist/{relay-factory-C1X3G3WY.js → relay-factory-N9QobQxG.js} +6 -6
- package/dist/{relay-factory-C1X3G3WY.js.map → relay-factory-N9QobQxG.js.map} +1 -1
- package/dist/{relay-worker-BUXI0K0b.js → relay-worker-B5HKkGUY.js} +4 -4
- package/dist/{relay-worker-BUXI0K0b.js.map → relay-worker-B5HKkGUY.js.map} +1 -1
- package/dist/relay-worker-DcyboK43.d.ts.map +1 -1
- package/dist/test-runner/bin.js +8 -8
- package/dist/test-runner/bin.js.map +1 -1
- package/dist/test-runner/config.js +1 -1
- package/dist/test-runner/pool.js +1 -1
- package/dist/test-runner/relay-factory.js +5 -5
- package/dist/test-runner/relay-worker.js +1 -1
- package/dist/{tunnel-DjtSENJU.cjs → tunnel-BVSMXctM.cjs} +2 -2
- package/dist/{tunnel-DjtSENJU.cjs.map → tunnel-BVSMXctM.cjs.map} +1 -1
- package/dist/{tunnel-5eBncITa.js → tunnel-D7xkimBu.js} +2 -2
- package/dist/{tunnel-5eBncITa.js.map → tunnel-D7xkimBu.js.map} +1 -1
- package/dist/unplugin/index.cjs +1 -1
- package/dist/unplugin/index.js +1 -1
- package/dist/unplugin/tunnel.cjs +1 -1
- package/dist/unplugin/tunnel.js +1 -1
- package/package.json +2 -2
- package/dist/qr-http-server-CTLdclg_.js.map +0 -1
- package/dist/qr-http-server-Cz1mA07b.cjs.map +0 -1
- package/dist/qr-http-server-D16Lq2ag.cjs.map +0 -1
- package/dist/qr-http-server-D1hpoyBF.js.map +0 -1
- package/dist/qr-http-server-D4rGz8M7.js.map +0 -1
- package/dist/qr-http-server-DIjCV7h_.js.map +0 -1
- package/dist/qr-http-server-wy3L7Yut.js +0 -1640
- package/dist/qr-http-server-wy3L7Yut.js.map +0 -1
package/README.en.md
CHANGED
|
@@ -20,7 +20,7 @@ Live demo: <https://devtools.aitc.dev/> (the `e2e/fixture/` from this repo deplo
|
|
|
20
20
|
|
|
21
21
|
## 15-second quickstart — pick your environment
|
|
22
22
|
|
|
23
|
-
There are
|
|
23
|
+
There are three runtime environments. Pick the card that fits your situation and follow the link to the detailed scenario doc.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -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
|
|
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).
|
|
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
|
|
|
@@ -83,7 +83,7 @@ What this single line does:
|
|
|
83
83
|
- **SDK bridge**: installs `window.__sdk` / `window.__sdkCall` so an agent can drive any SDK API directly over the CDP relay via `Runtime.evaluate`. Silently skipped if `@apps-in-toss/web-framework` is not available.
|
|
84
84
|
- **Types**: provides `Window.__sdk` / `__sdkCall` global type declarations automatically — no separate `globals.d.ts` needed in your project.
|
|
85
85
|
|
|
86
|
-
For
|
|
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
|
> For dog-food builds with TOTP authentication, inject `__DEBUG_TOTP_SECRET__` via your build define and use `@ait-co/devtools/in-app` directly with `evaluateDebugGate({ verifyTotpCode })` + `maybeAttach()`. `in-app/auto` does not inject a TOTP verifier, so Layer C3 is disabled.
|
|
89
89
|
|
|
@@ -1020,7 +1020,7 @@ Read-only tools only. Tools are registered in two tiers based on attach state
|
|
|
1020
1020
|
|
|
1021
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
1022
|
|
|
1023
|
-
|
|
1023
|
+
Environment 3 (intoss-private relay) — start `devtools-mcp` as-is, then enter via `start_debug(mode)`:
|
|
1024
1024
|
|
|
1025
1025
|
```json
|
|
1026
1026
|
{
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
## 15초 quickstart — 내 상황에 맞는 환경 고르기
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
3가지 실행 환경이 있습니다. 지금 상황에 맞는 카드 하나를 고르고, 해당 상세 시나리오 문서로 이동하세요.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -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).
|
|
51
51
|
|
|
52
52
|
사전: 폰에 `https://devtools.aitc.dev/launcher/` 를 홈 화면에 한 번 추가. 상세: [`docs/scenarios/env-2.md`](./docs/scenarios/env-2.md)
|
|
53
53
|
|
|
@@ -83,7 +83,7 @@ import '@ait-co/devtools/in-app/auto';
|
|
|
83
83
|
- **SDK 브리지**: `window.__sdk` / `window.__sdkCall`을 설치해 에이전트가 CDP relay의 `Runtime.evaluate`로 SDK API를 직접 구동할 수 있게 합니다. `@apps-in-toss/web-framework`가 없으면 조용히 skip합니다.
|
|
84
84
|
- **타입**: `Window.__sdk` / `__sdkCall` 글로벌 타입을 자동으로 제공합니다 — 별도 `globals.d.ts` 불필요.
|
|
85
85
|
|
|
86
|
-
환경 3
|
|
86
|
+
환경 3(intoss-private relay) 빌드는 relay QR deep-link가 `?debug=1&relay=<wss>` 파라미터를 실어 보내므로, 이 한 줄만 있으면 별도 게이트 코드가 필요 없습니다. 환경 2(PWA, `tunnel: { cdp: true }`)도 동일하게 동작합니다.
|
|
87
87
|
|
|
88
88
|
> TOTP 인증이 필요한 dog-food 빌드는 빌드 define으로 `__DEBUG_TOTP_SECRET__`을 주입하고 `@ait-co/devtools/in-app`을 직접 import해 `evaluateDebugGate({ verifyTotpCode })` + `maybeAttach()`를 사용하세요. `in-app/auto`는 TOTP verifier를 주입하지 않으므로 C3 레이어가 비활성화됩니다.
|
|
89
89
|
|
|
@@ -1058,7 +1058,7 @@ tunnel로 공개 `wss://*.trycloudflare.com` URL을 발급한 뒤 QR을 터미
|
|
|
1058
1058
|
에이전트가 `chrome-devtools-mcp` 호환 tool로 console/network/page 상태를 read합니다. 사람이 폰을
|
|
1059
1059
|
지켜볼 필요 없이 회귀를 단독 진단하는 것이 목표입니다.
|
|
1060
1060
|
|
|
1061
|
-
환경 3
|
|
1061
|
+
환경 3 (intoss-private relay) — `devtools-mcp`를 그대로 기동한 뒤 `start_debug(mode)`로 진입합니다:
|
|
1062
1062
|
|
|
1063
1063
|
```json
|
|
1064
1064
|
{
|
|
@@ -1606,7 +1606,7 @@ async function renderAndMaybeWait(deps, prep, waitForAttach, callTimeoutMs, conn
|
|
|
1606
1606
|
let totpIssuedAt = nowMs();
|
|
1607
1607
|
let reminted = 0;
|
|
1608
1608
|
const relayUrl = parts.wssUrl;
|
|
1609
|
-
const header = "This tool result is shown to the user directly — do NOT re-print the QR below in your reply (it wastes output tokens). Just tell the user to scan the QR in this output (Ctrl+O to expand if collapsed)
|
|
1609
|
+
const header = "This tool result is shown to the user directly — do NOT re-print the QR below in your reply (it wastes output tokens). Just tell the user to scan the QR in this output (Ctrl+O to expand if collapsed).\n\n테스트가 끝날 때까지 앱을 화면 앞에 유지하세요 — 백그라운드로 전환하면 디버그 세션이 끊어집니다.";
|
|
1610
1610
|
const warningPrefix = authorityWarning ? `⚠️ scheme_url 경고: ${authorityWarning}\n\n` : "";
|
|
1611
1611
|
const guiAvailable = canOpenBrowserFn();
|
|
1612
1612
|
/** Builds the totp object surfaced in results (fresh expiresAt + reminted). */
|
|
@@ -1732,9 +1732,35 @@ async function renderAndMaybeWait(deps, prep, waitForAttach, callTimeoutMs, conn
|
|
|
1732
1732
|
}, null, 2)}\n\n${qr}`);
|
|
1733
1733
|
}
|
|
1734
1734
|
/**
|
|
1735
|
+
* How long the disconnected badge stays on screen before it fades and removes
|
|
1736
|
+
* itself (#748). Long enough to read, short enough not to linger; a reconnect
|
|
1737
|
+
* within this window cancels the self-dismiss (transient tunnel blips do not
|
|
1738
|
+
* flash-remove the badge).
|
|
1739
|
+
*/
|
|
1740
|
+
const INDICATOR_SELF_DISMISS_MS = 5e3;
|
|
1741
|
+
/** Fade duration before the self-dismissed badge is detached from the DOM. */
|
|
1742
|
+
const INDICATOR_FADE_MS = 400;
|
|
1743
|
+
/**
|
|
1744
|
+
* Heartbeat / pending-call render tick (#749). 1 Hz — cheap enough to be
|
|
1745
|
+
* invisible (a single text write per second, no layout thrash) while making a
|
|
1746
|
+
* JS main-thread wedge obvious: the compositor-driven pulse dot keeps animating
|
|
1747
|
+
* but this JS-driven `♥<beats>` token freezes. Pending-call elapsed times are
|
|
1748
|
+
* recomputed on the same tick so they advance without any bridge event.
|
|
1749
|
+
*/
|
|
1750
|
+
const INDICATOR_HEARTBEAT_MS = 1e3;
|
|
1751
|
+
/**
|
|
1752
|
+
* Display-side staleness guard (#749): the badge skips rendering a pending call
|
|
1753
|
+
* older than this. A safety net independent of the in-app observer's own prune
|
|
1754
|
+
* (`bridge-observer.ts` MAX_PENDING_AGE_MS) — kept local so the daemon-graph
|
|
1755
|
+
* expression builder never imports the in-app module (install-graph invariant).
|
|
1756
|
+
* Generous enough that a genuinely slow native call still shows while plausibly
|
|
1757
|
+
* in flight.
|
|
1758
|
+
*/
|
|
1759
|
+
const INDICATOR_PENDING_STALE_MS = 12e4;
|
|
1760
|
+
/**
|
|
1735
1761
|
* Builds a self-contained IIFE DOM expression that renders a LIVE
|
|
1736
|
-
* "Debugger Connected" /
|
|
1737
|
-
*
|
|
1762
|
+
* "Debugger Connected" / disconnected badge on the bottom-left of the phone
|
|
1763
|
+
* screen (#730), with a graceful self-dismiss on disconnect (#748).
|
|
1738
1764
|
*
|
|
1739
1765
|
* **Pure function** — returns a JS expression string; does NOT inject it.
|
|
1740
1766
|
* Injection is performed by {@link injectDebugIndicator} in `cell.ts`.
|
|
@@ -1751,7 +1777,18 @@ async function renderAndMaybeWait(deps, prep, waitForAttach, callTimeoutMs, conn
|
|
|
1751
1777
|
* 3. A `pointerdown` listener dismisses (hides) the badge on tap — dismiss
|
|
1752
1778
|
* is NON-terminal: a later state transition un-dismisses it, so a
|
|
1753
1779
|
* genuine disconnect after a dismissed tap is still visible.
|
|
1754
|
-
* 4.
|
|
1780
|
+
* 4. **Graceful self-dismiss (#748)** — the disconnected badge is NON-BLOCKING
|
|
1781
|
+
* (`pointer-events:none` the moment it flips to disconnected, so it can
|
|
1782
|
+
* never absorb a tap) and SELF-DISMISSING (it fades and detaches itself
|
|
1783
|
+
* after {@link INDICATOR_SELF_DISMISS_MS}). This is why a run that ends
|
|
1784
|
+
* with `close()` injecting `{ state: 'disconnected' }` no longer leaves a
|
|
1785
|
+
* permanent grey "Debugger Disconnected" element on the phone. A reconnect
|
|
1786
|
+
* (`setState(c, 'attached')`) cancels the pending self-dismiss and
|
|
1787
|
+
* re-mounts the badge if it had already detached — transient tunnel blips
|
|
1788
|
+
* do not flash-remove it, and a genuine re-attach restores it. The
|
|
1789
|
+
* controller object is retained across dismiss (never `delete`d), so a
|
|
1790
|
+
* later re-injection reuses it and never double-wraps `window.WebSocket`.
|
|
1791
|
+
* 5. Observes relay-socket lifecycle WITHOUT opening any new connection:
|
|
1755
1792
|
* - Preferred path: if the in-app module (`src/in-app/attach.ts`) has
|
|
1756
1793
|
* already installed its relay-WS observer (`window.__ait_relay_ws_observed`),
|
|
1757
1794
|
* subscribe to the `ait:relay-ws-state` CustomEvent it broadcasts.
|
|
@@ -1759,25 +1796,50 @@ async function renderAndMaybeWait(deps, prep, waitForAttach, callTimeoutMs, conn
|
|
|
1759
1796
|
* by PATHNAME SHAPE only (`/target/`) — never by host/wss value — so a
|
|
1760
1797
|
* bare CDP-injected badge (no in-app bundle) still reacts to the
|
|
1761
1798
|
* chii target socket's own open/close lifecycle.
|
|
1799
|
+
* 6. **Freeze/spinner triage (#749)** — renders three debug-only signals so a
|
|
1800
|
+
* real-device spinner is attributable at a glance (run7):
|
|
1801
|
+
* - **Main-thread heartbeat**: a compositor-driven pulse dot
|
|
1802
|
+
* (`Element.animate`, keeps running during JS jank) PLUS a JS-driven
|
|
1803
|
+
* `♥<beats>` token incremented by a 1 Hz `setInterval`. `CSS pulse alive
|
|
1804
|
+
* + ♥ frozen = JS main-thread wedge`.
|
|
1805
|
+
* - **Pending bridge calls**: in-flight native calls (API name + live
|
|
1806
|
+
* elapsed) read from `window.__ait_bridge` (published by the in-app
|
|
1807
|
+
* bridge observer, `src/in-app/bridge-observer.ts`). `⏳ present =
|
|
1808
|
+
* native/Toss-app spinner`.
|
|
1809
|
+
* - **Last SDK call stamp**: the most recent call's API name + wall-clock.
|
|
1810
|
+
* `no ⏳ + heartbeat healthy = the miniapp's own UI`.
|
|
1811
|
+
* The `title` tooltip states this mapping. When no in-app observer is
|
|
1812
|
+
* present (env 2 mock / no bridge) the pending/last lines are simply empty
|
|
1813
|
+
* — the heartbeat still renders. The 1 Hz interval is stored on the
|
|
1814
|
+
* controller (`c.hb`) and stopped by `c.stop()` (called from
|
|
1815
|
+
* `detachDebugSurface`) and by the self-dismiss removal, so no timer leaks
|
|
1816
|
+
* past detach (#748 lifecycle).
|
|
1762
1817
|
*
|
|
1763
1818
|
* The expression intentionally contains NO relay URLs, wss addresses, TOTP
|
|
1764
|
-
* codes, or any other secrets.
|
|
1819
|
+
* codes, or any other secrets. `window.__ait_bridge` holds API NAMES + timings
|
|
1820
|
+
* only (never call arguments/results — see `bridge-observer.ts`
|
|
1821
|
+
* SECRET-HANDLING). It is pure DOM UI text + enum/name state only.
|
|
1765
1822
|
*
|
|
1766
1823
|
* SECRET-HANDLING: this expression contains no secrets, relay URLs, wss
|
|
1767
1824
|
* addresses, or TOTP codes whatsoever — DOM label text + a structural
|
|
1768
1825
|
* pathname match (`/target/`) only.
|
|
1769
1826
|
*
|
|
1770
1827
|
* @param opts.label - Attached-state badge text (default: `'Debugger Connected'`).
|
|
1771
|
-
* @param opts.disconnectedLabel - Disconnected-state badge text
|
|
1828
|
+
* @param opts.disconnectedLabel - Disconnected-state badge text. Default is the
|
|
1829
|
+
* Korean notice `'디버거 연결 끊김'` (ko-primary in-app string convention) —
|
|
1830
|
+
* shown briefly then self-dismissed.
|
|
1772
1831
|
* @param opts.state - Initial/forced state for THIS injection call (default: `'attached'`).
|
|
1773
1832
|
* @returns A JS expression string suitable for `Runtime.evaluate`.
|
|
1774
1833
|
*/
|
|
1775
1834
|
function buildIndicatorExpression(opts) {
|
|
1776
1835
|
const label = opts?.label ?? "Debugger Connected";
|
|
1777
|
-
const disconnectedLabel = opts?.disconnectedLabel ?? "
|
|
1778
|
-
|
|
1836
|
+
const disconnectedLabel = opts?.disconnectedLabel ?? "디버거 연결 끊김";
|
|
1837
|
+
const safeLabel = JSON.stringify(label);
|
|
1838
|
+
const safeDisconnectedLabel = JSON.stringify(disconnectedLabel);
|
|
1839
|
+
const safeState = JSON.stringify(opts?.state ?? "attached");
|
|
1840
|
+
return `(() => {var W = window;function pad2(n) { return (n < 10 ? '0' : '') + n; }function clock(ms) { var d = new Date(ms); return pad2(d.getHours()) + ':' + pad2(d.getMinutes()) + ':' + pad2(d.getSeconds()); }function renderDetail(c) {c.beatEl.textContent = ' \\u2665' + c.beats;var b = W.__ait_bridge;var now = Date.now();var lines = [];if (b) {if (b.last) { lines.push('last: ' + b.last.method + ' ' + clock(b.last.at)); }var p = b.pending || {};var ids = Object.keys(p);var shown = 0;for (var i = 0; i < ids.length; i++) {var e = p[ids[i]];if (!e || now - e.startedAt > ${INDICATOR_PENDING_STALE_MS}) { continue; }if (shown < 3) { lines.push('\\u23f3 ' + e.method + ' ' + Math.max(0, Math.round((now - e.startedAt) / 1000)) + 's'); }shown++;}if (shown > 3) { lines.push('+' + (shown - 3) + ' more'); }}c.detailEl.textContent = lines.join('\\n');}function mount(c) { if (!c.el.isConnected && document.body) { document.body.appendChild(c.el); } }function render(c) {if (c.removed) { c.el.style.display = 'none'; return; }mount(c);if (c.dismissed) { c.el.style.display = 'none'; return; }c.el.style.display = 'block';c.el.style.opacity = '1';var up = c.state !== 'disconnected';c.el.style.background = up ? '#e5484d' : '#8a8f98';c.el.style.pointerEvents = up ? 'auto' : 'none';c.labelEl.textContent = up ? ${safeLabel} : ${safeDisconnectedLabel};c.dotEl.style.display = up ? 'inline-block' : 'none';c.beatEl.style.display = up ? 'inline' : 'none';c.detailEl.style.display = up ? 'block' : 'none';if (up) { renderDetail(c); } else { c.beatEl.textContent = ''; c.detailEl.textContent = ''; }}function clearTimers(c) { if (c.t1) { clearTimeout(c.t1); c.t1 = 0; } if (c.t2) { clearTimeout(c.t2); c.t2 = 0; } }function setState(c, next) {clearTimers(c);c.state = next; c.dismissed = false; c.removed = false;render(c);if (next === 'disconnected') {c.t1 = setTimeout(function () {try { c.el.style.transition = 'opacity ${INDICATOR_FADE_MS}ms ease'; c.el.style.opacity = '0'; } catch (_) {}c.t2 = setTimeout(function () { c.removed = true; if (c.hb) { clearInterval(c.hb); c.hb = 0; } if (c.el.parentNode) { c.el.parentNode.removeChild(c.el); } }, ${INDICATOR_FADE_MS});}, ${INDICATOR_SELF_DISMISS_MS});}}var c = W.__ait_indicator;if (!c) {var el = document.createElement('div');el.id = '__ait_debug_indicator';try { el.title = ${JSON.stringify("⏳ 네이티브 호출 대기 = 토스앱 스피너 · ♥ 정지 = JS 멈춤 · ⏳ 없고 ♥ 정상 = 앱 UI")}; } catch (_) {}el.style.cssText = ['position:fixed','left:max(12px,calc(env(safe-area-inset-left,0px) + 8px))','bottom:max(12px,calc(env(safe-area-inset-bottom,0px) + 8px))','z-index:2147483647','color:#fff','font:bold 11px/1.2 system-ui,sans-serif','padding:5px 9px','border-radius:6px','max-width:72vw','pointer-events:auto','user-select:none',].join(';');var dotEl = document.createElement('span');dotEl.style.cssText = 'display:inline-block;width:6px;height:6px;border-radius:50%;background:#fff;margin-right:5px;vertical-align:middle';var labelEl = document.createElement('span');labelEl.id = '__ait_indicator_label';var beatEl = document.createElement('span');beatEl.style.cssText = 'font-weight:normal;opacity:0.85;margin-left:6px';var detailEl = document.createElement('div');detailEl.style.cssText = 'font-weight:normal;font-size:10px;line-height:1.35;margin-top:3px;white-space:pre-line;opacity:0.95';el.appendChild(dotEl); el.appendChild(labelEl); el.appendChild(beatEl); el.appendChild(detailEl);document.body.appendChild(el);c = { el: el, dotEl: dotEl, labelEl: labelEl, beatEl: beatEl, detailEl: detailEl, state: 'attached', dismissed: false, removed: false, beats: 0, t1: 0, t2: 0, hb: 0 };try { dotEl.animate([{ opacity: 1 }, { opacity: 0.25 }, { opacity: 1 }], { duration: 1400, iterations: Infinity }); } catch (_) {}c.hb = (typeof setInterval !== 'undefined') ? setInterval(function () {if (c.removed || !c.el.isConnected) { if (c.hb) { clearInterval(c.hb); c.hb = 0; } return; }c.beats = (c.beats || 0) + 1;if (c.state !== 'disconnected' && !c.dismissed) { renderDetail(c); }}, ${INDICATOR_HEARTBEAT_MS}) : 0;c.stop = function () { clearTimers(c); if (c.hb) { clearInterval(c.hb); c.hb = 0; } };el.addEventListener('pointerdown', function () { c.dismissed = true; render(c); }, { passive: true });W.addEventListener('ait:bridge-call', function () { if (c.state !== 'disconnected' && !c.dismissed && !c.removed) { renderDetail(c); } });W.__ait_indicator = c;if (W.__ait_relay_ws_observed) {W.addEventListener('ait:relay-ws-state', function (e) {setState(c, e.detail && e.detail.state === 'open' ? 'attached' : 'disconnected');});} else {try {var Native = W.WebSocket;W.WebSocket = new Proxy(Native, {construct: function (t, a) {var ws = Reflect.construct(t, a);try {var u = new URL(String(a[0]), location.href);if (/\\/target\\//.test(u.pathname)) {ws.addEventListener('open', function () { setState(c, 'attached'); });ws.addEventListener('close', function () { setState(c, 'disconnected'); });ws.addEventListener('error', function () { setState(c, 'disconnected'); });}} catch (_) {}return ws;},});} catch (_) {}}}setState(c, ${safeState});})()`;
|
|
1779
1841
|
}
|
|
1780
1842
|
//#endregion
|
|
1781
1843
|
export { buildIndicatorExpression as a, generateAttachToken as c, startQuickTunnel as d, startTunnelHealthProbe as f, attach_orchestrator_exports as i, makeTunnelStatus as l, logInfo as m, START_ATTACH_REMINT_THRESHOLD_MS as n, extractDeploymentId as o, logError as p, START_ATTACH_SEGMENT_MS as r, isSandboxPageFresh as s, RELAY_SANDBOX_STALE_PAGE_MS as t, printAttachBanner as u };
|
|
1782
1844
|
|
|
1783
|
-
//# sourceMappingURL=attach-orchestrator-
|
|
1845
|
+
//# sourceMappingURL=attach-orchestrator-0F0m_UqQ.js.map
|