@yourgpt/copilot-sdk 1.4.0 → 1.4.2

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.
@@ -8,12 +8,99 @@ var DEFAULT_OPTIONS = {
8
8
  maxHeight: 1080,
9
9
  includeCursor: false
10
10
  };
11
- var html2canvasPromise = null;
12
- async function getHtml2Canvas() {
13
- if (!html2canvasPromise) {
14
- html2canvasPromise = import('html2canvas').then((mod) => mod.default);
11
+ var htmlToImagePromise = null;
12
+ async function getHtmlToImage() {
13
+ if (!htmlToImagePromise) {
14
+ htmlToImagePromise = import('html-to-image');
15
+ }
16
+ return htmlToImagePromise;
17
+ }
18
+ async function captureWithHtmlToImage(element, opts) {
19
+ const htmlToImage = await getHtmlToImage();
20
+ const rect = element.getBoundingClientRect();
21
+ const width = rect.width || window.innerWidth;
22
+ const height = rect.height || window.innerHeight;
23
+ const scale = Math.min(opts.maxWidth / width, opts.maxHeight / height, 1);
24
+ let dataUrl;
25
+ if (opts.format === "jpeg") {
26
+ dataUrl = await htmlToImage.toJpeg(element, {
27
+ quality: opts.quality,
28
+ pixelRatio: scale,
29
+ skipAutoScale: true,
30
+ cacheBust: true
31
+ });
32
+ } else {
33
+ dataUrl = await htmlToImage.toPng(element, {
34
+ pixelRatio: scale,
35
+ skipAutoScale: true,
36
+ cacheBust: true
37
+ });
38
+ }
39
+ const img = new Image();
40
+ await new Promise((resolve, reject) => {
41
+ img.onload = () => resolve();
42
+ img.onerror = () => reject(new Error("Failed to load captured image"));
43
+ img.src = dataUrl;
44
+ });
45
+ return {
46
+ data: dataUrl,
47
+ format: opts.format,
48
+ width: img.width,
49
+ height: img.height,
50
+ timestamp: Date.now()
51
+ };
52
+ }
53
+ async function captureWithDisplayMedia(opts) {
54
+ const stream = await navigator.mediaDevices.getDisplayMedia({
55
+ video: {
56
+ displaySurface: "browser"
57
+ },
58
+ audio: false,
59
+ // @ts-expect-error - preferCurrentTab is a newer API
60
+ preferCurrentTab: true
61
+ });
62
+ try {
63
+ const track = stream.getVideoTracks()[0];
64
+ const settings = track.getSettings();
65
+ const video = document.createElement("video");
66
+ video.srcObject = stream;
67
+ video.muted = true;
68
+ await new Promise((resolve, reject) => {
69
+ video.onloadedmetadata = () => {
70
+ video.play().then(() => resolve()).catch(reject);
71
+ };
72
+ video.onerror = () => reject(new Error("Failed to load video stream"));
73
+ });
74
+ await new Promise((resolve) => setTimeout(resolve, 100));
75
+ const videoWidth = settings.width || video.videoWidth || window.innerWidth;
76
+ const videoHeight = settings.height || video.videoHeight || window.innerHeight;
77
+ const scale = Math.min(
78
+ opts.maxWidth / videoWidth,
79
+ opts.maxHeight / videoHeight,
80
+ 1
81
+ );
82
+ const width = Math.round(videoWidth * scale);
83
+ const height = Math.round(videoHeight * scale);
84
+ const canvas = document.createElement("canvas");
85
+ canvas.width = width;
86
+ canvas.height = height;
87
+ const ctx = canvas.getContext("2d");
88
+ if (!ctx) {
89
+ throw new Error("Failed to create canvas context");
90
+ }
91
+ ctx.drawImage(video, 0, 0, width, height);
92
+ const mimeType = `image/${opts.format === "jpeg" ? "jpeg" : opts.format}`;
93
+ const data = canvas.toDataURL(mimeType, opts.quality);
94
+ return {
95
+ data,
96
+ format: opts.format,
97
+ width,
98
+ height,
99
+ timestamp: Date.now()
100
+ };
101
+ } finally {
102
+ stream.getTracks().forEach((track) => track.stop());
15
103
  }
16
- return html2canvasPromise;
17
104
  }
18
105
  async function captureScreenshot(options = {}) {
19
106
  if (!isBrowser) {
@@ -23,77 +110,45 @@ async function captureScreenshot(options = {}) {
23
110
  }
24
111
  const opts = { ...DEFAULT_OPTIONS, ...options };
25
112
  const element = opts.element || document.body;
113
+ try {
114
+ return await captureWithHtmlToImage(element, opts);
115
+ } catch (error) {
116
+ console.warn(
117
+ "[Copilot SDK] html-to-image capture failed, trying native API",
118
+ error
119
+ );
120
+ }
121
+ const hasDisplayMedia = typeof navigator !== "undefined" && typeof navigator.mediaDevices !== "undefined" && typeof navigator.mediaDevices.getDisplayMedia === "function";
122
+ if (hasDisplayMedia) {
123
+ try {
124
+ return await captureWithDisplayMedia(opts);
125
+ } catch (error) {
126
+ console.warn(
127
+ "[Copilot SDK] Screen capture cancelled or not supported",
128
+ error
129
+ );
130
+ }
131
+ }
26
132
  const rect = element.getBoundingClientRect();
27
133
  let width = rect.width || window.innerWidth;
28
134
  let height = rect.height || window.innerHeight;
29
135
  const scale = Math.min(opts.maxWidth / width, opts.maxHeight / height, 1);
30
136
  width = Math.round(width * scale);
31
137
  height = Math.round(height * scale);
32
- let canvas;
33
- try {
34
- const html2canvas = await getHtml2Canvas();
35
- canvas = await html2canvas(element, {
36
- scale,
37
- useCORS: true,
38
- // Enable cross-origin images
39
- allowTaint: false,
40
- // Don't allow tainted canvas
41
- backgroundColor: null,
42
- // Transparent background (uses element's bg)
43
- logging: false,
44
- // Disable internal logging
45
- width: rect.width,
46
- height: rect.height,
47
- windowWidth: window.innerWidth,
48
- windowHeight: window.innerHeight,
49
- scrollX: 0,
50
- scrollY: 0,
51
- x: rect.left + window.scrollX,
52
- y: rect.top + window.scrollY
53
- });
54
- } catch (error) {
55
- canvas = document.createElement("canvas");
56
- canvas.width = width;
57
- canvas.height = height;
58
- const ctx = canvas.getContext("2d");
59
- if (ctx) {
60
- createPlaceholder(ctx, width, height, element, String(error));
61
- }
138
+ const canvas = document.createElement("canvas");
139
+ canvas.width = width;
140
+ canvas.height = height;
141
+ const ctx = canvas.getContext("2d");
142
+ if (ctx) {
143
+ createPlaceholder(ctx, width, height, element, "Screenshot capture failed");
62
144
  }
63
145
  const mimeType = `image/${opts.format === "jpeg" ? "jpeg" : opts.format}`;
64
- let data;
65
- try {
66
- data = canvas.toDataURL(mimeType, opts.quality);
67
- } catch (e) {
68
- if (e instanceof DOMException && e.name === "SecurityError") {
69
- console.warn(
70
- "[Copilot SDK] Canvas tainted by cross-origin content. Creating placeholder."
71
- );
72
- const cleanCanvas = document.createElement("canvas");
73
- cleanCanvas.width = width;
74
- cleanCanvas.height = height;
75
- const cleanCtx = cleanCanvas.getContext("2d");
76
- if (cleanCtx) {
77
- createPlaceholder(
78
- cleanCtx,
79
- width,
80
- height,
81
- element,
82
- "Cross-origin content blocked"
83
- );
84
- data = cleanCanvas.toDataURL(mimeType, opts.quality);
85
- } else {
86
- throw new Error("Failed to create placeholder canvas");
87
- }
88
- } else {
89
- throw e;
90
- }
91
- }
146
+ const data = canvas.toDataURL(mimeType, opts.quality);
92
147
  return {
93
148
  data,
94
149
  format: opts.format,
95
- width: canvas.width,
96
- height: canvas.height,
150
+ width,
151
+ height,
97
152
  timestamp: Date.now()
98
153
  };
99
154
  }
@@ -120,7 +175,7 @@ function createPlaceholder(ctx, width, height, element, errorMessage) {
120
175
  width / 2,
121
176
  height / 2
122
177
  );
123
- if (errorMessage) {
178
+ {
124
179
  ctx.fillStyle = "#999";
125
180
  ctx.font = "12px system-ui, sans-serif";
126
181
  ctx.fillText(
@@ -1132,6 +1187,10 @@ function createScreenshotTool(options) {
1132
1187
  }
1133
1188
 
1134
1189
  // src/core/tools/builtin/console.ts
1190
+ var isBrowser4 = typeof window !== "undefined" && typeof console !== "undefined";
1191
+ if (isBrowser4 && !isConsoleCaptureActive()) {
1192
+ startConsoleCapture();
1193
+ }
1135
1194
  var consoleLogsTool = tool({
1136
1195
  description: "Get recent console logs from the browser. Use this when debugging JavaScript errors, checking for warnings, or understanding what's happening in the application.",
1137
1196
  location: "client",
@@ -2706,5 +2765,5 @@ function createThreadManager(config, callbacks) {
2706
2765
  }
2707
2766
 
2708
2767
  export { CLOUD_MAX_FILE_SIZE, DEFAULT_YOURGPT_ENDPOINT, SimpleThreadManagerState, ThreadManager, actionToTool, builtinTools, captureCurrentLogs, captureScreenshot, clearConsoleLogs, clearNetworkRequests, consoleLogsTool, createAssistantMessage, createCloudStorage, createConsoleLogsTool, createCustomDetector, createLocalStorageAdapter, createMemoryAdapter, createMessage, createNetworkRequestsTool, createSSEStream, createScreenshotTool, createServerAdapter, createThreadManager, createToolCall, createToolMessage, createToolResult, createUserMessage, defaultSystemMessage, defineClientTool, defineServerTool, defineTool, detectIntent, failure, formatLogsForAI, formatRequestsForAI, formatSSE, generateId, generateMessageId, generateSuggestionReason, generateThreadId, generateThreadTitle, generateToolCallId, getAttachmentTypeFromMime, getConsoleErrors, getConsoleLogs, getConsoleWarnings, getFailedRequests, getNetworkRequests, getPrimaryTool, hasToolCalls, hasToolSuggestions, isConsoleCaptureActive, isNetworkCaptureActive, isScreenshotSupported, isToolResult, localStorageAdapter, networkRequestsTool, noopAdapter, parseSSELine, parseStreamEvent, parseToolCallArgs, processFileToAttachment, resizeScreenshot, screenshotTool, serializeStreamEvent, startConsoleCapture, startNetworkCapture, stopConsoleCapture, stopNetworkCapture, streamSSE, success, tool, toolToAnthropicFormat, toolToOpenAIFormat, zodObjectToInputSchema, zodToJsonSchema };
2709
- //# sourceMappingURL=chunk-CVD3X4MN.js.map
2710
- //# sourceMappingURL=chunk-CVD3X4MN.js.map
2768
+ //# sourceMappingURL=chunk-55EABH45.js.map
2769
+ //# sourceMappingURL=chunk-55EABH45.js.map