GitHub Docs

Overview

Control VibeCody agent sessions from your wrist. The watch bridge provides secure, low-latency session relay between Apple Watch (watchOS) and Wear OS companions and the VibeCLI daemon running on your Mac or Linux machine.


Quick Start

# Start the daemon with watch bridge enabled (default port 7860)
vibecli --serve

# Pair your Apple Watch (watchOS companion app)
vibecli --watch pair --platform apple

# Pair a Wear OS device
vibecli --watch pair --platform wearos

# List paired devices
vibecli --watch devices

# Check wrist-suspension status
vibecli --watch status

Apple Watch Companion

The watchOS companion (VibeCody Watch) communicates over WatchConnectivity / HTTP/2:

┌────────────────────┐        HMAC-SHA256 JWT        ┌──────────────────────┐
│  Apple Watch       │ ─────────────────────────────► │  VibeCLI Daemon      │
│  watchOS companion │ ◄───────────────────────────── │  /watch/* endpoints  │
│  (SwiftUI)         │        SSE event stream        │  port 7860           │
└────────────────────┘                                └──────────────────────┘

Wrist capabilities:

  • Start / stop / pause agent sessions
  • Receive streaming output digest (last N tokens)
  • Approve or reject tool-use confirmations
  • View cost ticker (tokens used, estimated $)
  • Wrist-suspension lock: raising the watch resumes; lowering suspends

Wear OS Companion

The Kotlin companion (VibeCodyWear) uses the Wearable Data Layer API:

# Android companion auto-pairs via WearDataLayerService
# Manual trigger from the Wear OS device settings:
adb -s <wear-device-id> shell am start \
  -n com.vibecody.wear/.MainActivity

Wear OS features:

  • Tile showing active session name and token count
  • Complication with cost-per-minute display
  • Haptic feedback on tool-use events

Security Model

Authentication uses HMAC-SHA256 JWTs with per-device Ed25519 keys:

# Inspect the device key registry
cat ~/.vibecli/watch-devices.json

# Rotate a device key (invalidates existing tokens)
vibecli --watch rotate --device <device-id>

# Revoke a device entirely
vibecli --watch revoke --device <device-id>

Token lifetimes:

  • Access token: 15 minutes (auto-refreshed by companion)
  • Refresh token: 7 days (requires re-pair after expiry)
  • Nonce registry: replay protection (64-entry LRU window)

Wrist Suspension

When the watch is taken off (wrist sensor reports on_wrist = false), active sessions are automatically suspended:

[watch] Wrist event received: on_wrist=false, device=ABC123
[watch] Session "my-task" → SUSPENDED (wrist-lock)
[watch] Session resumes automatically when watch is back on wrist

Override via:

vibecli --watch unlock --session my-task

HTTP API (daemon)

The watch bridge exposes REST endpoints under /watch/:

Method Path Description
POST /watch/auth/pair Register new device + issue JWT
POST /watch/auth/refresh Refresh access token
GET /watch/session/stream SSE stream of session events
POST /watch/session/control Start / stop / pause
POST /watch/wrist-event Report wrist-on/off state
GET /watch/devices List registered devices
DELETE /watch/devices/{id} Revoke a device

Rust Modules

Module Purpose
watch_auth JWT generation/validation, Ed25519 device keys, nonce registry
watch_session_relay SSE broadcast, session control, event buffering
watch_bridge HTTP route handlers, daemon integration

BDD Coverage

Feature: Watch Auth
  Scenario: Pair new Apple Watch device
  Scenario: Reject expired JWT
  Scenario: Replay attack blocked by nonce registry
  Scenario: Wrist suspension locks active session
  ...10 scenarios total

Feature: Watch Session Relay
  Scenario: Stream session events to paired watch
  Scenario: Control message pauses running agent
  Scenario: Resume on wrist-on event
  ...15 scenarios total

Feature: Watch Bridge
  Scenario: Full pair → stream → control flow
  Scenario: Multi-device concurrent streams
  ...10 scenarios total

Run the BDD suites:

cargo test --test watch_auth_bdd
cargo test --test watch_session_relay_bdd
cargo test --test watch_bridge_bdd