Turn an unused controller into an inspectable control surface for vibe coding.
Early prototype. Built and tested on macOS; the Tauri + Rust architecture is intentionally portable, but Windows input and window-switching have not yet been validated.
-
Download the
.dmgfor your Apple Silicon Mac from GitHub Releases. -
Open it and drag
VibeCon.appto Applications. -
This preview is ad-hoc signed but is not Apple-notarized yet. macOS may show an "Apple cannot verify" warning. Run the following once in Terminal after moving the app to Applications:
xattr -dr com.apple.quarantine "/Applications/VibeCon.app" -
Open
VibeConfrom Applications, then grant Accessibility only when you enable the experimental window-switch mapping.
Only run this command for a release downloaded from this repository. Developer ID signing and Apple notarization are planned for a future public release.
VibeCon starts from a simple idea: a Joy-Con—or another controller you already own—can be a better physical control surface for AI-assisted coding than an expensive, opaque keyboard.
Before it automates anything, VibeCon makes the controller observable: raw HID reports, live sticks, button highlights, sampling, and local labels. Then you can opt into a small, reviewable mapping.
Joy-Con window switching in action. Click to view the source video.
- Detect paired Joy-Con (L) and Joy-Con (R) devices through the native Tauri/Rust HID backend.
- Inspect one or both controllers at once; grouped logs keep a single timestamp with aligned L/R report rows.
- Decode native
0x30and macOS compact0x3FJoy-Con reports, including button bitfields and the observed eight-way HAT profile. - Surface the first raw accelerometer / gyroscope sample from native
0x30reports. These values are intentionally uncalibrated observation data, not motion gestures yet. - Visualize both Joy-Cons in CSS: sticks move live; held controls glow and taps briefly persist as afterglow.
- Choose a log policy: key operations, legacy 75 ms snapshots, 60/30/10 Hz samples, or every report; clear the visible log whenever needed.
- Label captured reports as stick positions or button press/release samples. Labels are stored locally in
~/.vibecon/annotations.jsonland shown again for matching reports. - Preset-based macOS mappings: choose Code, Codex Cowork, Inspect Only, or the opt-in Keyboard Focus experiment. The first two can switch windows with left-stick right/left and focus Codex with Joy-Con (L) D-pad Up / Joy-Con (R) X. Keyboard Focus sends Tab / Shift+Tab / Space to the foreground app. Every preset and binding is opt-in, stored in
~/.vibecon/mappings.json, and inactive on the Debug page. - Experimental Joy-Con output: a manual, short Test selected Joy-Con vibration pulse is available on Mappings. It is never triggered from a binding or task event, and any HID write failure is shown instead of retried.
On the current macOS Bluetooth HID path, compact 0x3F reports expose Joy-Con (L)'s stick as an eight-way HAT: values 0–7 are directions and 8 is neutral. Button fields are bitmasks—decode each byte with bitwise AND/OR, not as one additive HEX value.
Requires current Node.js, pnpm, and a Rust toolchain.
cd /Users/carbon/Desktop/vibecon
pnpm install
pnpm tauri devPair a Joy-Con from System Settings → Bluetooth first. In VibeCon, click Refresh controllers, select one or both Joy-Cons, then move a stick or press a button.
Do not use
pnpm devfor controller testing. It starts only the browser UI, without Tauri's Rust backend or local HID access.
- On Debug, select the controller you want to use. Select both Joy-Cons if you want both Codex-focus shortcuts.
- Open Mappings, choose a preset, then enable its master switch and any bindings you want. Code offers window navigation; Codex Cowork adds the two Codex-focus buttons; Inspect Only deliberately sends no macOS actions; Keyboard Focus sends Tab / Shift+Tab / Space to the foreground app. Debug rendering and logging pause while this page is active, but the HID reader remains active for mappings.
- For window switching, grant Accessibility to VibeCon. The Mappings page can open the exact System Settings pane if it is missing.
Window switching posts a native macOS Quartz shortcut, so Accessibility is the only permission it requires. Focusing Codex uses the macOS application launcher and does not require Accessibility.
Mappings are readable JSON at ~/.vibecon/mappings.json. The Copy Agent Prompt button gives a coding agent the schema and safety boundary. VibeCon accepts only its known Joy-Con controls and these safe actions: window_previous, window_next, focus_codex, focus_next, focus_previous, and activate_focused; it never runs arbitrary shell commands from a mapping file. Reset defaults restores the four built-in presets.
Keyboard Focus is deliberately keyboard-based rather than a full accessibility-tree controller: it works wherever the foreground app supports standard Tab navigation and is subject to that app's own focus rules.
pnpm build # TypeScript + Vite
cd src-tauri && cargo check # Rust/Tauri/HID backendsrc/App.vue Vue debug and mapping UI
src/components/JoyCon.vue Live CSS controller visualizer
src-tauri/src/lib.rs HID stream, Joy-Con decoding, native commands
docs/images/ Logo and README screenshots
For the current release candidate's real-device checks, see the 0.0.4 manual QA list.
The desktop UI and controller logic are not tied to Swift or macOS APIs. However, the current window mapping is macOS-only and Windows HID behavior still needs real-device testing. Windows support is a product goal—not a claim of current compatibility.
- Profiles and calibration for Joy-Con, DualSense, Xbox, and 8BitDo.
- More deliberate mappings, with clear per-platform permissions.
- Spatial / motion input exploration.
- Exportable, shareable controller profiles.
Controller reports and annotations remain local. VibeCon sends no telemetry. Its only automated actions are explicitly enabled window switching and focusing Codex; it does not execute shell commands or approve AI-agent actions.
MIT © 2026 CoderSerio.


