@ytspar/sweetlink 0.0.1 → 1.0.0-canary.e1f65d0

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 (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +586 -29
  3. package/dist/browser/SweetlinkBridge.d.ts +70 -0
  4. package/dist/browser/SweetlinkBridge.d.ts.map +1 -0
  5. package/dist/browser/SweetlinkBridge.js +370 -0
  6. package/dist/browser/SweetlinkBridge.js.map +1 -0
  7. package/dist/browser/commands/dom.d.ts +11 -0
  8. package/dist/browser/commands/dom.d.ts.map +1 -0
  9. package/dist/browser/commands/dom.js +79 -0
  10. package/dist/browser/commands/dom.js.map +1 -0
  11. package/dist/browser/commands/exec.d.ts +14 -0
  12. package/dist/browser/commands/exec.d.ts.map +1 -0
  13. package/dist/browser/commands/exec.js +47 -0
  14. package/dist/browser/commands/exec.js.map +1 -0
  15. package/dist/browser/commands/index.d.ts +10 -0
  16. package/dist/browser/commands/index.d.ts.map +1 -0
  17. package/dist/browser/commands/index.js +10 -0
  18. package/dist/browser/commands/index.js.map +1 -0
  19. package/dist/browser/commands/logs.d.ts +11 -0
  20. package/dist/browser/commands/logs.d.ts.map +1 -0
  21. package/dist/browser/commands/logs.js +26 -0
  22. package/dist/browser/commands/logs.js.map +1 -0
  23. package/dist/browser/commands/screenshot.d.ts +16 -0
  24. package/dist/browser/commands/screenshot.d.ts.map +1 -0
  25. package/dist/browser/commands/screenshot.js +122 -0
  26. package/dist/browser/commands/screenshot.js.map +1 -0
  27. package/dist/browser/consoleCapture.d.ts +107 -0
  28. package/dist/browser/consoleCapture.d.ts.map +1 -0
  29. package/dist/browser/consoleCapture.js +223 -0
  30. package/dist/browser/consoleCapture.js.map +1 -0
  31. package/dist/browser/hmr.d.ts +25 -0
  32. package/dist/browser/hmr.d.ts.map +1 -0
  33. package/dist/browser/hmr.js +94 -0
  34. package/dist/browser/hmr.js.map +1 -0
  35. package/dist/browser/screenshotUtils.d.ts +102 -0
  36. package/dist/browser/screenshotUtils.d.ts.map +1 -0
  37. package/dist/browser/screenshotUtils.js +145 -0
  38. package/dist/browser/screenshotUtils.js.map +1 -0
  39. package/dist/browser.d.ts +2 -0
  40. package/dist/browser.d.ts.map +1 -0
  41. package/dist/browser.js +5 -0
  42. package/dist/browser.js.map +1 -0
  43. package/dist/cdp.d.ts +99 -0
  44. package/dist/cdp.d.ts.map +1 -0
  45. package/dist/cdp.js +341 -0
  46. package/dist/cdp.js.map +1 -0
  47. package/dist/cli/sweetlink-dev.d.ts +14 -0
  48. package/dist/cli/sweetlink-dev.d.ts.map +1 -0
  49. package/dist/cli/sweetlink-dev.js +36 -0
  50. package/dist/cli/sweetlink-dev.js.map +1 -0
  51. package/dist/cli/sweetlink.d.ts +9 -0
  52. package/dist/cli/sweetlink.d.ts.map +1 -0
  53. package/dist/cli/sweetlink.js +1003 -0
  54. package/dist/cli/sweetlink.js.map +1 -0
  55. package/dist/index.d.ts +17 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +22 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/playwright.d.ts +29 -0
  60. package/dist/playwright.d.ts.map +1 -0
  61. package/dist/playwright.js +172 -0
  62. package/dist/playwright.js.map +1 -0
  63. package/dist/ruler.d.ts +82 -0
  64. package/dist/ruler.d.ts.map +1 -0
  65. package/dist/ruler.js +296 -0
  66. package/dist/ruler.js.map +1 -0
  67. package/dist/server/anthropic.d.ts +19 -0
  68. package/dist/server/anthropic.d.ts.map +1 -0
  69. package/dist/server/anthropic.js +26 -0
  70. package/dist/server/anthropic.js.map +1 -0
  71. package/dist/server/constants.d.ts +17 -0
  72. package/dist/server/constants.d.ts.map +1 -0
  73. package/dist/server/constants.js +17 -0
  74. package/dist/server/constants.js.map +1 -0
  75. package/dist/server/handlers/designReview.d.ts +27 -0
  76. package/dist/server/handlers/designReview.d.ts.map +1 -0
  77. package/dist/server/handlers/designReview.js +165 -0
  78. package/dist/server/handlers/designReview.js.map +1 -0
  79. package/dist/server/handlers/hmr.d.ts +21 -0
  80. package/dist/server/handlers/hmr.d.ts.map +1 -0
  81. package/dist/server/handlers/hmr.js +81 -0
  82. package/dist/server/handlers/hmr.js.map +1 -0
  83. package/dist/server/handlers/index.d.ts +11 -0
  84. package/dist/server/handlers/index.d.ts.map +1 -0
  85. package/dist/server/handlers/index.js +11 -0
  86. package/dist/server/handlers/index.js.map +1 -0
  87. package/dist/server/handlers/outline.d.ts +19 -0
  88. package/dist/server/handlers/outline.d.ts.map +1 -0
  89. package/dist/server/handlers/outline.js +41 -0
  90. package/dist/server/handlers/outline.js.map +1 -0
  91. package/dist/server/handlers/schema.d.ts +19 -0
  92. package/dist/server/handlers/schema.d.ts.map +1 -0
  93. package/dist/server/handlers/schema.js +49 -0
  94. package/dist/server/handlers/schema.js.map +1 -0
  95. package/dist/server/handlers/screenshot.d.ts +22 -0
  96. package/dist/server/handlers/screenshot.d.ts.map +1 -0
  97. package/dist/server/handlers/screenshot.js +72 -0
  98. package/dist/server/handlers/screenshot.js.map +1 -0
  99. package/dist/server/index.d.ts +33 -0
  100. package/dist/server/index.d.ts.map +1 -0
  101. package/dist/server/index.js +507 -0
  102. package/dist/server/index.js.map +1 -0
  103. package/dist/server/subscriptions.d.ts +26 -0
  104. package/dist/server/subscriptions.d.ts.map +1 -0
  105. package/dist/server/subscriptions.js +35 -0
  106. package/dist/server/subscriptions.js.map +1 -0
  107. package/dist/server.d.ts +8 -0
  108. package/dist/server.d.ts.map +1 -0
  109. package/dist/server.js +8 -0
  110. package/dist/server.js.map +1 -0
  111. package/dist/types.d.ts +130 -0
  112. package/dist/types.d.ts.map +1 -0
  113. package/dist/types.js +8 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/urlUtils.d.ts +75 -0
  116. package/dist/urlUtils.d.ts.map +1 -0
  117. package/dist/urlUtils.js +121 -0
  118. package/dist/urlUtils.js.map +1 -0
  119. package/dist/viewportUtils.d.ts +51 -0
  120. package/dist/viewportUtils.d.ts.map +1 -0
  121. package/dist/viewportUtils.js +58 -0
  122. package/dist/viewportUtils.js.map +1 -0
  123. package/package.json +98 -6
  124. package/scripts/setup-claude-context.mjs +101 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * SweetlinkBridge - Vanilla JS WebSocket bridge for browser-side Sweetlink integration
3
+ *
4
+ * This module provides framework-agnostic browser integration for Sweetlink,
5
+ * eliminating the React dependency to avoid conflicts with host applications.
6
+ *
7
+ * @version 2.1.0
8
+ */
9
+ import type { ServerInfo } from '../types.js';
10
+ export interface SweetlinkBridgeConfig {
11
+ basePort?: number;
12
+ maxPortRetries?: number;
13
+ hmrScreenshots?: boolean;
14
+ hmrDebounceMs?: number;
15
+ hmrCaptureDelay?: number;
16
+ }
17
+ export declare class SweetlinkBridge {
18
+ private ws;
19
+ private connected;
20
+ private serverInfo;
21
+ private verified;
22
+ private consoleLogs;
23
+ private reconnectTimeout;
24
+ private savedScreenshotTimeout;
25
+ private savedReviewTimeout;
26
+ private hmrState;
27
+ private readonly basePort;
28
+ private readonly maxPortRetries;
29
+ private readonly hmrScreenshots;
30
+ private readonly hmrConfig;
31
+ private readonly currentAppPort;
32
+ private currentPort;
33
+ private cleanupFunctions;
34
+ private originalConsole;
35
+ constructor(config?: SweetlinkBridgeConfig);
36
+ /**
37
+ * Initialize the bridge - call this to start the connection
38
+ */
39
+ init(): void;
40
+ /**
41
+ * Clean up and disconnect
42
+ */
43
+ destroy(): void;
44
+ /**
45
+ * Check if connected to server
46
+ */
47
+ isConnected(): boolean;
48
+ /**
49
+ * Get server info
50
+ */
51
+ getServerInfo(): ServerInfo | null;
52
+ private setupConsoleCapture;
53
+ private setupErrorHandlers;
54
+ private connectWebSocket;
55
+ private handleCommand;
56
+ }
57
+ /**
58
+ * Initialize Sweetlink Bridge - call from host application
59
+ */
60
+ export declare function initSweetlinkBridge(config?: SweetlinkBridgeConfig): SweetlinkBridge;
61
+ /**
62
+ * Get the global bridge instance
63
+ */
64
+ export declare function getSweetlinkBridge(): SweetlinkBridge | null;
65
+ /**
66
+ * Destroy the global bridge instance
67
+ */
68
+ export declare function destroySweetlinkBridge(): void;
69
+ export default SweetlinkBridge;
70
+ //# sourceMappingURL=SweetlinkBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SweetlinkBridge.d.ts","sourceRoot":"","sources":["../../src/browser/SweetlinkBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAmD,UAAU,EAAE,MAAM,aAAa,CAAC;AA6C/F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,sBAAsB,CAA8C;IAC5E,OAAO,CAAC,kBAAkB,CAA8C;IAGxE,OAAO,CAAC,QAAQ,CAId;IAGF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,WAAW,CAA2B;IAG9C,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,eAAe,CAAyB;gBAEpC,MAAM,GAAE,qBAA0B;IA8C9C;;OAEG;IACH,IAAI,IAAI,IAAI;IAyBZ;;OAEG;IACH,OAAO,IAAI,IAAI;IA6Cf;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAQlC,OAAO,CAAC,mBAAmB;IAmC3B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,gBAAgB;YA0HV,aAAa;CAyB5B;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAQnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAK7C;AAGD,eAAe,eAAe,CAAC"}
@@ -0,0 +1,370 @@
1
+ /**
2
+ * SweetlinkBridge - Vanilla JS WebSocket bridge for browser-side Sweetlink integration
3
+ *
4
+ * This module provides framework-agnostic browser integration for Sweetlink,
5
+ * eliminating the React dependency to avoid conflicts with host applications.
6
+ *
7
+ * @version 2.1.0
8
+ */
9
+ import { formatArgs, MAX_CONSOLE_LOGS, createErrorHandler, createRejectionHandler } from './consoleCapture.js';
10
+ // Import command handlers
11
+ import { handleScreenshot, handleRequestScreenshot, handleQueryDOM, handleGetLogs, handleExecJS, } from './commands/index.js';
12
+ // Import HMR utilities
13
+ import { setupHmrDetection, captureHmrScreenshot, } from './hmr.js';
14
+ // ============================================================================
15
+ // Constants
16
+ // ============================================================================
17
+ /** Port offset from app port to calculate WebSocket port */
18
+ const SWEETLINK_PORT_OFFSET = 6223;
19
+ const DEFAULT_WS_PORT = 9223;
20
+ const DEFAULT_MAX_PORT_RETRIES = 10;
21
+ /** HMR settings */
22
+ const DEFAULT_HMR_DEBOUNCE_MS = 300;
23
+ const DEFAULT_HMR_CAPTURE_DELAY_MS = 100;
24
+ /** Reconnection settings */
25
+ const RECONNECT_DELAY_MS = 2000;
26
+ const VERIFICATION_TIMEOUT_MS = 1000;
27
+ const PORT_RETRY_DELAY_MS = 100;
28
+ const PORT_SEARCH_FAIL_RETRY_MS = 3000;
29
+ // ============================================================================
30
+ // SweetlinkBridge Class
31
+ // ============================================================================
32
+ export class SweetlinkBridge {
33
+ ws = null;
34
+ connected = false;
35
+ serverInfo = null;
36
+ verified = false;
37
+ consoleLogs = [];
38
+ reconnectTimeout = null;
39
+ savedScreenshotTimeout = null;
40
+ savedReviewTimeout = null;
41
+ // HMR tracking
42
+ hmrState = {
43
+ sequence: 0,
44
+ debounceTimeout: null,
45
+ lastCaptureTime: 0,
46
+ };
47
+ // Configuration
48
+ basePort;
49
+ maxPortRetries;
50
+ hmrScreenshots;
51
+ hmrConfig;
52
+ currentAppPort;
53
+ currentPort = DEFAULT_WS_PORT;
54
+ // Cleanup functions
55
+ cleanupFunctions = [];
56
+ originalConsole;
57
+ constructor(config = {}) {
58
+ // Skip on server-side
59
+ if (typeof window === 'undefined') {
60
+ this.basePort = DEFAULT_WS_PORT;
61
+ this.maxPortRetries = DEFAULT_MAX_PORT_RETRIES;
62
+ this.hmrScreenshots = false;
63
+ this.hmrConfig = {
64
+ debounceMs: DEFAULT_HMR_DEBOUNCE_MS,
65
+ captureDelay: DEFAULT_HMR_CAPTURE_DELAY_MS,
66
+ };
67
+ this.currentAppPort = 0;
68
+ this.currentPort = DEFAULT_WS_PORT;
69
+ this.originalConsole = {
70
+ log: console.log,
71
+ error: console.error,
72
+ warn: console.warn,
73
+ info: console.info
74
+ };
75
+ return;
76
+ }
77
+ // Calculate app port from URL
78
+ this.currentAppPort = parseInt(window.location.port, 10) ||
79
+ (window.location.protocol === 'https:' ? 443 : 80);
80
+ // Calculate expected WS port (appPort + port offset)
81
+ this.basePort = config.basePort ??
82
+ (this.currentAppPort > 0 ? this.currentAppPort + SWEETLINK_PORT_OFFSET : DEFAULT_WS_PORT);
83
+ this.maxPortRetries = config.maxPortRetries ?? DEFAULT_MAX_PORT_RETRIES;
84
+ this.hmrScreenshots = config.hmrScreenshots ?? false;
85
+ this.hmrConfig = {
86
+ debounceMs: config.hmrDebounceMs ?? DEFAULT_HMR_DEBOUNCE_MS,
87
+ captureDelay: config.hmrCaptureDelay ?? DEFAULT_HMR_CAPTURE_DELAY_MS,
88
+ };
89
+ this.currentPort = this.basePort;
90
+ // Store original console methods
91
+ this.originalConsole = {
92
+ log: console.log.bind(console),
93
+ error: console.error.bind(console),
94
+ warn: console.warn.bind(console),
95
+ info: console.info.bind(console)
96
+ };
97
+ }
98
+ /**
99
+ * Initialize the bridge - call this to start the connection
100
+ */
101
+ init() {
102
+ if (typeof window === 'undefined')
103
+ return;
104
+ this.setupConsoleCapture();
105
+ this.setupErrorHandlers();
106
+ this.connectWebSocket(this.basePort);
107
+ if (this.hmrScreenshots) {
108
+ const cleanup = setupHmrDetection((trigger, changedFile, hmrMetadata) => {
109
+ if (this.verified) {
110
+ captureHmrScreenshot(this.ws, this.consoleLogs, this.hmrState, this.hmrConfig, trigger, changedFile, hmrMetadata);
111
+ }
112
+ });
113
+ this.cleanupFunctions.push(cleanup);
114
+ }
115
+ }
116
+ /**
117
+ * Clean up and disconnect
118
+ */
119
+ destroy() {
120
+ // Clear timeouts
121
+ if (this.reconnectTimeout)
122
+ clearTimeout(this.reconnectTimeout);
123
+ if (this.savedScreenshotTimeout)
124
+ clearTimeout(this.savedScreenshotTimeout);
125
+ if (this.savedReviewTimeout)
126
+ clearTimeout(this.savedReviewTimeout);
127
+ if (this.hmrState.debounceTimeout)
128
+ clearTimeout(this.hmrState.debounceTimeout);
129
+ // Null out timeout references to prevent stale references
130
+ this.reconnectTimeout = null;
131
+ this.savedScreenshotTimeout = null;
132
+ this.savedReviewTimeout = null;
133
+ // Reset HMR state to prevent memory leaks from closure references
134
+ this.hmrState = {
135
+ sequence: 0,
136
+ debounceTimeout: null,
137
+ lastCaptureTime: 0,
138
+ };
139
+ // Close WebSocket
140
+ if (this.ws) {
141
+ this.ws.close();
142
+ this.ws = null;
143
+ }
144
+ // Restore console
145
+ console.log = this.originalConsole.log;
146
+ console.error = this.originalConsole.error;
147
+ console.warn = this.originalConsole.warn;
148
+ console.info = this.originalConsole.info;
149
+ // Run cleanup functions
150
+ this.cleanupFunctions.forEach(fn => fn());
151
+ this.cleanupFunctions = [];
152
+ // Clear console logs array to free memory
153
+ this.consoleLogs = [];
154
+ // Clear server info
155
+ this.serverInfo = null;
156
+ this.connected = false;
157
+ this.verified = false;
158
+ }
159
+ /**
160
+ * Check if connected to server
161
+ */
162
+ isConnected() {
163
+ return this.connected && this.verified;
164
+ }
165
+ /**
166
+ * Get server info
167
+ */
168
+ getServerInfo() {
169
+ return this.serverInfo;
170
+ }
171
+ // ==========================================================================
172
+ // Private Methods
173
+ // ==========================================================================
174
+ setupConsoleCapture() {
175
+ const captureLog = (level, args) => {
176
+ this.consoleLogs.push({
177
+ level,
178
+ message: formatArgs(args),
179
+ timestamp: Date.now()
180
+ });
181
+ // Keep only last N logs
182
+ if (this.consoleLogs.length > MAX_CONSOLE_LOGS) {
183
+ this.consoleLogs = this.consoleLogs.slice(-MAX_CONSOLE_LOGS);
184
+ }
185
+ };
186
+ console.log = (...args) => {
187
+ captureLog('log', args);
188
+ this.originalConsole.log(...args);
189
+ };
190
+ console.error = (...args) => {
191
+ captureLog('error', args);
192
+ this.originalConsole.error(...args);
193
+ };
194
+ console.warn = (...args) => {
195
+ captureLog('warn', args);
196
+ this.originalConsole.warn(...args);
197
+ };
198
+ console.info = (...args) => {
199
+ captureLog('info', args);
200
+ this.originalConsole.info(...args);
201
+ };
202
+ }
203
+ setupErrorHandlers() {
204
+ const logsRef = { logs: this.consoleLogs };
205
+ const errorHandler = createErrorHandler(logsRef, MAX_CONSOLE_LOGS);
206
+ const rejectionHandler = createRejectionHandler(logsRef, MAX_CONSOLE_LOGS);
207
+ window.addEventListener('error', errorHandler);
208
+ window.addEventListener('unhandledrejection', rejectionHandler);
209
+ this.cleanupFunctions.push(() => {
210
+ window.removeEventListener('error', errorHandler);
211
+ window.removeEventListener('unhandledrejection', rejectionHandler);
212
+ });
213
+ }
214
+ connectWebSocket(port) {
215
+ const wsUrl = `ws://localhost:${port}`;
216
+ const ws = new WebSocket(wsUrl);
217
+ this.ws = ws;
218
+ this.currentPort = port;
219
+ this.verified = false;
220
+ // Timeout for server-info response
221
+ const verificationTimeout = setTimeout(() => {
222
+ if (!this.verified && ws.readyState === WebSocket.OPEN) {
223
+ // Server didn't send server-info (old version) - accept for backwards compatibility
224
+ console.log(`[Sweetlink] Server on port ${port} is old version (no server-info). Accepting for backwards compatibility.`);
225
+ this.verified = true;
226
+ this.connected = true;
227
+ }
228
+ }, VERIFICATION_TIMEOUT_MS);
229
+ ws.onopen = () => {
230
+ console.log(`[Sweetlink] Connected to server on port ${port}`);
231
+ ws.send(JSON.stringify({ type: 'browser-client-ready' }));
232
+ };
233
+ ws.onmessage = async (event) => {
234
+ try {
235
+ const message = JSON.parse(event.data);
236
+ // Handle confirmation and info messages
237
+ switch (message.type) {
238
+ case 'screenshot-saved':
239
+ console.log('[Sweetlink] Screenshot saved:', message.path);
240
+ return;
241
+ case 'design-review-saved':
242
+ console.log('[Sweetlink] Design review saved:', message.reviewPath);
243
+ return;
244
+ case 'design-review-error':
245
+ console.error('[Sweetlink] Design review failed:', message.error);
246
+ return;
247
+ case 'server-info': {
248
+ clearTimeout(verificationTimeout);
249
+ const info = message;
250
+ console.log('[Sweetlink] Server info received:', info);
251
+ const serverMatchesApp = info.appPort === null || info.appPort === this.currentAppPort;
252
+ if (!serverMatchesApp) {
253
+ console.log(`[Sweetlink] Server is for port ${info.appPort}, but we're on port ${this.currentAppPort}. Trying next port...`);
254
+ ws.close();
255
+ const nextPort = port + 1;
256
+ if (nextPort < this.basePort + this.maxPortRetries) {
257
+ setTimeout(() => this.connectWebSocket(nextPort), PORT_RETRY_DELAY_MS);
258
+ }
259
+ else {
260
+ console.log(`[Sweetlink] No matching server found for port ${this.currentAppPort}. Will retry...`);
261
+ setTimeout(() => this.connectWebSocket(this.basePort), PORT_SEARCH_FAIL_RETRY_MS);
262
+ }
263
+ return;
264
+ }
265
+ this.verified = true;
266
+ this.serverInfo = info;
267
+ this.connected = true;
268
+ console.log(`[Sweetlink] Verified connection to server for port ${info.appPort ?? 'any'} (project: ${info.projectDir})`);
269
+ return;
270
+ }
271
+ }
272
+ if (!this.verified) {
273
+ console.warn('[Sweetlink] Ignoring command before verification');
274
+ return;
275
+ }
276
+ const command = message;
277
+ console.log('[Sweetlink] Received command:', command.type);
278
+ const response = await this.handleCommand(command);
279
+ ws.send(JSON.stringify(response));
280
+ }
281
+ catch (error) {
282
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
283
+ console.error('[Sweetlink] Error handling command:', errorMessage);
284
+ ws.send(JSON.stringify({
285
+ success: false,
286
+ error: errorMessage,
287
+ timestamp: Date.now()
288
+ }));
289
+ }
290
+ };
291
+ ws.onclose = (event) => {
292
+ clearTimeout(verificationTimeout);
293
+ console.log('[Sweetlink] Disconnected from server');
294
+ this.connected = false;
295
+ this.serverInfo = null;
296
+ this.verified = false;
297
+ // If closed due to origin mismatch (code 4001), try next port immediately
298
+ if (event.code === 4001) {
299
+ const nextPort = port + 1;
300
+ if (nextPort < this.basePort + this.maxPortRetries) {
301
+ console.log(`[Sweetlink] Origin mismatch, trying port ${nextPort}...`);
302
+ setTimeout(() => this.connectWebSocket(nextPort), PORT_RETRY_DELAY_MS);
303
+ return;
304
+ }
305
+ }
306
+ // Try to reconnect
307
+ this.reconnectTimeout = setTimeout(() => {
308
+ console.log('[Sweetlink] Attempting to reconnect...');
309
+ this.connectWebSocket(this.basePort);
310
+ }, RECONNECT_DELAY_MS);
311
+ };
312
+ ws.onerror = (error) => {
313
+ clearTimeout(verificationTimeout);
314
+ console.error('[Sweetlink] WebSocket error:', error);
315
+ };
316
+ }
317
+ async handleCommand(command) {
318
+ switch (command.type) {
319
+ case 'screenshot':
320
+ return await handleScreenshot(command);
321
+ case 'request-screenshot':
322
+ return await handleRequestScreenshot(command, this.ws);
323
+ case 'query-dom':
324
+ return handleQueryDOM(command);
325
+ case 'get-logs':
326
+ return handleGetLogs(command, this.consoleLogs);
327
+ case 'exec-js':
328
+ return handleExecJS(command);
329
+ default:
330
+ return {
331
+ success: false,
332
+ error: `Unknown command: ${command.type}`,
333
+ timestamp: Date.now()
334
+ };
335
+ }
336
+ }
337
+ }
338
+ // ============================================================================
339
+ // Auto-initialization function for script tag usage
340
+ // ============================================================================
341
+ let globalBridge = null;
342
+ /**
343
+ * Initialize Sweetlink Bridge - call from host application
344
+ */
345
+ export function initSweetlinkBridge(config) {
346
+ if (globalBridge) {
347
+ return globalBridge;
348
+ }
349
+ globalBridge = new SweetlinkBridge(config);
350
+ globalBridge.init();
351
+ return globalBridge;
352
+ }
353
+ /**
354
+ * Get the global bridge instance
355
+ */
356
+ export function getSweetlinkBridge() {
357
+ return globalBridge;
358
+ }
359
+ /**
360
+ * Destroy the global bridge instance
361
+ */
362
+ export function destroySweetlinkBridge() {
363
+ if (globalBridge) {
364
+ globalBridge.destroy();
365
+ globalBridge = null;
366
+ }
367
+ }
368
+ // Export default for backwards compatibility
369
+ export default SweetlinkBridge;
370
+ //# sourceMappingURL=SweetlinkBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SweetlinkBridge.js","sourceRoot":"","sources":["../../src/browser/SweetlinkBridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * DOM Command Handlers
3
+ *
4
+ * Handles DOM query commands from the server.
5
+ */
6
+ import type { SweetlinkCommand, SweetlinkResponse } from '../../types.js';
7
+ /**
8
+ * Handle query-dom command
9
+ */
10
+ export declare function handleQueryDOM(command: SweetlinkCommand): SweetlinkResponse;
11
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/browser/commands/dom.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CA0E3E"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * DOM Command Handlers
3
+ *
4
+ * Handles DOM query commands from the server.
5
+ */
6
+ /**
7
+ * Handle query-dom command
8
+ */
9
+ export function handleQueryDOM(command) {
10
+ try {
11
+ if (!command.selector) {
12
+ return {
13
+ success: false,
14
+ error: 'Selector is required',
15
+ timestamp: Date.now()
16
+ };
17
+ }
18
+ const elements = document.querySelectorAll(command.selector);
19
+ if (elements.length === 0) {
20
+ return {
21
+ success: true,
22
+ data: {
23
+ found: false,
24
+ count: 0,
25
+ elements: []
26
+ },
27
+ timestamp: Date.now()
28
+ };
29
+ }
30
+ const results = Array.from(elements).map((el, index) => {
31
+ const result = {
32
+ index,
33
+ tagName: el.tagName.toLowerCase(),
34
+ id: el.id || null,
35
+ className: el.className || null,
36
+ textContent: el.textContent?.slice(0, 200) || null
37
+ };
38
+ if (command.property) {
39
+ const prop = command.property;
40
+ if (prop === 'computedStyle') {
41
+ const style = window.getComputedStyle(el);
42
+ result.computedStyle = {
43
+ display: style.display,
44
+ visibility: style.visibility,
45
+ opacity: style.opacity,
46
+ position: style.position
47
+ };
48
+ }
49
+ else if (prop === 'boundingRect') {
50
+ result.boundingRect = el.getBoundingClientRect();
51
+ }
52
+ else if (prop === 'attributes') {
53
+ result.attributes = Object.fromEntries(Array.from(el.attributes).map(attr => [attr.name, attr.value]));
54
+ }
55
+ else {
56
+ result[prop] = el[prop];
57
+ }
58
+ }
59
+ return result;
60
+ });
61
+ return {
62
+ success: true,
63
+ data: {
64
+ found: true,
65
+ count: elements.length,
66
+ elements: results
67
+ },
68
+ timestamp: Date.now()
69
+ };
70
+ }
71
+ catch (error) {
72
+ return {
73
+ success: false,
74
+ error: error instanceof Error ? error.message : 'Query failed',
75
+ timestamp: Date.now()
76
+ };
77
+ }
78
+ }
79
+ //# sourceMappingURL=dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.js","sourceRoot":"","sources":["../../../src/browser/commands/dom.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAyB;IACtD,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,sBAAsB;gBAC7B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE7D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,CAAC;oBACR,QAAQ,EAAE,EAAE;iBACb;gBACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YACrD,MAAM,MAAM,GAA4B;gBACtC,KAAK;gBACL,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE;gBACjC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,IAAI;gBACjB,SAAS,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI;gBAC/B,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI;aACnD,CAAC;YAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;gBAC9B,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;oBAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;oBAC1C,MAAM,CAAC,aAAa,GAAG;wBACrB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC;gBACJ,CAAC;qBAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;oBACnC,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;gBACnD,CAAC;qBAAM,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;oBACjC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAC/D,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,GAAI,EAAyC,CAAC,IAAI,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,QAAQ,CAAC,MAAM;gBACtB,QAAQ,EAAE,OAAO;aAClB;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;YAC9D,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Exec Command Handlers
3
+ *
4
+ * Handles JavaScript execution commands.
5
+ *
6
+ * SECURITY WARNING: This module executes arbitrary JavaScript for debugging.
7
+ * It is restricted to localhost connections and development environments only.
8
+ */
9
+ import type { SweetlinkCommand, SweetlinkResponse } from '../../types.js';
10
+ /**
11
+ * Handle exec-js command with security guards
12
+ */
13
+ export declare function handleExecJS(command: SweetlinkCommand): SweetlinkResponse;
14
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../../src/browser/commands/exec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAQ1E;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAkCzE"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Exec Command Handlers
3
+ *
4
+ * Handles JavaScript execution commands.
5
+ *
6
+ * SECURITY WARNING: This module executes arbitrary JavaScript for debugging.
7
+ * It is restricted to localhost connections and development environments only.
8
+ */
9
+ const MAX_CODE_LENGTH = 10000;
10
+ function errorResponse(error) {
11
+ return { success: false, error, timestamp: Date.now() };
12
+ }
13
+ /**
14
+ * Handle exec-js command with security guards
15
+ */
16
+ export function handleExecJS(command) {
17
+ // Security: Block in production environments
18
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
19
+ return errorResponse('exec-js is disabled in production for security reasons');
20
+ }
21
+ if (!command.code) {
22
+ return errorResponse('Code is required');
23
+ }
24
+ if (typeof command.code !== 'string') {
25
+ return errorResponse('Code must be a string');
26
+ }
27
+ if (command.code.length > MAX_CODE_LENGTH) {
28
+ return errorResponse(`Code exceeds maximum length of ${MAX_CODE_LENGTH} characters`);
29
+ }
30
+ try {
31
+ // Execute the code - intentional for dev tools debugging
32
+ // eslint-disable-next-line no-eval
33
+ const result = (0, eval)(command.code);
34
+ return {
35
+ success: true,
36
+ data: {
37
+ result: typeof result === 'object' ? JSON.parse(JSON.stringify(result)) : result,
38
+ type: typeof result
39
+ },
40
+ timestamp: Date.now()
41
+ };
42
+ }
43
+ catch (error) {
44
+ return errorResponse(error instanceof Error ? error.message : 'Execution failed');
45
+ }
46
+ }
47
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/browser/commands/exec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAyB;IACpD,6CAA6C;IAC7C,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC7E,OAAO,aAAa,CAAC,wDAAwD,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QAC1C,OAAO,aAAa,CAAC,kCAAkC,eAAe,aAAa,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,CAAC;QACH,yDAAyD;QACzD,mCAAmC;QACnC,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEvC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;gBAChF,IAAI,EAAE,OAAO,MAAM;aACpB;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,aAAa,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Browser Command Handlers
3
+ *
4
+ * Re-exports all command handler functions.
5
+ */
6
+ export { handleScreenshot, handleRequestScreenshot } from './screenshot.js';
7
+ export { handleQueryDOM } from './dom.js';
8
+ export { handleGetLogs } from './logs.js';
9
+ export { handleExecJS } from './exec.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/browser/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Browser Command Handlers
3
+ *
4
+ * Re-exports all command handler functions.
5
+ */
6
+ export { handleScreenshot, handleRequestScreenshot } from './screenshot.js';
7
+ export { handleQueryDOM } from './dom.js';
8
+ export { handleGetLogs } from './logs.js';
9
+ export { handleExecJS } from './exec.js';
10
+ //# sourceMappingURL=index.js.map