{"_id":"@actionkit/rn-voice-actions","_rev":"2-6ff8a517f54a1f7759cbb33cf969f6b3","name":"@actionkit/rn-voice-actions","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@actionkit/rn-voice-actions","version":"0.1.0","keywords":["react-native","voice","speech","commands","actions","voice-control","speech-recognition","voice-commands","actionkit"],"license":"MIT","_id":"@actionkit/rn-voice-actions@0.1.0","maintainers":[{"name":"rasjonell","email":"info.gurgen@gmail.com"}],"homepage":"https://github.com/AKCodeWorks/rn-voice-actions#readme","bugs":{"url":"https://github.com/AKCodeWorks/rn-voice-actions/issues"},"dist":{"shasum":"982014ee8865318bcd50f4149f182d2d439c9bbb","tarball":"https://registry.npmjs.org/@actionkit/rn-voice-actions/-/rn-voice-actions-0.1.0.tgz","fileCount":23,"integrity":"sha512-1VcTSJ8uNS23/MAKS0TSt0fDyFGFrLJM//+VyVx82cthc6aMKjOQA1UC2HfXcAK6LfOLbPEqNpz+dbf1yZMRQA==","signatures":[{"sig":"MEUCIAza2vGG1TDFocy/kkdntp5fZNYnGLF1k04+5s9ebXkpAiEA8FkNmFYSj/yoyminmgnNL49X2b+MBIki5d7/e6i8Alc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95623},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","require":"./dist/react.cjs"},"./adapters":{"types":"./dist/adapters.d.ts","import":"./dist/adapters.js","require":"./dist/adapters.cjs"}},"gitHead":"04068e34bb030adce5f1b48e32449c3cef9a2a26","scripts":{"build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"rasjonell","email":"info.gurgen@gmail.com"},"repository":{"url":"git+https://github.com/AKCodeWorks/rn-voice-actions.git","type":"git"},"_npmVersion":"10.9.3","description":"Voice-driven action engine for React Native. Define actions, match voice commands, and execute handlers with confidence scoring.","directories":{},"_nodeVersion":"22.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.6.3","@types/react":"^19.2.10","@react-native-community/voice":">=1.1.0"},"peerDependencies":{"react":">=18.0.0","@react-native-community/voice":">=1.1.0"},"peerDependenciesMeta":{"react":{"optional":true},"@react-native-community/voice":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/rn-voice-actions_0.1.0_1773910207757_0.8793585363429601","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@actionkit/rn-voice-actions","version":"0.1.1","description":"Voice-driven action engine for React Native. Define actions, match voice commands, and execute handlers with confidence scoring.","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","require":"./dist/react.cjs"},"./adapters":{"types":"./dist/adapters.d.ts","import":"./dist/adapters.js","require":"./dist/adapters.cjs"}},"scripts":{"build":"tsup","clean":"rm -rf dist","prepublishOnly":"npm run build","typecheck":"tsc --noEmit"},"keywords":["react-native","voice","speech","commands","actions","voice-control","speech-recognition","voice-commands","actionkit"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/get-actionkit/rn-voice-actions.git"},"homepage":"https://github.com/get-actionkit/rn-voice-actions#readme","bugs":{"url":"https://github.com/get-actionkit/rn-voice-actions/issues"},"peerDependencies":{"react":">=18.0.0","@react-native-community/voice":">=1.1.0"},"peerDependenciesMeta":{"react":{"optional":true},"@react-native-community/voice":{"optional":true}},"devDependencies":{"@react-native-community/voice":">=1.1.0","@types/react":"^19.2.10","tsup":"^8.5.1","typescript":"^5.6.3"},"_id":"@actionkit/rn-voice-actions@0.1.1","gitHead":"04068e34bb030adce5f1b48e32449c3cef9a2a26","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-NGicFYw/l1SkYFf3cqTYxuEw8cso1KSamagX7o2RGcqm6moRMxkF3Yxz8gClzbAG+J/xburd3ti41nvFJTa3dA==","shasum":"c86671e6b76e6b59af553339cbde21b73edd56e9","tarball":"https://registry.npmjs.org/@actionkit/rn-voice-actions/-/rn-voice-actions-0.1.1.tgz","fileCount":23,"unpackedSize":95629,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCOm1kPyktxIznbriehDw7Soc+/ulYWoL5V0PpEDR4+BAIhAMsVHIItyVputakISjgcHmbQG03aY8CmvwKjTUIM/rBB"}]},"_npmUser":{"name":"rasjonell","email":"info.gurgen@gmail.com"},"directories":{},"maintainers":[{"name":"rasjonell","email":"info.gurgen@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rn-voice-actions_0.1.1_1773910853930_0.5813362589520388"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-19T08:50:07.668Z","modified":"2026-03-19T09:00:54.209Z","0.1.0":"2026-03-19T08:50:07.970Z","0.1.1":"2026-03-19T09:00:54.080Z"},"bugs":{"url":"https://github.com/get-actionkit/rn-voice-actions/issues"},"license":"MIT","homepage":"https://github.com/get-actionkit/rn-voice-actions#readme","keywords":["react-native","voice","speech","commands","actions","voice-control","speech-recognition","voice-commands","actionkit"],"repository":{"type":"git","url":"git+https://github.com/get-actionkit/rn-voice-actions.git"},"description":"Voice-driven action engine for React Native. Define actions, match voice commands, and execute handlers with confidence scoring.","maintainers":[{"name":"rasjonell","email":"info.gurgen@gmail.com"}],"readme":"# @actionkit/rn-voice-actions\n\nVoice-driven action engine for React Native. Define actions with phrase patterns, match voice input with confidence scoring, and execute handlers — all with a minimal, composable API.\n\n## Features\n\n- **Action registry** — declare actions with multiple trigger phrases\n- **Smart matching** — exact, substring, and token-based Jaccard similarity scoring\n- **Confidence thresholds** — filter matches by configurable minimum confidence\n- **React bindings** — provider + hook for session state and capture lifecycle\n- **Pluggable input** — swap voice providers or use a static stub for testing\n- **Event system** — subscribe to `capturing`, `recognized`, `matched`, `no_match`, `executed`, and `error` events\n- **TypeScript-first** — full type safety with generics for action context\n- **Dual format** — ships ESM and CommonJS\n\n## Installation\n\n```bash\nnpm install @actionkit/rn-voice-actions\n```\n\nFor voice input on React Native, also install:\n\n```bash\nnpm install @react-native-community/voice\n```\n\n> `react` and `@react-native-community/voice` are optional peer dependencies. The core engine works standalone without either.\n\n## Quick start\n\n```tsx\nimport { createActions } from \"@actionkit/rn-voice-actions\";\nimport { ActionsProvider, useActions } from \"@actionkit/rn-voice-actions/react\";\nimport { createReactNativeVoiceProvider } from \"@actionkit/rn-voice-actions/adapters\";\nimport Voice from \"@react-native-community/voice\";\n\n// 1. Create an input provider\nconst input = createReactNativeVoiceProvider({ Voice, locale: \"en-US\" });\n\n// 2. Define actions and create the engine\nconst engine = createActions({\n  actions: [\n    {\n      id: \"nav.home\",\n      phrases: [\"go home\", \"home\", \"back to home\"],\n      handler: ({ router }) => router.navigate(\"Home\"),\n    },\n    {\n      id: \"nav.settings\",\n      phrases: [\"open settings\", \"settings\"],\n      handler: ({ router }) => router.navigate(\"Settings\"),\n    },\n  ],\n  threshold: 0.6,\n  getContext: () => ({ router }),\n  input,\n});\n\n// 3. Wrap your app\nexport default function App() {\n  return (\n    <ActionsProvider engine={engine}>\n      <MicButton />\n    </ActionsProvider>\n  );\n}\n\n// 4. Use the hook\nfunction MicButton() {\n  const { state, startCapture, stopCapture } = useActions();\n\n  return (\n    <Pressable onPressIn={startCapture} onPressOut={stopCapture}>\n      <Text>{state.status === \"capturing\" ? \"Listening...\" : \"Hold to speak\"}</Text>\n    </Pressable>\n  );\n}\n```\n\n## Package exports\n\n| Import path | Description |\n|---|---|\n| `@actionkit/rn-voice-actions` | Core engine, types, resolver, and utilities |\n| `@actionkit/rn-voice-actions/react` | `ActionsProvider` and `useActions` hook |\n| `@actionkit/rn-voice-actions/adapters` | Input providers (React Native Voice, static stub) |\n\n## API\n\n### `createActions(config)`\n\nCreates an action engine instance.\n\n```ts\nconst engine = createActions({\n  actions: Action[],          // required — array of action definitions\n  threshold: number,          // optional — minimum confidence to match (default: 0.55)\n  resolver: Resolver | \"basic\", // optional — custom resolver function (default: \"basic\")\n  getContext: () => Context,  // optional — returns context passed to handlers\n  input: InputProvider,       // optional — input source for voice capture\n});\n```\n\n**Returns:** `Actions` object with `resolve()`, `runAction()`, `on()`, `off()`, `emit()`.\n\n### `Action`\n\n```ts\ntype Action<C> = {\n  id: string;                        // unique action identifier\n  phrases: string[];                 // trigger phrases to match against\n  handler: (ctx: C) => void | Promise<void>; // executed on match\n  enabled?: (ctx: C) => boolean;     // optional gate — skip when false\n  meta?: {\n    description?: string;\n    category?: string;\n  };\n};\n```\n\n### `engine.resolve(input, context?)`\n\nMatch an input string against registered actions. Returns a `MatchResult`:\n\n```ts\n// Successful match\n{ type: \"match\", actionId: \"nav.home\", confidence: 1.0 }\n\n// No match\n{ type: \"no_match\", confidence: 0.3, candidates: [...] }\n```\n\n### `engine.runAction(match, context?)`\n\nExecute the handler for a matched action.\n\n### Built-in resolver scoring\n\n| Match type | Confidence |\n|---|---|\n| Exact match | `1.0` |\n| Substring match | `0.8` |\n| Token Jaccard similarity | up to `0.7` |\n\nActions below the `threshold` are filtered out. You can replace the resolver entirely with a custom function.\n\n---\n\n## React integration\n\n### `ActionsProvider`\n\nWraps your component tree and manages capture lifecycle.\n\n```tsx\n<ActionsProvider\n  engine={engine}       // required — engine from createActions()\n  input={inputProvider}  // optional — override engine's input provider\n  locale=\"en-US\"        // optional — locale for speech recognition\n  onEvent={(event, payload) => {}} // optional — callback for all events\n>\n  {children}\n</ActionsProvider>\n```\n\n### `useActions()`\n\nAccess the engine, session state, and capture controls.\n\n```ts\nconst {\n  engine,       // the action engine instance\n  state,        // { status, input?, partial?, match?, error? }\n  last,         // summary of last completed session\n  startCapture, // begin listening\n  stopCapture,  // stop listening and process input\n  cancel,       // cancel current session\n} = useActions();\n```\n\n**`state.status`** cycles through: `idle` → `capturing` → `processing` → `executing` → `idle`\n\n---\n\n## Adapters\n\n### `createReactNativeVoiceProvider(options)`\n\nWraps `@react-native-community/voice` as an `InputProvider`.\n\n```ts\nimport { createReactNativeVoiceProvider } from \"@actionkit/rn-voice-actions/adapters\";\nimport Voice from \"@react-native-community/voice\";\n\nconst input = createReactNativeVoiceProvider({\n  Voice,              // required — the Voice module\n  locale: \"en-US\",    // optional — default locale\n  onError: (err) => {}, // optional — error callback\n});\n```\n\n### `createStaticInputProvider(input)`\n\nReturns a fixed string on every capture. Useful for testing.\n\n```ts\nimport { createStaticInputProvider } from \"@actionkit/rn-voice-actions/adapters\";\n\nconst input = createStaticInputProvider(\"open settings\");\n```\n\n### Custom input provider\n\nImplement the `InputProvider` interface to support any input source:\n\n```ts\ntype InputProvider = {\n  start: (opts?: { locale?: string }) => Promise<void>;\n  stop: () => Promise<{ input: string }>;\n  cancel?: () => Promise<void>;\n  onPartial?: (cb: (partial: string) => void) => () => void;\n};\n```\n\n---\n\n## Events\n\nSubscribe to engine events directly or via the `onEvent` prop on `ActionsProvider`.\n\n```ts\nconst unsub = engine.on(\"matched\", ({ input, match, context }) => {\n  console.log(`Matched \"${input}\" → ${match.actionId} (${match.confidence})`);\n});\n\n// Clean up\nunsub();\n```\n\n| Event | Payload |\n|---|---|\n| `capturing` | `{ locale? }` |\n| `recognized` | `{ input }` |\n| `matched` | `{ input, match, context }` |\n| `no_match` | `{ input, result, context }` |\n| `executed` | `{ input, actionId, context }` |\n| `error` | `{ error }` |\n\n---\n\n## Custom resolver\n\nReplace the built-in resolver with your own matching logic:\n\n```ts\nconst engine = createActions({\n  actions,\n  resolver: ({ input, actions, threshold, context }) => {\n    // Your matching logic here\n    // Return: { type: \"match\", actionId, confidence }\n    //     or: { type: \"no_match\", confidence, candidates }\n  },\n});\n```\n\n---\n\n## Example project\n\nA full Expo Router example with voice-controlled navigation is included in [`examples/voice-navigation`](./examples/voice-navigation).\n\n```bash\n# From repo root\nnpm install\nnpm run build\n\n# Run the example\ncd examples/voice-navigation\nnpm install\nnpx expo prebuild --platform ios\nnpx expo run:ios\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}