cursor-buddy 0.0.1 → 0.0.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.
package/README.md CHANGED
@@ -8,7 +8,8 @@ AI-powered cursor companion for web apps. Push-to-talk voice assistant that can
8
8
  - **Screenshot context** — AI sees your current viewport
9
9
  - **Voice responses** — Text-to-speech playback
10
10
  - **Cursor pointing** — AI can point at UI elements it references
11
- - **Framework agnostic** — Adapter-based server, works with Next.js, Express, Hono
11
+ - **Voice interruption** — Start talking again to cut off current response
12
+ - **Framework agnostic** — Core client works without React, adapter-based architecture
12
13
  - **Customizable** — CSS variables, custom components, headless mode
13
14
 
14
15
  ## Installation
@@ -53,7 +54,7 @@ Add the `<CursorBuddy />` component to your app.
53
54
 
54
55
  ```tsx
55
56
  // app/layout.tsx
56
- import { CursorBuddy } from "cursor-buddy/client"
57
+ import { CursorBuddy } from "cursor-buddy/react"
57
58
 
58
59
  export default function RootLayout({ children }) {
59
60
  return (
@@ -112,7 +113,6 @@ createCursorBuddyHandler({
112
113
 
113
114
  // Optional
114
115
  hotkey="ctrl+alt" // Push-to-talk hotkey (default: "ctrl+alt")
115
- muted={false} // Disable TTS playback
116
116
  container={element} // Portal container (default: document.body)
117
117
 
118
118
  // Custom components
@@ -159,7 +159,7 @@ Cursor buddy styles are customizable via CSS variables. Override them in your st
159
159
  Replace default components with your own:
160
160
 
161
161
  ```tsx
162
- import { CursorBuddy, type CursorRenderProps } from "cursor-buddy/client"
162
+ import { CursorBuddy, type CursorRenderProps } from "cursor-buddy/react"
163
163
 
164
164
  function MyCursor({ state, rotation, scale }: CursorRenderProps) {
165
165
  return (
@@ -183,7 +183,7 @@ For full control, use the provider and hook directly:
183
183
  import {
184
184
  CursorBuddyProvider,
185
185
  useCursorBuddy
186
- } from "cursor-buddy/client"
186
+ } from "cursor-buddy/react"
187
187
 
188
188
  function App() {
189
189
  return (
@@ -200,7 +200,6 @@ function MyCustomUI() {
200
200
  response, // Latest AI response
201
201
  audioLevel, // 0-1, for waveform visualization
202
202
  isEnabled,
203
- isSpeaking,
204
203
  isPointing,
205
204
  error,
206
205
 
@@ -208,8 +207,8 @@ function MyCustomUI() {
208
207
  startListening,
209
208
  stopListening,
210
209
  setEnabled,
211
- speak, // Manually trigger TTS
212
210
  pointAt, // Manually point at coordinates
211
+ dismissPointing,
213
212
  reset,
214
213
  } = useCursorBuddy()
215
214
 
@@ -227,6 +226,32 @@ function MyCustomUI() {
227
226
  }
228
227
  ```
229
228
 
229
+ ## Framework-Agnostic Usage
230
+
231
+ For non-React environments, use the core client directly:
232
+
233
+ ```ts
234
+ import { CursorBuddyClient } from "cursor-buddy"
235
+
236
+ const client = new CursorBuddyClient("/api/cursor-buddy", {
237
+ onStateChange: (state) => console.log("State:", state),
238
+ onTranscript: (text) => console.log("Transcript:", text),
239
+ onResponse: (text) => console.log("Response:", text),
240
+ onError: (err) => console.error("Error:", err),
241
+ })
242
+
243
+ // Subscribe to state changes
244
+ client.subscribe(() => {
245
+ const snapshot = client.getSnapshot()
246
+ console.log(snapshot)
247
+ })
248
+
249
+ // Trigger voice interaction
250
+ client.startListening()
251
+ // ... user speaks ...
252
+ client.stopListening()
253
+ ```
254
+
230
255
  ## Render Props Types
231
256
 
232
257
  ```ts
@@ -250,6 +275,15 @@ interface WaveformRenderProps {
250
275
 
251
276
  ## API Reference
252
277
 
278
+ ### Core Exports (`cursor-buddy`)
279
+
280
+ | Export | Description |
281
+ |--------|-------------|
282
+ | `CursorBuddyClient` | Framework-agnostic client class |
283
+ | `VoiceState` | Type: `"idle" \| "listening" \| "processing" \| "responding"` |
284
+ | `PointingTarget` | Type: `{ x: number, y: number, label: string }` |
285
+ | `Point` | Type: `{ x: number, y: number }` |
286
+
253
287
  ### Server Exports (`cursor-buddy/server`)
254
288
 
255
289
  | Export | Description |
@@ -265,7 +299,7 @@ interface WaveformRenderProps {
265
299
  |--------|-------------|
266
300
  | `toNextJsHandler` | Convert handler to Next.js App Router format |
267
301
 
268
- ### Client Exports (`cursor-buddy/client`)
302
+ ### React Exports (`cursor-buddy/react`)
269
303
 
270
304
  | Export | Description |
271
305
  |--------|-------------|
@@ -273,25 +307,17 @@ interface WaveformRenderProps {
273
307
  | `CursorBuddyProvider` | Headless provider for custom UI |
274
308
  | `useCursorBuddy` | Hook to access state and actions |
275
309
 
276
- ### Types (`cursor-buddy/client`)
310
+ ### Types (`cursor-buddy/react`)
277
311
 
278
312
  | Export | Description |
279
313
  |--------|-------------|
280
314
  | `CursorBuddyProps` | Props for `<CursorBuddy />` |
281
315
  | `CursorBuddyProviderProps` | Props for `<CursorBuddyProvider />` |
282
- | `CursorBuddyContextValue` | Return type of `useCursorBuddy()` |
316
+ | `UseCursorBuddyReturn` | Return type of `useCursorBuddy()` |
283
317
  | `CursorRenderProps` | Props passed to custom cursor |
284
318
  | `SpeechBubbleRenderProps` | Props passed to custom speech bubble |
285
319
  | `WaveformRenderProps` | Props passed to custom waveform |
286
320
 
287
- ### Core Types (`cursor-buddy`)
288
-
289
- | Export | Description |
290
- |--------|-------------|
291
- | `VoiceState` | `"idle" \| "listening" \| "processing" \| "responding"` |
292
- | `PointingTarget` | `{ x: number, y: number, label: string }` |
293
- | `Point` | `{ x: number, y: number }` |
294
-
295
321
  ## How It Works
296
322
 
297
323
  1. User holds the hotkey (Ctrl+Alt)
@@ -303,11 +329,15 @@ interface WaveformRenderProps {
303
329
  7. AI responds with text, optionally including `[POINT:x,y:label]` tag in screenshot-image coordinates
304
330
  8. Response is spoken via TTS
305
331
  9. If pointing tag present, coordinates are mapped back to the live viewport and the cursor animates to the target location
332
+ 10. **If user presses hotkey again at any point, current response is interrupted**
333
+
334
+ ## TODOs
306
335
 
307
- ## TODOS
336
+ - [ ] More test coverage for internal services
337
+ - [ ] Add `muted` prop for TTS control
308
338
  - [ ] Faster transcription -> chat -> TTS flow (eg single endpoint instead of 3 calls)
309
339
  - [ ] Composition pattern for custom components
310
- - [ ] Better hotkey management
340
+ - [ ] Better hotkey registering code
311
341
 
312
342
  ## License
313
343