macOS visual gesture & voice control
17
stars
316
commits
Swift
primary language
Sep 3, 2026
updated
Touch-free hand control for your Mac
Pawvis turns your webcam into a pointing device that works from thin air. Raise your open hand anywhere the camera can see it and the cursor follows; dip a finger to click, hold it down to drag, fold two fingers to scroll. Nothing under your palm, nothing to touch: your hand is the mouse. There's also a voice mode, in beta: talk to your Mac by name ("Pawvis, open Safari"), with the aim of growing into an accessibility-grade voice control more intuitive and capable than the built-in one.
Hand tracking runs entirely on-device with Apple's Vision framework; speech recognition is Apple's on-device engine; and free-form visual commands are resolved by on-device Apple Intelligence. By default, nothing you do leaves your Mac; the one exception is the opt-in agent hand-off below.
⬇ Download Pawvis for macOS
Signed and notarized · macOS 14+ · unzip and drag to Applications
Watch the demo film on YouTube
[!IMPORTANT] Pawvis really does control your Mac. It moves the cursor and posts real clicks, drags and scrolls, so an accidental finger dip is an accidental click, and a click lands on whatever is under the cursor at that moment (Send, Delete, Confirm). Treat it like handing someone else your mouse. Give it a few minutes somewhere harmless, like the Finder or a scratch document, until the gestures feel deliberate, and keep the menu bar toggle in reach: tracking stops the moment you switch it off, and the cursor parks whenever you close your hand or take it out of the camera's view. With voice control on, spoken commands do the same thing, and a misheard sentence is still a command. Pawvis is provided as is, without warranty of any kind: its developer accepts no liability for any action taken with it, intentional or not, or for any resulting loss or damage. Please use it responsibly.
Your hands are tracked whenever tracking is on, but the cursor only follows once you show an open hand: all four fingers up, thumb free. Close it into a fist for a moment, or take it out of view, to park the cursor again; the claw fades while it's parked. That keeps a hand that's merely visible (resting, typing, gesturing) from dragging the cursor around. Settings → Tracking switches back to "Any detected hand" if you'd rather have no trigger at all, or all the way to "Never — custom gestures only", which keeps the mouse untouched entirely: your hands become a remote that only fires the gestures you've assigned.
Once you have it, your hand is the mouse: the cursor rides your palm, and your fingers are the buttons. Everything below is tunable in Settings → Mouse.
The on-screen claw is your cursor: open while pointing, retracted and purple while the left button is held, blue for the right button, pink for the middle button, ringed in light blue while scrolling, faded while control is parked, with a ring that tightens as your click forms and a pulse confirming every click. Small dots mark each detected fingertip.
The menu bar icon opens a live status panel (hands seen, whether control is armed, voice-control state, and a camera picker once more than one camera is around) plus a Gesture Guide window that walks through every gesture.
Off by default while in beta. Enable it in Settings → Voice (Beta),
then press Start next to Voice control in the menu bar. Address Pawvis
by its wake word (default Pawvis, configurable; mishearings are
tolerated). Filler before it is fine too, like "Um, Pawvis, open Chrome",
and a garbled wake word still gets a second look from on-device Apple
Intelligence before Pawvis gives up on the command. Every command starts
with the wake word. Speech without it is ignored and never typed or
displayed. Commands are understood by a fast built-in grammar first, then
by on-device Apple Intelligence, and only genuinely visual requests drive
the screen step by step:
| Say | Pawvis does |
|---|---|
| "Pawvis, go to heresalexandria dot com" or "open discord dot com in Chrome" | Navigates there in the frontmost browser (via the address bar), or in a named app; falls back to your default browser, saying so, if you don't name one or it isn't found. Non-URL targets become a web search. |
| "Pawvis, type good morning" | Types exactly that text into the focused app. One-shot, no lingering dictation mode. |
| "Pawvis, press command shift T" | Presses any key or shortcut: enter, tab, escape, arrows, page up/down, F-keys, letters and digits with modifiers. |
| "Pawvis, open Notes" | Launches (or brings forward) an app, with fuzzy name matching. |
| "Pawvis, switch to Chrome" | Brings a running app forward. |
| "Pawvis, click / right click / double click" | Clicks at the pointer. |
| "Pawvis, scroll down / up a page" | Scrolls at the pointer. |
| "Pawvis, pause / play" | Presses the hardware play/pause key. macOS routes it to whatever's actually playing, not necessarily the frontmost app. |
| "Pawvis, close the window / minimize / new tab / copy / paste / undo / save / select all / quit Safari" | Instant window and edit commands, no AI round-trip. |
| "Pawvis, anything else" | On-device Apple Intelligence carries it out step by step: it reads the screen (accessibility + OCR, menus included), does the next action, looks again, and repeats until the request is done, up to 8 steps. Multi-step commands work: "open Notes and start a new note", "select the pawvis project and start a new conversation". A bottom-right panel streams each step with a Cancel button. |
| "Pawvis, stop" | Cancels the running command mid-flight: a navigation, a chained sequence, or a step-by-step run. With nothing running, turns voice control off. |
| "Pawvis, stop listening" | Turns voice control off. |
You can chain several commands into one sentence and Pawvis runs each step in order, like "Pawvis, pause this, open a new tab, and go to youtube dot com".
Speech recognition is Apple's on-device engine: private, free, no API key, no cloud (SpeechAnalyzer on macOS 26+, SFSpeechRecognizer before that). The step-by-step autopilot needs macOS 26 with Apple Intelligence enabled; everything else works without it. Autopilot runs verify each step actually happened before reporting a command done, rather than taking the model's word for it.
Settings → Voice can hand every command to an installed agent CLI (Claude Code or Codex) instead of the on-device brain. "Pawvis, anything" then pipes everything after the wake word to the agent, asked to perform it via computer use, as a headless auto-approved run in the background. While it runs, a panel at the bottom-right of the screen streams the agent's output live with a Cancel button (running sessions are also listed, and cancellable, under Settings → Voice → Background agent sessions), and the outcome, success or failure, always flashes in the top-of-screen capsule. Only "Pawvis, stop listening" stays local, so you can always shut it off instantly. Pausing after the wake word is fine: a bare "Pawvis" keeps listening a few seconds for the command, and if dictation mangles the wake word ("Paw this…"), the on-device model confirms it was meant for Pawvis and recovers the command before the hand-off.
By default the hand-off confirms first: the command is read back in the capsule ("Send to Claude Code: …?") and sent only after you say "Pawvis yes". "Pawvis no" cancels it, ten seconds of silence cancels it, and a new command replaces it; the read-back can be switched off in Settings → Voice. Agent runs also go one at a time (a second command while one is running is refused with a notice, not queued behind your back), and every hand-off is recorded with its outcome in a local log only your account can read (Settings → Voice → Open agent log).
[!WARNING] The agent relays are the sharpest thing in Pawvis. They do not ask. Claude Code and Codex are launched with their own permission prompts turned off (
--dangerously-skip-permissions,--dangerously-bypass-approvals-and-sandbox), so nothing pauses to confirm anything: the agent simply carries out what it was handed, with your user account, your files, your logged-in sessions and your credentials. That covers deleting or rewriting files, installing software, running shell commands, opening apps, and sending things on your behalf. Speech recognition is not perfect, and a misheard command is still executed. It is also the one mode that sends what you say beyond your Mac, to the agent CLI you picked. It is off by default, and Pawvis makes you accept this warning in a dialog before it will turn on. The spoken read-back above is the one check standing in front of a send, it can be switched off, and once a command is sent nothing asks again. Turning it on is your call and your responsibility: no liability is accepted for what an agent does with your machine, however it was asked.
Download Pawvis.zip
(always the latest release), unzip, and drag Pawvis.app to your
Applications folder. Homebrew users: a cask scaffold lives in
Casks/pawvis.rb, pending submission to homebrew/cask.
Pawvis starts with you after every login, so gesture control is just there. Turn it off in Settings → General → Launch Pawvis at login (or in System Settings → General → Login Items; Pawvis won't put itself back).
Pawvis checks for updates once a day and can install them itself. A new version announces itself in a macOS notification, once per version, with an Install… button that opens Settings → About where the release notes and the one-click install live. Check Now on that page runs the check on demand.
Any camera macOS can see works: the one built into your Mac, a USB webcam, or your iPhone as a Continuity Camera. Automatic (the default) is the built-in camera, and Pawvis never switches cameras on its own. When macOS offers your iPhone (nearby, signed in to the same Apple Account, over a cable or not) it simply appears in the camera picker in Settings → General and in the menu bar, next to any webcam, and using it is one pick. A picked camera stays yours: if it unplugs or walks away, tracking rides the built-in camera until it returns, then goes back to it.
One thing to know about the iPhone: Continuity Camera uses its rear camera (the lenses on the back), not the selfie camera, so point the back of the phone at you, screen facing away. If Pawvis says the camera shows no image, the lens is looking at nothing (a phone lying face-down, or a covered webcam); aim it at you and tracking resumes on its own. Apple does not let a Mac app use the iPhone's front camera, so there is no front/rear choice for the phone.
On first run Pawvis asks for:
Releases are signed with a Developer ID and notarized by Apple, so they open normally: no right-click → Open, and the Accessibility permission you grant carries across updates.
Requires macOS 14+ and the Xcode toolchain.
make app # release build → build/Pawvis.app
open build/Pawvis.app
swift test # the full unit suite, keep it green
swift build # debug build
Every icon asset (app icon, .icns, menu bar glyph, claw cursor) is derived
from the hand-drawn claw.png by one deterministic script. Re-running it on an
unchanged claw.png reproduces the committed art byte for byte:
make icon # == swift scripts/process_claw.swift
See AGENTS.md for architecture notes, the settings-UI rules, and the hard-won gesture-engine constraints.
Sources/
PawvisCore/ pure logic, unit-tested, no AppKit/AVFoundation
Geometry/ Vec2 · One Euro filter · interaction-box mapper
Hands/ 21-landmark model · pinch/dip/curl metrics
Gestures/ GestureEngine: frames → clicks, drags, scrolls, cursor moves
+ the custom one-shot gestures (wiggles, held poses, flings)
+ user-trained gestures (recorded takes → matched templates)
Actions/ gesture actions · typed-shortcut parsing · window placement math
VoiceControl/ wake-word + command parser · spoken URLs & key chords
Update/ semantic versions · check / offer / notify policy
Config/ settings tree (field-tolerant decoding)
Camera/ camera selection policy · idle throttle · stall clock · attention gate
Pawvis/ the menu bar app
Camera/ AVCaptureSession · Continuity Camera hand-over · Vision hand pose
Control/ CGEvent mouse + keyboard synthesis
Overlay/ click-through claw cursor and indicators
VoiceControl/ on-device speech engine · command executor ·
screen context (AX + OCR) · Apple Intelligence resolver
Update/ update checking · self-update · the "new version" banner
Support/ permissions · logging · theme
App/ UI/ menu bar, settings, gesture guide
The gesture engine is deterministic and clock-free, with all timing coming from frame timestamps, so click chaining, drag timing, hysteresis, debounce and tracking-loss recovery are covered by unit tests rather than by hand.
~/Library/Application Support/Pawvis/agent-log.jsonl, readable only by
your account), so you can always see exactly what was sent.MIT
316 commits
Swift
91.5%
HTML
5.3%
Shell
1.3%
Python
1.3%
macOS visual gesture & voice control
17
stars
316
commits
Swift
primary language
Sep 3, 2026
updated
Touch-free hand control for your Mac
Pawvis turns your webcam into a pointing device that works from thin air. Raise your open hand anywhere the camera can see it and the cursor follows; dip a finger to click, hold it down to drag, fold two fingers to scroll. Nothing under your palm, nothing to touch: your hand is the mouse. There's also a voice mode, in beta: talk to your Mac by name ("Pawvis, open Safari"), with the aim of growing into an accessibility-grade voice control more intuitive and capable than the built-in one.
Hand tracking runs entirely on-device with Apple's Vision framework; speech recognition is Apple's on-device engine; and free-form visual commands are resolved by on-device Apple Intelligence. By default, nothing you do leaves your Mac; the one exception is the opt-in agent hand-off below.
⬇ Download Pawvis for macOS
Signed and notarized · macOS 14+ · unzip and drag to Applications
Watch the demo film on YouTube
[!IMPORTANT] Pawvis really does control your Mac. It moves the cursor and posts real clicks, drags and scrolls, so an accidental finger dip is an accidental click, and a click lands on whatever is under the cursor at that moment (Send, Delete, Confirm). Treat it like handing someone else your mouse. Give it a few minutes somewhere harmless, like the Finder or a scratch document, until the gestures feel deliberate, and keep the menu bar toggle in reach: tracking stops the moment you switch it off, and the cursor parks whenever you close your hand or take it out of the camera's view. With voice control on, spoken commands do the same thing, and a misheard sentence is still a command. Pawvis is provided as is, without warranty of any kind: its developer accepts no liability for any action taken with it, intentional or not, or for any resulting loss or damage. Please use it responsibly.
Your hands are tracked whenever tracking is on, but the cursor only follows once you show an open hand: all four fingers up, thumb free. Close it into a fist for a moment, or take it out of view, to park the cursor again; the claw fades while it's parked. That keeps a hand that's merely visible (resting, typing, gesturing) from dragging the cursor around. Settings → Tracking switches back to "Any detected hand" if you'd rather have no trigger at all, or all the way to "Never — custom gestures only", which keeps the mouse untouched entirely: your hands become a remote that only fires the gestures you've assigned.
Once you have it, your hand is the mouse: the cursor rides your palm, and your fingers are the buttons. Everything below is tunable in Settings → Mouse.
The on-screen claw is your cursor: open while pointing, retracted and purple while the left button is held, blue for the right button, pink for the middle button, ringed in light blue while scrolling, faded while control is parked, with a ring that tightens as your click forms and a pulse confirming every click. Small dots mark each detected fingertip.
The menu bar icon opens a live status panel (hands seen, whether control is armed, voice-control state, and a camera picker once more than one camera is around) plus a Gesture Guide window that walks through every gesture.
Off by default while in beta. Enable it in Settings → Voice (Beta),
then press Start next to Voice control in the menu bar. Address Pawvis
by its wake word (default Pawvis, configurable; mishearings are
tolerated). Filler before it is fine too, like "Um, Pawvis, open Chrome",
and a garbled wake word still gets a second look from on-device Apple
Intelligence before Pawvis gives up on the command. Every command starts
with the wake word. Speech without it is ignored and never typed or
displayed. Commands are understood by a fast built-in grammar first, then
by on-device Apple Intelligence, and only genuinely visual requests drive
the screen step by step:
| Say | Pawvis does |
|---|---|
| "Pawvis, go to heresalexandria dot com" or "open discord dot com in Chrome" | Navigates there in the frontmost browser (via the address bar), or in a named app; falls back to your default browser, saying so, if you don't name one or it isn't found. Non-URL targets become a web search. |
| "Pawvis, type good morning" | Types exactly that text into the focused app. One-shot, no lingering dictation mode. |
| "Pawvis, press command shift T" | Presses any key or shortcut: enter, tab, escape, arrows, page up/down, F-keys, letters and digits with modifiers. |
| "Pawvis, open Notes" | Launches (or brings forward) an app, with fuzzy name matching. |
| "Pawvis, switch to Chrome" | Brings a running app forward. |
| "Pawvis, click / right click / double click" | Clicks at the pointer. |
| "Pawvis, scroll down / up a page" | Scrolls at the pointer. |
| "Pawvis, pause / play" | Presses the hardware play/pause key. macOS routes it to whatever's actually playing, not necessarily the frontmost app. |
| "Pawvis, close the window / minimize / new tab / copy / paste / undo / save / select all / quit Safari" | Instant window and edit commands, no AI round-trip. |
| "Pawvis, anything else" | On-device Apple Intelligence carries it out step by step: it reads the screen (accessibility + OCR, menus included), does the next action, looks again, and repeats until the request is done, up to 8 steps. Multi-step commands work: "open Notes and start a new note", "select the pawvis project and start a new conversation". A bottom-right panel streams each step with a Cancel button. |
| "Pawvis, stop" | Cancels the running command mid-flight: a navigation, a chained sequence, or a step-by-step run. With nothing running, turns voice control off. |
| "Pawvis, stop listening" | Turns voice control off. |
You can chain several commands into one sentence and Pawvis runs each step in order, like "Pawvis, pause this, open a new tab, and go to youtube dot com".
Speech recognition is Apple's on-device engine: private, free, no API key, no cloud (SpeechAnalyzer on macOS 26+, SFSpeechRecognizer before that). The step-by-step autopilot needs macOS 26 with Apple Intelligence enabled; everything else works without it. Autopilot runs verify each step actually happened before reporting a command done, rather than taking the model's word for it.
Settings → Voice can hand every command to an installed agent CLI (Claude Code or Codex) instead of the on-device brain. "Pawvis, anything" then pipes everything after the wake word to the agent, asked to perform it via computer use, as a headless auto-approved run in the background. While it runs, a panel at the bottom-right of the screen streams the agent's output live with a Cancel button (running sessions are also listed, and cancellable, under Settings → Voice → Background agent sessions), and the outcome, success or failure, always flashes in the top-of-screen capsule. Only "Pawvis, stop listening" stays local, so you can always shut it off instantly. Pausing after the wake word is fine: a bare "Pawvis" keeps listening a few seconds for the command, and if dictation mangles the wake word ("Paw this…"), the on-device model confirms it was meant for Pawvis and recovers the command before the hand-off.
By default the hand-off confirms first: the command is read back in the capsule ("Send to Claude Code: …?") and sent only after you say "Pawvis yes". "Pawvis no" cancels it, ten seconds of silence cancels it, and a new command replaces it; the read-back can be switched off in Settings → Voice. Agent runs also go one at a time (a second command while one is running is refused with a notice, not queued behind your back), and every hand-off is recorded with its outcome in a local log only your account can read (Settings → Voice → Open agent log).
[!WARNING] The agent relays are the sharpest thing in Pawvis. They do not ask. Claude Code and Codex are launched with their own permission prompts turned off (
--dangerously-skip-permissions,--dangerously-bypass-approvals-and-sandbox), so nothing pauses to confirm anything: the agent simply carries out what it was handed, with your user account, your files, your logged-in sessions and your credentials. That covers deleting or rewriting files, installing software, running shell commands, opening apps, and sending things on your behalf. Speech recognition is not perfect, and a misheard command is still executed. It is also the one mode that sends what you say beyond your Mac, to the agent CLI you picked. It is off by default, and Pawvis makes you accept this warning in a dialog before it will turn on. The spoken read-back above is the one check standing in front of a send, it can be switched off, and once a command is sent nothing asks again. Turning it on is your call and your responsibility: no liability is accepted for what an agent does with your machine, however it was asked.
Download Pawvis.zip
(always the latest release), unzip, and drag Pawvis.app to your
Applications folder. Homebrew users: a cask scaffold lives in
Casks/pawvis.rb, pending submission to homebrew/cask.
Pawvis starts with you after every login, so gesture control is just there. Turn it off in Settings → General → Launch Pawvis at login (or in System Settings → General → Login Items; Pawvis won't put itself back).
Pawvis checks for updates once a day and can install them itself. A new version announces itself in a macOS notification, once per version, with an Install… button that opens Settings → About where the release notes and the one-click install live. Check Now on that page runs the check on demand.
Any camera macOS can see works: the one built into your Mac, a USB webcam, or your iPhone as a Continuity Camera. Automatic (the default) is the built-in camera, and Pawvis never switches cameras on its own. When macOS offers your iPhone (nearby, signed in to the same Apple Account, over a cable or not) it simply appears in the camera picker in Settings → General and in the menu bar, next to any webcam, and using it is one pick. A picked camera stays yours: if it unplugs or walks away, tracking rides the built-in camera until it returns, then goes back to it.
One thing to know about the iPhone: Continuity Camera uses its rear camera (the lenses on the back), not the selfie camera, so point the back of the phone at you, screen facing away. If Pawvis says the camera shows no image, the lens is looking at nothing (a phone lying face-down, or a covered webcam); aim it at you and tracking resumes on its own. Apple does not let a Mac app use the iPhone's front camera, so there is no front/rear choice for the phone.
On first run Pawvis asks for:
Releases are signed with a Developer ID and notarized by Apple, so they open normally: no right-click → Open, and the Accessibility permission you grant carries across updates.
Requires macOS 14+ and the Xcode toolchain.
make app # release build → build/Pawvis.app
open build/Pawvis.app
swift test # the full unit suite, keep it green
swift build # debug build
Every icon asset (app icon, .icns, menu bar glyph, claw cursor) is derived
from the hand-drawn claw.png by one deterministic script. Re-running it on an
unchanged claw.png reproduces the committed art byte for byte:
make icon # == swift scripts/process_claw.swift
See AGENTS.md for architecture notes, the settings-UI rules, and the hard-won gesture-engine constraints.
Sources/
PawvisCore/ pure logic, unit-tested, no AppKit/AVFoundation
Geometry/ Vec2 · One Euro filter · interaction-box mapper
Hands/ 21-landmark model · pinch/dip/curl metrics
Gestures/ GestureEngine: frames → clicks, drags, scrolls, cursor moves
+ the custom one-shot gestures (wiggles, held poses, flings)
+ user-trained gestures (recorded takes → matched templates)
Actions/ gesture actions · typed-shortcut parsing · window placement math
VoiceControl/ wake-word + command parser · spoken URLs & key chords
Update/ semantic versions · check / offer / notify policy
Config/ settings tree (field-tolerant decoding)
Camera/ camera selection policy · idle throttle · stall clock · attention gate
Pawvis/ the menu bar app
Camera/ AVCaptureSession · Continuity Camera hand-over · Vision hand pose
Control/ CGEvent mouse + keyboard synthesis
Overlay/ click-through claw cursor and indicators
VoiceControl/ on-device speech engine · command executor ·
screen context (AX + OCR) · Apple Intelligence resolver
Update/ update checking · self-update · the "new version" banner
Support/ permissions · logging · theme
App/ UI/ menu bar, settings, gesture guide
The gesture engine is deterministic and clock-free, with all timing coming from frame timestamps, so click chaining, drag timing, hysteresis, debounce and tracking-loss recovery are covered by unit tests rather than by hand.
~/Library/Application Support/Pawvis/agent-log.jsonl, readable only by
your account), so you can always see exactly what was sent.MIT
316 commits
Swift
91.5%
HTML
5.3%
Shell
1.3%
Python
1.3%