@winstonfassett/webdev-gateway 0.1.0-alpha.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +78 -0
  4. package/dist/adapter-helpers.d.ts +64 -0
  5. package/dist/adapter-helpers.d.ts.map +1 -0
  6. package/dist/adapter-helpers.js +297 -0
  7. package/dist/adapter-helpers.js.map +1 -0
  8. package/dist/admin/assets/index-DEDI8OIx.css +2 -0
  9. package/dist/admin/assets/index-DaI40ww1.js +70 -0
  10. package/dist/admin/assets/tinykeys.module-CjuTRcEz.js +1 -0
  11. package/dist/admin/index.html +13 -0
  12. package/dist/admin-rpc.d.ts +27 -0
  13. package/dist/admin-rpc.d.ts.map +1 -0
  14. package/dist/admin-rpc.js +147 -0
  15. package/dist/admin-rpc.js.map +1 -0
  16. package/dist/admin.d.ts +10 -0
  17. package/dist/admin.d.ts.map +1 -0
  18. package/dist/admin.js +202 -0
  19. package/dist/admin.js.map +1 -0
  20. package/dist/auto-register.d.ts +10 -0
  21. package/dist/auto-register.d.ts.map +1 -0
  22. package/dist/auto-register.js +145 -0
  23. package/dist/auto-register.js.map +1 -0
  24. package/dist/cdp-relay.d.ts +110 -0
  25. package/dist/cdp-relay.d.ts.map +1 -0
  26. package/dist/cdp-relay.js +616 -0
  27. package/dist/cdp-relay.js.map +1 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +95 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/doctor.d.ts +6 -0
  33. package/dist/doctor.d.ts.map +1 -0
  34. package/dist/doctor.js +149 -0
  35. package/dist/doctor.js.map +1 -0
  36. package/dist/element-grab-client.js +305 -0
  37. package/dist/element-grab.d.ts +15 -0
  38. package/dist/element-grab.d.ts.map +1 -0
  39. package/dist/element-grab.js +102 -0
  40. package/dist/element-grab.js.map +1 -0
  41. package/dist/gateway.d.ts +5 -0
  42. package/dist/gateway.d.ts.map +1 -0
  43. package/dist/gateway.js +534 -0
  44. package/dist/gateway.js.map +1 -0
  45. package/dist/installer.d.ts +48 -0
  46. package/dist/installer.d.ts.map +1 -0
  47. package/dist/installer.js +637 -0
  48. package/dist/installer.js.map +1 -0
  49. package/dist/libs/element-source.js +35 -0
  50. package/dist/libs/modern-screenshot.js +14 -0
  51. package/dist/log-reader.d.ts +30 -0
  52. package/dist/log-reader.d.ts.map +1 -0
  53. package/dist/log-reader.js +174 -0
  54. package/dist/log-reader.js.map +1 -0
  55. package/dist/mcp-server.d.ts +22 -0
  56. package/dist/mcp-server.d.ts.map +1 -0
  57. package/dist/mcp-server.js +115 -0
  58. package/dist/mcp-server.js.map +1 -0
  59. package/dist/mcp-tools-core.d.ts +30 -0
  60. package/dist/mcp-tools-core.d.ts.map +1 -0
  61. package/dist/mcp-tools-core.js +375 -0
  62. package/dist/mcp-tools-core.js.map +1 -0
  63. package/dist/mcp-tools-full.d.ts +4 -0
  64. package/dist/mcp-tools-full.d.ts.map +1 -0
  65. package/dist/mcp-tools-full.js +141 -0
  66. package/dist/mcp-tools-full.js.map +1 -0
  67. package/dist/playwright-commands.d.ts +33 -0
  68. package/dist/playwright-commands.d.ts.map +1 -0
  69. package/dist/playwright-commands.js +356 -0
  70. package/dist/playwright-commands.js.map +1 -0
  71. package/dist/registry.d.ts +83 -0
  72. package/dist/registry.d.ts.map +1 -0
  73. package/dist/registry.js +205 -0
  74. package/dist/registry.js.map +1 -0
  75. package/dist/rpc-server.d.ts +54 -0
  76. package/dist/rpc-server.d.ts.map +1 -0
  77. package/dist/rpc-server.js +207 -0
  78. package/dist/rpc-server.js.map +1 -0
  79. package/dist/session.d.ts +13 -0
  80. package/dist/session.d.ts.map +1 -0
  81. package/dist/session.js +61 -0
  82. package/dist/session.js.map +1 -0
  83. package/dist/types.d.ts +76 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +2 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/webdev-client.js +20 -0
  88. package/dist/writers/base.d.ts +24 -0
  89. package/dist/writers/base.d.ts.map +1 -0
  90. package/dist/writers/base.js +98 -0
  91. package/dist/writers/base.js.map +1 -0
  92. package/dist/writers/console.d.ts +8 -0
  93. package/dist/writers/console.d.ts.map +1 -0
  94. package/dist/writers/console.js +14 -0
  95. package/dist/writers/console.js.map +1 -0
  96. package/dist/writers/dev-events.d.ts +28 -0
  97. package/dist/writers/dev-events.d.ts.map +1 -0
  98. package/dist/writers/dev-events.js +53 -0
  99. package/dist/writers/dev-events.js.map +1 -0
  100. package/dist/writers/errors.d.ts +8 -0
  101. package/dist/writers/errors.d.ts.map +1 -0
  102. package/dist/writers/errors.js +14 -0
  103. package/dist/writers/errors.js.map +1 -0
  104. package/dist/writers/network.d.ts +9 -0
  105. package/dist/writers/network.d.ts.map +1 -0
  106. package/dist/writers/network.js +17 -0
  107. package/dist/writers/network.js.map +1 -0
  108. package/dist/writers/server-console.d.ts +8 -0
  109. package/dist/writers/server-console.d.ts.map +1 -0
  110. package/dist/writers/server-console.js +14 -0
  111. package/dist/writers/server-console.js.map +1 -0
  112. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { type WebSocket as WsWebSocket } from 'ws';
2
+ type BrowserEventCallback = (event: 'connect' | 'disconnect' | 'init', data: {
3
+ connId: string;
4
+ browserId: string | null;
5
+ serverId: string | null;
6
+ url?: string | null;
7
+ title?: string | null;
8
+ }) => void;
9
+ export declare function onBrowserEvent(cb: BrowserEventCallback): () => boolean;
10
+ type LogEventCallback = (data: {
11
+ channel: string;
12
+ payload: any;
13
+ browserId?: string;
14
+ }) => void;
15
+ export declare function onLogEvent(cb: LogEventCallback): () => boolean;
16
+ export declare function emitLogEvent(data: {
17
+ channel: string;
18
+ payload: any;
19
+ browserId?: string;
20
+ }): void;
21
+ /**
22
+ * Send a command to a specific browser.
23
+ * Targeting priority:
24
+ * 1. browserId (exact) — locked session target
25
+ * 2. serverId (latest) — pick latest browser for this server
26
+ * 3. global latest — any connected browser
27
+ */
28
+ export declare function browserCommand(opts: {
29
+ browserId?: string;
30
+ serverId?: string;
31
+ }, method: string, params?: any, timeoutMs?: number): Promise<any>;
32
+ /** Legacy API: send a command by serverId string (backward compat during migration) */
33
+ export declare function browserCommandLegacy(serverId: string | undefined, method: string, params?: any, timeoutMs?: number): Promise<any>;
34
+ export declare function getAllBrowsers(): Array<{
35
+ connId: string;
36
+ browserId: string | null;
37
+ serverId: string | null;
38
+ url: string | null;
39
+ title: string | null;
40
+ connectedAt: number;
41
+ }>;
42
+ /** Get browsers affiliated with a specific server */
43
+ export declare function getBrowsersByServer(serverId: string): Array<{
44
+ connId: string;
45
+ browserId: string | null;
46
+ url: string | null;
47
+ title: string | null;
48
+ connectedAt: number;
49
+ }>;
50
+ export declare function setupRpcWebSocket(httpServer: {
51
+ on(event: string, listener: (...args: any[]) => void): void;
52
+ }, rpcPath: string): import("ws").Server<typeof WsWebSocket, typeof import("node:http").IncomingMessage>;
53
+ export {};
54
+ //# sourceMappingURL=rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../src/rpc-server.ts"],"names":[],"mappings":"AASA,OAAO,EAAmB,KAAK,SAAS,IAAI,WAAW,EAAE,MAAM,IAAI,CAAA;AA0BnE,KAAK,oBAAoB,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,EAAE,IAAI,EAAE;IAC3E,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB,KAAK,IAAI,CAAA;AAEV,wBAAgB,cAAc,CAAC,EAAE,EAAE,oBAAoB,iBAGtD;AAGD,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAA;AAE7F,wBAAgB,UAAU,CAAC,EAAE,EAAE,gBAAgB,iBAG9C;AACD,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,QAEvF;AA2CD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,GAAG,CAAC,CAwBd;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAEjI;AAED,wBAAgB,cAAc,IAAI,KAAK,CAAC;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CASD;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAED;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE;IAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;CAAE,EAAE,OAAO,EAAE,MAAM,uFA+F7H"}
@@ -0,0 +1,207 @@
1
+ // Browser command WebSocket — simple JSON protocol
2
+ //
3
+ // Gateway → Browser: { id, method, params }
4
+ // Browser → Gateway: { id, result } | { id, error }
5
+ //
6
+ // Browsers connect with ?server=<serverId> where serverId is the stable
7
+ // server identity (projectId:type). This survives server restarts.
8
+ // Browsers are never evicted — they disconnect naturally when tabs close.
9
+ import { WebSocketServer } from 'ws';
10
+ const browsers = new Map();
11
+ const connectionOrder = [];
12
+ const browserEventListeners = new Set();
13
+ export function onBrowserEvent(cb) {
14
+ browserEventListeners.add(cb);
15
+ return () => browserEventListeners.delete(cb);
16
+ }
17
+ const logEventListeners = new Set();
18
+ export function onLogEvent(cb) {
19
+ logEventListeners.add(cb);
20
+ return () => logEventListeners.delete(cb);
21
+ }
22
+ export function emitLogEvent(data) {
23
+ for (const cb of logEventListeners)
24
+ cb(data);
25
+ }
26
+ /** Send a command to a browser and wait for the response */
27
+ function sendCommand(conn, method, params, timeoutMs = 30000) {
28
+ return new Promise((resolve, reject) => {
29
+ if (conn.ws.readyState !== 1 /* OPEN */) {
30
+ reject(new Error('Browser WebSocket not open'));
31
+ return;
32
+ }
33
+ const id = String(++conn.nextId);
34
+ const timer = setTimeout(() => {
35
+ conn.pending.delete(id);
36
+ reject(new Error(`Command ${method} timed out after ${timeoutMs}ms`));
37
+ }, timeoutMs);
38
+ conn.pending.set(id, { resolve, reject, timer });
39
+ conn.ws.send(JSON.stringify({ id, method, params }));
40
+ });
41
+ }
42
+ /** Get a browser connection by browserId (exact targeting) */
43
+ function getBrowserByBrowserId(browserId) {
44
+ for (const conn of browsers.values()) {
45
+ if (conn.browserId === browserId)
46
+ return conn;
47
+ }
48
+ return undefined;
49
+ }
50
+ /** Get the latest browser connection, optionally filtered by serverId */
51
+ function getLatestBrowser(serverId) {
52
+ if (serverId) {
53
+ for (let i = connectionOrder.length - 1; i >= 0; i--) {
54
+ const conn = browsers.get(connectionOrder[i]);
55
+ if (conn?.serverId === serverId)
56
+ return conn;
57
+ }
58
+ return undefined;
59
+ }
60
+ if (connectionOrder.length === 0)
61
+ return undefined;
62
+ const connId = connectionOrder[connectionOrder.length - 1];
63
+ return browsers.get(connId);
64
+ }
65
+ /**
66
+ * Send a command to a specific browser.
67
+ * Targeting priority:
68
+ * 1. browserId (exact) — locked session target
69
+ * 2. serverId (latest) — pick latest browser for this server
70
+ * 3. global latest — any connected browser
71
+ */
72
+ export function browserCommand(opts, method, params, timeoutMs) {
73
+ let conn;
74
+ if (opts.browserId) {
75
+ conn = getBrowserByBrowserId(opts.browserId);
76
+ if (!conn) {
77
+ return Promise.reject(new Error(`Browser ${opts.browserId} not connected`));
78
+ }
79
+ }
80
+ else {
81
+ conn = getLatestBrowser(opts.serverId);
82
+ }
83
+ if (!conn) {
84
+ const all = getAllBrowsers();
85
+ const details = all.length > 0
86
+ ? ` (${all.length} browser(s) connected: ${all.map(b => b.serverId ?? 'untagged').join(', ')})`
87
+ : ' (no browsers connected)';
88
+ return Promise.reject(new Error(opts.serverId
89
+ ? `No browser connected for server ${opts.serverId}${details}`
90
+ : `No browser connected${details}`));
91
+ }
92
+ return sendCommand(conn, method, params, timeoutMs);
93
+ }
94
+ /** Legacy API: send a command by serverId string (backward compat during migration) */
95
+ export function browserCommandLegacy(serverId, method, params, timeoutMs) {
96
+ return browserCommand({ serverId }, method, params, timeoutMs);
97
+ }
98
+ export function getAllBrowsers() {
99
+ return Array.from(browsers.entries()).map(([connId, conn]) => ({
100
+ connId,
101
+ browserId: conn.browserId,
102
+ serverId: conn.serverId,
103
+ url: conn.url,
104
+ title: conn.title,
105
+ connectedAt: conn.connectedAt,
106
+ }));
107
+ }
108
+ /** Get browsers affiliated with a specific server */
109
+ export function getBrowsersByServer(serverId) {
110
+ return getAllBrowsers().filter(b => b.serverId === serverId);
111
+ }
112
+ export function setupRpcWebSocket(httpServer, rpcPath) {
113
+ const wss = new WebSocketServer({ noServer: true });
114
+ httpServer.on('upgrade', (request, socket, head) => {
115
+ const url = request.url ?? '';
116
+ if (url === rpcPath || url.startsWith(rpcPath + '?')) {
117
+ wss.handleUpgrade(request, socket, head, (ws) => {
118
+ wss.emit('connection', ws, request);
119
+ });
120
+ }
121
+ });
122
+ wss.on('connection', (ws, request) => {
123
+ const connId = Math.random().toString(36).slice(2);
124
+ // Parse server ID from query parameter — now carries stable identity (projectId:type)
125
+ let serverId = null;
126
+ const url = request.url ?? '';
127
+ const match = url.match(/[?&]server=([^&]+)/);
128
+ if (match) {
129
+ serverId = decodeURIComponent(match[1]);
130
+ }
131
+ const conn = {
132
+ ws,
133
+ connId,
134
+ browserId: null,
135
+ serverId,
136
+ url: null,
137
+ title: null,
138
+ connectedAt: Date.now(),
139
+ pending: new Map(),
140
+ nextId: 0,
141
+ };
142
+ browsers.set(connId, conn);
143
+ connectionOrder.push(connId);
144
+ // Handle responses from browser
145
+ ws.on('message', (data) => {
146
+ try {
147
+ const msg = JSON.parse(data.toString());
148
+ // Response to a pending command
149
+ if (msg.id && conn.pending.has(msg.id)) {
150
+ const pending = conn.pending.get(msg.id);
151
+ conn.pending.delete(msg.id);
152
+ clearTimeout(pending.timer);
153
+ if (msg.error) {
154
+ pending.reject(new Error(msg.error));
155
+ }
156
+ else {
157
+ pending.resolve(msg.result);
158
+ }
159
+ return;
160
+ }
161
+ // Unsolicited message from browser (e.g. browserId announcement)
162
+ if (msg.type === 'init' && msg.browserId) {
163
+ conn.browserId = msg.browserId;
164
+ if (msg.url)
165
+ conn.url = msg.url;
166
+ if (msg.title)
167
+ conn.title = msg.title;
168
+ const parts = [`[webdev] Browser ${msg.browserId.slice(0, 8)}`];
169
+ if (msg.title)
170
+ parts.push(`"${msg.title}"`);
171
+ if (msg.url)
172
+ parts.push(msg.url);
173
+ if (serverId)
174
+ parts.push(`server=${serverId}`);
175
+ console.log(parts.join(' '));
176
+ for (const cb of browserEventListeners)
177
+ cb('init', { connId, browserId: conn.browserId, serverId, url: conn.url, title: conn.title });
178
+ }
179
+ }
180
+ catch {
181
+ // Ignore malformed messages
182
+ }
183
+ });
184
+ const serverInfo = serverId ? ` for server ${serverId}` : '';
185
+ console.log(`[webdev] Browser connected (${connId})${serverInfo}`);
186
+ for (const cb of browserEventListeners)
187
+ cb('connect', { connId, browserId: conn.browserId, serverId });
188
+ ws.on('close', () => {
189
+ // Reject all pending commands
190
+ for (const [, pending] of conn.pending) {
191
+ clearTimeout(pending.timer);
192
+ pending.reject(new Error('Browser disconnected'));
193
+ }
194
+ conn.pending.clear();
195
+ const bid = conn.browserId;
196
+ browsers.delete(connId);
197
+ const idx = connectionOrder.indexOf(connId);
198
+ if (idx >= 0)
199
+ connectionOrder.splice(idx, 1);
200
+ console.log(`[webdev] Browser disconnected (${connId})`);
201
+ for (const cb of browserEventListeners)
202
+ cb('disconnect', { connId, browserId: bid, serverId });
203
+ });
204
+ });
205
+ return wss;
206
+ }
207
+ //# sourceMappingURL=rpc-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-server.js","sourceRoot":"","sources":["../src/rpc-server.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,4CAA4C;AAC5C,oDAAoD;AACpD,EAAE;AACF,wEAAwE;AACxE,mEAAmE;AACnE,0EAA0E;AAE1E,OAAO,EAAE,eAAe,EAAiC,MAAM,IAAI,CAAA;AAsBnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA6B,CAAA;AACrD,MAAM,eAAe,GAAa,EAAE,CAAA;AAUpC,MAAM,qBAAqB,GAA8B,IAAI,GAAG,EAAE,CAAA;AAClE,MAAM,UAAU,cAAc,CAAC,EAAwB;IACrD,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7B,OAAO,GAAG,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAC/C,CAAC;AAID,MAAM,iBAAiB,GAA0B,IAAI,GAAG,EAAE,CAAA;AAC1D,MAAM,UAAU,UAAU,CAAC,EAAoB;IAC7C,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzB,OAAO,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAC3C,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAA2D;IACtF,KAAK,MAAM,EAAE,IAAI,iBAAiB;QAAE,EAAE,CAAC,IAAI,CAAC,CAAA;AAC9C,CAAC;AAED,4DAA4D;AAC5D,SAAS,WAAW,CAAC,IAAuB,EAAE,MAAc,EAAE,MAAY,EAAE,SAAS,GAAG,KAAK;IAC3F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAA;YAC/C,OAAM;QACR,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACvB,MAAM,CAAC,IAAI,KAAK,CAAC,WAAW,MAAM,oBAAoB,SAAS,IAAI,CAAC,CAAC,CAAA;QACvE,CAAC,EAAE,SAAS,CAAC,CAAA;QAEb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QAChD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,8DAA8D;AAC9D,SAAS,qBAAqB,CAAC,SAAiB;IAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,yEAAyE;AACzE,SAAS,gBAAgB,CAAC,QAAiB;IACzC,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7C,IAAI,IAAI,EAAE,QAAQ,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;QAC9C,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAClD,MAAM,MAAM,GAAG,eAAe,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC1D,OAAO,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,IAA+C,EAC/C,MAAc,EACd,MAAY,EACZ,SAAkB;IAElB,IAAI,IAAmC,CAAA;IAEvC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,gBAAgB,CAAC,CAAC,CAAA;QAC7E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,cAAc,EAAE,CAAA;QAC5B,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC;YAC5B,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,0BAA0B,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAC/F,CAAC,CAAC,0BAA0B,CAAA;QAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAC7B,IAAI,CAAC,QAAQ;YACX,CAAC,CAAC,mCAAmC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE;YAC9D,CAAC,CAAC,uBAAuB,OAAO,EAAE,CACrC,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;AACrD,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,oBAAoB,CAAC,QAA4B,EAAE,MAAc,EAAE,MAAY,EAAE,SAAkB;IACjH,OAAO,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,cAAc;IAQ5B,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM;QACN,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CAAC,CAAA;AACL,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAOlD,OAAO,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAA2E,EAAE,OAAe;IAC5H,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAEnD,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAY,EAAE,MAAW,EAAE,IAAS,EAAE,EAAE;QAChE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAA;QAC7B,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;gBAC9C,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;YACrC,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,OAAY,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAElD,sFAAsF;QACtF,IAAI,QAAQ,GAAkB,IAAI,CAAA;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAA;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACzC,CAAC;QAED,MAAM,IAAI,GAAsB;YAC9B,EAAE;YACF,MAAM;YACN,SAAS,EAAE,IAAI;YACf,QAAQ;YACR,GAAG,EAAE,IAAI;YACT,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,OAAO,EAAE,IAAI,GAAG,EAAE;YAClB,MAAM,EAAE,CAAC;SACV,CAAA;QAED,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC1B,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAE5B,gCAAgC;QAChC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAEvC,gCAAgC;gBAChC,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAA;oBACzC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAC3B,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;oBAC3B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;wBACd,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;oBACtC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;oBAC7B,CAAC;oBACD,OAAM;gBACR,CAAC;gBAED,iEAAiE;gBACjE,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;oBACzC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;oBAC9B,IAAI,GAAG,CAAC,GAAG;wBAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAA;oBAC/B,IAAI,GAAG,CAAC,KAAK;wBAAE,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAA;oBACrC,MAAM,KAAK,GAAG,CAAC,oBAAoB,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;oBAC/D,IAAI,GAAG,CAAC,KAAK;wBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,CAAA;oBAC3C,IAAI,GAAG,CAAC,GAAG;wBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,QAAQ;wBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,EAAE,CAAC,CAAA;oBAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;oBAC7B,KAAK,MAAM,EAAE,IAAI,qBAAqB;wBAAE,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;gBACvI,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5D,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,IAAI,UAAU,EAAE,CAAC,CAAA;QAClE,KAAK,MAAM,EAAE,IAAI,qBAAqB;YAAE,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;QAEtG,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,8BAA8B;YAC9B,KAAK,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;gBAC3B,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAA;YACnD,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;YAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAA;YAC1B,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACvB,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAC3C,IAAI,GAAG,IAAI,CAAC;gBAAE,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YAC5C,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,GAAG,CAAC,CAAA;YACxD,KAAK,MAAM,EAAE,IAAI,qBAAqB;gBAAE,EAAE,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAA;QAChG,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SessionInfo, GatewayOptions } from './types.js';
2
+ export interface SessionState {
3
+ info: SessionInfo;
4
+ logDir: string;
5
+ files: Record<string, string>;
6
+ channels: string[];
7
+ startedAt: number;
8
+ checkpointTs: number | null;
9
+ browserCheckpoints: Record<string, number>;
10
+ }
11
+ export declare function initSession(options: GatewayOptions, serverUrl: string, mcpPath: string): SessionState;
12
+ export declare function truncateChannelFiles(files: Record<string, string>, channels?: string[]): Record<string, number>;
13
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAc7D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC3C;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,YAAY,CAiCd;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmB/G"}
@@ -0,0 +1,61 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdirSync, writeFileSync, readFileSync, truncateSync, existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ const VERSION = '0.1.0';
5
+ function computeSessionId(target) {
6
+ return createHash('sha256').update(target).digest('hex').slice(0, 6);
7
+ }
8
+ function getLogDir(target, options) {
9
+ if (options.logDir)
10
+ return options.logDir;
11
+ // Default to .webdev/ in current directory instead of /tmp to avoid permissions issues
12
+ return join(process.cwd(), '.webdev');
13
+ }
14
+ export function initSession(options, serverUrl, mcpPath) {
15
+ const sessionId = computeSessionId(serverUrl);
16
+ const logDir = getLogDir(serverUrl, options);
17
+ const mcpUrl = `${serverUrl}${mcpPath}/sse`;
18
+ mkdirSync(logDir, { recursive: true });
19
+ const channels = ['console', 'errors', 'dev-events', 'server-console'];
20
+ if (options.network)
21
+ channels.push('network');
22
+ const files = {};
23
+ for (const ch of channels) {
24
+ files[ch] = join(logDir, `${ch}.ndjson`);
25
+ }
26
+ // Truncate all NDJSON files on session start
27
+ for (const filePath of Object.values(files)) {
28
+ writeFileSync(filePath, '');
29
+ }
30
+ const info = {
31
+ sessionId,
32
+ logDir,
33
+ files,
34
+ channels,
35
+ serverUrl,
36
+ mcpUrl,
37
+ startedAt: Date.now(),
38
+ };
39
+ writeFileSync(join(logDir, 'session.json'), JSON.stringify(info, null, 2) + '\n');
40
+ return { info, logDir, files, channels, startedAt: info.startedAt, checkpointTs: null, browserCheckpoints: {} };
41
+ }
42
+ export function truncateChannelFiles(files, channels) {
43
+ const countsBefore = {};
44
+ const toTruncate = channels ?? Object.keys(files);
45
+ for (const ch of toTruncate) {
46
+ const filePath = files[ch];
47
+ if (!filePath)
48
+ continue;
49
+ if (existsSync(filePath)) {
50
+ const content = readFileSync(filePath, 'utf-8');
51
+ countsBefore[ch] = content.trim() ? content.trim().split('\n').length : 0;
52
+ truncateSync(filePath, 0);
53
+ }
54
+ else {
55
+ countsBefore[ch] = 0;
56
+ writeFileSync(filePath, '');
57
+ }
58
+ }
59
+ return countsBefore;
60
+ }
61
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ export interface GatewayOptions {
2
+ port?: number;
3
+ network?: boolean;
4
+ https?: boolean;
5
+ cert?: string;
6
+ key?: string;
7
+ logDir?: string;
8
+ maxFileSizeMb?: number;
9
+ }
10
+ export interface HarnessEvent {
11
+ id: number;
12
+ ts: number;
13
+ channel: string;
14
+ payload: unknown;
15
+ }
16
+ export interface ConsolePayload {
17
+ level: 'log' | 'warn' | 'error' | 'info' | 'debug';
18
+ args: string[];
19
+ stack?: string;
20
+ }
21
+ export interface ErrorPayload {
22
+ type: 'console-error' | 'unhandled-exception' | 'unhandled-rejection';
23
+ message: string;
24
+ stack?: string;
25
+ file?: string;
26
+ line?: number;
27
+ }
28
+ export interface ServerConsolePayload {
29
+ level: 'log' | 'warn' | 'error' | 'info' | 'debug';
30
+ args: string[];
31
+ source: 'server';
32
+ stack?: string;
33
+ }
34
+ export interface NetworkPayload {
35
+ method: string;
36
+ url: string;
37
+ status: number;
38
+ duration: number;
39
+ initiator: 'fetch' | 'xhr';
40
+ }
41
+ export interface SessionInfo {
42
+ sessionId: string;
43
+ logDir: string;
44
+ files: Record<string, string>;
45
+ channels: string[];
46
+ serverUrl: string;
47
+ mcpUrl: string;
48
+ startedAt: number;
49
+ }
50
+ export interface BuildStatus {
51
+ last_update_at: number | null;
52
+ last_error_at: number | null;
53
+ last_error: string | undefined;
54
+ update_count: number;
55
+ error_count: number;
56
+ pending: boolean;
57
+ }
58
+ export interface DiagnosticSummary {
59
+ error_count: number;
60
+ warning_count: number;
61
+ server_error_count: number;
62
+ failed_requests: number;
63
+ has_unhandled_rejections: boolean;
64
+ }
65
+ export interface DiagnosticsResult {
66
+ build: BuildStatus;
67
+ logs: {
68
+ console: HarnessEvent[];
69
+ errors: HarnessEvent[];
70
+ network: HarnessEvent[];
71
+ server_console: HarnessEvent[];
72
+ };
73
+ summary: DiagnosticSummary;
74
+ checkpoint_ts: number | null;
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAClD,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,qBAAqB,CAAA;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAClD,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,QAAQ,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,GAAG,KAAK,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,eAAe,EAAE,MAAM,CAAA;IACvB,wBAAwB,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE;QACJ,OAAO,EAAE,YAAY,EAAE,CAAA;QACvB,MAAM,EAAE,YAAY,EAAE,CAAA;QACtB,OAAO,EAAE,YAAY,EAAE,CAAA;QACvB,cAAc,EAAE,YAAY,EAAE,CAAA;KAC/B,CAAA;IACD,OAAO,EAAE,iBAAiB,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ "use strict";(()=>{var ae=Object.create;var Z=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,he=Object.prototype.hasOwnProperty;var ge=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(o,s)=>(typeof require<"u"?require:o)[s]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var ye=(r,o,s,c)=>{if(o&&typeof o=="object"||typeof o=="function")for(let d of fe(o))!he.call(r,d)&&d!==s&&Z(r,d,{get:()=>o[d],enumerable:!(c=de(o,d))||c.enumerable});return r};var pe=(r,o,s)=>(s=r!=null?ae(me(r)):{},ye(o||!r||!r.__esModule?Z(s,"default",{value:r,enumerable:!0}):s,r));function we(r){try{let o=Object.keys(r).find(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactInternalInstance$"));if(!o)return null;let c=r[o];for(;c;){if(c.type&&typeof c.type=="function"){let d=c.type.displayName||c.type.name;if(d&&d.length>1&&d[0]===d[0].toUpperCase()&&d!=="Fragment"&&d!=="Suspense"){let E=c._debugSource;return{component:d,file:E?.fileName??null,line:E?.lineNumber??null,column:E?.columnNumber??null}}}c=c.return}}catch{}return null}function be(r){try{let o=r.getAttribute("data-v-inspector");if(o){let c=o.split(":");if(c.length>=2){let d=c.slice(0,-2).join(":")||c[0],E=parseInt(c[c.length-2],10),W=parseInt(c[c.length-1],10);return{component:ee(r),file:d,line:isNaN(E)?null:E,column:isNaN(W)?null:W}}}let s=ee(r);if(s)return{component:s,file:null,line:null,column:null}}catch{}return null}function ee(r){let o=r;for(;o;){let s=o.__vueParentComponent;if(s){let c=s.type;if(c){let d=c.name||c.__name;if(d&&d!=="Fragment")return d}}o=o.parentElement}return null}function Ee(r){try{let o=r;for(;o;){let s=o.__svelte_meta;if(s?.loc){let c=s.loc,d=typeof c.file=="string"?c.file:null,E=typeof c.line=="number"?c.line:null,W=typeof c.column=="number"?c.column+1:null,H=null,k=s.parent;for(;k;){if(typeof k.componentTag=="string"){H=k.componentTag;break}k=k.parent}return{component:H,file:d,line:E,column:W}}o=o.parentElement}}catch{}return null}function _e(r){try{let o=r.__c||r._component;if(o){let s=o.constructor?.displayName||o.constructor?.name,c=o.__v?.__source||o.props?.__source;return{component:s&&s!=="Fragment"?s:null,file:c?.fileName??null,line:c?.lineNumber??null,column:c?.columnNumber??null}}}catch{}return null}var P;async function te(){if(P!==void 0)return P;try{let o=await import((window.__WEBDEV_ORIGIN__||window.location.origin)+"/__libs/element-source.js");return P=o,o}catch{return P=null,null}}te();async function ve(r){let o=P;if(!o)return null;try{let s=await o.resolveElementInfo(r);return s?{component:s.componentName??null,file:s.source?.filePath??null,line:s.source?.lineNumber??null,column:s.source?.columnNumber??null}:null}catch{return null}}var Se=[we,be,Ee,_e];function U(r){for(let o of Se){let s=o(r);if(s)return s}return null}async function ne(r){if(await te()){let s=await ve(r);if(s)return s}return U(r)}function K(r){if(!r.file)return null;let o=r.file;return r.line!=null&&(o+=":"+r.line),r.column!=null&&(o+=":"+r.column),o}(function(){if(window.__WEBDEV_LOADED__)return;window.__WEBDEV_LOADED__=!0;let r=window.__WEBDEV_ORIGIN__||window.location.origin;if(r&&window.location.hostname!=="localhost"&&window.location.hostname!=="127.0.0.1")try{let e=new URL(r);(e.hostname==="localhost"||e.hostname==="127.0.0.1")&&(e.hostname=window.location.hostname,r=e.origin)}catch{}let o=r.replace(/^https?:\/\//,""),s=r.startsWith("https")?"wss:":"ws:",c="__webdev_browser_id__",d=sessionStorage.getItem(c);d||(d=Math.random().toString(36).slice(2)+Date.now().toString(36),sessionStorage.setItem(c,d));let E=null,W=[],H=null,k=window.__WEBDEV_SERVER__||null;function V(){let e=s+"//"+o+"/__events";k&&(e+="?server="+encodeURIComponent(k)),E=new WebSocket(e),E.onopen=()=>{for(let t of W)E.send(t);W=[]},E.onclose=()=>{E=null,H||(H=setTimeout(()=>{H=null,V()},2e3))},E.onerror=()=>{}}function O(e,t){let n=JSON.stringify({channel:e,payload:t,browserId:d});E&&E.readyState===WebSocket.OPEN?E.send(n):W.length<1e3&&W.push(n)}V();let D={log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console),debug:console.debug.bind(console)},re=["log","warn","error","info","debug"];for(let e of re)console[e]=(...t)=>{D[e](...t);let n=t.map(i=>{try{let m=typeof i=="string"?i:JSON.stringify(i);return m&&m.length>2e3?m.slice(0,2e3)+"\u2026":m??String(i)}catch{return String(i)}}),l={level:e,args:n};e==="error"&&t[0]instanceof Error&&(l.stack=t[0].stack),O("console",l),e==="error"&&O("error",{type:"console-error",message:n.join(" "),stack:l.stack})};window.addEventListener("error",e=>{O("error",{type:"unhandled-exception",message:e.message,stack:e.error?.stack,file:e.filename,line:e.lineno})}),window.addEventListener("unhandledrejection",e=>{let t=e.reason;O("error",{type:"unhandled-rejection",message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0})});let oe=["/__","/@","/node_modules"];function J(e){return oe.some(t=>e.includes(t))}let B=window.fetch.bind(window);window.fetch=async(e,t)=>{let n=typeof e=="string"?e:e instanceof URL?e.href:e.url;if(J(n))return B(e,t);let l=performance.now(),i=await B(e,t),m=Math.round(performance.now()-l);return O("network",{method:(t?.method??"GET").toUpperCase(),url:n,status:i.status,duration:m,initiator:"fetch"}),i};let le=XMLHttpRequest.prototype.open,X=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(e,t,...n){return this.__harness_method=e,this.__harness_url=typeof t=="string"?t:t.href,le.call(this,e,t,...n)},XMLHttpRequest.prototype.send=function(e){let t=this.__harness_url;if(J(t))return X.call(this,e);let n=performance.now();return this.addEventListener("loadend",()=>{O("network",{method:(this.__harness_method??"GET").toUpperCase(),url:t,status:this.status,duration:Math.round(performance.now()-n),initiator:"xhr"})}),X.call(this,e)};let ie={};function R(e){if(e.startsWith("text=")){let t=e.slice(5),n=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT),l;for(;l=n.nextNode();){let m=l,p=Array.from(m.childNodes).filter(a=>a.nodeType===3).map(a=>(a.textContent||"").trim()).join(" ");if(p&&p.includes(t))return m}let i=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT);for(;l=i.nextNode();)if(l.textContent?.includes(t)){let m=l.querySelectorAll("*");for(let p=m.length-1;p>=0;p--)if(m[p].textContent?.trim().includes(t)&&m[p].children.length===0)return m[p];return l}return null}return document.querySelector(e)}let se={eval(e){let n=new Function("return ("+e+")")();return n&&typeof n=="object"&&typeof n.then=="function"?n.then(l=>typeof l=="string"?l:JSON.stringify(l)):typeof n=="string"?n:JSON.stringify(n)},async elementSource(e){let t=R(e);if(!t)return{error:"Element not found: "+e};try{let n=await ne(t);return n?{component:n.component,file:n.file,line:n.line,column:n.column,source:K(n)}:{error:"No source info available (not a framework component or not in dev mode)"}}catch(n){return{error:n.message}}},markdown(e){return q.getPageMarkdown({selector:e})},async screenshot(e){return q.screenshot(typeof e=="string"?{selector:e}:e)},navigate(e){return q.navigate({url:e})},click(e){return q.click({selector:e})},fill(e,t){return q.fill({selector:e,value:t})},async waitFor(e,t=100,n=5e3){let l=Date.now()+n;for(;Date.now()<l;){try{let i;if(typeof e=="string"?i=document.querySelector(e):(i=e(),i&&typeof i.then=="function"&&(i=await i)),i)return i}catch{}await new Promise(i=>setTimeout(i,t))}throw new Error(`waitFor timed out after ${n}ms`)}},q={getPageInfo(){return{id:d,title:z(),url:window.location.href,type:"page"}},async eval(e){let t=Object.getPrototypeOf(async function(){}).constructor,n=[document,window,localStorage,sessionStorage,ie,se],l=["document","window","localStorage","sessionStorage","state","browser"];function i(u){return typeof u=="string"?u:u===void 0?"undefined":u===null?"null":u instanceof Node?u instanceof HTMLElement?u.outerHTML.slice(0,2e3):u.textContent?.slice(0,2e3)??"":JSON.stringify(u,null,2)}async function m(u){return u&&typeof u=="object"&&typeof u.then=="function"?await u:u}function p(u=150,f=3e3){return new Promise(y=>{let S=null,M=setTimeout(()=>{w(),y()},f),T=new MutationObserver(()=>{S&&clearTimeout(S),S=setTimeout(()=>{w(),y()},u)});T.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0}),S=setTimeout(()=>{w(),y()},u);function w(){T.disconnect(),clearTimeout(M),S&&clearTimeout(S)}})}let a=Array.isArray(e.code)?e.code:[e.code],g;for(let u=0;u<a.length;u++){let f;try{f=new t(...l,"return ("+a[u]+")")}catch{f=new t(...l,a[u])}g=await m(await f(...n)),u<a.length-1&&await p()}return i(g)},queryDom(e){let{max_depth:t=3,attributes:n=["id","class","href","src","value","type","placeholder","role","aria-label"],text_length:l=100,include_source:i=!1,visible_only:m=!0}=e,p=Math.max(1e3,Math.min(e.max_output??3e4,2e5)),a=e.on_limit==="file"?"file":"hint",g=e.selector||"body",u=document.querySelector(g)??document.body;if(!u)return{html:"",element_count:0,truncated:!1,error:"No element found"};function f(T){let w=T.children,L=[],b=15;for(let _=0;_<Math.min(w.length,b);_++){let x=w[_],N=x.tagName.toLowerCase(),A=x.getAttribute("id"),C=x.getAttribute("role"),h=x.getAttribute("class");A?L.push(`<${N} id="${A}">`):C?L.push(`<${N} role="${C}">`):h?L.push(`<${N} class="${h.length>30?h.slice(0,30)+"\u2026":h}">`):L.push(`<${N}>`)}return w.length>b&&L.push(`\u2026and ${w.length-b} more`),L}let y=0;function S(T,w,L){if(w>t)return"\u2026";if(T.nodeType===3){let h=T.textContent.trim();return h?h.length>l?h.slice(0,l)+"\u2026":h:""}if(T.nodeType!==1)return"";let b=T,_=b.tagName.toLowerCase();if(["script","style","svg","noscript","link","meta"].includes(_))return"";if(m){let h=window.getComputedStyle(b);if(h.display==="none"||h.visibility==="hidden"||h.opacity==="0"||b.getAttribute("aria-hidden")==="true"||b.hidden)return"";let v=b.getBoundingClientRect();if(v.width===0&&v.height===0&&h.display!=="contents")return""}y++;let x=" ".repeat(L),N="";for(let h of n){let v=b.getAttribute(h);if(v!==null&&v!==""){let ue=h==="class"&&v.length>80?v.slice(0,80)+"\u2026":v;N+=" "+h+'="'+ue.replace(/"/g,"&quot;")+'"'}}if(i){let h=U(b);if(h){let v=K(h);v&&(N+=' source="'+v.replace(/"/g,"&quot;")+'"'),h.component&&(N+=' component="'+h.component.replace(/"/g,"&quot;")+'"')}}if(["br","hr","img","input"].includes(_))return x+"<"+_+N+"/>";let A=Array.from(b.childNodes),C=[];for(let h of A){let v=S(h,w+1,L+1);v&&C.push(v)}if(C.length===0){let h=b.textContent?.trim()??"",v=h.length>l?h.slice(0,l)+"\u2026":h;return v?x+"<"+_+N+">"+v+"</"+_+">":x+"<"+_+N+"/>"}return C.length===1&&!C[0].includes(`
2
+ `)&&C[0].length<80?x+"<"+_+N+">"+C[0].trim()+"</"+_+">":x+"<"+_+N+`>
3
+ `+C.join(`
4
+ `)+`
5
+ `+x+"</"+_+">"}let M=S(u,0,0);if(M.length>p){let T=f(u);return a==="file"?{html:M,element_count:y,truncated:!1,write_to_file:!0,child_count:u.children.length,children_hints:T}:{html:M.slice(0,p)+`
6
+ \u2026(truncated)`,element_count:y,truncated:!0,too_large:!0,child_count:u.children.length,children_hints:T,hint:`Output truncated at ${p} chars (full size: ${M.length} chars, ${y} elements). ${u.children.length} direct children: ${T.join(", ")}. Narrow your selector or increase max_output.`}}return{html:M,element_count:y,truncated:!1}},async screenshot(e={}){let t=e.selector,n=t?document.querySelector(t):document.documentElement;if(!n)return{error:"Element not found: "+t};if(n instanceof HTMLCanvasElement)try{let f=e.format==="png"?"image/png":"image/jpeg";return{data:n.toDataURL(f,e.quality?e.quality/100:.8),width:n.width,height:n.height}}catch(f){return{error:"Canvas screenshot failed: "+f.message}}let l=e.preset||(t?"element":"viewport"),i={viewport:{scale:1,format:"jpeg",quality:80,maxWidth:1024,fullPage:!1},element:{scale:1,format:"jpeg",quality:80,maxWidth:1024,fullPage:!1},full:{scale:1,format:"jpeg",quality:80,maxWidth:1024,fullPage:!0},thumb:{scale:1,format:"jpeg",quality:60,maxWidth:512,fullPage:!1},hd:{scale:1,format:"png",quality:100,maxWidth:1568,fullPage:!1}},m=i[l]||i.viewport,p=e.format||m.format,a=e.quality??m.quality,g=e.scale??m.scale,u=e.maxWidth??m.maxWidth;if(!window.__modernScreenshot)try{let y=await import(r+"/__libs/modern-screenshot.js").catch(()=>import("https://esm.sh/modern-screenshot@4.6.8"));window.__modernScreenshot=y}catch(f){return{error:"Failed to load screenshot library: "+f.message}}try{let{domToPng:f,domToJpeg:y}=window.__modernScreenshot,S=p==="png"?f:y,M={scale:g,quality:a/100};(l==="viewport"||l!=="full"&&l!=="element")&&(M.height=window.innerHeight,M.style={overflow:"hidden"});let T=await S(n,M),w=new Image;if(await new Promise((L,b)=>{w.onload=()=>L(),w.onerror=()=>b(new Error("Failed to decode screenshot")),w.src=T}),w.naturalWidth>u){let L=u/w.naturalWidth,b=Math.round(w.naturalWidth*L),_=Math.round(w.naturalHeight*L),x=document.createElement("canvas");return x.width=b,x.height=_,x.getContext("2d").drawImage(w,0,0,b,_),{data:x.toDataURL(p==="png"?"image/png":"image/jpeg",a/100),width:b,height:_}}return{data:T,width:w.naturalWidth,height:w.naturalHeight}}catch(f){return{error:"Screenshot failed: "+f.message}}},click(e){let t=R(e.selector);return t?(t.click(),{clicked:e.selector,tag:t.tagName.toLowerCase()}):{error:"Element not found: "+e.selector}},fill(e){let t=R(e.selector);if(!t)return{error:"Element not found: "+e.selector};let n=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set||Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,"value")?.set;return n?n.call(t,e.value):t.value=e.value,t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0})),{filled:e.selector,value:e.value}},selectOption(e){let t=R(e.selector);if(!t||t.tagName!=="SELECT")return{error:"Select element not found: "+e.selector};let n=Array.from(t.options),l=n.find(i=>i.value===e.value)||n.find(i=>i.textContent?.trim()===e.value);return l?(t.value=l.value,t.dispatchEvent(new Event("change",{bubbles:!0})),{selected:e.selector,value:l.value,text:l.textContent?.trim()||""}):{error:"Option not found: "+e.value}},hover(e){let t=R(e.selector);return t?(t.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0})),t.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0})),{hovered:e.selector}):{error:"Element not found: "+e.selector}},pressKey(e){let t=e.selector?document.querySelector(e.selector):document.activeElement||document.body;if(e.selector&&!t)return{error:"Element not found: "+e.selector};let n={key:e.key,code:e.key.length===1?"Key"+e.key.toUpperCase():e.key,bubbles:!0,cancelable:!0,ctrlKey:e.modifiers?.ctrl||!1,shiftKey:e.modifiers?.shift||!1,altKey:e.modifiers?.alt||!1,metaKey:e.modifiers?.meta||!1};return t.dispatchEvent(new KeyboardEvent("keydown",n)),t.dispatchEvent(new KeyboardEvent("keypress",n)),t.dispatchEvent(new KeyboardEvent("keyup",n)),{key:e.key,target:e.selector||"activeElement"}},scroll(e){if(e.selector){let t=document.querySelector(e.selector);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),{scrolledTo:e.selector}):{error:"Element not found: "+e.selector}}return window.scrollTo({left:e.x||0,top:e.y||0,behavior:"smooth"}),{scrolledTo:{x:e.x||0,y:e.y||0}}},navigate(e){return window.location.href=e.url,{navigated:e.url}},getVisibleText(e){let t=e.selector?document.querySelector(e.selector):document.body;return t?{text:t.innerText,length:t.innerText.length}:{error:"Element not found: "+e.selector}},getPageMarkdown(e){let t=e.selector?document.querySelector(e.selector):document.body;if(!t)return{error:"Element not found: "+e.selector};let n=new Set(["script","style","noscript","svg","link","meta","head"]),l=new Set(["div","p","section","article","main","header","footer","nav","li","tr","td","th","blockquote","pre","figure","figcaption","details","summary"]);function i(p){if(p.nodeType===3)return p.textContent||"";if(p.nodeType!==1)return"";let a=p,g=a.tagName.toLowerCase();if(n.has(g)||a.hidden||a.getAttribute("aria-hidden")==="true")return"";let u=window.getComputedStyle(a);if(u.display==="none"||u.visibility==="hidden")return"";let f="";for(let y of a.childNodes)f+=i(y);if(f=f.replace(/\n{3,}/g,`
7
+
8
+ `),g==="a"){let y=a.getAttribute("href"),S=f.trim();return S?y?"["+S+"]("+y+")":S:""}if(g==="img")return"!["+(a.getAttribute("alt")||"")+"]("+(a.getAttribute("src")||"")+")";if(g==="br")return`
9
+ `;if(g==="hr")return`
10
+ ---
11
+ `;if(/^h[1-6]$/.test(g))return`
12
+ `+"#".repeat(parseInt(g[1]))+" "+f.trim()+`
13
+ `;if(g==="li")return(a.parentElement?.tagName.toLowerCase()==="ol"?Array.from(a.parentElement.children).indexOf(a)+1+". ":"- ")+f.trim()+`
14
+ `;if(g==="pre")return"\n```\n"+a.textContent+"\n```\n";if(g==="code")return"`"+f.trim()+"`";if(g==="strong"||g==="b")return"**"+f.trim()+"**";if(g==="em"||g==="i")return"*"+f.trim()+"*";if(g==="input"||g==="textarea"||g==="select"||g==="button"){let y=g;return a.type&&(y+="["+a.type+"]"),a.placeholder&&(y+=' placeholder="'+a.placeholder+'"'),a.value&&(y+=' value="'+a.value+'"'),a.id&&(y+=" #"+a.id),g==="button"&&(y+=": "+f.trim()),"<"+y+">"}return l.has(g)?`
15
+ `+f+`
16
+ `:f}let m=i(t).replace(/\n{3,}/g,`
17
+
18
+ `).trim();return m.length>3e4&&(m=m.slice(0,3e4)+`
19
+
20
+ ...(truncated)`),{markdown:m,length:m.length}}},j="\u{1F440} ",$=null;function z(){return document.title.startsWith(j)?document.title.slice(j.length):document.title}function G(){document.title.startsWith(j)||(document.title=j+document.title)}function ce(){$||(G(),$=new MutationObserver(G),$.observe(document.head,{childList:!0,subtree:!0,characterData:!0}))}let I=null,F=null;function Q(){let e=s+"//"+o+"/__rpc";k&&(e+="?server="+encodeURIComponent(k)),I=new WebSocket(e),I.onopen=()=>{I.send(JSON.stringify({type:"init",browserId:d,url:location.href,title:z()})),ce(),D.log("[webdev] Command channel connected")},I.onmessage=async t=>{try{let n=JSON.parse(t.data);if(!n.id||!n.method)return;let l=q[n.method];if(!l){I.send(JSON.stringify({id:n.id,error:"Unknown method: "+n.method}));return}try{let i=await l(n.params||{});I.send(JSON.stringify({id:n.id,result:i}))}catch(i){I.send(JSON.stringify({id:n.id,error:i.message??String(i)}))}}catch{}},I.onclose=()=>{I=null,F||(F=setTimeout(()=>{F=null,Q()},2e3))},I.onerror=()=>{}}Q(),D.log(`[webdev] Client loaded browser=${d.slice(0,8)} server=${k||"none"} gateway=${r}`);let Y=()=>{let e=document.createElement("script");e.src=r+"/__element-grab.js",e.async=!0,document.head.appendChild(e)};"requestIdleCallback"in window?window.requestIdleCallback(Y):setTimeout(Y,1e3)})();})();
@@ -0,0 +1,24 @@
1
+ import type { HarnessEvent } from '../types.js';
2
+ export declare class NdjsonWriter {
3
+ private filePath;
4
+ private channel;
5
+ private nextId;
6
+ private maxFileSize;
7
+ private maxFiles;
8
+ constructor(filePath: string, channel: string, maxFileSizeMb?: number, maxFiles?: number);
9
+ write(payload: unknown): HarnessEvent;
10
+ /** Rotate current file and clean up old rotated files */
11
+ private rotate;
12
+ resetId(): void;
13
+ getLastId(): number;
14
+ }
15
+ export declare class BufferedNdjsonWriter extends NdjsonWriter {
16
+ private flushIntervalMs;
17
+ private buffer;
18
+ private timer;
19
+ constructor(filePath: string, channel: string, maxFileSizeMb?: number, flushIntervalMs?: number);
20
+ writeBuffered(payload: unknown): HarnessEvent;
21
+ flush(): void;
22
+ destroy(): void;
23
+ }
24
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/writers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,OAAO;IANjB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAQ;gBAGd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM;IAMnB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY;IAuBrC,yDAAyD;IACzD,OAAO,CAAC,MAAM;IAqBd,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,MAAM;CAGpB;AAED,qBAAa,oBAAqB,SAAQ,YAAY;IAQlD,OAAO,CAAC,eAAe;IAPzB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,KAAK,CAA6C;gBAGxD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACd,eAAe,SAAM;IAK/B,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY;IAiB7C,KAAK,IAAI,IAAI;IAYb,OAAO,IAAI,IAAI;CAMhB"}