cursor-buddy 0.0.10 → 0.0.11

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.
@@ -1,3 +1,109 @@
1
+ //#region src/core/tools/types.d.ts
2
+ /**
3
+ * Tool call lifecycle status
4
+ */
5
+ type ToolCallStatus = "pending" | "awaiting_approval" | "approved" | "denied" | "completed" | "failed";
6
+ /**
7
+ * Internal tool call state tracked by ToolCallManager
8
+ */
9
+ interface ToolCallState {
10
+ /** Unique tool call ID from the stream */
11
+ id: string;
12
+ /** Name of the tool */
13
+ toolName: string;
14
+ /** Arguments passed to the tool */
15
+ args: unknown;
16
+ /** Current status */
17
+ status: ToolCallStatus;
18
+ /** Pre-resolved label from config or auto-generated */
19
+ label: string;
20
+ /** Tool result when completed */
21
+ result?: unknown;
22
+ /** Error message when failed */
23
+ error?: string;
24
+ /** Approval ID for approval flow */
25
+ approvalId?: string;
26
+ /** Timestamp when tool entered the queue */
27
+ enteredQueueAt: number;
28
+ }
29
+ /**
30
+ * Render props for tool bubble components
31
+ */
32
+ interface ToolBubbleRenderProps {
33
+ /** Name of the tool */
34
+ toolName: string;
35
+ /** Arguments passed to the tool */
36
+ args: unknown;
37
+ /** Current status */
38
+ status: ToolCallStatus;
39
+ /** Pre-resolved label */
40
+ label: string;
41
+ /** Tool result when completed */
42
+ result?: unknown;
43
+ /** Error message when failed */
44
+ error?: string;
45
+ /** Approve the tool call (only when status === "awaiting_approval") */
46
+ approve?: () => void;
47
+ /** Deny the tool call (only when status === "awaiting_approval") */
48
+ deny?: () => void;
49
+ /** Dismiss the bubble manually */
50
+ dismiss: () => void;
51
+ }
52
+ /**
53
+ * Error handler return types
54
+ */
55
+ type ToolErrorHandlerResult = void | {
56
+ label: string;
57
+ } | {
58
+ hide: true;
59
+ } | {
60
+ render: (props: ToolBubbleRenderProps) => React.ReactNode;
61
+ };
62
+ /**
63
+ * Configuration for displaying a single tool
64
+ */
65
+ interface ToolDisplayOptions {
66
+ /** Display mode. Default: "bubble" */
67
+ mode?: "bubble" | "hidden";
68
+ /** Label shown in bubble. Auto-generated if omitted. */
69
+ label?: string | ((args: unknown, status: ToolCallStatus) => string);
70
+ /** Minimum display time in ms. Default: 1500 */
71
+ minDisplayTime?: number;
72
+ /** Custom render for bubble content */
73
+ render?: (props: ToolBubbleRenderProps) => React.ReactNode;
74
+ /** Error handling */
75
+ onError?: (error: string, args: unknown) => ToolErrorHandlerResult;
76
+ }
77
+ /**
78
+ * Tool display configuration map
79
+ * Use "*" key for default options applied to all tools
80
+ */
81
+ interface ToolDisplayConfig {
82
+ [toolName: string]: ToolDisplayOptions;
83
+ }
84
+ /**
85
+ * Event emitted when a tool is called
86
+ */
87
+ interface ToolCallEvent {
88
+ /** Unique tool call ID */
89
+ id: string;
90
+ /** Name of the tool */
91
+ toolName: string;
92
+ /** Arguments passed to the tool */
93
+ args: unknown;
94
+ }
95
+ /**
96
+ * Event emitted when a tool completes
97
+ */
98
+ interface ToolResultEvent {
99
+ /** Tool call ID */
100
+ id: string;
101
+ /** Name of the tool */
102
+ toolName: string;
103
+ /** Tool result */
104
+ result: unknown;
105
+ }
106
+ //#endregion
1
107
  //#region src/core/types.d.ts
2
108
  /**
3
109
  * Voice state machine states
@@ -215,6 +321,11 @@ interface CursorBuddyClientOptions {
215
321
  * `{ mode: "server", allowStreaming: false }`.
216
322
  */
217
323
  speech?: CursorBuddySpeechConfig;
324
+ /**
325
+ * Tool display configuration.
326
+ * Use "*" key for default options applied to all tools.
327
+ */
328
+ toolDisplay?: ToolDisplayConfig;
218
329
  /** Callback when transcript is ready */
219
330
  onTranscript?: (text: string) => void;
220
331
  /** Callback when AI responds */
@@ -225,6 +336,10 @@ interface CursorBuddyClientOptions {
225
336
  onStateChange?: (state: VoiceState) => void;
226
337
  /** Callback when error occurs */
227
338
  onError?: (error: Error) => void;
339
+ /** Callback when a tool is called */
340
+ onToolCall?: (event: ToolCallEvent) => void;
341
+ /** Callback when a tool completes */
342
+ onToolResult?: (event: ToolResultEvent) => void;
228
343
  }
229
344
  /**
230
345
  * Client snapshot for React's useSyncExternalStore
@@ -247,185 +362,13 @@ interface CursorBuddySnapshot {
247
362
  isPointing: boolean;
248
363
  /** Whether the buddy is enabled */
249
364
  isEnabled: boolean;
365
+ /** All tool calls in current turn */
366
+ toolCalls: ToolCallState[];
367
+ /** Visible, non-expired tool calls */
368
+ activeToolCalls: ToolCallState[];
369
+ /** Tool awaiting user approval, or null */
370
+ pendingApproval: ToolCallState | null;
250
371
  }
251
372
  //#endregion
252
- //#region src/core/client.d.ts
253
- /**
254
- * Framework-agnostic client for cursor buddy voice interactions.
255
- *
256
- * Manages the complete voice interaction flow:
257
- * idle -> listening -> processing -> responding -> idle
258
- *
259
- * Supports interruption: pressing hotkey during any state aborts
260
- * in-flight work and immediately transitions to listening.
261
- */
262
- declare class CursorBuddyClient {
263
- private endpoint;
264
- private options;
265
- private voiceCapture;
266
- private audioPlayback;
267
- private browserSpeech;
268
- private liveTranscription;
269
- private screenCapture;
270
- private pointerController;
271
- private stateMachine;
272
- private liveTranscript;
273
- private transcript;
274
- private response;
275
- private error;
276
- private abortController;
277
- private historyCommittedForTurn;
278
- private speechProviderForTurn;
279
- private screenshotPromise;
280
- private cachedSnapshot;
281
- private listeners;
282
- constructor(endpoint: string, options?: CursorBuddyClientOptions, services?: CursorBuddyServices);
283
- /**
284
- * Start listening for voice input.
285
- * Aborts any in-flight work from previous session.
286
- */
287
- startListening(): void;
288
- /**
289
- * Stop listening and process the voice input.
290
- */
291
- stopListening(): Promise<void>;
292
- /**
293
- * Enable or disable the buddy.
294
- */
295
- setEnabled(enabled: boolean): void;
296
- /**
297
- * Manually point at coordinates.
298
- */
299
- pointAt(x: number, y: number, label: string): void;
300
- /**
301
- * Dismiss the current pointing target.
302
- */
303
- dismissPointing(): void;
304
- /**
305
- * Reset to idle state and stop any in-progress work.
306
- */
307
- reset(): void;
308
- /**
309
- * Update buddy position to follow cursor.
310
- * Call this on cursor position changes.
311
- */
312
- updateCursorPosition(): void;
313
- /**
314
- * Subscribe to state changes.
315
- */
316
- subscribe(listener: () => void): () => void;
317
- /**
318
- * Get current state snapshot for React's useSyncExternalStore.
319
- * Returns a cached object to ensure referential stability.
320
- */
321
- getSnapshot(): CursorBuddySnapshot;
322
- /**
323
- * Build a new snapshot object.
324
- */
325
- private buildSnapshot;
326
- private abort;
327
- /**
328
- * Commit partial turn to history when interrupted.
329
- * Only commits if we have both transcript and response,
330
- * and haven't already committed for this turn.
331
- */
332
- private commitPartialHistory;
333
- private transcribe;
334
- /**
335
- * Stream the chat response, keep the visible text updated, and feed complete
336
- * speech segments into the TTS queue as soon as they are ready.
337
- */
338
- private chatAndSpeak;
339
- /**
340
- * Request server-side TTS audio for one text segment.
341
- */
342
- private synthesizeSpeech;
343
- /**
344
- * Resolve the initial speech provider for this turn.
345
- *
346
- * Decision tree:
347
- * 1. In `server` mode, always synthesize on the server.
348
- * 2. In `browser` mode, require browser speech support up front.
349
- * 3. In `auto` mode, prefer browser speech when available and keep that
350
- * choice cached so later segments stay on the same provider unless a
351
- * browser failure forces a one-way fallback to the server.
352
- */
353
- private prepareSpeechMode;
354
- /**
355
- * Prepare a playback task for one text segment.
356
- *
357
- * The queue calls this eagerly so server synthesis can overlap with the
358
- * currently playing segment, but the returned task is still executed in the
359
- * original enqueue order.
360
- */
361
- private prepareSpeechSegment;
362
- /**
363
- * Synthesize server audio immediately and return a playback task that reuses
364
- * the prepared blob later.
365
- */
366
- private prepareServerSpeechTask;
367
- /**
368
- * Return a browser playback task for one text segment.
369
- */
370
- private prepareBrowserSpeechTask;
371
- /**
372
- * Prepare a playback task for `auto` mode.
373
- *
374
- * We prefer the browser for low latency, but if browser speech fails for any
375
- * segment we permanently switch the remainder of the turn to server TTS so
376
- * later segments do not keep retrying the failing browser path.
377
- */
378
- private prepareAutoSpeechTask;
379
- /**
380
- * Read the current provider choice for `auto` mode, lazily defaulting to the
381
- * browser when supported and the server otherwise.
382
- */
383
- private getAutoSpeechProvider;
384
- private handleError;
385
- /**
386
- * Resolve the effective transcription mode for the current client.
387
- */
388
- private getTranscriptionMode;
389
- /**
390
- * Resolve the effective speech mode for the current client.
391
- */
392
- private getSpeechMode;
393
- /**
394
- * Decide whether speech should start before the full chat response is ready.
395
- */
396
- private isSpeechStreamingEnabled;
397
- /**
398
- * Decide whether this turn should attempt browser speech recognition.
399
- */
400
- private shouldAttemptBrowserTranscription;
401
- /**
402
- * Decide whether browser speech recognition is mandatory for this turn.
403
- */
404
- private isBrowserTranscriptionRequired;
405
- /**
406
- * Start the recorder and browser speech recognition together.
407
- *
408
- * The recorder always runs so we keep waveform updates and preserve a raw
409
- * audio backup for server fallback in `auto` mode.
410
- */
411
- private beginListeningSession;
412
- /**
413
- * Stop browser speech recognition and return the best final transcript it
414
- * produced for this turn.
415
- */
416
- private stopLiveTranscription;
417
- /**
418
- * Choose the transcript that should drive the turn.
419
- *
420
- * Decision tree:
421
- * 1. Use the browser transcript when it is available.
422
- * 2. In browser-only mode, fail if the browser produced nothing usable.
423
- * 3. In auto/server modes, fall back to the recorded audio upload.
424
- */
425
- private resolveTranscript;
426
- private updateResponse;
427
- private notify;
428
- }
429
- //#endregion
430
- 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 };
431
- //# sourceMappingURL=client-sjVVGYPU.d.mts.map
373
+ export { ToolCallState as _, CursorBuddySnapshot as a, ToolDisplayOptions as b, CursorRenderProps as c, SpeechBubbleRenderProps as d, VoiceEvent as f, ToolCallEvent as g, ToolBubbleRenderProps as h, CursorBuddyServices as i, Point as l, WaveformRenderProps as m, CursorBuddyClientOptions as n, CursorBuddySpeechConfig as o, VoiceState as p, CursorBuddyMediaMode as r, CursorBuddyTranscriptionConfig as s, BrowserSpeechPort as t, PointingTarget as u, ToolCallStatus as v, ToolResultEvent as x, ToolDisplayConfig as y };
374
+ //# sourceMappingURL=types-BU0Gegg2.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-BU0Gegg2.d.mts","names":[],"sources":["../src/core/tools/types.ts","../src/core/types.ts"],"mappings":";;AAGA;;KAAY,cAAA;;;AAWZ;UAAiB,aAAA;;EAEf,EAAA;EAAA;EAEA,QAAA;EAEA;EAAA,IAAA;EAEQ;EAAR,MAAA,EAAQ,cAAA;EAIR;EAFA,KAAA;EAMA;EAJA,MAAA;EAMc;EAJd,KAAA;EAUe;EARf,UAAA;;EAEA,cAAA;AAAA;;;;UAMe,qBAAA;EAUf;EARA,QAAA;EAYA;EAVA,IAAA;EAcA;EAZA,MAAA,EAAQ,cAAA;EAYD;EAVP,KAAA;EAgBgC;EAdhC,MAAA;EAkB6D;EAhB7D,KAAA;EAeI;EAbJ,OAAA;EAcoB;EAZpB,IAAA;EAY8C;EAV9C,OAAA;AAAA;;AAeF;;KATY,sBAAA;EAEN,KAAA;AAAA;EACA,IAAA;AAAA;EACA,MAAA,GAAS,KAAA,EAAO,qBAAA,KAA0B,KAAA,CAAM,SAAA;AAAA;;;;UAKrC,kBAAA;EAImB;EAFlC,IAAA;EAMA;EAJA,KAAA,cAAmB,IAAA,WAAe,MAAA,EAAQ,cAAA;EAIhC;EAFV,cAAA;EAEiD;EAAjD,MAAA,IAAU,KAAA,EAAO,qBAAA,KAA0B,KAAA,CAAM,SAAA;EAEtC;EAAX,OAAA,IAAW,KAAA,UAAe,IAAA,cAAkB,sBAAA;AAAA;;;AAO9C;;UAAiB,iBAAA;EAAA,CACd,QAAA,WAAmB,kBAAA;AAAA;AAMtB;;;AAAA,UAAiB,aAAA;EAEf;EAAA,EAAA;EAIA;EAFA,QAAA;EAEI;EAAJ,IAAA;AAAA;;;;UAMe,eAAA;EAMf;EAJA,EAAA;EAIM;EAFN,QAAA;;EAEA,MAAA;AAAA;;;;AA9GF;;KCAY,UAAA;;;ADWZ;KCNY,UAAA;EACN,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAe,KAAA,EAAO,KAAA;AAAA;;;;UAKX,cAAA;EDoBqB;EClBpC,CAAA;EDwBsB;ECtBtB,CAAA;EDoBA;EClBA,KAAA;AAAA;;;;UAMe,KAAA;EACf,CAAA;EACA,CAAA;AAAA;;AD8BF;;UCxBiB,gBAAA;ED4B8C;EC1B7D,SAAA;EDyBI;ECvBJ,KAAA;EDwBoB;ECtBpB,MAAA;EDsB8C;ECpB9C,aAAA;EDoB6D;EClB7D,cAAA;EDuBe;ECrBf,WAAA;;EAEA,eAAA,EAAiB,GAAA,SAAY,WAAA;AAAA;;;;KAuBnB,oBAAA;;;ADaZ;UCRiB,8BAAA;;;;ADejB;;;;;;;;;AAYA;ECbE,IAAA,GAAO,oBAAA;AAAA;;;;UAMQ,uBAAA;EDaT;;;;;AC9GR;;;;;AAKA;EAwGE,IAAA,GAAO,oBAAA;;;;;;;;;EAUP,cAAA;AAAA;;AAxGF;;UA8GiB,gBAAA;EACf,KAAA,IAAS,OAAA;EACT,IAAA,IAAQ,OAAA,CAAQ,IAAA;EAChB,OAAA,CAAQ,QAAA,GAAW,KAAA;EACnB,OAAA;AAAA;;AAtGF;;UA4GiB,iBAAA;EACf,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,MAAA,GAAS,WAAA,GAAc,OAAA;EACxC,IAAA;AAAA;;;;UAMe,qBAAA;EACf,WAAA;EACA,KAAA,IAAS,OAAA;EACT,IAAA,IAAQ,OAAA;EACR,SAAA,CAAU,QAAA,GAAW,IAAA;EACrB,OAAA;AAAA;;;;UAMe,iBAAA;EACf,WAAA;EACA,KAAA,CAAM,IAAA,UAAc,MAAA,GAAS,WAAA,GAAc,OAAA;EAC3C,IAAA;AAAA;;AAhFF;;UAsFiB,iBAAA;EACf,OAAA,IAAW,OAAA,CAAQ,gBAAA;AAAA;AAnErB;;;AAAA,UAyEiB,qBAAA;EACf,OAAA,CAAQ,MAAA,EAAQ,cAAA;EAChB,OAAA;EACA,UAAA;EACA,SAAA,CAAU,QAAA;EACV,oBAAA;AAAA;;;;UAMe,mBAAA;EACf,YAAA,GAAe,gBAAA;EACf,aAAA,GAAgB,iBAAA;EAChB,iBAAA,GAAoB,qBAAA;EACpB,aAAA,GAAgB,iBAAA;EAChB,aAAA,GAAgB,iBAAA;EAChB,iBAAA,GAAoB,qBAAA;AAAA;;;;UAML,iBAAA;EAhEf;EAkEA,KAAA,EAAO,UAAA;EAlEA;EAoEP,UAAA;EA9DgC;EAgEhC,QAAA;EA/DW;EAiEX,KAAA;AAAA;;;;UAMe,uBAAA;EAvEV;EAyEL,IAAA;EAzEiB;EA2EjB,SAAA;EA1EA;EA4EA,OAAA;AAAA;AAtEF;;;AAAA,UA4EiB,mBAAA;EA3Ef;EA6EA,UAAA;EA5ES;EA8ET,WAAA;AAAA;;;;UAMe,wBAAA;EAjFR;;AAMT;;;EAiFE,aAAA,GAAgB,8BAAA;EAhFhB;;;;;;EAuFA,MAAA,GAAS,uBAAA;EArFL;;AAMN;;EAoFE,WAAA,GALgC,iBAAA;EA9Ed;EAqFlB,YAAA,IAAgB,IAAA;EArFL;EAuFX,UAAA,IAAc,IAAA;EAvFqB;EAyFnC,OAAA,IAAW,MAAA,EAAQ,cAAA;EAnFJ;EAqFf,aAAA,IAAiB,KAAA,EAAO,UAAA;;EAExB,OAAA,IAAW,KAAA,EAAO,KAAA;EAtFlB;EAwFA,UAAA,IAAc,KAAA,EAFS,aAAA;EAtFf;EA0FR,YAAA,IAAgB,KAAA,EAF0C,eAAA;AAAA;;;;UAQ3C,mBAAA;EA5FK;EA8FpB,KAAA,EAAO,UAAA;EAxF2B;;;;EA6FlC,cAAA;EAzFgB;EA2FhB,UAAA;EAzFoB;EA2FpB,QAAA;EA3FyC;EA6FzC,KAAA,EAAO,KAAA;EAlGQ;EAoGf,UAAA;EAnGgB;EAqGhB,SAAA;EApGoB;EAsGpB,SAAA,EANY,aAAA;EA/FI;EAuGhB,eAAA,EAFgD,aAAA;EApGhC;EAwGhB,eAAA,EAFsD,aAAA;AAAA"}
@@ -42,4 +42,4 @@ interface CursorBuddyHandler {
42
42
  }
43
43
  //#endregion
44
44
  export { CursorBuddyHandlerConfig as n, CursorBuddyHandler as t };
45
- //# sourceMappingURL=types-BJfkApb_.d.mts.map
45
+ //# sourceMappingURL=types-ClkvIgAm.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-BJfkApb_.d.mts","names":[],"sources":["../src/server/types.ts"],"mappings":";;;;;AAKA;UAAiB,wBAAA;;EAEf,KAAA,EAAO,aAAA;EACP,qBAAA,GAAwB,MAAA;EAMV;;;;EAAd,WAAA,GAAc,WAAA;EACd,WAAA;EARA;;;;EAcA,kBAAA,GAAqB,kBAAA;EAPP;;;;EAad,MAAA,cAAoB,GAAA;IAAO,aAAA;EAAA;EAG3B;EAAA,KAAA,GAAQ,MAAA,SAAe,IAAA;EAAA;EAGvB,UAAA;AAAA;;AAMF;;UAAiB,kBAAA;EAEI;EAAnB,OAAA,GAAU,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EAAR;EAG/B,MAAA,EAAQ,wBAAA;AAAA"}
1
+ {"version":3,"file":"types-ClkvIgAm.d.mts","names":[],"sources":["../src/server/types.ts"],"mappings":";;;;;AAKA;UAAiB,wBAAA;;EAEf,KAAA,EAAO,aAAA;EACP,qBAAA,GAAwB,MAAA;EAMV;;;;EAAd,WAAA,GAAc,WAAA;EACd,WAAA;EARA;;;;EAcA,kBAAA,GAAqB,kBAAA;EAPP;;;;EAad,MAAA,cAAoB,GAAA;IAAO,aAAA;EAAA;EAG3B;EAAA,KAAA,GAAQ,MAAA,SAAe,IAAA;EAAA;EAGvB,UAAA;AAAA;;AAMF;;UAAiB,kBAAA;EAEI;EAAnB,OAAA,GAAU,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EAAR;EAG/B,MAAA,EAAQ,wBAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursor-buddy",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "AI-powered cursor companion for web apps",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -81,12 +81,13 @@
81
81
  "ai": "^6.0.158",
82
82
  "html2canvas-pro": "^2.0.2",
83
83
  "nanostores": "^1.2.0",
84
- "zod": "^3.24.0"
84
+ "zod": "^4.3.6"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@types/react": "^19.0.8",
88
88
  "@types/react-dom": "^19.2.3",
89
89
  "happy-dom": "^20.9.0",
90
+ "lightningcss": "^1.32.0",
90
91
  "react": "^19.0.0",
91
92
  "react-dom": "^19.0.0",
92
93
  "tsdown": "^0.21.7",