cursor-buddy 0.0.7 → 0.0.9-beta.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.
@@ -42,10 +42,7 @@ type VoiceEvent = {
42
42
  error: Error;
43
43
  };
44
44
  /**
45
- * Point coordinates parsed from AI response.
46
- * Supports two formats:
47
- * - Marker-based: [POINT:5:label] - references a numbered marker
48
- * - Coordinate-based: [POINT:640,360:label] - raw pixel coordinates
45
+ * Point coordinates for cursor pointing.
49
46
  */
50
47
  interface PointingTarget {
51
48
  /** X coordinate in viewport pixels (top-left origin) */
@@ -460,4 +457,4 @@ declare class CursorBuddyClient {
460
457
  }
461
458
  //#endregion
462
459
  export { CursorBuddySnapshot as a, CursorRenderProps as c, SpeechBubbleRenderProps as d, VoiceEvent as f, CursorBuddyMediaMode as i, Point as l, WaveformRenderProps as m, BrowserSpeechPort as n, CursorBuddySpeechConfig as o, VoiceState as p, CursorBuddyClientOptions as r, CursorBuddyTranscriptionConfig as s, CursorBuddyClient as t, PointingTarget as u };
463
- //# sourceMappingURL=client-Crn8tW7w.d.mts.map
460
+ //# sourceMappingURL=client-Ba6rv-du.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-Ba6rv-du.d.mts","names":[],"sources":["../src/core/utils/elements.ts","../src/core/types.ts","../src/core/client.ts"],"mappings":"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"}
@@ -21,80 +21,6 @@ const $isEnabled = atom(true);
21
21
  atom(false);
22
22
  const $conversationHistory = atom([]);
23
23
  //#endregion
24
- //#region src/core/pointing.ts
25
- /**
26
- * Parses POINT tags from AI responses.
27
- *
28
- * Supports two formats:
29
- * - Marker-based: [POINT:5:label] - 3 parts, references a numbered marker
30
- * - Coordinate-based: [POINT:640,360:label] - 4 parts, raw pixel coordinates
31
- */
32
- const POINTING_TAG_REGEX = /\[POINT:(\d+)(?:,(\d+))?:([^\]]+)\]\s*$/;
33
- const PARTIAL_POINTING_PREFIXES = new Set([
34
- "[",
35
- "[P",
36
- "[PO",
37
- "[POI",
38
- "[POIN",
39
- "[POINT",
40
- "[POINT:"
41
- ]);
42
- function stripTrailingPointingTag(response, trimResult) {
43
- const stripped = response.replace(POINTING_TAG_REGEX, "");
44
- return trimResult ? stripped.trim() : stripped;
45
- }
46
- function getPartialPointingTagStart(response) {
47
- const lastOpenBracket = response.lastIndexOf("[");
48
- if (lastOpenBracket === -1) return -1;
49
- const suffix = response.slice(lastOpenBracket).trimEnd();
50
- if (suffix.includes("]")) return -1;
51
- if (suffix.startsWith("[POINT:")) {
52
- let start = lastOpenBracket;
53
- while (start > 0 && /\s/.test(response[start - 1] ?? "")) start--;
54
- return start;
55
- }
56
- return PARTIAL_POINTING_PREFIXES.has(suffix) ? lastOpenBracket : -1;
57
- }
58
- /**
59
- * Parse pointing tag into structured result.
60
- * Returns null if no valid POINT tag is found at the end.
61
- */
62
- function parsePointingTagRaw(response) {
63
- const match = response.match(POINTING_TAG_REGEX);
64
- if (!match) return null;
65
- const first = Number.parseInt(match[1], 10);
66
- const second = match[2] ? Number.parseInt(match[2], 10) : null;
67
- const label = match[3].trim();
68
- if (second !== null) return {
69
- type: "coordinates",
70
- x: first,
71
- y: second,
72
- label
73
- };
74
- return {
75
- type: "marker",
76
- markerId: first,
77
- label
78
- };
79
- }
80
- /**
81
- * Remove POINT tag from response text for display/TTS.
82
- */
83
- function stripPointingTag(response) {
84
- return stripTrailingPointingTag(response, true);
85
- }
86
- /**
87
- * Strip complete or partial trailing POINT syntax while the response streams.
88
- * This keeps the visible text and TTS input stable even if the tag arrives
89
- * incrementally over multiple chunks.
90
- */
91
- function stripTrailingPointingSyntax(response) {
92
- const withoutCompleteTag = stripTrailingPointingTag(response, false);
93
- const partialTagStart = getPartialPointingTagStart(withoutCompleteTag);
94
- if (partialTagStart === -1) return withoutCompleteTag.trimEnd();
95
- return withoutCompleteTag.slice(0, partialTagStart).trimEnd();
96
- }
97
- //#endregion
98
24
  //#region src/core/utils/error.ts
99
25
  /**
100
26
  * Normalize unknown thrown values into Error instances.
@@ -906,6 +832,48 @@ function resolveMarkerToCoordinates(markerMap, markerId) {
906
832
  //#endregion
907
833
  //#region src/core/utils/screenshot.ts
908
834
  const CLONE_RESOURCE_TIMEOUT_MS = 3e3;
835
+ /** Maximum width for compressed screenshots (maintains aspect ratio) */
836
+ const MAX_SCREENSHOT_WIDTH = 1280;
837
+ /** JPEG quality for compressed screenshots (0-1) */
838
+ const JPEG_QUALITY = .8;
839
+ /**
840
+ * Compress a canvas image by downscaling and converting to JPEG.
841
+ * Maintains aspect ratio and falls back to original if compression fails.
842
+ *
843
+ * @param sourceCanvas - The source canvas to compress
844
+ * @param maxWidth - Maximum width for the compressed image (default: MAX_SCREENSHOT_WIDTH)
845
+ * @param quality - JPEG quality 0-1 (default: JPEG_QUALITY)
846
+ * @returns Compression result with compressed image data and dimensions
847
+ */
848
+ function compressImage(sourceCanvas, maxWidth = MAX_SCREENSHOT_WIDTH, quality = JPEG_QUALITY) {
849
+ const sourceWidth = sourceCanvas.width;
850
+ const sourceHeight = sourceCanvas.height;
851
+ if (sourceWidth <= maxWidth) return {
852
+ imageData: sourceCanvas.toDataURL("image/jpeg", quality),
853
+ width: sourceWidth,
854
+ height: sourceHeight
855
+ };
856
+ const scale = maxWidth / sourceWidth;
857
+ const targetWidth = Math.round(maxWidth);
858
+ const targetHeight = Math.round(sourceHeight * scale);
859
+ const canvas = document.createElement("canvas");
860
+ canvas.width = targetWidth;
861
+ canvas.height = targetHeight;
862
+ const ctx = canvas.getContext("2d");
863
+ if (!ctx) return {
864
+ imageData: sourceCanvas.toDataURL("image/jpeg", quality),
865
+ width: sourceWidth,
866
+ height: sourceHeight
867
+ };
868
+ ctx.imageSmoothingEnabled = true;
869
+ ctx.imageSmoothingQuality = "high";
870
+ ctx.drawImage(sourceCanvas, 0, 0, targetWidth, targetHeight);
871
+ return {
872
+ imageData: canvas.toDataURL("image/jpeg", quality),
873
+ width: targetWidth,
874
+ height: targetHeight
875
+ };
876
+ }
909
877
  function getCaptureMetrics() {
910
878
  return {
911
879
  viewportWidth: window.innerWidth,
@@ -1004,7 +972,7 @@ function createFallbackCanvas() {
1004
972
  }
1005
973
  /**
1006
974
  * Capture a screenshot of the current viewport.
1007
- * Uses html2canvas to render the DOM to a canvas, then exports as JPEG.
975
+ * Uses html2canvas to render the DOM to a canvas, then compresses to JPEG.
1008
976
  * Falls back to a placeholder if capture fails (e.g., due to unsupported CSS).
1009
977
  */
1010
978
  async function captureViewport() {
@@ -1015,10 +983,20 @@ async function captureViewport() {
1015
983
  } catch {
1016
984
  canvas = createFallbackCanvas();
1017
985
  }
986
+ let compressed;
987
+ try {
988
+ compressed = compressImage(canvas);
989
+ } catch {
990
+ compressed = {
991
+ imageData: canvas.toDataURL("image/png"),
992
+ width: canvas.width,
993
+ height: canvas.height
994
+ };
995
+ }
1018
996
  return {
1019
- imageData: canvas.toDataURL("image/png"),
1020
- width: canvas.width,
1021
- height: canvas.height,
997
+ imageData: compressed.imageData,
998
+ width: compressed.width,
999
+ height: compressed.height,
1022
1000
  viewportWidth: captureMetrics.viewportWidth,
1023
1001
  viewportHeight: captureMetrics.viewportHeight
1024
1002
  };
@@ -1039,10 +1017,20 @@ async function captureAnnotatedViewport() {
1039
1017
  }
1040
1018
  const canvas = markerMap.size > 0 ? createAnnotatedCanvas(sourceCanvas, markerMap) : sourceCanvas;
1041
1019
  const markerContext = generateMarkerContext(markerMap);
1020
+ let compressed;
1021
+ try {
1022
+ compressed = compressImage(canvas);
1023
+ } catch {
1024
+ compressed = {
1025
+ imageData: canvas.toDataURL("image/png"),
1026
+ width: canvas.width,
1027
+ height: canvas.height
1028
+ };
1029
+ }
1042
1030
  return {
1043
- imageData: canvas.toDataURL("image/png"),
1044
- width: canvas.width,
1045
- height: canvas.height,
1031
+ imageData: compressed.imageData,
1032
+ width: compressed.width,
1033
+ height: compressed.height,
1046
1034
  viewportWidth: captureMetrics.viewportWidth,
1047
1035
  viewportHeight: captureMetrics.viewportHeight,
1048
1036
  markerMap,
@@ -1522,6 +1510,47 @@ function createStateMachine(initial = "idle") {
1522
1510
  };
1523
1511
  }
1524
1512
  //#endregion
1513
+ //#region src/core/utils/ui-stream-parser.ts
1514
+ /**
1515
+ * Parse a single line from the UI message stream.
1516
+ * The stream format is SSE with "data: " prefix followed by JSON.
1517
+ */
1518
+ function parseUIStreamLine(line) {
1519
+ const trimmed = line.trim();
1520
+ if (!trimmed) return null;
1521
+ let jsonStr = trimmed;
1522
+ if (trimmed.startsWith("data: ")) jsonStr = trimmed.slice(6);
1523
+ if (jsonStr === "[DONE]") return null;
1524
+ try {
1525
+ const chunk = JSON.parse(jsonStr);
1526
+ switch (chunk.type) {
1527
+ case "text-delta": return {
1528
+ type: "text-delta",
1529
+ delta: chunk.delta ?? ""
1530
+ };
1531
+ case "tool-input-available": return {
1532
+ type: "tool-input-available",
1533
+ toolName: chunk.toolName ?? "",
1534
+ input: chunk.input
1535
+ };
1536
+ case "finish": return { type: "finish" };
1537
+ case "error": return {
1538
+ type: "error",
1539
+ errorText: chunk.errorText ?? "Unknown error"
1540
+ };
1541
+ default: return { type: "unknown" };
1542
+ }
1543
+ } catch {
1544
+ return null;
1545
+ }
1546
+ }
1547
+ /**
1548
+ * Check if a tool call is a point tool call with valid input.
1549
+ */
1550
+ function isPointToolCall(chunk) {
1551
+ return chunk.type === "tool-input-available" && chunk.toolName === "point" && chunk.input != null && typeof chunk.input === "object" && "type" in chunk.input && "label" in chunk.input;
1552
+ }
1553
+ //#endregion
1525
1554
  //#region src/core/utils/response-processor.ts
1526
1555
  const COMMON_ABBREVIATIONS = [
1527
1556
  "mr.",
@@ -1590,32 +1619,58 @@ function extractCompletedSegments(text) {
1590
1619
  };
1591
1620
  }
1592
1621
  /**
1593
- * Tracks a streaming assistant response, exposes a tag-free visible version for
1594
- * the UI, and emits speakable segments as sentence boundaries become stable.
1622
+ * Processes a streaming AI SDK UI message stream response.
1623
+ * Extracts text for display/TTS and captures point tool calls.
1595
1624
  */
1596
1625
  var ProgressiveResponseProcessor = class {
1597
- consumedVisibleTextLength = 0;
1626
+ consumedTextLength = 0;
1598
1627
  pendingShortSegment = "";
1599
- rawResponse = "";
1628
+ rawText = "";
1629
+ buffer = "";
1630
+ pointToolCall = null;
1631
+ /**
1632
+ * Push raw stream data and extract text chunks and tool calls.
1633
+ * The UI message stream format is newline-delimited JSON.
1634
+ */
1600
1635
  push(chunk) {
1601
- this.rawResponse += chunk;
1602
- const visibleText = stripTrailingPointingSyntax(this.rawResponse);
1603
- const { consumedLength, segments } = extractCompletedSegments(visibleText.slice(this.consumedVisibleTextLength));
1604
- this.consumedVisibleTextLength += consumedLength;
1636
+ this.buffer += chunk;
1637
+ const lines = this.buffer.split("\n");
1638
+ this.buffer = lines.pop() ?? "";
1639
+ const newTextParts = [];
1640
+ for (const line of lines) {
1641
+ const parsed = parseUIStreamLine(line);
1642
+ if (!parsed) continue;
1643
+ if (parsed.type === "text-delta") newTextParts.push(parsed.delta);
1644
+ else if (isPointToolCall(parsed)) {
1645
+ if (!this.pointToolCall) this.pointToolCall = parsed.input;
1646
+ }
1647
+ }
1648
+ if (newTextParts.length > 0) this.rawText += newTextParts.join("");
1649
+ const { consumedLength, segments } = extractCompletedSegments(this.rawText.slice(this.consumedTextLength));
1650
+ this.consumedTextLength += consumedLength;
1605
1651
  return {
1606
- visibleText,
1607
- speechSegments: this.coalesceSegments(segments)
1652
+ visibleText: this.rawText,
1653
+ speechSegments: this.coalesceSegments(segments),
1654
+ pointToolCall: this.pointToolCall
1608
1655
  };
1609
1656
  }
1657
+ /**
1658
+ * Finalize processing and return any remaining text/tool call.
1659
+ */
1610
1660
  finish() {
1611
- const finalResponseText = stripPointingTag(this.rawResponse);
1612
- const trailingText = finalResponseText.slice(this.consumedVisibleTextLength).trim();
1661
+ if (this.buffer) {
1662
+ const parsed = parseUIStreamLine(this.buffer);
1663
+ if (parsed?.type === "text-delta") this.rawText += parsed.delta;
1664
+ else if (parsed && isPointToolCall(parsed) && !this.pointToolCall) this.pointToolCall = parsed.input;
1665
+ this.buffer = "";
1666
+ }
1667
+ const trailingText = this.rawText.slice(this.consumedTextLength).trim();
1613
1668
  const finalSegmentParts = [this.pendingShortSegment, trailingText].filter(Boolean);
1614
1669
  this.pendingShortSegment = "";
1615
1670
  return {
1616
- fullResponse: this.rawResponse,
1617
- finalResponseText,
1618
- speechSegments: finalSegmentParts.length ? [finalSegmentParts.join(" ").trim()] : []
1671
+ finalResponseText: this.rawText.trim(),
1672
+ speechSegments: finalSegmentParts.length ? [finalSegmentParts.join(" ").trim()] : [],
1673
+ pointToolCall: this.pointToolCall
1619
1674
  };
1620
1675
  }
1621
1676
  coalesceSegments(segments) {
@@ -1777,7 +1832,7 @@ var CursorBuddyClient = class {
1777
1832
  this.options.onTranscript?.(transcript);
1778
1833
  this.notify();
1779
1834
  this.prepareSpeechMode();
1780
- const { cleanResponse, fullResponse, playbackQueue } = await this.chatAndSpeak(transcript, screenshot, signal, {
1835
+ const { cleanResponse, pointToolCall, playbackQueue } = await this.chatAndSpeak(transcript, screenshot, signal, {
1781
1836
  onFailure: failTurn,
1782
1837
  onPlaybackStart: () => {
1783
1838
  this.stateMachine.transition({ type: "RESPONSE_STARTED" });
@@ -1785,18 +1840,17 @@ var CursorBuddyClient = class {
1785
1840
  });
1786
1841
  if (turnFailure) throw turnFailure;
1787
1842
  if (signal?.aborted) return;
1788
- const parsed = parsePointingTagRaw(fullResponse);
1789
1843
  this.options.onResponse?.(cleanResponse);
1790
1844
  let pointTarget = null;
1791
- if (parsed) if (parsed.type === "marker") {
1792
- const coords = resolveMarkerToCoordinates(screenshot.markerMap, parsed.markerId);
1845
+ if (pointToolCall) if (pointToolCall.type === "marker") {
1846
+ const coords = resolveMarkerToCoordinates(screenshot.markerMap, pointToolCall.markerId);
1793
1847
  if (coords) pointTarget = {
1794
1848
  ...coords,
1795
- label: parsed.label
1849
+ label: pointToolCall.label
1796
1850
  };
1797
1851
  } else pointTarget = {
1798
- ...mapCoordinatesToViewport(parsed.x, parsed.y, screenshot),
1799
- label: parsed.label
1852
+ ...mapCoordinatesToViewport(pointToolCall.x, pointToolCall.y, screenshot),
1853
+ label: pointToolCall.label
1800
1854
  };
1801
1855
  if (pointTarget) {
1802
1856
  this.options.onPoint?.(pointTarget);
@@ -1999,7 +2053,7 @@ var CursorBuddyClient = class {
1999
2053
  this.updateResponse(finalizedResponse.finalResponseText);
2000
2054
  return {
2001
2055
  cleanResponse: finalizedResponse.finalResponseText,
2002
- fullResponse: finalizedResponse.fullResponse,
2056
+ pointToolCall: finalizedResponse.pointToolCall,
2003
2057
  playbackQueue
2004
2058
  };
2005
2059
  }
@@ -2197,4 +2251,4 @@ var CursorBuddyClient = class {
2197
2251
  //#endregion
2198
2252
  export { $buddyScale as a, $buddyRotation as i, $audioLevel as n, $cursorPosition as o, $buddyPosition as r, $pointingTarget as s, CursorBuddyClient as t };
2199
2253
 
2200
- //# sourceMappingURL=client-DZNTKnnD.mjs.map
2254
+ //# sourceMappingURL=client-CevxN9EX.mjs.map