[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-96476":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":14,"forks30d":14,"starsTrendScore":17,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":24,"readmeContent":25,"aiSummary":9,"trendingCount":14,"starSnapshotCount":14,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},96476,"jev-voice-browser","moritzkremb\u002Fjev-voice-browser","moritzkremb","Control a real browser by voice. Jev (TypeSafe System One) decides intent + target in ~300 ms per spoken word; Playwright acts — often before you finish the sentence.",null,"JavaScript",194,27,103,0,49,91,189,4.34,"MIT License",false,"main",true,[],"2026-09-22 02:04:35","# voice-browser — talk to a real browser, it acts before you finish the sentence\n\nA Node app that controls a **headed Chromium window** (Playwright) by voice. Speech is streamed\nword by word from the browser's Web Speech API to a small Node server; on every partial transcript\nthe server asks **Jev** (TypeSafe's System One model, `jev-1.13.0`) one request with a dozen typed\nquestions — intent, target element, site, \"is the command complete?\", \"is this even addressed to\nme?\", \"is it destructive?\" — gets typed probabilities back in ~250–350 ms, and code decides whether\nto act, wait, ask, or ignore.\n\nJev never generates text. Search queries, typed text and URLs are extracted as candidate spans by\ncode and Jev only *picks* one, which is copied verbatim.\n\n```\n mic (Chrome, Web Speech API)          Node server (owns the API key)             controlled window\n ───────────────────────────    ws     ───────────────────────────────────         ──────────────────\n partial transcripts  ───────────────▶ debounce 200 ms                            headed Chromium via\n \"go to\"  \"go to wiki\"                 snapshot page (≤100 elements, e01..eNN) ◀── Playwright, persistent\n \"go to wikipedia\" (final)             ONE Jev request: 9–11 questions             profile, overlay\n                                       policy (thresholds in constants.js)  ───▶  highlight \u002F toast \u002F\n control page ◀─────────────────────── decision + bars + latency + cost            numbered candidates\n```\n\n## Run it\n\nRequirements: Node ≥ 20 (tested on 22), npm, Chrome or Edge for the microphone (the Web Speech API\nis not available in Firefox\u002FSafari). Real API calls cost ~$0.0002 each.\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fmoritzkremb\u002Fjev-voice-browser.git\ncd jev-voice-browser\nnpm install\nnpx playwright install chromium\ncp .env.example .env          # paste your TypeSafe API key (https:\u002F\u002Fconsole.typesafe.ai\u002Fkeys)\n.\u002Frun.sh                      # starts the server on http:\u002F\u002Flocalhost:8787\n```\n\nThen open **http:\u002F\u002Flocalhost:8787 in your normal Chrome**, click **Start mic**, allow the\nmicrophone, and speak. A separate Chromium window (the *controlled* browser) is opened by the server;\nthat is the one that acts. Keep the control page visible on a second screen \u002F half the screen for\nthe live probability bars.\n\nOptions: `.\u002Frun.sh --port 9000`, `--host 0.0.0.0` (LAN, see Security), `--start-url https:\u002F\u002F…`, `--headless` (CI), or attach to a Chrome\nyou already have running instead of launching one:\n\n```bash\n# start your Chrome with a debugging port, then:\n.\u002Frun.sh --cdp http:\u002F\u002F127.0.0.1:9222\n```\n\nSet the key yourself instead of `.env`: `export TYPESAFE_API_KEY=…` (legacy `JEV_API_KEY` is\nalso accepted) and `npm start`. The key is only ever read by the Node process; the control page\nnever sees it.\n\n**Security:** the server listens on `127.0.0.1` only. Anyone who can reach the control port can\ndrive the browser and spend your API credits, so only use `--host 0.0.0.0` on a network you trust.\nThe controlled Chromium uses a persistent profile in `.browser-profile\u002F` (gitignored) — don't log\ninto accounts there that you wouldn't want a mis-heard \"click place order\" to touch; destructive\nclicks require a spoken \"confirm\", but treat that as a convenience, not a guarantee.\n\nNo microphone? Type a command into the text box on the control page and press Enter.\n\n## What you can say\n\n| Say | What happens |\n| --- | --- |\n| \"go to wikipedia\" \u002F \"open youtube\" \u002F \"go to example dot com\" | navigates (site list or spoken domain, code owns the URLs) |\n| \"search for alan turing\" | uses the page's own search box if it has one (Wikipedia, YouTube…), else DuckDuckGo |\n| \"search youtube for lofi beats\" | site-specific search URL template |\n| \"click the first result\" \u002F \"click the new link\" \u002F \"open the comments tab\" | clicks the element Jev picked from the snapshot; ambiguous → numbered overlays, say \"two\" |\n| \"type hello world into the search box\" | types verbatim (Jev picked the span, code copies it) |\n| \"scroll down a bit\" \u002F \"scroll to the bottom\" \u002F \"scroll up a page\" | scroll with amount from a 3-level Score |\n| \"go back\" \u002F \"go forward\" \u002F \"reload\" | history |\n| \"open a new tab\" \u002F \"close this tab\" \u002F \"next tab\" | tabs |\n| \"click place order\" | destructive → toast asks you to say **\"confirm\"** (or \"cancel\") |\n| \"so anyway I think we should get lunch\" | ignored (`is_command` ≈ 0.02) |\n\nTwo commands in one breath work too: \"go to example dot com and click the more information link\".\n\n## How a decision is made\n\nEvery transcript update produces exactly one Jev request (`src\u002Fjev.js`). State:\n\n```json\n{ \"transcript\": \"click the first result\",\n  \"page\": { \"url\": \"...\", \"title\": \"...\", \"site\": \"duckduckgo\" },\n  \"elements\": [\"e02 combobox \\\"jev typesafe\\\" (placeholder: Search privately)\", \"e20 link \\\"TypeSafe — Jev\\\" → typesafe.ai\", \"...\"] }\n```\n\nQuestions (all in `src\u002Fconstants.js`, asked together, answered in parallel):\n\n| id | type | answers |\n| --- | --- | --- |\n| `intent` | Choice | navigate_url · search_web · click_element · type_into_field · select_option · press_enter · scroll_down\u002Fup · go_back\u002Fforward · reload · open\u002Fclose\u002Fswitch tab · confirm · cancel · none — each option has `{what, not_for, examples}` |\n| `target` | Choice | the element ids on the page + `none` |\n| `site` | Choice | google · duckduckgo · the_web · youtube · wikipedia · github · amazon · reddit · twitter_x · hacker_news · example_com · other_named_site · none |\n| `complete` | Noul | has the user finished the command? (lets us act on partial speech) |\n| `is_command` | Noul | is the user addressing the browser at all? |\n| `destructive` | Noul | would it submit \u002F buy \u002F delete \u002F send? |\n| `scroll_amount` | Score | a little · one page · to the end |\n| `text_span` | Choice | verbatim candidate spans extracted by regex (+ `none`) — only when the transcript has any |\n| `url_span` | Choice | domain-looking spans (+ `none`) — only when present |\n| `tab_direction` | Choice | next · previous · first · none |\n\nPolicy (`src\u002Fpolicy.js`, thresholds `T` in `constants.js`), shown live in the UI as a gate table:\n\n1. `is_command ≥ 0.5` else **ignore**\n2. `intent.confidence ≥ 0.55` and not `none` else **wait**\n3. `complete ≥ 0.6`, or 900 ms of silence, or the recognizer's final result — else **wait**\n4. free-text intents (search \u002F type) additionally wait for the final result or 600 ms silence, so a\n   query is never truncated (\"search for alan\" vs \"search for alan turing\")\n5. build the action in code: URL templates, search-box fallback, verbatim span copy\n6. click\u002Ftype targets need `target.confidence ≥ 0.45` and top probability ≥ 0.35, else the top 2–3\n   candidates get numbered overlays in the page and a spoken number picks one (no model call)\n7. `destructive ≥ 0.5` on a click → **confirm** (say \"confirm\" \u002F \"cancel\")\n\nRequests overlap: up to 2 in flight; older ones are cancelled with `AbortSignal`. A response for a\npartial transcript may still act if the words already commit to a closed-set action (\"go back\"),\nbut is never treated as final for free text.\n\n## Project layout\n\n```\nsrc\u002Fconstants.js   MODEL pin, thresholds, every question text — the one file to review on camera\nsrc\u002Fjev.js         builds state + questions, calls @typesafe-ai\u002Fsdk, returns answers\u002Flatency\u002Fusage\u002Fcost\nsrc\u002Fspans.js       candidate extraction (text payloads, spoken URLs, number words) — code, not Jev\nsrc\u002Fsnapshot.js    in-page element collector (tags data-vb-id), compaction + size guard, site detection\nsrc\u002Fpolicy.js      answers → act \u002F wait \u002F ignore \u002F confirm \u002F disambiguate, with reasons\nsrc\u002Fexecutor.js    Playwright actions + overlay feedback\nsrc\u002Fbrowser.js     launch headed Chromium (persistent profile) or attach via CDP; tabs\nsrc\u002Foverlay.js     injected highlight \u002F toast \u002F numbered badges\nsrc\u002Fcontroller.js  debounce, in-flight management, one action per utterance, chaining, stats\nsrc\u002Fserver.js      Express + ws, serves src\u002Fpublic\u002Findex.html (control page)\nscripts\u002Fdemo.js    word-by-word replay against real sites = end-to-end test\ntest\u002Funit\u002F         spans, snapshot compaction, policy (mocked Jev), controller (mocked Jev + browser)\ntest\u002Fintegration\u002F  27 real-API cases on captured page fixtures, prints pass rate + latency\n```\n\n## Tests and demo\n\n```bash\nnpm test                 # unit tests (no network)\nnpm run test:integration # real Jev calls on fixtures; prints pass rate (expects ≥ 90%)\nnpm run demo             # headed replay of 16 spoken commands against real sites, asserts URLs\nnpm run demo:ci          # same, headless; exit code 1 on failure\nnode scripts\u002Fdemo.js --headless --only 1,2,3 --word-ms 250\n```\n\nLatest measured (Sep 2026, from this machine): integration 27\u002F27 (100%), Jev latency avg ≈ 330 ms\n(p50 ≈ 300 ms, 3–6k input tokens per request; the first request of a process is ~700 ms for the\nTLS handshake), last-word→decision ≈ 300 ms including the 200 ms debounce, whole demo ≈ $0.01.\n\n## Notes and limitations\n\n- Web Speech API only in Chrome\u002FEdge; it sends audio to Google. Interim results arrive in bursts, so\n  \"acting before you finish\" is most visible on longer sentences.\n- One action per utterance; extra words after an executed command are treated as a new command\n  only if there are at least two of them.\n- Element snapshot is capped at 100 items (viewport first) and 60 chars of text each — deep pages\n  need a scroll before \"click …\" finds below-fold items. Elements inside iframes are not seen.\n- Sites with heavy bot protection (Google consent, some search engines in headless mode) may not\n  render results; the demo uses Wikipedia, example.com, Hacker News and DuckDuckGo.\n- `select_option` matches the option label in code by substring; `switch_tab` cycles.\n- Confidence gates are calibrated on `jev-1.13.0`; re-check `T` if you move the model alias.\n",2,"2026-09-20 02:30:11","CREATED_QUERY"]