@ytspar/sweetlink 0.0.1 → 1.0.0-canary.2b99e1e
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/LICENSE +21 -0
- package/README.md +579 -28
- package/dist/browser/SweetlinkBridge.d.ts +69 -0
- package/dist/browser/SweetlinkBridge.d.ts.map +1 -0
- package/dist/browser/SweetlinkBridge.js +360 -0
- package/dist/browser/SweetlinkBridge.js.map +1 -0
- package/dist/browser/commands/dom.d.ts +11 -0
- package/dist/browser/commands/dom.d.ts.map +1 -0
- package/dist/browser/commands/dom.js +79 -0
- package/dist/browser/commands/dom.js.map +1 -0
- package/dist/browser/commands/exec.d.ts +14 -0
- package/dist/browser/commands/exec.d.ts.map +1 -0
- package/dist/browser/commands/exec.js +47 -0
- package/dist/browser/commands/exec.js.map +1 -0
- package/dist/browser/commands/index.d.ts +10 -0
- package/dist/browser/commands/index.d.ts.map +1 -0
- package/dist/browser/commands/index.js +10 -0
- package/dist/browser/commands/index.js.map +1 -0
- package/dist/browser/commands/logs.d.ts +11 -0
- package/dist/browser/commands/logs.d.ts.map +1 -0
- package/dist/browser/commands/logs.js +25 -0
- package/dist/browser/commands/logs.js.map +1 -0
- package/dist/browser/commands/screenshot.d.ts +16 -0
- package/dist/browser/commands/screenshot.d.ts.map +1 -0
- package/dist/browser/commands/screenshot.js +118 -0
- package/dist/browser/commands/screenshot.js.map +1 -0
- package/dist/browser/consoleCapture.d.ts +107 -0
- package/dist/browser/consoleCapture.d.ts.map +1 -0
- package/dist/browser/consoleCapture.js +215 -0
- package/dist/browser/consoleCapture.js.map +1 -0
- package/dist/browser/hmr.d.ts +25 -0
- package/dist/browser/hmr.d.ts.map +1 -0
- package/dist/browser/hmr.js +97 -0
- package/dist/browser/hmr.js.map +1 -0
- package/dist/browser/screenshotUtils.d.ts +102 -0
- package/dist/browser/screenshotUtils.d.ts.map +1 -0
- package/dist/browser/screenshotUtils.js +143 -0
- package/dist/browser/screenshotUtils.js.map +1 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +5 -0
- package/dist/browser.js.map +1 -0
- package/dist/cdp.d.ts +99 -0
- package/dist/cdp.d.ts.map +1 -0
- package/dist/cdp.js +347 -0
- package/dist/cdp.js.map +1 -0
- package/dist/cli/sweetlink-dev.d.ts +14 -0
- package/dist/cli/sweetlink-dev.d.ts.map +1 -0
- package/dist/cli/sweetlink-dev.js +36 -0
- package/dist/cli/sweetlink-dev.js.map +1 -0
- package/dist/cli/sweetlink.d.ts +9 -0
- package/dist/cli/sweetlink.d.ts.map +1 -0
- package/dist/cli/sweetlink.js +1018 -0
- package/dist/cli/sweetlink.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/playwright.d.ts +29 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +172 -0
- package/dist/playwright.js.map +1 -0
- package/dist/ruler.d.ts +82 -0
- package/dist/ruler.d.ts.map +1 -0
- package/dist/ruler.js +293 -0
- package/dist/ruler.js.map +1 -0
- package/dist/server/anthropic.d.ts +19 -0
- package/dist/server/anthropic.d.ts.map +1 -0
- package/dist/server/anthropic.js +26 -0
- package/dist/server/anthropic.js.map +1 -0
- package/dist/server/constants.d.ts +17 -0
- package/dist/server/constants.d.ts.map +1 -0
- package/dist/server/constants.js +17 -0
- package/dist/server/constants.js.map +1 -0
- package/dist/server/handlers/designReview.d.ts +27 -0
- package/dist/server/handlers/designReview.d.ts.map +1 -0
- package/dist/server/handlers/designReview.js +165 -0
- package/dist/server/handlers/designReview.js.map +1 -0
- package/dist/server/handlers/hmr.d.ts +21 -0
- package/dist/server/handlers/hmr.d.ts.map +1 -0
- package/dist/server/handlers/hmr.js +81 -0
- package/dist/server/handlers/hmr.js.map +1 -0
- package/dist/server/handlers/index.d.ts +12 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/index.js +12 -0
- package/dist/server/handlers/index.js.map +1 -0
- package/dist/server/handlers/outline.d.ts +19 -0
- package/dist/server/handlers/outline.d.ts.map +1 -0
- package/dist/server/handlers/outline.js +41 -0
- package/dist/server/handlers/outline.js.map +1 -0
- package/dist/server/handlers/schema.d.ts +19 -0
- package/dist/server/handlers/schema.d.ts.map +1 -0
- package/dist/server/handlers/schema.js +49 -0
- package/dist/server/handlers/schema.js.map +1 -0
- package/dist/server/handlers/screenshot.d.ts +51 -0
- package/dist/server/handlers/screenshot.d.ts.map +1 -0
- package/dist/server/handlers/screenshot.js +101 -0
- package/dist/server/handlers/screenshot.js.map +1 -0
- package/dist/server/handlers/settings.d.ts +53 -0
- package/dist/server/handlers/settings.d.ts.map +1 -0
- package/dist/server/handlers/settings.js +69 -0
- package/dist/server/handlers/settings.js.map +1 -0
- package/dist/server/index.d.ts +33 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +539 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/subscriptions.d.ts +26 -0
- package/dist/server/subscriptions.d.ts.map +1 -0
- package/dist/server/subscriptions.js +35 -0
- package/dist/server/subscriptions.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +132 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/urlUtils.d.ts +75 -0
- package/dist/urlUtils.d.ts.map +1 -0
- package/dist/urlUtils.js +121 -0
- package/dist/urlUtils.js.map +1 -0
- package/dist/viewportUtils.d.ts +51 -0
- package/dist/viewportUtils.d.ts.map +1 -0
- package/dist/viewportUtils.js +70 -0
- package/dist/viewportUtils.js.map +1 -0
- package/package.json +99 -6
- package/scripts/setup-claude-context.mjs +101 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logs Command Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles console log retrieval commands.
|
|
5
|
+
*/
|
|
6
|
+
import type { ConsoleLog, SweetlinkCommand, SweetlinkResponse } from '../../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle get-logs command
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleGetLogs(command: SweetlinkCommand, consoleLogs: ConsoleLog[]): SweetlinkResponse;
|
|
11
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/browser/commands/logs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtF;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,gBAAgB,EACzB,WAAW,EAAE,UAAU,EAAE,GACxB,iBAAiB,CAmBnB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logs Command Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles console log retrieval commands.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Handle get-logs command
|
|
8
|
+
*/
|
|
9
|
+
export function handleGetLogs(command, consoleLogs) {
|
|
10
|
+
let logs = [...consoleLogs];
|
|
11
|
+
if (command.filter) {
|
|
12
|
+
const filterLower = command.filter.toLowerCase();
|
|
13
|
+
logs = logs.filter((log) => log.level === filterLower || log.message.toLowerCase().includes(filterLower));
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
success: true,
|
|
17
|
+
data: {
|
|
18
|
+
logs,
|
|
19
|
+
totalCount: consoleLogs.length,
|
|
20
|
+
filteredCount: logs.length,
|
|
21
|
+
},
|
|
22
|
+
timestamp: Date.now(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/browser/commands/logs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAyB,EACzB,WAAyB;IAEzB,IAAI,IAAI,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;IAE5B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACjD,IAAI,GAAG,IAAI,CAAC,MAAM,CAChB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CACtF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE;YACJ,IAAI;YACJ,UAAU,EAAE,WAAW,CAAC,MAAM;YAC9B,aAAa,EAAE,IAAI,CAAC,MAAM;SAC3B;QACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Command Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles screenshot-related commands from the server.
|
|
5
|
+
*/
|
|
6
|
+
import type { SweetlinkCommand, SweetlinkResponse } from '../../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle basic screenshot command
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleScreenshot(command: SweetlinkCommand): Promise<SweetlinkResponse>;
|
|
11
|
+
/**
|
|
12
|
+
* Handle request-screenshot command (from CLI/Agent)
|
|
13
|
+
* This version sends the response directly over WebSocket
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleRequestScreenshot(command: SweetlinkCommand, ws: WebSocket | null): Promise<SweetlinkResponse>;
|
|
16
|
+
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/browser/commands/screenshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAQ1E;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsC5F;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,gBAAgB,EACzB,EAAE,EAAE,SAAS,GAAG,IAAI,GACnB,OAAO,CAAC,iBAAiB,CAAC,CA0E5B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Command Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles screenshot-related commands from the server.
|
|
5
|
+
*/
|
|
6
|
+
import html2canvas from 'html2canvas-pro';
|
|
7
|
+
import { canvasToDataUrl, DEFAULT_SCREENSHOT_QUALITY, DEFAULT_SCREENSHOT_SCALE, scaleCanvas, } from '../screenshotUtils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Handle basic screenshot command
|
|
10
|
+
*/
|
|
11
|
+
export async function handleScreenshot(command) {
|
|
12
|
+
try {
|
|
13
|
+
const element = command.selector ? document.querySelector(command.selector) : document.body;
|
|
14
|
+
if (!element) {
|
|
15
|
+
return {
|
|
16
|
+
success: false,
|
|
17
|
+
error: `Element not found: ${command.selector}`,
|
|
18
|
+
timestamp: Date.now(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const canvas = await html2canvas(element, {
|
|
22
|
+
logging: false,
|
|
23
|
+
useCORS: true,
|
|
24
|
+
allowTaint: true,
|
|
25
|
+
...command.options,
|
|
26
|
+
});
|
|
27
|
+
const dataUrl = canvas.toDataURL('image/png');
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
data: {
|
|
31
|
+
screenshot: dataUrl,
|
|
32
|
+
width: canvas.width,
|
|
33
|
+
height: canvas.height,
|
|
34
|
+
selector: command.selector || 'body',
|
|
35
|
+
},
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: error instanceof Error ? error.message : 'Screenshot failed',
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Handle request-screenshot command (from CLI/Agent)
|
|
49
|
+
* This version sends the response directly over WebSocket
|
|
50
|
+
*/
|
|
51
|
+
export async function handleRequestScreenshot(command, ws) {
|
|
52
|
+
try {
|
|
53
|
+
const element = command.selector ? document.querySelector(command.selector) : document.body;
|
|
54
|
+
if (!element) {
|
|
55
|
+
const errorResponse = {
|
|
56
|
+
type: 'screenshot-response',
|
|
57
|
+
requestId: command.requestId,
|
|
58
|
+
success: false,
|
|
59
|
+
error: `Element not found: ${command.selector}`,
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
};
|
|
62
|
+
ws?.send(JSON.stringify(errorResponse));
|
|
63
|
+
return errorResponse;
|
|
64
|
+
}
|
|
65
|
+
const scaleFactor = command.scale || DEFAULT_SCREENSHOT_SCALE;
|
|
66
|
+
const format = command.format || 'jpeg';
|
|
67
|
+
const quality = command.quality || DEFAULT_SCREENSHOT_QUALITY;
|
|
68
|
+
const originalCanvas = await html2canvas(element, {
|
|
69
|
+
logging: false,
|
|
70
|
+
useCORS: true,
|
|
71
|
+
allowTaint: true,
|
|
72
|
+
...command.options,
|
|
73
|
+
});
|
|
74
|
+
// Scale down using shared utility
|
|
75
|
+
const smallCanvas = scaleCanvas(originalCanvas, { scale: scaleFactor });
|
|
76
|
+
const dataUrl = canvasToDataUrl(smallCanvas, { format, quality });
|
|
77
|
+
const responseData = {
|
|
78
|
+
screenshot: dataUrl,
|
|
79
|
+
width: smallCanvas.width,
|
|
80
|
+
height: smallCanvas.height,
|
|
81
|
+
selector: command.selector || 'body',
|
|
82
|
+
};
|
|
83
|
+
if (command.includeMetadata !== false) {
|
|
84
|
+
responseData.url = window.location.href;
|
|
85
|
+
responseData.timestamp = Date.now();
|
|
86
|
+
responseData.viewport = {
|
|
87
|
+
width: window.innerWidth,
|
|
88
|
+
height: window.innerHeight,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const response = {
|
|
92
|
+
type: 'screenshot-response',
|
|
93
|
+
requestId: command.requestId,
|
|
94
|
+
success: true,
|
|
95
|
+
data: responseData,
|
|
96
|
+
timestamp: Date.now(),
|
|
97
|
+
};
|
|
98
|
+
ws?.send(JSON.stringify(response));
|
|
99
|
+
return {
|
|
100
|
+
success: true,
|
|
101
|
+
data: responseData,
|
|
102
|
+
timestamp: Date.now(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const errorMessage = error instanceof Error ? error.message : 'Screenshot failed';
|
|
107
|
+
const errorResponse = {
|
|
108
|
+
type: 'screenshot-response',
|
|
109
|
+
requestId: command.requestId,
|
|
110
|
+
success: false,
|
|
111
|
+
error: errorMessage,
|
|
112
|
+
timestamp: Date.now(),
|
|
113
|
+
};
|
|
114
|
+
ws?.send(JSON.stringify(errorResponse));
|
|
115
|
+
return errorResponse;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/browser/commands/screenshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console Capture Utility
|
|
3
|
+
*
|
|
4
|
+
* Shared console capturing logic used by both GlobalDevBar and SweetlinkBridge.
|
|
5
|
+
* Provides consistent console interception and log formatting.
|
|
6
|
+
*/
|
|
7
|
+
import type { ConsoleLog } from '../types.js';
|
|
8
|
+
/** Maximum number of console logs to retain */
|
|
9
|
+
export declare const MAX_CONSOLE_LOGS = 100;
|
|
10
|
+
/**
|
|
11
|
+
* Original console methods stored for restoration
|
|
12
|
+
*/
|
|
13
|
+
export interface OriginalConsoleMethods {
|
|
14
|
+
log: typeof console.log;
|
|
15
|
+
error: typeof console.error;
|
|
16
|
+
warn: typeof console.warn;
|
|
17
|
+
info: typeof console.info;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Console capture state
|
|
21
|
+
*/
|
|
22
|
+
export interface ConsoleCaptureState {
|
|
23
|
+
logs: ConsoleLog[];
|
|
24
|
+
errorCount: number;
|
|
25
|
+
warningCount: number;
|
|
26
|
+
originalConsole: OriginalConsoleMethods | null;
|
|
27
|
+
isPatched: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuration for console capture
|
|
31
|
+
*/
|
|
32
|
+
export interface ConsoleCaptureConfig {
|
|
33
|
+
maxLogs?: number;
|
|
34
|
+
trackCounts?: boolean;
|
|
35
|
+
onLog?: (log: ConsoleLog) => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a single argument for logging
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatArg(arg: unknown): string;
|
|
41
|
+
/**
|
|
42
|
+
* Format multiple arguments into a single message string
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatArgs(args: unknown[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* ConsoleCapture - Captures console output and stores logs
|
|
47
|
+
*/
|
|
48
|
+
export declare class ConsoleCapture {
|
|
49
|
+
private logs;
|
|
50
|
+
private errorCount;
|
|
51
|
+
private warningCount;
|
|
52
|
+
private originalConsole;
|
|
53
|
+
private isPatched;
|
|
54
|
+
private maxLogs;
|
|
55
|
+
private trackCounts;
|
|
56
|
+
private onLog?;
|
|
57
|
+
constructor(config?: ConsoleCaptureConfig);
|
|
58
|
+
/**
|
|
59
|
+
* Start capturing console output
|
|
60
|
+
*/
|
|
61
|
+
start(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Stop capturing and restore original console methods
|
|
64
|
+
*/
|
|
65
|
+
stop(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Get all captured logs
|
|
68
|
+
*/
|
|
69
|
+
getLogs(): ConsoleLog[];
|
|
70
|
+
/**
|
|
71
|
+
* Get filtered logs
|
|
72
|
+
*/
|
|
73
|
+
getFilteredLogs(filter: string): ConsoleLog[];
|
|
74
|
+
/**
|
|
75
|
+
* Get error count
|
|
76
|
+
*/
|
|
77
|
+
getErrorCount(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Get warning count
|
|
80
|
+
*/
|
|
81
|
+
getWarningCount(): number;
|
|
82
|
+
/**
|
|
83
|
+
* Get current state
|
|
84
|
+
*/
|
|
85
|
+
getState(): ConsoleCaptureState;
|
|
86
|
+
/**
|
|
87
|
+
* Import logs from another source (e.g., early capture)
|
|
88
|
+
*/
|
|
89
|
+
importLogs(logs: ConsoleLog[]): void;
|
|
90
|
+
/**
|
|
91
|
+
* Clear all logs and reset counts
|
|
92
|
+
*/
|
|
93
|
+
clear(): void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create error event handler that captures to console logs
|
|
97
|
+
*/
|
|
98
|
+
export declare function createErrorHandler(logsRef: {
|
|
99
|
+
logs: ConsoleLog[];
|
|
100
|
+
}, maxLogs?: number): (event: ErrorEvent) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Create unhandled rejection handler that captures to console logs
|
|
103
|
+
*/
|
|
104
|
+
export declare function createRejectionHandler(logsRef: {
|
|
105
|
+
logs: ConsoleLog[];
|
|
106
|
+
}, maxLogs?: number): (event: PromiseRejectionEvent) => void;
|
|
107
|
+
//# sourceMappingURL=consoleCapture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consoleCapture.d.ts","sourceRoot":"","sources":["../../src/browser/consoleCapture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAMpC;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IACxB,KAAK,EAAE,OAAO,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IAC1B,IAAI,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC/C,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAoB9C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAElD;AAMD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,KAAK,CAAC,CAA4B;gBAE9B,MAAM,GAAE,oBAAyB;IAM7C;;OAEG;IACH,KAAK,IAAI,IAAI;IA8Cb;;OAEG;IACH,IAAI,IAAI,IAAI;IAWZ;;OAEG;IACH,OAAO,IAAI,UAAU,EAAE;IAIvB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAO7C;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,QAAQ,IAAI,mBAAmB;IAU/B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI;IAIpC;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE;IAAE,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,EAC/B,OAAO,GAAE,MAAyB,GACjC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAc7B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE;IAAE,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,EAC/B,OAAO,GAAE,MAAyB,GACjC,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAmBxC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console Capture Utility
|
|
3
|
+
*
|
|
4
|
+
* Shared console capturing logic used by both GlobalDevBar and SweetlinkBridge.
|
|
5
|
+
* Provides consistent console interception and log formatting.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Constants
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/** Maximum number of console logs to retain */
|
|
11
|
+
export const MAX_CONSOLE_LOGS = 100;
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Formatting Utilities
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Format a single argument for logging
|
|
17
|
+
*/
|
|
18
|
+
export function formatArg(arg) {
|
|
19
|
+
if (arg instanceof Error) {
|
|
20
|
+
return `${arg.name}: ${arg.message}${arg.stack ? `\n${arg.stack}` : ''}`;
|
|
21
|
+
}
|
|
22
|
+
if (typeof arg === 'string' || typeof arg === 'number' || typeof arg === 'boolean') {
|
|
23
|
+
return String(arg);
|
|
24
|
+
}
|
|
25
|
+
if (typeof arg === 'object' && arg !== null) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.stringify(arg, (_key, val) => {
|
|
28
|
+
if (val instanceof Error) {
|
|
29
|
+
return `${val.name}: ${val.message}`;
|
|
30
|
+
}
|
|
31
|
+
return val;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return '[object]';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return String(arg);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Format multiple arguments into a single message string
|
|
42
|
+
*/
|
|
43
|
+
export function formatArgs(args) {
|
|
44
|
+
return args.map(formatArg).join(' ');
|
|
45
|
+
}
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Console Capture Class
|
|
48
|
+
// ============================================================================
|
|
49
|
+
/**
|
|
50
|
+
* ConsoleCapture - Captures console output and stores logs
|
|
51
|
+
*/
|
|
52
|
+
export class ConsoleCapture {
|
|
53
|
+
logs = [];
|
|
54
|
+
errorCount = 0;
|
|
55
|
+
warningCount = 0;
|
|
56
|
+
originalConsole = null;
|
|
57
|
+
isPatched = false;
|
|
58
|
+
maxLogs;
|
|
59
|
+
trackCounts;
|
|
60
|
+
onLog;
|
|
61
|
+
constructor(config = {}) {
|
|
62
|
+
this.maxLogs = config.maxLogs ?? MAX_CONSOLE_LOGS;
|
|
63
|
+
this.trackCounts = config.trackCounts ?? true;
|
|
64
|
+
this.onLog = config.onLog;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Start capturing console output
|
|
68
|
+
*/
|
|
69
|
+
start() {
|
|
70
|
+
if (typeof window === 'undefined')
|
|
71
|
+
return;
|
|
72
|
+
if (this.isPatched)
|
|
73
|
+
return;
|
|
74
|
+
this.originalConsole = {
|
|
75
|
+
log: console.log.bind(console),
|
|
76
|
+
error: console.error.bind(console),
|
|
77
|
+
warn: console.warn.bind(console),
|
|
78
|
+
info: console.info.bind(console),
|
|
79
|
+
};
|
|
80
|
+
const captureLog = (level, args) => {
|
|
81
|
+
const log = {
|
|
82
|
+
level,
|
|
83
|
+
message: formatArgs(args),
|
|
84
|
+
timestamp: Date.now(),
|
|
85
|
+
};
|
|
86
|
+
this.logs.push(log);
|
|
87
|
+
if (this.logs.length > this.maxLogs) {
|
|
88
|
+
this.logs = this.logs.slice(-this.maxLogs);
|
|
89
|
+
}
|
|
90
|
+
if (this.trackCounts) {
|
|
91
|
+
if (level === 'error')
|
|
92
|
+
this.errorCount++;
|
|
93
|
+
if (level === 'warn')
|
|
94
|
+
this.warningCount++;
|
|
95
|
+
}
|
|
96
|
+
if (this.onLog) {
|
|
97
|
+
this.onLog(log);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
// Patch all console methods with a unified wrapper
|
|
101
|
+
const levels = ['log', 'error', 'warn', 'info'];
|
|
102
|
+
for (const level of levels) {
|
|
103
|
+
const original = this.originalConsole[level];
|
|
104
|
+
console[level] = (...args) => {
|
|
105
|
+
captureLog(level, args);
|
|
106
|
+
original(...args);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
this.isPatched = true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Stop capturing and restore original console methods
|
|
113
|
+
*/
|
|
114
|
+
stop() {
|
|
115
|
+
if (!this.isPatched || !this.originalConsole)
|
|
116
|
+
return;
|
|
117
|
+
console.log = this.originalConsole.log;
|
|
118
|
+
console.error = this.originalConsole.error;
|
|
119
|
+
console.warn = this.originalConsole.warn;
|
|
120
|
+
console.info = this.originalConsole.info;
|
|
121
|
+
this.isPatched = false;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all captured logs
|
|
125
|
+
*/
|
|
126
|
+
getLogs() {
|
|
127
|
+
return [...this.logs];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get filtered logs
|
|
131
|
+
*/
|
|
132
|
+
getFilteredLogs(filter) {
|
|
133
|
+
const filterLower = filter.toLowerCase();
|
|
134
|
+
return this.logs.filter((log) => log.level === filterLower || log.message.toLowerCase().includes(filterLower));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get error count
|
|
138
|
+
*/
|
|
139
|
+
getErrorCount() {
|
|
140
|
+
return this.errorCount;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get warning count
|
|
144
|
+
*/
|
|
145
|
+
getWarningCount() {
|
|
146
|
+
return this.warningCount;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get current state
|
|
150
|
+
*/
|
|
151
|
+
getState() {
|
|
152
|
+
return {
|
|
153
|
+
logs: this.getLogs(),
|
|
154
|
+
errorCount: this.errorCount,
|
|
155
|
+
warningCount: this.warningCount,
|
|
156
|
+
originalConsole: this.originalConsole,
|
|
157
|
+
isPatched: this.isPatched,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Import logs from another source (e.g., early capture)
|
|
162
|
+
*/
|
|
163
|
+
importLogs(logs) {
|
|
164
|
+
this.logs = [...logs, ...this.logs].slice(-this.maxLogs);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Clear all logs and reset counts
|
|
168
|
+
*/
|
|
169
|
+
clear() {
|
|
170
|
+
this.logs = [];
|
|
171
|
+
this.errorCount = 0;
|
|
172
|
+
this.warningCount = 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Error Handler Utilities
|
|
177
|
+
// ============================================================================
|
|
178
|
+
/**
|
|
179
|
+
* Create error event handler that captures to console logs
|
|
180
|
+
*/
|
|
181
|
+
export function createErrorHandler(logsRef, maxLogs = MAX_CONSOLE_LOGS) {
|
|
182
|
+
return (event) => {
|
|
183
|
+
logsRef.logs.push({
|
|
184
|
+
level: 'error',
|
|
185
|
+
message: `Uncaught: ${event.message}`,
|
|
186
|
+
timestamp: Date.now(),
|
|
187
|
+
source: event.filename,
|
|
188
|
+
stack: event.error?.stack,
|
|
189
|
+
});
|
|
190
|
+
if (logsRef.logs.length > maxLogs) {
|
|
191
|
+
logsRef.logs = logsRef.logs.slice(-maxLogs);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Create unhandled rejection handler that captures to console logs
|
|
197
|
+
*/
|
|
198
|
+
export function createRejectionHandler(logsRef, maxLogs = MAX_CONSOLE_LOGS) {
|
|
199
|
+
return (event) => {
|
|
200
|
+
const reason = event.reason;
|
|
201
|
+
const message = reason instanceof Error
|
|
202
|
+
? `Unhandled rejection: ${reason.name}: ${reason.message}`
|
|
203
|
+
: `Unhandled rejection: ${String(reason)}`;
|
|
204
|
+
logsRef.logs.push({
|
|
205
|
+
level: 'error',
|
|
206
|
+
message,
|
|
207
|
+
timestamp: Date.now(),
|
|
208
|
+
stack: reason?.stack,
|
|
209
|
+
});
|
|
210
|
+
if (logsRef.logs.length > maxLogs) {
|
|
211
|
+
logsRef.logs = logsRef.logs.slice(-maxLogs);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=consoleCapture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consoleCapture.js","sourceRoot":"","sources":["../../src/browser/consoleCapture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMR Detection and Capture
|
|
3
|
+
*
|
|
4
|
+
* Handles Hot Module Replacement detection and automatic screenshot capture.
|
|
5
|
+
*/
|
|
6
|
+
import type { ConsoleLog, HmrScreenshotData } from '../types.js';
|
|
7
|
+
export interface HmrCaptureConfig {
|
|
8
|
+
debounceMs: number;
|
|
9
|
+
captureDelay: number;
|
|
10
|
+
}
|
|
11
|
+
export interface HmrCaptureState {
|
|
12
|
+
sequence: number;
|
|
13
|
+
debounceTimeout: ReturnType<typeof setTimeout> | null;
|
|
14
|
+
lastCaptureTime: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Set up HMR detection listeners
|
|
18
|
+
* Returns a cleanup function to remove the listeners
|
|
19
|
+
*/
|
|
20
|
+
export declare function setupHmrDetection(onCapture: (trigger: string, changedFile?: string, hmrMetadata?: HmrScreenshotData['hmrMetadata']) => void): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Capture an HMR screenshot
|
|
23
|
+
*/
|
|
24
|
+
export declare function captureHmrScreenshot(ws: WebSocket | null, consoleLogs: ConsoleLog[], state: HmrCaptureState, config: HmrCaptureConfig, trigger: string, changedFile?: string, hmrMetadata?: HmrScreenshotData['hmrMetadata']): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=hmr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/browser/hmr.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQjE,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;IACtD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,CACT,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,KAC3C,IAAI,GACR,MAAM,IAAI,CA2BZ;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,SAAS,GAAG,IAAI,EACpB,WAAW,EAAE,UAAU,EAAE,EACzB,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAoEf"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMR Detection and Capture
|
|
3
|
+
*
|
|
4
|
+
* Handles Hot Module Replacement detection and automatic screenshot capture.
|
|
5
|
+
*/
|
|
6
|
+
import html2canvas from 'html2canvas-pro';
|
|
7
|
+
import { canvasToDataUrl, DEFAULT_SCREENSHOT_QUALITY, DEFAULT_SCREENSHOT_SCALE, scaleCanvas, } from './screenshotUtils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Set up HMR detection listeners
|
|
10
|
+
* Returns a cleanup function to remove the listeners
|
|
11
|
+
*/
|
|
12
|
+
export function setupHmrDetection(onCapture) {
|
|
13
|
+
console.log('[Sweetlink] Setting up HMR detection for automatic screenshots');
|
|
14
|
+
const cleanupFunctions = [];
|
|
15
|
+
// Vite HMR detection
|
|
16
|
+
const viteAfterUpdate = () => onCapture('vite');
|
|
17
|
+
document.addEventListener('vite:afterUpdate', viteAfterUpdate);
|
|
18
|
+
cleanupFunctions.push(() => document.removeEventListener('vite:afterUpdate', viteAfterUpdate));
|
|
19
|
+
// Vite custom event
|
|
20
|
+
const viteHmrHandler = (event) => {
|
|
21
|
+
const detail = event.detail;
|
|
22
|
+
onCapture('vite', detail?.file);
|
|
23
|
+
};
|
|
24
|
+
document.addEventListener('vite:hmr', viteHmrHandler);
|
|
25
|
+
cleanupFunctions.push(() => document.removeEventListener('vite:hmr', viteHmrHandler));
|
|
26
|
+
// Remix HMR detection
|
|
27
|
+
const remixHmrHandler = () => onCapture('remix');
|
|
28
|
+
window.addEventListener('remix-hmr', remixHmrHandler);
|
|
29
|
+
cleanupFunctions.push(() => window.removeEventListener('remix-hmr', remixHmrHandler));
|
|
30
|
+
// Return combined cleanup function
|
|
31
|
+
return () => {
|
|
32
|
+
cleanupFunctions.forEach((fn) => fn());
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Capture an HMR screenshot
|
|
37
|
+
*/
|
|
38
|
+
export async function captureHmrScreenshot(ws, consoleLogs, state, config, trigger, changedFile, hmrMetadata) {
|
|
39
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
40
|
+
return;
|
|
41
|
+
// Debounce rapid HMR events
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
if (now - state.lastCaptureTime < config.debounceMs) {
|
|
44
|
+
if (state.debounceTimeout) {
|
|
45
|
+
clearTimeout(state.debounceTimeout);
|
|
46
|
+
}
|
|
47
|
+
state.debounceTimeout = setTimeout(() => {
|
|
48
|
+
captureHmrScreenshot(ws, consoleLogs, state, config, trigger, changedFile, hmrMetadata);
|
|
49
|
+
}, config.debounceMs);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
state.lastCaptureTime = now;
|
|
53
|
+
// Wait for DOM to settle
|
|
54
|
+
await new Promise((resolve) => setTimeout(resolve, config.captureDelay));
|
|
55
|
+
try {
|
|
56
|
+
const originalCanvas = await html2canvas(document.body, {
|
|
57
|
+
logging: false,
|
|
58
|
+
useCORS: true,
|
|
59
|
+
allowTaint: true,
|
|
60
|
+
});
|
|
61
|
+
// Scale down for efficiency using shared utility
|
|
62
|
+
const smallCanvas = scaleCanvas(originalCanvas, { scale: DEFAULT_SCREENSHOT_SCALE });
|
|
63
|
+
const dataUrl = canvasToDataUrl(smallCanvas, {
|
|
64
|
+
format: 'jpeg',
|
|
65
|
+
quality: DEFAULT_SCREENSHOT_QUALITY,
|
|
66
|
+
});
|
|
67
|
+
// Prepare logs
|
|
68
|
+
const allLogs = [...consoleLogs];
|
|
69
|
+
const errors = allLogs.filter((l) => l.level === 'error');
|
|
70
|
+
const warnings = allLogs.filter((l) => l.level === 'warn');
|
|
71
|
+
state.sequence++;
|
|
72
|
+
const hmrData = {
|
|
73
|
+
trigger,
|
|
74
|
+
changedFile,
|
|
75
|
+
screenshot: dataUrl,
|
|
76
|
+
url: window.location.href,
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
sequenceNumber: state.sequence,
|
|
79
|
+
logs: {
|
|
80
|
+
all: allLogs,
|
|
81
|
+
errors,
|
|
82
|
+
warnings,
|
|
83
|
+
sinceLastCapture: allLogs.length,
|
|
84
|
+
},
|
|
85
|
+
hmrMetadata,
|
|
86
|
+
};
|
|
87
|
+
ws.send(JSON.stringify({
|
|
88
|
+
type: 'hmr-screenshot',
|
|
89
|
+
data: hmrData,
|
|
90
|
+
}));
|
|
91
|
+
console.log(`[Sweetlink] HMR screenshot captured (${trigger})`);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('[Sweetlink] HMR screenshot capture failed:', error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=hmr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../../src/browser/hmr.ts"],"names":[],"mappings":"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"}
|