@speechos/react 1.0.0 → 1.0.3

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.
@@ -17,17 +17,14 @@ export interface SpeechOSWidgetProps {
17
17
  * Optional user identifier for tracking
18
18
  */
19
19
  userId?: string;
20
- /**
21
- * Position of the widget on screen
22
- * @default 'bottom-center'
23
- */
24
- position?: "bottom-center" | "bottom-right" | "bottom-left";
25
20
  /**
26
21
  * Backend host URL (for development/testing)
27
22
  */
28
23
  host?: string;
29
24
  /**
30
- * Custom z-index for the widget overlay
25
+ * Custom z-index for the widget overlay.
26
+ * Note: This is handled by @speechos/client, not core SDK.
27
+ * @deprecated Use SpeechOS.init() from @speechos/client with zIndex instead
31
28
  */
32
29
  zIndex?: number;
33
30
  /**
@@ -98,4 +95,4 @@ declare global {
98
95
  * }
99
96
  * ```
100
97
  */
101
- export declare function SpeechOSWidget({ apiKey, userId, position, host, zIndex, debug, onTranscription, onEdit, onError, onShow, onHide, className, }: SpeechOSWidgetProps): React.ReactNode;
98
+ export declare function SpeechOSWidget({ apiKey, userId, host, zIndex, debug, onTranscription, onEdit, onError, onShow, onHide, className, }: SpeechOSWidgetProps): React.ReactNode;
@@ -17,17 +17,14 @@ export interface SpeechOSWidgetProps {
17
17
  * Optional user identifier for tracking
18
18
  */
19
19
  userId?: string;
20
- /**
21
- * Position of the widget on screen
22
- * @default 'bottom-center'
23
- */
24
- position?: "bottom-center" | "bottom-right" | "bottom-left";
25
20
  /**
26
21
  * Backend host URL (for development/testing)
27
22
  */
28
23
  host?: string;
29
24
  /**
30
- * Custom z-index for the widget overlay
25
+ * Custom z-index for the widget overlay.
26
+ * Note: This is handled by @speechos/client, not core SDK.
27
+ * @deprecated Use SpeechOS.init() from @speechos/client with zIndex instead
31
28
  */
32
29
  zIndex?: number;
33
30
  /**
@@ -98,4 +95,4 @@ declare global {
98
95
  * }
99
96
  * ```
100
97
  */
101
- export declare function SpeechOSWidget({ apiKey, userId, position, host, zIndex, debug, onTranscription, onEdit, onError, onShow, onHide, className, }: SpeechOSWidgetProps): React.ReactNode;
98
+ export declare function SpeechOSWidget({ apiKey, userId, host, zIndex, debug, onTranscription, onEdit, onError, onShow, onHide, className, }: SpeechOSWidgetProps): React.ReactNode;
@@ -5,29 +5,49 @@
5
5
  * Uses useSyncExternalStore for efficient state synchronization.
6
6
  */
7
7
  import React, { type ReactNode } from "react";
8
- import { type SpeechOSConfig, type SpeechOSState, type SpeechOSEventMap, type UnsubscribeFn } from "@speechos/core";
8
+ import { type SpeechOSCoreConfig, type SpeechOSState, type SpeechOSEventMap, type UnsubscribeFn, type CommandDefinition, type CommandResult } from "@speechos/core";
9
+ import type { FormDetectorInterface } from "@speechos/client";
10
+ import type { TextInputHandlerInterface } from "@speechos/client";
9
11
  /**
10
12
  * Context value exposed by SpeechOSProvider
11
13
  */
12
14
  export interface SpeechOSContextValue {
13
15
  state: SpeechOSState;
14
16
  isInitialized: boolean;
15
- init: (config: SpeechOSConfig) => void;
17
+ init: (config: SpeechOSCoreConfig) => void;
16
18
  dictate: () => Promise<string>;
17
19
  stopDictation: () => Promise<string>;
18
20
  edit: (text: string) => Promise<string>;
19
21
  stopEdit: () => Promise<string>;
22
+ command: (commands: CommandDefinition[]) => Promise<CommandResult | null>;
23
+ stopCommand: () => Promise<CommandResult | null>;
20
24
  cancel: () => Promise<void>;
21
- connect: () => Promise<void>;
22
- disconnect: () => Promise<void>;
23
- enableMicrophone: () => Promise<void>;
24
- waitUntilReady: () => Promise<void>;
25
- stopAndGetTranscript: () => Promise<string>;
26
- stopAndEdit: (originalText: string) => Promise<string>;
27
25
  on: <K extends keyof SpeechOSEventMap>(event: K, callback: (payload: SpeechOSEventMap[K]) => void) => UnsubscribeFn;
28
26
  off: <K extends keyof SpeechOSEventMap>(event: K, callback: (payload: SpeechOSEventMap[K]) => void) => void;
29
27
  }
30
28
  declare const SpeechOSContext: React.Context<SpeechOSContextValue | undefined>;
29
+ /**
30
+ * Extended config for React provider
31
+ * Includes client-specific options like form detection and text input handler
32
+ */
33
+ export interface SpeechOSReactConfig extends SpeechOSCoreConfig {
34
+ /** Command definitions for voice command matching */
35
+ commands?: CommandDefinition[];
36
+ /** Custom z-index for widget overlay (default: 999999) */
37
+ zIndex?: number;
38
+ /**
39
+ * Form detection behavior:
40
+ * - true (default): Enable automatic form field detection
41
+ * - false: Disable automatic detection (manual control only)
42
+ * - FormDetectorInterface: Custom implementation
43
+ */
44
+ formDetection?: boolean | FormDetectorInterface;
45
+ /**
46
+ * Custom text input handler for cursor/selection detection and text operations.
47
+ * Default: handles input, textarea, and contenteditable elements.
48
+ */
49
+ textInputHandler?: TextInputHandlerInterface;
50
+ }
31
51
  /**
32
52
  * Props for SpeechOSProvider
33
53
  */
@@ -35,8 +55,9 @@ export interface SpeechOSProviderProps {
35
55
  /**
36
56
  * Optional initial configuration.
37
57
  * If provided, SDK will be initialized automatically.
58
+ * Supports all core config options plus client-specific options like formDetection.
38
59
  */
39
- config?: SpeechOSConfig;
60
+ config?: SpeechOSReactConfig;
40
61
  children: ReactNode;
41
62
  }
42
63
  /**
package/dist/context.d.ts CHANGED
@@ -5,29 +5,49 @@
5
5
  * Uses useSyncExternalStore for efficient state synchronization.
6
6
  */
7
7
  import React, { type ReactNode } from "react";
8
- import { type SpeechOSConfig, type SpeechOSState, type SpeechOSEventMap, type UnsubscribeFn } from "@speechos/core";
8
+ import { type SpeechOSCoreConfig, type SpeechOSState, type SpeechOSEventMap, type UnsubscribeFn, type CommandDefinition, type CommandResult } from "@speechos/core";
9
+ import type { FormDetectorInterface } from "@speechos/client";
10
+ import type { TextInputHandlerInterface } from "@speechos/client";
9
11
  /**
10
12
  * Context value exposed by SpeechOSProvider
11
13
  */
12
14
  export interface SpeechOSContextValue {
13
15
  state: SpeechOSState;
14
16
  isInitialized: boolean;
15
- init: (config: SpeechOSConfig) => void;
17
+ init: (config: SpeechOSCoreConfig) => void;
16
18
  dictate: () => Promise<string>;
17
19
  stopDictation: () => Promise<string>;
18
20
  edit: (text: string) => Promise<string>;
19
21
  stopEdit: () => Promise<string>;
22
+ command: (commands: CommandDefinition[]) => Promise<CommandResult | null>;
23
+ stopCommand: () => Promise<CommandResult | null>;
20
24
  cancel: () => Promise<void>;
21
- connect: () => Promise<void>;
22
- disconnect: () => Promise<void>;
23
- enableMicrophone: () => Promise<void>;
24
- waitUntilReady: () => Promise<void>;
25
- stopAndGetTranscript: () => Promise<string>;
26
- stopAndEdit: (originalText: string) => Promise<string>;
27
25
  on: <K extends keyof SpeechOSEventMap>(event: K, callback: (payload: SpeechOSEventMap[K]) => void) => UnsubscribeFn;
28
26
  off: <K extends keyof SpeechOSEventMap>(event: K, callback: (payload: SpeechOSEventMap[K]) => void) => void;
29
27
  }
30
28
  declare const SpeechOSContext: React.Context<SpeechOSContextValue | undefined>;
29
+ /**
30
+ * Extended config for React provider
31
+ * Includes client-specific options like form detection and text input handler
32
+ */
33
+ export interface SpeechOSReactConfig extends SpeechOSCoreConfig {
34
+ /** Command definitions for voice command matching */
35
+ commands?: CommandDefinition[];
36
+ /** Custom z-index for widget overlay (default: 999999) */
37
+ zIndex?: number;
38
+ /**
39
+ * Form detection behavior:
40
+ * - true (default): Enable automatic form field detection
41
+ * - false: Disable automatic detection (manual control only)
42
+ * - FormDetectorInterface: Custom implementation
43
+ */
44
+ formDetection?: boolean | FormDetectorInterface;
45
+ /**
46
+ * Custom text input handler for cursor/selection detection and text operations.
47
+ * Default: handles input, textarea, and contenteditable elements.
48
+ */
49
+ textInputHandler?: TextInputHandlerInterface;
50
+ }
31
51
  /**
32
52
  * Props for SpeechOSProvider
33
53
  */
@@ -35,8 +55,9 @@ export interface SpeechOSProviderProps {
35
55
  /**
36
56
  * Optional initial configuration.
37
57
  * If provided, SDK will be initialized automatically.
58
+ * Supports all core config options plus client-specific options like formDetection.
38
59
  */
39
- config?: SpeechOSConfig;
60
+ config?: SpeechOSReactConfig;
40
61
  children: ReactNode;
41
62
  }
42
63
  /**
@@ -8,4 +8,5 @@ export { useSpeechOSState } from "./useSpeechOSState.js";
8
8
  export { useSpeechOSEvents } from "./useSpeechOSEvents.js";
9
9
  export { useDictation, type UseDictationResult } from "./useDictation.js";
10
10
  export { useEdit, type UseEditResult } from "./useEdit.js";
11
- export { useTranscription, type UseTranscriptionResult } from "./useTranscription.js";
11
+ export { useCommand, type UseCommandResult } from "./useCommand.js";
12
+ export { useSpeechOSWidget, type UseSpeechOSWidgetResult } from "./useSpeechOSWidget.js";
@@ -8,4 +8,5 @@ export { useSpeechOSState } from "./useSpeechOSState.js";
8
8
  export { useSpeechOSEvents } from "./useSpeechOSEvents.js";
9
9
  export { useDictation, type UseDictationResult } from "./useDictation.js";
10
10
  export { useEdit, type UseEditResult } from "./useEdit.js";
11
- export { useTranscription, type UseTranscriptionResult } from "./useTranscription.js";
11
+ export { useCommand, type UseCommandResult } from "./useCommand.js";
12
+ export { useSpeechOSWidget, type UseSpeechOSWidgetResult } from "./useSpeechOSWidget.js";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * useCommand - Simplified hook for voice command workflows
3
+ *
4
+ * Provides a simple start/stop interface for voice command matching.
5
+ */
6
+ import type { CommandDefinition, CommandResult } from "@speechos/core";
7
+ /**
8
+ * Return type for useCommand hook
9
+ */
10
+ export interface UseCommandResult {
11
+ /** Start command listening - begins recording */
12
+ start: (commands: CommandDefinition[]) => Promise<void>;
13
+ /** Stop command listening - ends recording and returns matched command */
14
+ stop: () => Promise<CommandResult | null>;
15
+ /** Whether currently listening for commands */
16
+ isListening: boolean;
17
+ /** Whether processing the command */
18
+ isProcessing: boolean;
19
+ /** The matched command result (null if no match or not yet processed) */
20
+ result: CommandResult | null;
21
+ /** Any error that occurred */
22
+ error: string | null;
23
+ /** Clear the result and error state */
24
+ clear: () => void;
25
+ }
26
+ /**
27
+ * Simplified hook for voice command workflows
28
+ *
29
+ * Provides an easy-to-use interface for voice command matching
30
+ * with automatic state management.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * const commands = [
35
+ * { name: 'scroll_down', description: 'Scroll the page down' },
36
+ * { name: 'open_settings', description: 'Open the settings modal' },
37
+ * {
38
+ * name: 'search',
39
+ * description: 'Search for something',
40
+ * arguments: [{ name: 'query', description: 'The search query' }]
41
+ * },
42
+ * ];
43
+ *
44
+ * function VoiceCommands() {
45
+ * const { start, stop, isListening, isProcessing, result, error } = useCommand();
46
+ *
47
+ * const handleCommand = async () => {
48
+ * await start(commands);
49
+ * };
50
+ *
51
+ * const handleStop = async () => {
52
+ * const matched = await stop();
53
+ * if (matched) {
54
+ * console.log('Matched command:', matched.name, matched.arguments);
55
+ * }
56
+ * };
57
+ *
58
+ * return (
59
+ * <div>
60
+ * <button onClick={isListening ? handleStop : handleCommand} disabled={isProcessing}>
61
+ * {isListening ? 'Execute' : 'Say Command'}
62
+ * </button>
63
+ * {isProcessing && <span>Processing...</span>}
64
+ * {result && <p>Command: {result.name}</p>}
65
+ * {error && <p style={{ color: 'red' }}>{error}</p>}
66
+ * </div>
67
+ * );
68
+ * }
69
+ * ```
70
+ *
71
+ * @returns Command controls and state
72
+ */
73
+ export declare function useCommand(): UseCommandResult;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * useCommand - Simplified hook for voice command workflows
3
+ *
4
+ * Provides a simple start/stop interface for voice command matching.
5
+ */
6
+ import type { CommandDefinition, CommandResult } from "@speechos/core";
7
+ /**
8
+ * Return type for useCommand hook
9
+ */
10
+ export interface UseCommandResult {
11
+ /** Start command listening - begins recording */
12
+ start: (commands: CommandDefinition[]) => Promise<void>;
13
+ /** Stop command listening - ends recording and returns matched command */
14
+ stop: () => Promise<CommandResult | null>;
15
+ /** Whether currently listening for commands */
16
+ isListening: boolean;
17
+ /** Whether processing the command */
18
+ isProcessing: boolean;
19
+ /** The matched command result (null if no match or not yet processed) */
20
+ result: CommandResult | null;
21
+ /** Any error that occurred */
22
+ error: string | null;
23
+ /** Clear the result and error state */
24
+ clear: () => void;
25
+ }
26
+ /**
27
+ * Simplified hook for voice command workflows
28
+ *
29
+ * Provides an easy-to-use interface for voice command matching
30
+ * with automatic state management.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * const commands = [
35
+ * { name: 'scroll_down', description: 'Scroll the page down' },
36
+ * { name: 'open_settings', description: 'Open the settings modal' },
37
+ * {
38
+ * name: 'search',
39
+ * description: 'Search for something',
40
+ * arguments: [{ name: 'query', description: 'The search query' }]
41
+ * },
42
+ * ];
43
+ *
44
+ * function VoiceCommands() {
45
+ * const { start, stop, isListening, isProcessing, result, error } = useCommand();
46
+ *
47
+ * const handleCommand = async () => {
48
+ * await start(commands);
49
+ * };
50
+ *
51
+ * const handleStop = async () => {
52
+ * const matched = await stop();
53
+ * if (matched) {
54
+ * console.log('Matched command:', matched.name, matched.arguments);
55
+ * }
56
+ * };
57
+ *
58
+ * return (
59
+ * <div>
60
+ * <button onClick={isListening ? handleStop : handleCommand} disabled={isProcessing}>
61
+ * {isListening ? 'Execute' : 'Say Command'}
62
+ * </button>
63
+ * {isProcessing && <span>Processing...</span>}
64
+ * {result && <p>Command: {result.name}</p>}
65
+ * {error && <p style={{ color: 'red' }}>{error}</p>}
66
+ * </div>
67
+ * );
68
+ * }
69
+ * ```
70
+ *
71
+ * @returns Command controls and state
72
+ */
73
+ export declare function useCommand(): UseCommandResult;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * useSpeechOSWidget - Hook for programmatic widget control
3
+ *
4
+ * Provides methods to show, hide, and position the SpeechOS widget
5
+ * without relying on automatic form field detection.
6
+ */
7
+ /**
8
+ * Result type for useSpeechOSWidget hook
9
+ */
10
+ export interface UseSpeechOSWidgetResult {
11
+ /**
12
+ * Show widget positioned for a specific element.
13
+ * On mobile, widget anchors below the element.
14
+ * On desktop, widget stays at center bottom but tracks element for dictation/edit.
15
+ */
16
+ showFor: (element: HTMLElement) => void;
17
+ /**
18
+ * Attach widget to persistently track a specific element.
19
+ * Equivalent to showFor() - widget tracks element until detach() is called.
20
+ */
21
+ attachTo: (element: HTMLElement) => void;
22
+ /**
23
+ * Detach widget from any attached element.
24
+ * Returns widget to default positioning (center bottom of screen).
25
+ */
26
+ detach: () => void;
27
+ /**
28
+ * Show the widget (default position)
29
+ */
30
+ show: () => void;
31
+ /**
32
+ * Hide the widget
33
+ */
34
+ hide: () => void;
35
+ /**
36
+ * Whether the widget is currently visible
37
+ */
38
+ isVisible: boolean;
39
+ /**
40
+ * Whether the widget is currently expanded (showing action bubbles)
41
+ */
42
+ isExpanded: boolean;
43
+ /**
44
+ * The currently focused/attached element, if any
45
+ */
46
+ focusedElement: HTMLElement | null;
47
+ }
48
+ /**
49
+ * Hook for programmatic widget control
50
+ *
51
+ * Use this hook when you want to control the widget manually instead of
52
+ * relying on automatic form field detection.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * function MyComponent() {
57
+ * const { showFor, hide, isVisible } = useSpeechOSWidget();
58
+ * const textareaRef = useRef<HTMLTextAreaElement>(null);
59
+ *
60
+ * return (
61
+ * <div>
62
+ * <textarea ref={textareaRef} />
63
+ * <button onClick={() => showFor(textareaRef.current!)}>
64
+ * Enable Voice Input
65
+ * </button>
66
+ * {isVisible && (
67
+ * <button onClick={hide}>Hide Widget</button>
68
+ * )}
69
+ * </div>
70
+ * );
71
+ * }
72
+ * ```
73
+ */
74
+ export declare function useSpeechOSWidget(): UseSpeechOSWidgetResult;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * useSpeechOSWidget - Hook for programmatic widget control
3
+ *
4
+ * Provides methods to show, hide, and position the SpeechOS widget
5
+ * without relying on automatic form field detection.
6
+ */
7
+ /**
8
+ * Result type for useSpeechOSWidget hook
9
+ */
10
+ export interface UseSpeechOSWidgetResult {
11
+ /**
12
+ * Show widget positioned for a specific element.
13
+ * On mobile, widget anchors below the element.
14
+ * On desktop, widget stays at center bottom but tracks element for dictation/edit.
15
+ */
16
+ showFor: (element: HTMLElement) => void;
17
+ /**
18
+ * Attach widget to persistently track a specific element.
19
+ * Equivalent to showFor() - widget tracks element until detach() is called.
20
+ */
21
+ attachTo: (element: HTMLElement) => void;
22
+ /**
23
+ * Detach widget from any attached element.
24
+ * Returns widget to default positioning (center bottom of screen).
25
+ */
26
+ detach: () => void;
27
+ /**
28
+ * Show the widget (default position)
29
+ */
30
+ show: () => void;
31
+ /**
32
+ * Hide the widget
33
+ */
34
+ hide: () => void;
35
+ /**
36
+ * Whether the widget is currently visible
37
+ */
38
+ isVisible: boolean;
39
+ /**
40
+ * Whether the widget is currently expanded (showing action bubbles)
41
+ */
42
+ isExpanded: boolean;
43
+ /**
44
+ * The currently focused/attached element, if any
45
+ */
46
+ focusedElement: HTMLElement | null;
47
+ }
48
+ /**
49
+ * Hook for programmatic widget control
50
+ *
51
+ * Use this hook when you want to control the widget manually instead of
52
+ * relying on automatic form field detection.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * function MyComponent() {
57
+ * const { showFor, hide, isVisible } = useSpeechOSWidget();
58
+ * const textareaRef = useRef<HTMLTextAreaElement>(null);
59
+ *
60
+ * return (
61
+ * <div>
62
+ * <textarea ref={textareaRef} />
63
+ * <button onClick={() => showFor(textareaRef.current!)}>
64
+ * Enable Voice Input
65
+ * </button>
66
+ * {isVisible && (
67
+ * <button onClick={hide}>Hide Widget</button>
68
+ * )}
69
+ * </div>
70
+ * );
71
+ * }
72
+ * ```
73
+ */
74
+ export declare function useSpeechOSWidget(): UseSpeechOSWidgetResult;