Yaver
Supports integration with AMP as one of the AI agents that can be used for autonomous development tasks within the Yaver ecosystem.
Supports Android device testing and deployment through the Yaver mobile app, enabling hot reload and real-device testing for Android applications.
Supports Apple ecosystem integration including iOS development, App Store deployment, and native iOS app testing through the Yaver mobile app.
Enables deployment to Apple's App Store as part of the automated shipping process, with one-tap deployment capabilities for iOS applications.
Supports deployment to Cloudflare platforms as one of the deployment targets that can be automatically detected and used for shipping applications.
Enables deployment to Cloudflare Workers as part of the automated shipping process for serverless applications.
Enables delivery of daily development summaries and notifications through Discord as part of the morning summary feature.
Provides containerization capabilities for exporting and running promoted backends on user's own cloud infrastructure using Docker.
Supports Expo framework hot reload over P2P connections for React Native development within the Yaver ecosystem.
Supports Firebase as an escape hatch/alternative backend system that can be used instead of Yaver's native backend solution.
Supports Flutter framework development with hot reload capabilities and Feedback SDK integration for Flutter applications.
Enables deployment to Fly.io as one of the deployment targets that can be automatically detected and used for shipping applications.
Provides git integration as part of the 473 MCP tools available for version control and development workflow management.
Integrates with GitHub for version control, repository management, and potentially GitHub-based deployment workflows.
Supports GitHub Actions integration as part of the CI/CD tooling available through the MCP server's 473 tools.
Integrates with GitLab for version control and repository management within the development workflow.
Enables deployment to Google Play Store as part of the automated shipping process, with one-tap deployment capabilities for Android applications.
Provides Kubernetes integration as part of the 473 MCP tools available for container orchestration and deployment management.
Supports Next.js framework development with hot reload capabilities over P2P connections within the Yaver ecosystem.
Integrates with Ollama AI agent for autonomous development tasks and code generation within the Yaver workflow.
Integrates with OpenAI's Codex AI agent for autonomous development tasks, code generation, and bug fixing within the Yaver workflow.
Enables delivery of daily development summaries and notifications through Slack as part of the morning summary feature.
Provides native SQLite-backed data persistence for local phone-project sandboxing with schema, auth personas, and CRUD operations.
Supports Stripe integration for payment processing as part of automated feature implementation tasks like 'add Stripe' to applications.
Supports Supabase as an escape hatch/alternative backend system that can be used instead of Yaver's native backend, with deployment capabilities.
Enables delivery of daily development summaries and notifications through Telegram as part of the morning summary feature.
Supports Turso as an escape hatch/alternative database system that can be used instead of Yaver's native backend solution.
Enables deployment to Vercel as one of the deployment targets that can be automatically detected and used for shipping applications.
Supports Vite framework development with hot reload capabilities over P2P connections within the Yaver ecosystem.
Yaver
Docs: CI setup · Test SDK · Runtime Control Plane
Build apps and game loops from your phone. Keep the backend and build machine local until you decide otherwise.
Using an AI agent? If a coding agent (Claude Code, Codex, Cursor, Aider, …) is reading this because the human asked it to "install yaver" or "set up yaver", stop here and fetch https://yaver.io/llms.txt — that file is the canonical, machine-readable install + configure guide. It covers headless / WSL / SSH, the resumable device-code flow, and exactly what to surface back to the human. Do not scrape the rest of this README as a substitute.
Yaver's short-term product target is phone-first app and backend creation, then promotion to your own dev machine, then optional promotion to Yaver Cloud. The core claim is narrow on purpose:
phone sandbox -> your dev machine -> Yaver Cloud
What is real in the repo today:
Hermes reload from Linux, WSL, macOS, or a remote host into the Yaver mobile app
local phone-project sandboxing with SQLite-backed data, schema, auth personas, seed data, and CRUD
portable export/import/push of a phone project to another
yaver serveagentremote dev-box flows where the box is mostly web UI + backend, runs Claude Code / Codex / other coding agents, and streams run/test output back to mobile
MCP and CLI surfaces for phone project export, import, and push
local-first runtime API for third-party apps using per-project tokens
npm-based install and upgrade via
npm install -g yaver-cliacross macOS, Linux, and WSLUnity feedback/build/test/relaunch groundwork for mobile and desktop projects
What is still incomplete:
the default one-tap monorepo scaffold for phone-created projects
more polish on the AI prompt-to-project scaffold
a fully proven end-to-end App Store / TestFlight release loop from this machine
The Clear Story
Yaver's primary loop is:
Start on the phone.
Vibe-code the app and backend from the phone.
Run the first backend tier in the phone sandbox.
Grow the same project onto your dev machine, your own server, or Yaver Cloud.
Keep Supabase, Convex, Postgres, Turso, Firebase, and similar systems as escape hatches, not the default destination.
What is first-class today:
Hermes reload from Linux / WSL / remote host to iPhone or Android through the Yaver mobile app
Mobile-first backend sandbox with schema, auth personas, seed data, CRUD, and local persistence
Promotion to your own hardware via
yaver serveon a Mac, Linux box, Pi, VPS, or other reachable machineRemote coding-box workflows where your machine is just the app/backend box, Yaver runs the app or tests there, and the phone watches the live stream
Promotion to Yaver Cloud via the same portable bundle and the same
yaver servebinaryContainerized export for running the promoted backend on your own cloud with Docker
Escape routes to systems like Supabase and Convex as secondary trust signals
What is not fully finished yet:
Phone-first monorepo scaffolding as the default one-tap
initpathPrompt scaffold quality polish for the phone-created full-stack starter
The headline path is Yaver-native:
phone sandbox -> your dev machine / your cloud / Yaver Cloud
Everything else is there so the user knows they can leave later.
For a WSL-based developer, that means:
Run
yaver serveor the Go agent tooling on WSL/Linux.Build the Hermes bundle on that host.
Open the app inside the Yaver mobile app on the phone.
Use native-install paths only when you actually need a full store/native build.
The Three Pieces of Yaver
Yaver is built for solo developers and small teams who ship from anywhere. It has three distinct pieces:
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ 📱 MOBILE APP (yaver.io) 🔧 AGENT (yaver) │
│ App Store / Play Store npm install -g yaver-cli │
│ │
│ Remote control for everything. The brain on your dev machine. │
│ Send tasks to AI agents, test apps on Runs AI agents (Claude Code, │
│ real hardware, hot reload, visual QA. Codex, Aider). Serves P2P │
│ Native container for RN apps (not WebView). connections, manages builds, │
│ Works from beach, coffee shop, anywhere. pushes RN bundles to phones, │
│ MCP server with 473 tools. │
│ │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ 🐛 FEEDBACK SDK │
│ yaver feedback setup │
│ │
│ Embed in YOUR app during dev. Shake to report bugs with screenshots + │
│ voice. Black box flight recorder streams all events to your AI agent. │
│ React Native, Flutter, Web. │
│ │
└─────────────────────────────────────────────────────────────────────────────┘You might use:
Just the mobile app + agent — control AI agents from your phone, hot reload any framework
Add the Feedback SDK — embed a debug console in your app, shake to report bugs to your AI agent. If you pair a guest app with Yaver, let the Feedback SDK own haptics; do not keep a second app-level
expo-hapticslayer active on top.All three together — the full loop: code on machine, push to device, test, report bugs, AI fixes, repeat
Yaver Protocol v1 — never feel disconnected
The agent is the producer; the mobile app and dashboard are consumers. They communicate over an SSE channel at /dev/events using a structured protocol with three guarantees:
Real progress, not fake. The agent regex-parses Metro / Expo / Hermesc stdout (
Bundling 67% (1247/2390)) into structuredprogressevents withpct,done,total,currentFile,etaMs, and aprogressSrcofexact/heuristic/unknown. Consumer renders an indeterminate spinner forunknown; never fakes a percentage.Snapshots every 5 seconds.
snapshotevents embed the full picture: every active topic's phase, last progress, recent log tail. A reconnecting consumer reads ONE snapshot and is fully caught up.Liveness contract decoupled from compile state. Consumer tracks time-since-last-byte separately from compile progress.
< 6s = live · 6–15s = syncing · 15–60s = reconnecting · > 60s = lost. Slow compiles never look like "lost" connections.
Topics: dev/start · webview/build · hermes/compile · bundle/push. Phases per topic and full event schema in docs/yaver-protocol.md.
AI + IoT Fix Architecture
Yaver is also the control-plane shape for an AI-driven IoT repair loop.
The architecture we are designing is:
mobile orchestrator -> cloud brain -> LLM coordinator -> c-agent runtime on device
The simple version is:
LLM writes code -> toolchain compiles it -> firmware already has c-agent -> device dynamically loads/runs it -> result comes back -> loop iterates
Each layer has one job:
Mobile orchestrator: operator UI, incident intake, approvals, live status
Cloud brain: session coordination, audit trail, retrieval, module registry, signing pipeline
LLM coordinator: decides which probe or fix should run next for this incident
c-agent runtime: small device-side runtime that verifies artifacts, binds capabilities, executes bounded code, and streams results back
The important distinction is that the LLM is not the runtime. The model writes the next probe or fix. The runtime is what makes that code actually runnable on the device.
That matters for real IoT repair cases. A Klipper printer, OpenWrt router, PX4 drone, or robotics host rarely fails in a way that a static predefined tool list fully covers. The useful system is one that can author a small incident-specific probe or fix, compile it, ship it, run it safely on the device, inspect the result, and iterate.
An important hardware/firmware design rule falls out of that: AI-fixable components should be able to enter a bounded stuck or degraded mode instead of crashing the whole device. If a dependency wedges, the component should quiesce, preserve enough state, report that it is waiting for replacement, and resume when a new module is inserted and validated. Good firmware architecture is mandatory. That is the difference between a system the brain can iteratively repair and a system that just hard-resets on every subsystem fault.
That loop looks like:
phone reports issue -> brain plans -> LLM writes bounded probe/fix -> build/sign -> c-agent verifies/runs -> telemetry returns -> LLM writes next attempt -> repeat until fixed or budget hit
This is the motivation behind the embedded/c-agent/ work in this repo and the architecture docs under docs/c-agent-*.md.
Key Features
Push to Device — Real-device testing in ~4 seconds. No TestFlight. 40+ native modules.
Visual QA Loop — Shake to report. AI sees screenshot, writes fix, hot reloads.
Autonomous Testing — Agent navigates screens, catches crashes, fixes, repeats.
P2P Encrypted — Code flows directly between devices. No cloud.
Any AI Agent — Claude Code, Codex, Aider, Ollama, Goose, Amp, or any CLI tool.
Hot Reload — Expo, Flutter, Vite, Next.js over P2P.
473 MCP Tools — Docker, K8s, git, CI/CD, databases.
Feedback SDKs — Debug console for React Native, Flutter, Web.
Unity Feedback SDK — In-game overlay, feedback/crash capture, content refresh, Unity test/build/relaunch hooks.
Session Transfer — Move AI sessions between machines.
Chained Tasks — Queue a whole feature: "build landing page, add Stripe, deploy." Tasks execute sequentially, next starts when previous succeeds.
Auto-Retry — Failed task? Agent retries with error context. Only pings you after 3 failures.
Ship It Button — One tap to deploy. Agent detects your project (Cloudflare, Vercel, TestFlight, Play Store, Fly.io, etc.) and ships.
Live Terminal Stream — Watch Claude Code work in real-time from your phone via SSE. Full terminal output, not just status updates.
Autoinit (cached project context) —
yaver autoinit <project>writes a projectinit.md(stack, layout, conventions, build/test/deploy commands, recent direction) that every later autoideas kick reads as cached context, so Claude doesn't re-grep the repo from scratch every kick. Each successful run auto-appends to the file's history block so the next session knows what was just shipped. Available as CLI, HTTP (POST /autoinit/start,GET /autoinit/status), and MCP (autoinit_start,autoinit_status).Autoideas (overnight idea generator) —
yaver autoideas <project>runs a long-lived loop that asks the AI for fresh single-PR-sized improvement ideas every tick and appends them as- [ ] <title>lines toideas.md. Mobile / web shows them as checkboxes; pick the ones you want and the daemon dispatches tasks for the curated subset. Generation continues in parallel with implementation.Always Native, Never WebView — React Native apps always load via Hermes bytecode into a native bridge with TurboModules + Fabric. WebView is never used for app loading.
Task Scheduling — Cron-like scheduling.
Notifications — Telegram, Discord, Slack, Teams, PagerDuty, Opsgenie, Linear, Jira, email.
CI/CD Webhooks — GitHub Actions, GitLab CI triggers.
Git Providers — Browse and clone repos from phone.
SDKs — Go, Python, JS/TS, Flutter/Dart, C.
Vibe Coding from Anywhere
Built for the solo developer who ships from a beach in Thailand. Dump tasks from your phone, let your machine do the work, check results over coffee.
Morning at the beach:
1. Open Yaver → Queue 5 tasks: "add dark mode", "fix login bug",
"write payment API", "add validation", "deploy to Cloudflare"
2. Agent chains them — each starts when the previous succeeds
3. If one fails, agent retries with the error context (up to 3x)
4. You get a push: "4/5 done, payment API retry 2/3 in progress"
Lunchtime:
5. Check the Summary — "4 tasks done ($0.32), 1 running"
6. Open the live terminal stream — watch Claude Code typing in real-time
7. Tap "Ship It" — one tap, agent deploys to Cloudflare Workers
Next morning:
8. Push notification: "5 tasks completed, site live at myapp.com"Chained Tasks (queue a whole feature)
# From the mobile app or API:
POST /chain
{
"tasks": [
{ "title": "Build a landing page with pricing section" },
{ "title": "Add Stripe checkout for $10/mo plan" },
{ "title": "Write tests for the payment flow" },
{ "title": "Deploy to Cloudflare Workers" }
],
"autoRetry": true
}
# → First task starts immediately. Each subsequent task starts when the previous completes.
# → If any task fails, it auto-retries with error context (up to 3x).
# → Chain stops if a task fails all retries.Ship It (one-tap deploy)
The agent auto-detects your project type and offers the right deploy target:
Detected | Deploy Target | Command |
| Cloudflare Workers |
|
| Vercel |
|
| Netlify |
|
| TestFlight |
|
| Google Play |
|
| Convex |
|
| Firebase |
|
| Fly.io |
|
| Docker Compose |
|
iOS TestFlight is LOCAL-ONLY — never run from CI
Don't add a CI workflow that uploads to TestFlight. It will fail on
provisioning every time, even when the local Mac uploads cleanly. CI runners
don't carry the developer-account-registered iPhone UDIDs that the
provisioning profile bakes in, so xcodebuild errors out at archive time with
Device "<UDID>" isn't registered in your developer account /
No profiles for 'io.yaver.mobile' were found. We tried and it kept burning
release minutes for no shipped build.
Always ship iOS from this Mac with the existing local script:
export APP_STORE_KEY_PATH="<your-apple-key-path>"
export APP_STORE_KEY_ID="<your-apple-key-id>"
export APP_STORE_KEY_ISSUER="<your-issuer-uuid>"
export APPLE_TEAM_ID="<your-apple-team-id>"
./scripts/deploy-testflight.shThe script auto-bumps CFBundleVersion, archives, and uploads to TestFlight
in one step (~25–30 min). Daily TestFlight upload cap is ~15–20 builds —
plenty of headroom for normal iteration. Android Play Store deploys can run
from CI (and currently from the same Mac via scripts/deploy-playstore.sh)
since the keystore lives in the gitignored keys/ dir / GH ANDROID_KEYSTORE
secret rather than being device-account-bound.
Cross-machine Android signing via vault
The Android upload keystore lives in the gitignored keys/ dir on the
machine that originally generated it. To build signed AABs from any of
your other PCs without copying the keystore over USB / iCloud, stash
the signing creds in your Yaver vault and let yaver vault sync do
the distribution:
One-time, on the source machine (the one that already has the keystore):
yaver vault add ANDROID_KEYSTORE_BASE64 --project mobile --category signing-key
yaver vault add ANDROID_KEYSTORE_PASSWORD --project mobile --category signing-key
yaver vault add ANDROID_KEY_ALIAS --project mobile --category signing-key
yaver vault add ANDROID_KEY_PASSWORD --project mobile --category signing-key
# `add` prompts for the value if you don't pass --value.
# For the keystore itself, pass: --value "$(base64 < keys/yaver-upload.keystore | tr -d '\n')"On any new PC you want to ship from:
npm install -g yaver-cli
yaver auth # OAuth (any provider)
yaver vault sync # P2P pull from your other devices
./scripts/bootstrap-android-signing.sh # decodes vault → materializes keys/ + keystore.properties
./scripts/deploy-playstore.sh # builds + uploads AAByaver vault sync is P2P over QUIC with last-write-wins by
UpdatedAt — whichever machine wrote the entry most recently wins
on conflict. Vault values never touch Convex; the privacy contract
keeps signing material out of the central backend
(desktop/agent/convex_privacy_test.go enforces this). Both
materialized files (keys/yaver-upload.keystore and
mobile/android/keystore.properties) are gitignored, and the
bootstrap script refuses to write either if it isn't ignored.
The vault also has a Bitwarden-style web UI
(web/components/dashboard/VaultView.tsx) and a mobile screen
(mobile/app/vault.tsx) for browsing / adding / revealing entries
without dropping to the CLI.
Unity
Yaver now also has a Unity lane.
The Unity contract is:
feedback SDK inside the Unity project
in-game overlay
screenshots, logs, crashes, black-box capture
vibing from inside the game
content refresh / scene reload / redeploy ladder
Unity EditMode/PlayMode tests on the agent machine
desktop build/relaunch flow for self-hosted iteration
Read more:
Always Native, Never WebView
React Native apps pushed to the Yaver phone app always load natively — never in a WebView. The pipeline:
Bundle: Metro bundles your JS into a single file
Compile:
hermesccompiles JS → Hermes bytecode (HBC, version 96, from RN 0.81.5)Validate: Both CLI and phone validate HBC magic (
0x1F1903C1) and BC version matchLoad: Phone creates a native bridge via
ExpoReactNativeFactorywith full New Architecture supportRun: Your app runs with TurboModules, Fabric, and JSI — same as if built with Xcode
The safeReloadBridge sequence invalidates the old bridge, waits for HadesGC cleanup (up to 3s weak-reference poll), then creates a fresh bridge. This prevents SIGABRT crashes from GC touching freed memory.
Why this matters: WebView-based "containers" (like some dev tools) can't access native modules, have different performance characteristics, and break any app using TurboModuleRegistry.getEnforcing(). Yaver's native bridge gives your app the same runtime as a production build.
Full Pipeline from Anywhere
Developer at the beach? No problem.
1. Open Yaver on your phone
2. Switch to your repo: "switch to my-flutter-app"
3. Chat with your AI agent — it writes code on your home machine
4. Build: yaver build flutter apk
5. Test: yaver test unit
6. Deploy: artifact transfers P2P to your phone — tap to install
Or run the full pipeline:
yaver pipeline --test --deploy p2p
Skip GitHub Actions. Skip TestFlight queues. Your build goes straight to your phone.Key capabilities:
Repo switching —
yaver repo switch my-appauto-discovers git repos under~/and changes the agent's working directory. No manual path typing.Auto-detect testing —
yaver test unitdetects your framework (Flutter, Jest, pytest, Go test, Cargo, XCTest, Espresso, Playwright, Cypress, Maestro) and runs the right command. Pass/fail counts stream to your phone.yaver-test-sdk — Embedded E2E test runner that replaces Playwright + Percy + axe-core. Drop YAML specs under
yaver-tests/, runyaver test run, and every test executes on your own hardware for $0/mo. Seedocs/yaver-test-sdk.md.Full pipeline —
yaver pipeline --test --deploy p2pbuilds, tests, and deploys in one command. Stops on test failure by default.Platform-aware builds — When you request a build from your phone, the agent knows your platform (iOS or Android) and builds the right artifact (APK/AAB for Android, IPA for iOS).
Expo support —
yaver build expo-androidandyaver build expo-iosfor Expo-managed projects. Runseas buildorexpo prebuild+ native build depending on your setup.Auto vault sync — When your phone connects to the agent, keys and signing credentials from the P2P encrypted vault sync automatically. No manual key management on each connect.
Store uploads —
yaver build push testflightandyaver build push playstoreupload directly to app stores. Credentials stay in the vault.
Self-Host a Relay Server
Install a relay on any VPS with one command:
curl -fsSL https://yaver.io/install-relay.sh | sudo bash -s -- \
--domain relay.example.com \
--password your-secretThis installs Docker, deploys the relay, sets up nginx + Let's Encrypt SSL, and configures auto-updates. The relay is a pass-through proxy — it never stores your data. All connections are encrypted via QUIC (TLS 1.3).
How It Works
┌─────────────┐ HTTP ┌──────────────┐ QUIC tunnel ┌──────────────┐
│ Mobile App │─────────────────►│ Relay Server │◄──────────────────│ Desktop Agent│
│ (React Native) short-lived │ (optional) │ persistent │ (Go CLI) │
│ Wi-Fi/5G │ HTTP requests │ public IP │ outbound conn │ behind NAT │
└──────┬──────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ Auth only │ Platform config │ Register device
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ Convex Backend │
│ Auth + Peer Discovery + Platform Config (relay server list) │
│ Apple / Google / Microsoft Sign-In │
└─────────────────────────────────────────────────────────────────────────────┘No code, task data, or AI output ever touches our servers. The relay is a pass-through proxy. When you're on the same network, traffic goes direct.
Quick Start
# Install
npm install -g yaver-cli
# Upgrade later
npm install -g yaver-cli@latest
# Sign in — GUI machine opens a browser, headless (Pi / VPS / SSH-only / Docker) uses --headless
yaver auth # opens browser automatically
yaver auth --headless # prints a URL + short code you approve from your phone
# `yaver auth` starts the agent automatically if needed
#
# Supported sign-in providers (all 6 linkable to the same account):
# Google · Apple · Microsoft/O365 · GitHub · GitLab · email/password
# See https://yaver.io/download#headless-auth for the full flow.
# Adopt a project (one-time, ~3 min) — caches stack/layout/conventions into init.md
cd ~/code/my-project
yaver autoinit my-project
# Generate ideas overnight (long-lived, detached, survives terminal close)
yaver autoideas my-project --hours 8 --engine codex
# Pick ideas later via mobile / web (checkboxes) → dispatches tasks for the picks
# Watch the live chat from any terminal
yaver stream autodev:my-projectHeadless machines (Mac mini upstairs, Hetzner VPS, Linux box over SSH)
You don't need a browser on the headless machine. Pick one:
# Option A — fresh OAuth via QR (Apple / GitHub / GitLab / Google / Microsoft)
yaver auth --headless
# → prints a QR code pointing at yaver.io/auth/device
# → scan it with your phone camera, sign in with whatever provider,
# the headless agent polls and receives the token.
# Option B — copy an existing signed-in token over the P2P relay
# (fastest path — no OAuth dance at all)
yaver auth pair
# → prints a 6-char pairing code + QR code.
# On a machine that's already signed in (your laptop), run:
yaver auth send <PAIR-CODE> <target-url-from-the-qr>
# Or scan the QR from the Yaver mobile app → More → Pair device.Both paths work the same for Apple, GitHub, GitLab, Google, and
Microsoft — the web sign-in page at yaver.io/auth/device accepts all
five and hands
the resulting token back through the device-code flow.
Headless reachability defaults:
Linux and macOS now block OS sleep while
yaver serveis runningWSL cannot block Windows host sleep from inside the distro
real pre-login macOS boot requires one extra privileged step:
sudo yaver serve --install-launchd-daemonWSL reboot recovery is best-effort: Yaver installs a shell helper and prefers a Windows Scheduled Task when available, but the Windows host still needs sleep disabled for unattended remote use
For a persistent Hetzner box that should stay installed as both your own owner-authenticated machine and a shared CI/guest host, see docs/hetzner-shared-owner-runbook.md. For the default security/functionality posture behind fresh installs, see docs/default-install-protection.md.
All Installation Methods
Method | Command |
npm |
|
Upgrade |
|
What it installs |
|
Default Protection / Functionality Balance
New installs should now be both usable and protected by default.
Yaver does not need root for normal daily use.
yaver auth,yaver serve, hot reload, vibe coding, feedback, and most build/deploy flows are designed to run as a normal user.Root is only needed for machine-level setup: installing OS packages, writing system services, changing Linux sysctls, enabling Docker for a service user, or provisioning a fresh remote box.
The Yaver agent stays host-native. That keeps hot reload, dev servers, Xcode, Gradle, Hermes, Expo/EAS, deploy flows, relay, and device bridging attached to the real machine.
Owner coding flows stay host-native too. Yaver's three first-class runners (
claude,codex,opencode) are not blindly forced into Yaver's Docker sandbox for normal owner tasks, because that breaks real auth/toolchain access on many machines.Guest and feedback-only tasks are the place where hard isolation matters most. Yaver keeps the guest restrictions there and can additionally containerize those tasks when Docker isolation is enabled.
On Linux, Yaver now prefers explicit blocked state over false readiness. If a runner is installed but the host still blocks its own sandbox prerequisites, the UI marks that runner as blocked instead of letting tasks hang and fail later.
Install-path expectations:
npm install -g yaver-clinow does a best-effort Linux bootstrap for runner safety. When the install has root privileges on Debian/Ubuntu, it enables the required user-namespace sysctls and installsbubblewrap/uidmapwhen those packages are missing.Managed cloud / Hetzner bootstrap paths now also ensure Docker is enabled, Linux user-namespace prerequisites are set, and the
yaverservice user is added to thedockergroup in service-user deployments.If a lean install does not have enough privilege to harden the host, Yaver leaves the machine unchanged and surfaces blocked runners clearly instead of pretending they are healthy.
That split is deliberate: protect untrusted guest execution without breaking the main Yaver loop of vibe coding, hot reload, build, and deploy.
Protecting A Remote Box From Destructive Agent Actions
Yaver has multiple layers here, but the boundary matters:
The command sandbox is enabled by default and blocks known-destructive commands such as recursive deletion of critical system paths, privilege escalation, raw disk writes, piping remote content into a shell, and similar host-compromise patterns.
The sandbox also specifically refuses recursive deletion of common workspace/code roots like
/Users,/home,$HOME, and common home subdirectories such as~/Workspace,~/Projects,~/Code,.ssh,.aws, and.yaver.Guest and feedback-only tasks can run in a Docker container instead of on the host. In that mode the task only sees the mounted project directory, selected env vars, and optional extra mounts that pass Yaver's mount validation.
Container mounts are validated so the sandbox cannot silently re-expose
/,/home,/Users,/etc, or the Docker socket back into the task container.
What this does not mean:
Yaver does not try to stop an owner-authorized host task from editing the current project. That would break legitimate coding work.
If you want the strongest protection for a remote shared box, prefer
--containerize-guestsand run untrusted work as guest/feedback sessions rather than as the owner.If you want protection against accidental repo loss even for owner tasks, use normal engineering safety nets too: git, remote origin, snapshots, or a dedicated throwaway worktree/clone.
Raspberry Pi 5 dev-node image
The download page also exposes a Raspberry Pi 5 dev-node image through the same Convex-backed public artifact pipeline as the CLI assets. The image build itself is Linux-native; from macOS use ./scripts/build-pi-image.sh --docker once Docker is running, or let the pi-image/vX.Y.Z GitHub workflow build and publish it. The Pi image is a two-stage appliance: it bakes in the OS image, the yaver binary, first-boot provisioning, cloud-init, and systemd services, then uses first boot to install the heavier dev/backend stack (claude-code, codex, opencode, TDD tools, sqlite3, vercel, convex, PostgreSQL, Redis, Supabase, MQTT).
Always-Up Mode (Boots Without Auth)
yaver serve is designed to start and stay reachable even on a brand-new install with no token. The HTTP server comes up in bootstrap mode the moment you run it for the first time, and on the primary always-on targets it also registers itself with the OS auto-start system.
Primary always-on targets:
macOS via LaunchAgent by default, or LaunchDaemon for real headless pre-login boot
Linux via systemd user service + linger
Windows via Scheduled Task
WSL support is different:
WSL is supported for the React Native / Hermes daily loop and headless auth
WSL is not the same as native Linux for reboot persistence
Yaver does not install a native systemd auto-start service inside WSL
Yaver installs a WSL startup helper and prefers a Windows Scheduled Task when available
WSL cannot stop the Windows host from sleeping; unattended remote use still requires Windows power settings and ideally Tailscale on Windows itself
native Linux and macOS still have the stronger always-on path
# Brand-new install. No `yaver auth` needed yet.
yaver serve
# → Yaver agent started in bootstrap mode (PID …, port 18080).
# → Registered as macOS LaunchAgent (will auto-start after login).
#
# This machine has no auth token yet. The agent is up and waiting.
# Open the Yaver mobile app (already signed in) on the same Wi-Fi —
# the box will appear as 'needs auth', tap it to pair.yaver status reflects the bootstrap state instead of bailing:
Yaver: v1.85.0
Auth: ● not signed in
Agent: ● running (bootstrap mode, port 18080)
Host: mac-mini.local
Mode: bootstrap — waiting for a phone to pair
Auto-start: ● installed (will run on login/boot)The bootstrap HTTP surface only mounts the pairing/recovery endpoints needed to receive a token — /health, /info, /auth/pair/{info,session,submit,encrypted}, and /auth/recover. Everything else (tasks, vault, exec, dev server) is gated behind a successful pairing.
Two Ways to Pair From the Mobile App
Path | When | How |
LAN beacon | Box and phone on the same Wi-Fi | Bootstrap mode broadcasts a UDP beacon every 3s. The mobile app's beacon listener picks it up automatically and shows it in More → Pair device with a one-tap "adopt this machine" button. |
Remote re-auth (host-only) | Box is reachable remotely and your phone or web dashboard already knows it | The caller POSTs to |
The mobile app automatically picks the right path based on whether the device is in your device list. Guests can never trigger the recovery flow on a host machine, even if they know the relay URL — the host check happens server-side in Convex against the original userId that registered the hardware fingerprint.
By default, /auth/recover stays reachable on the main HTTP listener. If you want the stricter posture, enable private-only recovery:
yaver config set require-private-recovery true
# or one-off for this serve process
yaver serve --recovery-policy=privateIn private-only mode, direct public HTTP hits to /auth/recover are rejected. Mobile can still recover over LAN or Tailscale; the web dashboard needs a private relay or an HTTPS Cloudflare Tunnel.
Survives Reboots
The first yaver serve writes the OS-native auto-start descriptor:
OS | What gets installed |
macOS | Default: |
Linux |
|
WSL | No native systemd service. Yaver installs a WSL startup helper and prefers a Windows Scheduled Task when available; Windows host sleep still has to be handled in Windows settings. |
Windows | A scheduled task that fires on user login. |
After the first install the agent comes back automatically on native Linux and Windows, and on macOS after login via the default LaunchAgent. For a truly headless macOS box that must come back before login, install the LaunchDaemon once. On WSL, keep the expectation narrower: the daily dev flow is supported and Yaver can install the helper + Windows-login path, but native Linux/macOS still provide the stronger always-on behavior.
Visual Feedback Loop
Test your build on your real device, record bugs visually, and the AI agent fixes them.
You test the app → Record screen + voice → AI agent sees the recording → Fixes the bugs → Rebuilds → RepeatThree runtime modes (user selects at runtime from within their app):
Mode | What happens | Best for |
Full Interactive | Screen + voice stream live to agent. Agent's vision model detects bugs in real-time. Hot reload pushes fixes as you speak. Say "make this bigger" and it happens. | Active development, quick iterations |
Semi Interactive | Screen + voice stream live. Agent comments on what it sees but doesn't auto-fix. Say "fix it now" or "keep in mind for later". | Code review, discussion, QA |
Post Mode | Record everything offline. No streaming. Compress and submit when done. Agent processes the full session afterwards. | Slow connections, detailed QA, batch reports |
Agent Commentary Levels (0-10): Controls how proactive the agent is. Level 0 = silent. Level 5 = comments on obvious issues. Level 10 = comments on everything it sees (layout, performance, accessibility). Like pair programming where the AI watches over your shoulder.
Feedback SDKs
Embed in your app during development. The SDK provides device discovery, connection UI, screen recording, voice annotation, and P2P upload — all in a single package. Disabled automatically in production builds.
Preferred install flow:
npm install -g yaver-cliOn Linux, the global install now does a best-effort bootstrap for hosted coding
agents too: if it has root, it enables the user-namespace sysctls Codex needs
and installs bubblewrap/uidmap when they're missing. If it does not have
enough privilege, Yaver leaves the machine unchanged and marks blocked runners
as blocked instead of pretending they're ready.
# Then, inside the project you want to wire up:
yaver feedback setup
# Or be explicit:
yaver sdk add feedback --platform web
yaver sdk add feedback --platform react-native
yaver sdk add feedback --platform flutterManual fallback:
# Web (any framework: React, Vue, Svelte, vanilla JS)
npm install yaver-feedback-web
# React Native
npm install yaver-feedback-react-native
# Flutter
flutter pub add yaver_feedbackQuick start (Web):
import { YaverFeedback } from 'yaver-feedback-web';
if (process.env.NODE_ENV === 'development') {
YaverFeedback.init({ trigger: 'floating-button' });
// That's it. A "Y" button appears. Click to record bugs.
// Auto-discovers your Yaver agent on the LAN.
}Quick start (React Native, 0.5+):
import { YaverFeedback, FeedbackModal } from 'yaver-feedback-react-native';
// Zero-config: no agentUrl, no authToken needed.
// The SDK ships its own login screen (native Apple on iOS, in-app browser
// OAuth for Google / GitHub / GitLab / Microsoft, plus email + password)
// and a machine picker that lists the user's own dev boxes plus guest-
// shared machines. Works LAN-direct and over Convex/relay off-LAN so
// Hermes bundle reloads keep working on cell data.
if (__DEV__) {
YaverFeedback.init({ trigger: 'shake' });
}
// In your root component:
<FeedbackModal /> // Embeds login + machine-picker modals automaticallyQuick start (Flutter):
import 'package:yaver_feedback/yaver_feedback.dart';
void main() {
if (kDebugMode) {
YaverFeedback.init(FeedbackConfig(
trigger: FeedbackTrigger.floatingButton,
mode: FeedbackMode.narrated,
agentCommentaryLevel: 5,
));
}
runApp(MyApp());
}
// Add the floating button:
Stack(children: [child, const YaverFeedbackButton()])What each SDK includes:
Device discovery — auto-finds your Yaver agent on the LAN
Connection UI — URL input, connect button, status indicator
Screen recording — ReplayKit (iOS), MediaProjection (Android), getDisplayMedia (Web)
Voice annotation — microphone recording synced to timeline
Screenshot capture — tap to annotate at any moment
P2P upload — multipart POST to agent, works through relay
Three runtime modes — user selects live/semi/post at runtime
Agent commentary — chat-like view of agent's observations
Voice commands — "fix this now", "push to TestFlight", "run the tests"
Auto-disabled in production — only active in
__DEV__/ development mode
CLI commands:
yaver feedback list # List bug reports from device testing
yaver feedback show <id> # View timeline, transcript, screenshots
yaver feedback fix <id> # AI agent creates a fix task from the report
yaver feedback delete <id> # Delete a reportDogfooding: Yaver's own mobile app embeds its own feedback SDK. We develop Yaver with Yaver.
QA Testing Workflow
Combine push-to-device with the Feedback SDK for a complete QA loop:
1. Push to device: yaver push
2. Test on real phone: tap around, find bugs
3. Report bug: shake phone → screenshot + voice → sent to AI agent
4. AI fixes it: agent sees screenshot, reads stack trace, writes fix
5. Re-push: yaver push → fix on device in ~4s
6. RepeatNo TestFlight queues. No Play Store reviews. Real-device testing in seconds. Works with any AI agent (Claude Code, Codex, Aider, Ollama).
MCP Integration
Yaver implements the Model Context Protocol (MCP) with 470+ tools. It is listed as io.github.kivanccakmak/yaver in the MCP Registry metadata and exposes agent-readable install instructions at https://yaver.io/llms.txt.
For the lowest-friction install, a user can paste one of these into the coding agent terminal before Yaver is installed globally:
claude mcp add --scope user yaver -- npx -y yaver-cli yaver-mcp
codex mcp add yaver -- npx -y yaver-cli yaver-mcpRestart the agent session if the new tools do not appear immediately, then call MCP tool yaver_lazy_setup. That tool handles npm bootstrap, resumable phone sign-in, mobile-app links, local daemon startup, and registration with other detected agent CLIs.
For first project capture, call MCP tool project_self_host_create after sign-in. It creates the default self-hosted monorepo: Convex backend, Cloudflare web UI, Cloudflare landing page, Expo React Native iOS/Android app, packages/shared, Yaver local service config, and mobile testing next steps. Managed Cloud comes later through yaver_managed_cloud_onboarding after explicit cost confirmation.
One-Command Setup
yaver mcp setup claude-code # Claude Code user MCP config
yaver mcp setup codex # Codex CLI MCP config
yaver mcp setup opencode # opencode MCP config
yaver mcp setup show # Show config JSON (copy/paste manually)The repo also ships registry metadata in server.json, glama.json, smithery.yaml, and generated well-known discovery files under web/public/.well-known/ so Yaver can be indexed by the official MCP Registry, Glama, Smithery-style installers, and web crawlers that probe MCP server cards.
Manual Setup — Any MCP Client
Add to your claude_desktop_config.json:
{
"mcpServers": {
"yaver": {
"command": "npx",
"args": ["-y", "yaver-cli", "yaver-mcp"]
}
}
}For Claude Code, Yaver can register itself through the Claude CLI instead of editing files manually:
claude mcp add --scope user yaver -- /path/to/yaver mcpyaver auth and yaver serve now try to do this automatically when claude is on PATH.
Network MCP (HTTP) — Remote / Claude Web UI
yaver mcp --mode http --port 18090Connect from any MCP client at http://your-machine:18090/mcp.
GitHub Action
Trigger AI tasks from CI/CD:
- uses: kivanccakmak/yaver.io@main
with:
agent-url: ${{ secrets.YAVER_AGENT_URL }}
webhook-secret: ${{ secrets.YAVER_WEBHOOK_SECRET }}
prompt: "Review this PR and suggest improvements"
runner: claudeAvailable MCP Tools
Category | Tools | Count |
Docker | ps, logs, exec, build, push, pull, prune, stats, inspect, compose, networks, volumes | 23 |
Kubernetes | pods, logs, describe, get, apply, exec, top, events, contexts, namespaces | 11 |
Terraform | plan, apply, state, output, init, validate | 6 |
Helm | list, status, values, search, repos, history | 6 |
Git | info, stash, blame, reflog, branches, tags, log advanced, shortlog, stats | 13 |
Compilers | gcc, clang, clang-tidy, clang-format, objdump, nm, binary size | 8 |
Rust/Cargo | build, test, clippy, fmt, doc, bench, tree, update, audit, check, add/remove | 14 |
Go | build, test (race/cover), vet, mod tidy/graph/why, generate, staticcheck, vulncheck | 11 |
Python | pytest (coverage/markers), ruff (check/format/fix), mypy, black, pip-compile, uv | 6 |
Node/TS | npm run, tsc, eslint (--fix), prettier, biome (check/format/lint) | 5 |
Make/CMake | targets, run, clean, configure, build, test, install | 7 |
Static Analysis | cppcheck, shellcheck, hadolint, semgrep, bandit, gosec, trivy | 10+ |
Profiling | valgrind (memcheck/callgrind/massif), perf, strace, ltrace, go pprof | 10+ |
Testing | run_tests (auto-detect), lint, format_code, type_check, benchmark | 4 |
Dependencies | outdated, audit, list — npm/pip/cargo/go auto-detect | 3 |
Package Registries | npm, PyPI, crates.io, Go modules, pub.dev, RubyGems, Maven, NuGet, Docker Hub | 24 |
GitHub + GitLab | PRs, issues, CI, releases, stars, trending, MRs, pipelines | 10 |
Platforms | Supabase, Convex, Cloudflare (Workers/Pages/R2/D1/KV), Netlify, Firebase, Fly.io, Railway | 33 |
Database | query + schema (SQLite, Postgres, MySQL, Redis) | 2 |
Network | tcpdump, tshark, nmap, netcat, port scan, arp, traceroute, mtr, curl timings | 18 |
Linux Sysadmin | dmesg, lsmod, modprobe, systemctl, journalctl, ufw, iptables, df, du, lsblk, tree, top, ps, vmstat | 30 |
Smart Home | Home Assistant, Philips Hue, Shelly, Sonos, Nanoleaf, Elgato, Tasmota, Govee | 20 |
Mobile Dev | App Store, TestFlight, Play Store, Xcode, Gradle, Flutter, Expo, CocoaPods | 25 |
Daily Utils | JWT decode, epoch, cron explain, subnet calc, fake data, domain check, color, QR | 13 |
Finance | stocks, crypto, currency exchange | 3 |
Location | EV charging, restaurants, hotels, geocode, directions, weather | 9 |
Productivity | standup, changelog, gist, badges, gitignore, license, invite | 13 |
Desktop | notify, volume, music, TTS, timer, calculator, clipboard | 26 |
Core | tasks, sessions, tmux, scheduling, email, notifications, ACL, MCP peers | 67 |
See MCP Integration Guide for full documentation.
Headless Clients (script the phone + dashboard from Node)
Two npm packages that expose the exact same HTTP / Convex / relay surfaces Yaver's mobile app and web dashboard use — but without any native runtime. Drive them from bun / node scripts, CLI pipelines, or MCP tool calls. Good fit for CI smoke tests, AI-assisted QA bots, remote control from SSH-only boxes, and anything where "open the UI and click the button" isn't an option.
Package | What it drives | When to use |
The React Native mobile app's lib (beacon discovery, Apple/OAuth auth, phone-project scaffolder, Hermes bundle push, shake-to-reload gesture) | You're automating anything that would otherwise require the iPhone / Android app to be open — LAN beacon discovery, push-to-device flows, phone-project CRUD, QA runs that simulate a tester shaking the phone. | |
The web dashboard's agent-client (dev-server preview URL composition, webview reload, vibing task dispatch, Reconnect & Fix recovery, | You're automating the browser dashboard — starting / stopping Vite + Next + Expo + Flutter dev servers, tailing preview URLs, kicking coding tasks, or running the full recovery loop when the iframe 401s. |
Common shape: connect(deviceId) → agent methods → JSON on stdout. Same ENV vars (YAVER_TOKEN, YAVER_CONVEX_URL). Mix them in the same script when a flow needs both (e.g. sign in once, tail dev-server logs via web-headless, then fire a shake gesture via mobile-headless).
# Install either or both globally
npm install -g yaver-mobile-headless yaver-web-headless
# Mobile: scaffold + push a phone project
yaver-mobile-headless phone-project-create --name="Todo" --template=todos
yaver-mobile-headless phone-project-push --slug=todo --base-url=https://your-box.example.com --target-token=$CLOUD_TOKEN
# Web: start a Vite dev server on a remote box and print the iframe URL
export YAVER_TOKEN=$(yaver-web-headless sign-in --email=... --password=... | jq -r .token)
yaver-web-headless dev-start --device=$DEVICE_ID --framework=vite --work-dir=/workspace/myapp
yaver-web-headless webview-url --device=$DEVICE_IDFull reference and package-specific verbs: docs/headless-clients.md.
Web Search MCP Tool
Yaver ships a built-in web_search MCP tool so any connected AI agent (Claude Code, Codex, Aider, ...) can ground its output in current information — competitor research, library docs, error messages, news — without each agent needing its own search integration.
Provider | Cost | Setup |
DuckDuckGo (default) | Free, no key | Works out of the box |
Paid (free tier 100 q/day) |
| |
Bing | Paid |
|
Set provider: "auto" and Yaver picks the best available backend (Google → Bing → DuckDuckGo).
Security Sandbox
The command sandbox is enabled by default and blocks dangerous operations:
Filesystem destruction:
rm -rf /,rm -rf ~, etc.Encryption/ransomware: bulk encryption of home/root
Privilege escalation:
sudo,su,doas(unless allowed)Disk manipulation:
mkfs,fdisk,ddto block devicesNetwork exfiltration:
curl|bash, piping sensitive filesSystem compromise: overwriting
/etc/passwd, disabling services
Configuration
// ~/.yaver/config.json
{
"sandbox": {
"enabled": true,
"allow_sudo": false,
"blocked_commands": ["terraform destroy", "kubectl delete namespace"],
"allowed_paths": ["/home/user/projects"],
"max_output_size_mb": 100
}
}yaver config set sandbox.allow-sudo true # Allow sudo
yaver config set sandbox.enabled false # Disable sandbox (not recommended)Multi-User Support
Multiple users can share the same machine (e.g. shared GPU server with Ollama). Each user runs their own agent:
# User A
yaver auth && yaver serve --port 18080
# User B
yaver auth && yaver serve --port 18081Each agent instance has:
Separate auth token and user ID
Isolated task store (
~/.yaver/tasks.json)Own sandbox configuration
Independent relay connections
Auth-aware LAN beacon (only same-user devices discover each other)
Cloudflare Tunnel
For a single always-on box, Cloudflare Tunnel is the easiest non-relay path from phone to machine. Yaver still does auth and permission checks; Cloudflare is only the HTTPS transport.
# Start the agent on the box
yaver auth
yaver serve
# Guided permanent setup
yaver tunnel cloudflare wizardThe wizard shells out to cloudflared, logs you into Cloudflare, creates a named tunnel, writes ingress to http://127.0.0.1:18080, creates the DNS route, and stores the resulting https://... URL in Yaver config.
For a quick temporary test:
cloudflared tunnel --url http://localhost:18080
yaver tunnel add https://<random>.trycloudflare.comHow Yaver uses it:
Same-owner phone + box: mobile tries LAN first, then Cloudflare Tunnel, then relay.
Requests still carry
Authorization: Bearer <your-yaver-token>.If you added Cloudflare Access service-token headers, Yaver can attach them locally on the host/client side too.
Important limitation: the account-level tunnelUrl sync is best for the simple case: one user, one primary box, one stable tunnel URL. If you have multiple boxes behind the same Yaver account, prefer per-device custom tunnels, direct LAN/Tailscale, or relays unless you are sure the tunnel URL belongs to the exact box you want.
Guest Access
Share your machine with anyone — no team or subscription needed. Invite by email, they accept from the Yaver app. Guests can run tasks and use dev server but cannot access shell, vault, or sessions.
# Invite a guest
yaver guests invite cousin@gmail.com
# → Invite code: K7WP3N (share this if they sign up with a different email)
# Configure guest limits
yaver guests config cousin@gmail.com limit=3600 mode=scheduled
yaver guests config cousin@gmail.com runners=claude,opencode
yaver guests config cousin@gmail.com machines=mac-mini,laptop
yaver guests config cousin@gmail.com guestkeys=false tunnels=false
yaver guests config cousin@gmail.com isolation=true
# View guest usage
yaver guests usage
# List all guests
yaver guests list
# Revoke access
yaver guests remove cousin@gmail.comGuest config options:
Setting | Values | Default | Description |
| seconds/day | unlimited | Daily task-seconds cap (e.g. |
|
|
| When the guest can use the machine |
| comma-separated | all | Which AI runners the guest can use |
| comma-separated device IDs | all shared by grant | Restrict access to some host machines instead of all |
|
|
| Allow guest-supplied API keys on shared infra |
|
|
| Allow raw tunnel forwarding to host-local services |
|
|
| Force Docker isolation for guest-triggered tasks |
How it works:
Host invites via CLI, mobile app, or MCP (
guest_invitetool)Guest signs in to Yaver app with any OAuth (Apple, Google, Microsoft)
Guest accepts via email match or 6-character invite code
Host's devices appear in guest's device list
Max 5 guests per host, invitations expire in 2 days
Config (limits, runners, usage mode) syncs via Convex. Project access is managed P2P on each agent.
Sharing Infra Safely
There are three different sharing shapes:
Share a box / some boxes: invite a guest and scope them to one machine or a selected set of machines.
Share infra but not raw secrets: let the guest use host-managed runners / build tools / storage under Yaver policy, while keeping raw provider values private.
Share code scope, not your whole disk: narrow the guest to selected projects so tasks, feedback fixes, and file browsing stay inside approved repos.
Examples:
# One teammate can use only the Mac mini and only the yaver repo
yaver guests invite teammate@example.com --scope=full --machines=mac-mini --projects=yaver
# End-user / tester: feedback-only access to one app project
yaver guests invite tester@example.com --projects=sfmg
# Existing guest: remove host-managed key usage, disable raw tunnels, require containers
yaver guests config teammate@example.com guestkeys=false tunnels=false isolation=trueGuest + Host Cloudflare Tunnel
If the host has already set up Cloudflare Tunnel for a box, a guest can benefit from that faster HTTPS path without having any Cloudflare account at all.
Guest signs into Yaver only.
Guest presents their own Yaver bearer token to the host agent through the host's tunnel URL.
Host agent validates that token, checks guest scope / machine / project policy, and only then serves the request.
Cloudflare carries bytes; Yaver decides authorization.
What the guest does not need:
a Cloudflare account
cloudflaredtheir own domain
direct access to Cloudflare credentials
What stays host-only:
Cloudflare Access service-token secrets (
CF-Access-Client-Id/CF-Access-Client-Secret)the raw tunnel setup itself
machine-level policy decisions
Caveat: automatic host-tunnel reuse is intentionally conservative. Yaver only projects an account-level tunnel hint onto a shared device when the share resolves to exactly one host box. If a host shares multiple devices under one account-level tunnel setting, guests should use relay/direct paths or host-specific tunnel entries instead of guessing.
Repo / Workspace Sharing
Classic guests is the safe “use parts of my machine” model. For deeper repo-oriented collaboration, Yaver also has a host-share surface for brokered workspace sessions:
yaver host-share prepare
yaver host-share create --projects yaver --session-ttl-min 480 --idle-timeout-min 30
yaver host-share join <invite-code>
yaver host-share attach-repo --session <session-id> --path ~/code/yaver
yaver host-share sync-repo --session <session-id> --to-host
yaver host-share sync-repo --session <session-id> --from-host
yaver host-share end <session-id>For the "my friend keeps the repo on their own machine, but borrows my Codex/tools" flow, the guest now attaches a local repo root to the borrowed workspace explicitly:
attach-repobinds one discovered local repo root to the session and seeds the host-side borrowed workspace from that guest machine.sync-repo --to-hostrefreshes the borrowed workspace from the guest repo.sync-repo --from-hostwrites host-side workspace changes back to the guest repo.If
attach-repocannot find the repo, runyaver repo refreshon the guest machine first so the root is discoverable.
That keeps the repo authority on the guest machine while the heavy runner/tool execution stays on the host.
Host control is explicit:
--session-ttl-minsets the hard lease lifetime when the invite is created.--idle-timeout-minends the lease if the session goes inactive.yaver host-share end <session-id>stops an active session immediately.yaver host-share revoke <invite-code>revokes the invite and any session created from it.
Use guests when you want:
tasks
feedback
dev server
bounded file/project access
Use host-share when you want:
a session-style collaboration flow
brokered workspace operations
guest-owned repo mirroring into a host-backed workspace
tighter repo-level boundaries for a specific sharing session
Neither model gives the guest your shell, vault, or raw provider secrets by default.
Vault & Deploy Script Generator
Yaver has an on-device vault that behaves like GitHub/GitLab secrets but stays on your own machines. Secrets are grouped by project, encrypted at rest (NaCl secretbox + Argon2id), and sync peer-to-peer between your paired devices — never through our servers.
A deploy-script generator sits on top of it: given an (app, target)
pair it emits a bash script that reads from the vault, runs a
toolchain preflight, and executes the build + upload commands on
your own machine. "Your machine = your CI runner" without the cloud
CI bill.
# 1. Put credentials in the vault (project-scoped).
yaver vault add APP_STORE_KEY_PATH --project mobile --value ~/keys/AuthKey.p8
yaver vault add APP_STORE_KEY_ID --project mobile --value <your-key-id>
yaver vault add APP_STORE_KEY_ISSUER --project mobile --value <your-issuer-uuid>
yaver vault add APPLE_TEAM_ID --project mobile --value <your-team-id>
# 2. Check the toolchain + vault are ready to ship.
yaver doctor build --target testflight --project mobile
# 3. Generate a reviewable bash script.
yaver deploy generate --app mobile --target testflight --out scripts/deploy-mobile-ios.sh
# 4. Ship. The script sources the vault, runs the preflight gate,
# then xcodebuild → export → upload to App Store Connect.
bash scripts/deploy-mobile-ios.sh
# 5. Sync the vault to your other Yaver-paired devices.
yaver vault syncSupported targets out of the box: testflight, playstore,
cloudflare, convex, npm-publish, pypi-publish. Adding one
is ~10 lines in desktop/agent/deploy_script_gen.go.
The existing scripts/deploy-*.sh are vault-aware too — drop values
in the vault once and they stop needing export in every shell.
GitHub Actions keep working unchanged: a CI host with no vault just
falls through to env vars set by secrets.*.
Shared-machine deploys (yaver deploy ship)
Guests you invite with the new deploy scope can trigger a deploy
on your machine from their laptop, without ever seeing the
secrets on your disk:
# Host
yaver guests invite friend@example.com --scope=deploy --projects=mobile
# Guest — runs on their laptop; the build actually happens on yours
yaver deploy ship --app mobile --target testflight --machine <host-device-id>The script body is generated on your machine, vault values are
injected into the subprocess env (never into the script source),
and only stdout/stderr stream back over SSE. Security model in
docs/vault-and-deploy.md.
Ship to multiple stores at once:
yaver deploy ship --app mobile --targets testflight,playstoreOne request, server-side fan-out. Preflight runs for every target
upfront — the whole composite is rejected atomically if anything is
missing. Events from per-target goroutines multiplex into a single
SSE stream with a target field; the CLI demuxes them with
[testflight] / [playstore] prefixes, prints a ── composite summary ── at the end, and exits with the worst per-target code.
Past runs are queryable:
yaver deploy runs # table of recent runs
yaver deploy logs <run-id> # full on-disk log of a past run
yaver deploy diagnose --app mobile --target testflight # preflightIn-memory ring buffer, last 100 runs. Each run stores who
triggered it, what target, exit code, duration, and the last ~8 KB
of stdout/stderr. The full output is also written to
~/.yaver/deploys/<id>/output.log so yaver deploy logs <id> can
replay the full build, not just the tail. Guests only see their own
runs.
Failures are auto-classified: vault_locked, toolchain_missing,
auth_error, signing_error, network_error, timeout,
already_uploaded (which is Apple's way of saying "this build is
already shipped" — treated as success, not failure), plus generic
build_failed when nothing specific matches.
If Apple upload hiccups after a 20-min archive, just rerun — the
iOS template is idempotent. The archive lives at
/tmp/yaver-deploy-<app>-testflight.xcarchive; the second run
checks its CFBundleVersion + mtime and skips straight to the
30-second export+upload phase. On success the archive is cleaned
up; on failure it's kept for the next attempt.
Want a ping on completion? Set deploy_webhook_url in
~/.yaver/config.json to a Slack/Discord/Zapier inbound URL. Every
finished run POSTs {id, app, target, exit_code, duration_ms, ok, error_class, is_guest, ...} — fire-and-forget, one retry on
non-2xx, then logged-and-forgotten. Especially useful for
overnight guest-triggered deploys where nobody is watching the
terminal. Add deploy_webhook_secret to get HMAC-signed POSTs
(X-Yaver-Timestamp + X-Yaver-Signature: sha256=<hex> over
"{timestamp}.{body}" — same shape as Slack / GitHub / Stripe).
Full reference: docs/vault-and-deploy.md.
Container Sandbox (Optional)
Run AI agent tasks inside Docker containers for full filesystem isolation. Optional and disabled by default — the default mode runs tasks directly on the host.
# Build the sandbox image (one-time, ~3 min)
yaver sandbox build
# Enable for guests only (security isolation)
yaver serve --containerize-guests
# Enable for all tasks (clean build environments)
yaver serve --containerize-host
# Check status
yaver sandbox statusWhat's in the container: Node.js, Python, Go, Rust, Java, Ruby, Claude Code, Aider, Expo CLI, Wrangler, and common build tools. Build caches (npm, Gradle, Cargo, Go modules) persist across tasks via Docker volumes.
Project-specific containers: Place a Dockerfile.yaver in your project root for custom toolchains. The agent auto-detects and builds it.
Extra host mounts (e.g. Android SDK): add to ~/.yaver/config.json:
{
"container_mounts": ["/opt/android-sdk:/opt/android-sdk:ro"]
}Note: Xcode/xcodebuild requires macOS and cannot run in Docker. iOS builds must use direct execution (non-containerized). Android builds via Gradle work fully inside containers.
Hot Reload — Dev Server to Phone
Start a dev server on your machine and preview the app on your phone in real time — all through the P2P channel. Works on any network (Wi-Fi, 4G, behind NAT).
# From the Yaver mobile app: tap a project → Open App
# Or from CLI:
yaver dev start --framework expo # Expo / React Native
yaver dev start --framework flutter # Flutter
yaver dev start --framework vite # Vite
yaver dev start --framework nextjs # Next.jsLinux / WSL / Remote iPhone Workflow
For React Native / Expo, this is a first-class path:
Run
yaveron Linux, WSL, or a remote boxPair your iPhone with the Yaver mobile app
Start Metro on the host
Tap
Open in Yaveron the phoneYaver builds a Hermes bundle on the host and pushes it into the Yaver iPhone app
This means your daily iPhone dev loop does not need Xcode or a Mac. The iPhone behaves like a real device attached to your remote workflow, not like a simulator tied to a local Mac.
What still needs macOS:
building a standalone native iOS binary
code signing / provisioning
App Store / TestFlight shipping
What does not need macOS:
React Native / Expo JS iteration
Metro-based hot reload on a real iPhone through Yaver
relay / Tailscale / remote-box workflows
If you are on Linux or WSL, Yaver should use the Hermes bundle path for iPhone work rather than xcodebuild.
Hermes reload — when it crashes and how to fix it
TL;DR — this can fail with apps that use native modules Yaver doesn't know about. The bundle download is rock-solid; the structural limit is what's compiled into Yaver's iOS / Android super-host. Apple forbids loading new native code at runtime, so the set of native modules a guest bundle can call equals the set already baked into the signed Yaver binary on disk (currently 113 modules in
mobile/sdk-manifest.json). Anything outside that set will surface in the "Incompatible native modules" dialog before the bridge swap; if you tap "Load anyway" and the JS actually calls the missing module, Hermes will crash. Background + mitigation roadmap:HERMES_RELOAD_STATUS.md,docs/native-module-architecture.md,docs/android-dynamic-native-modules.md, and the blog post Hermes vs WebView.
The bundle download path is reliable end-to-end (streaming relay protocol verified for 8.5 MB+ Hermes bytecode). But the bundle is just JS bytecode — it executes inside Yaver's iOS super-host and can only call native modules the host registers. If your app declares a native module that Yaver doesn't know about, the build still succeeds and the bundle still loads, but the JS will eventually call a TurboModule selector that resolves to nil, throw an NSException, and crash Hermes during the JSError-construction path.
The handshake check (cli/v1.99.94+)
Before every "Open in Yaver", the agent now diffs the project's package.json dependencies against Yaver's embedded mobile/sdk-manifest.json. The mobile app receives the missing-module list in the build response and shows you an "Incompatible native modules" dialog before doing the bridge swap. You can cancel, or Load anyway if you know the missing modules are guarded behind feature flags or platform checks.
The check is non-blocking on the agent side — the bundle still gets served — because there are legitimate cases (the Yaver Feedback SDK is one) where a "missing" module self-suppresses inside Yaver. The mobile dialog is the safety gate.
Common crash classes
Symptom | Probable cause | Where to look |
| A TurboModule selector threw | Compare your |
|
| Same diff. Either add the module to Yaver, or guard the call with |
| Project compiled against a different Hermes than Yaver ships. | Make sure |
Bundle downloads then silently does nothing | App is bundleless — the user's bundle is plain JS, not Hermes bytecode (HBC magic at offset 4 should be | Inspect with |
Fine on macOS host, crashes from Linux/WSL host | The compatibility check is the same on both — but a stale macOS DerivedData cache can mask a real native dep mismatch by reusing pre-built native code. Linux can't do that. | Always trust the Linux/WSL run when the two diverge. |
Adding a native module — invitation to PR
If your project depends on a native module that's missing from Yaver's super-host, the right fix is to add it. The contract:
Add the npm package to
mobile/package.json.Add a matching entry to
mobile/sdk-manifest.jsonundernativeModules(key = npm package name, value = installed version).Mirror the manifest into
mobile/android/app/src/main/assets/sdk-manifest.json,mobile/ios/Yaver/sdk-manifest.json,cli/sdk-manifest.json, anddesktop/agent/sdk-manifest.json. TheTestSDKManifestInSyncGo test fails the build if the agent copy drifts from the mobile master.For the iOS path:
cd mobile/ios && pod install, then make sure the module's headers and bridging code are reachable frommobile/ios/Yaver.xcworkspace. Most autolinked modules need no manual wiring beyondpod install.For Android:
cd mobile/android && ./gradlew clean, then re-bundle. Autolinking handles the registration.Open a PR. Include:
The
sdk-manifest.jsondiffOne smoke-test scenario (e.g. "loaded SFMG which uses
react-native-record-screen—RecordScreen.startRecording()no longer throws").The Hermes BC version you tested against (currently 96).
The sdk-manifest.json is the source of truth for "what Yaver guarantees a guest bundle can call". Adding a module here is a public commitment that the iOS and Android super-hosts both register it. Don't add a module to the manifest before the corresponding native code is wired — it'll just push the crash from the build-time warning to a runtime SIGSEGV. The TestSDKManifestInSync test catches drift between the agent and the mobile master, but it can't catch "manifest claims X is registered but no RCT_EXPORT_MODULE exists." That's a manual review item.
For follow-up reading:
HERMES_RELOAD_STATUS.md— current state of the agent ↔ relay ↔ phone handshake, what's verified, what's still stubbed.docs/native-module-architecture.md— full developer reference: the five mirrored manifest copies, the heuristic, the PR contract, common failure modes.docs/android-dynamic-native-modules.md— design sketch for an Android-only fast path that side-steps the wall by leveragingdlopen. Not shipped yet.Blog post: Hermes Bytecode vs WebView — what Hermes is, how iOS and Android allow runtime injection, where WebView fits, and where the long-tail-of-modules problem comes from.
Roadmap for closing the gap
The handshake catches mismatches today. Three more layers planned:
Auto-stub at build time. When the agent finds an incompatible module, inject a JS-side proxy that returns a controlled rejection (
Module X is not available inside Yaver) instead of throwing NSException. Apps that gate optional features behindif (Module.isAvailable)keep working — the specific feature is just disabled. Stops crashes for ~80% of cases.Popular-module preload. Bake the top 30-50 most-commonly-needed RN native modules into Yaver's super-host as one-time integration work. Binary grows ~30-50%, but the wall recedes for most users.
Per-project Yaver build. For high-value cases, build a custom Yaver-X binary in CI with that project's native modules linked in, ship via that user's Apple Developer account or ad-hoc enterprise distribution. Same model EAS Build uses for production apps.
Android dynamic loading. Android allows
dlopenof arbitrary.sofiles at runtime. The agent could cross-compile a missing module on the host, stream the.soto the phone via the relay, andSystem.loadit before the bridge swap. Only works on Android (Apple forbids it on iOS) — but it's a real escape hatch for Android-first teams. Seedocs/android-dynamic-native-modules.md.
Mobile-First Backend Continuum
Yaver is not just a phone-to-screen bridge. For the phone-project flow, the phone can be the first backend tier.
The same portable project bundle can move across three targets:
Tier | What runs it | Typical use |
Phone sandbox | Yaver mobile app | first CRUD loop, offline prototyping, quick demos |
Your dev machine / your own host |
| real-device testing, staging, privacy-sensitive self-hosting, or a remote coding box that runs your web UI + backend with Claude Code / Codex / similar agents |
Yaver Cloud | the same | managed deployment with zero-ops setup |
For a current-state audit of the mobile-first dedicated VPS flow, plus a practical setup path that approximates the future Yaver Cloud experience today, see docs/yaver-cloud-mobile-runbook-audit.md.
The promotion unit is the same portable manifest every time:
schema
auth personas
seed data
optional live SQLite rows
generated SQL
app spec and related metadata
This is the intended full-stack vibe-coding loop:
Create the project from the phone.
Prompt or edit the app and backend from the phone.
Run it locally in the phone sandbox.
Promote it to your own machine or cloud when it needs to grow.
Export or migrate only if you want an escape hatch later.
One important promoted shape is the remote dev box: the app lives on a Linux/macOS/VPS machine, that machine runs the web UI and backend plus coding agents like Claude Code or Codex, and Yaver uses the phone as the control/view surface. In that flow the phone does not just trigger prompts. It can tell the box to run the app, run tests, and surface a live terminal, recording, or VNC-like stream so the user can watch what the remote box is doing from mobile.
Project-Owned Remote Command Contract
For monorepos and self-hosted app stacks, the clean pattern is to let the repo expose one stable argv contract that Yaver can call on the selected machine.
Example:
./scripts/yaver_project_entry.sh \
--project my-app \
--machine primary \
--build webor:
./scripts/yaver_project_entry.sh \
--project my-app \
--machine primary \
--build test-seleniumThe important part is not the filename. The important part is the shape:
--project <project>--machine <alias>--build <target>
primary is the safe public example because Yaver already resolves it to the user's selected machine. Public docs should prefer aliases like primary or selected-machine over real hostnames, IPs, or internal device labels.
Typical --build values a repo might support:
bootstrapwebstop-webtest-yavertest-seleniumdeploy-webdeploy-backenddeploy-all
When --build web starts a preview, the repo-owned command should print a user-openable URL such as:
APP_URL=http://127.0.0.1:4173and ideally persist the same result to a small JSON status file so mobile, web UI, HTTP, or MCP can read it back without scraping logs.
That URL is what the human opens. If the project has Yaver's web feedback SDK wired to the selected agent, the opened page can immediately participate in screenshot/fix/reload loops from the phone.
Containerized Backend Export
If you want the phone-created backend to land on your own server with Docker, use the phone export / push containerization path:
yaver phone export --containerize --include-data my-todos
yaver phone push --to https://your-box.example.com --containerize my-todosThe exported bundle can include:
Dockerfiledocker-compose.yml.env.example.dockerignore
That gives you a short path from phone sandbox to your own VM, Hetzner box, or other Docker-capable host without changing runtimes.
Monorepo Position
The product direction is phone-first full-stack development with a monorepo:
mobile app
backend
shared schema/types
deploy/export path from the same project root
That monorepo bootstrap story is a priority, but the one-tap repo scaffolder is still in progress. Today the core backend continuum and promote/export path exist first; monorepo automation sits on top of that.
WSL To iPhone Quickstart
If your code lives in WSL and you want real iPhone reload, the daily loop is:
Install Yaver mobile on the phone.
Run
yaver serveinside WSL.Pair the phone with that agent.
Open the Expo / React Native project from Yaver.
Tap
Open in Yaver.Let Yaver build Metro + Hermes on the WSL host and load the bundle inside the phone app.
Important boundary:
WSL is supported for development and phone testing
WSL is not the primary always-on deployment target for Yaver itself
if you want the machine to survive power loss and come back without touching a terminal, prefer native Linux or macOS
if you stay on WSL, use Yaver's WSL startup helper and Windows Scheduled Task path
also disable Windows sleep; WSL itself cannot keep the Windows host awake
The important rule is:
WSL iPhone reload = Hermes bundle into Yaver mobile
WSL iPhone reload !=
xcodebuildWSL reboot persistence uses a helper path, not native Linux systemd
WSL unattended remote use depends on Windows power settings
Command-first version:
npm install -g yaver-cli
yaver auth
yaver serveOptional: force iPhone work to stay on bundle mode explicitly:
yaver mcp call set_ios_install_method '{"method":"bundle"}'Then from the phone:
select the paired machine
select the project
tap
Open in Yaver
What should happen:
Metro runs on the WSL host
Hermes bundle builds on the WSL host
the bundle is pushed to the phone
the app runs inside Yaver on the iPhone
If your cousin only remembers one line, make it this:
WSL -> Hermes bundle -> Yaver mobile app
This is the intended path for projects like sfmg when they are Expo / React Native apps.
Contributor workflow:
contributor clones
sfmgand edits source with Claude Codecontributor runs
yaver servecontributor opens the project from the Yaver phone app
if the project is source-only, Yaver now shows
Compile Hermescontributor taps
Open in Yaverto test on the phone inside the Yaver containercontributor commits and pushes
maintainer deploys the real TestFlight build later from the Mac/Xcode path
That means "never built before" is not a blocker for the daily contributor loop. Yaver can detect:
source-only project that still needs its first Hermes compile
previously compiled project that is ready to open
last Hermes build failed and should be rebuilt after fixing the error
Troubleshooting shortcut:
if the system tries to do a native iOS install on WSL, the mode is wrong
on WSL the resolved iOS install method should be
bundlemissing native-module support is a container compatibility issue, not a WSL issue
Full guide: docs/wsl-ios-hermes-quickstart.md
Do I Need To Modify My Project?
Usually, no.
For the normal Yaver agent flow (yaver running on Linux, WSL, macOS, or a remote host):
You do not need to inject the npm bootstrap package into the app
You do not need to add the Feedback SDK just to open the app in Yaver
Yaver starts Metro, builds the Hermes bundle, and loads it into the Yaver phone app
Use the npm package when:
you want direct push-to-device workflows without the full agent
you want compatibility analysis against Yaver's native module manifest
you want watch-mode push from a terminal with
yaver push --watch
Use the Feedback SDK when:
you want shake-to-report bug capture inside your own app
you want remote reload commands sent into your own app process
you want black-box event streaming and AI fix context
In short:
yaveragent + mobile app = enough for Hermes reload into Yaver on iPhone/Androidyaver-cli= npm distribution name for the unified bootstrap packageFeedback SDK = optional in-app debug/reload/reporting workflow
the phone UI now exposes
Compile Hermes,Rebuild Hermes, andOpen in Yaveras separate steps for source-only third-party apps
What can still block success:
unsupported native modules not present in the Yaver host container
React Native / Hermes version mismatch for direct push workflows
apps that depend on a custom native module outside Yaver's shipped manifest
Open App — dynamic dispatch (iOS)
The Yaver mobile app's Open App button dispatches dynamically based on the connection mode — never a WebView. Third-party React Native apps always load natively:
Connection | What runs | Outcome |
iOS + same Wi-Fi on macOS (direct LAN) |
| App is installed + launched on the real device the same way Xcode would do it manually — fastest full-native path when Xcode is available. |
iOS + cellular / relay |
| App runs inside Yaver with its full JS. Works over 4G / relay / anything. |
iOS + Linux / WSL / remote host | Same Hermes HBC push path as relay mode | The normal non-macOS workflow. Develop anywhere, hot reload on a real iPhone, no Xcode in the daily loop. |
Android | Hermes HBC push into the Yaver super-host (same path as iOS relay) | Single path — Android doesn't need a separate native install branch. |
The dispatch lives in mobile/app/(tabs)/apps.tsx's handleOpen + handleTapProject; the LAN native build uses the PlatformXcodeDeviceInstall build platform in desktop/agent/builds.go; and desktop/agent/device_install.go reads CFBundleIdentifier via PlistBuddy so the app auto-launches after install.
Supported frameworks:
Framework | Dev Server | Hot Reload |
Expo / React Native | Metro ( | Auto (Metro watches files) |
Flutter |
| Auto ( |
Vite |
| Auto (Vite HMR) |
Next.js |
| Auto (Fast Refresh) |
Expo modes: LAN native install on macOS (same Wi-Fi + iOS), Hermes HBC push to the Yaver super-host (any network, including Linux/WSL/remote hosts), or raw dev client (custom native build with all native modules).
Remote Reload — Trigger from Your Phone
When a third-party app has the Feedback SDK embedded and is connected to the same agent, you can trigger a reload from the Yaver mobile app — even while away from your desk. The agent broadcasts the reload command to all connected SDK devices via a persistent SSE command channel.
Yaver Mobile App ──tap "Reload"──► Agent ──SSE push──► Third-Party App (Feedback SDK)
│ ├─ onReload() callback
└─ /dev/reload-app └─ auto DevSettings.reload()Two modes: dev (hot reload from dev server) and bundle (rebuild Hermes bytecode + push). Works over both direct LAN and relay connections.
For the full current-state model of auth, re-auth, discovery, reload, vibing, feedback SDK control, and phone sandbox export/promotion, see docs/runtime-control-plane.md.
Push to Device — Test Existing RN Apps on Real Hardware
Yaver doubles as a native container app (like Expo Go, but for existing projects). Install the yaver.io app from the App Store / Play Store, then push your existing React Native project to it — no project modifications required.
# Install the npm bootstrap package
npm install -g yaver-cli
# Analyze your existing project
cd my-existing-rn-app
yaver push init
🔍 Analyzing your project...
React Native: 0.81.5 ✅ (yaver supports 0.81.x)
Hermes: enabled ✅
New Arch: enabled ✅
Native modules found in your project:
react-native-screens@4.16.0 ✅ available in yaver
react-native-reanimated@4.1.1 ✅ available in yaver
react-native-gesture-handler@2.28 ✅ available in yaver
react-native-ble-plx@3.2.0 ❌ NOT in yaver SDK
✅ Created yaver.json
# Push to your phone
yaver push
📡 Found: Kivanc's iPhone (192.168.1.42)
✅ Compatible
🔨 Bundling for ios...
⚡ Compiling Hermes bytecode...
📤 Pushing 847 KB...
🚀 Done in 4.1s — app loading on deviceWhat this is NOT: Not a WebView. Every <View> renders as a real UIView / android.view.View with full New Architecture support (TurboModules, Fabric). Not Metro dev server — the phone runs a production App Store binary with 80+ pre-installed native modules.
How It Works
yaver push initreads yourpackage.json, compares against the SDK manifest (React Native version, Hermes bytecode version, native modules), and reports compatibilityyaver pushbundles your JS withreact-native bundle, compiles to Hermes bytecode with the npm package's embeddedhermesc, validates the bytecode version matches the phone app, and pushes via HTTP to the phone's on-device server (port 8347)The phone validates the Hermes bytecode, saves it, and safely reloads the React Native bridge — polling for old bridge deallocation (Hermes GC teardown), then creating a new bridge with full New Architecture support (TurboModules, Fabric, JSI)
CLI Commands
yaver serve Start the Go agent from the npm bootstrap package
yaver push init Analyze project, show compatibility, create yaver.json
yaver push [--device <ip>] Bundle + validate + push
yaver push --watch Watch mode — re-push on file save
yaver push --ignore-missing Push even with missing native modules
yaver push doctor Deep compatibility report with fix suggestions
yaver push devices List discovered devices
yaver push modules List all SDK native modules (80+)
yaver push reset Clear pushed bundle on device
yaver push status Device + project status
yaver-push <same-subcommand> Legacy alias for existing scriptsHandling Missing Modules
If your project uses native modules not in the yaver SDK, you can still push — features using those modules will crash, but everything else works. Add graceful checks:
import { NativeModules } from 'react-native';
const isYaver = !!NativeModules.YaverInfo;
// Skip unavailable features in yaver
if (!isYaver) {
// use react-native-ble-plx normally
}SDK Manifest
The yaver.io app now ships with 80+ pre-installed native modules including: react-native-screens, react-native-reanimated, react-native-gesture-handler, react-native-svg, react-native-webview, react-native-maps, @shopify/react-native-skia, @shopify/flash-list, @react-native-picker/picker, react-native-view-shot, expo-camera, expo-location, expo-notifications, expo-updates, and more. Run yaver push modules for the full list.
That manifest is generated from the actual mobile host app dependencies and Expo plugin config, then copied into the CLI package and embedded iOS app bundle. Regenerate with node scripts/generate-sdk-manifest.mjs and verify drift in CI with node scripts/generate-sdk-manifest.mjs --check.
Platform Support
React Native has first-class push-to-device support. Other frameworks have hot reload or build-only support.
Platform | Push to Device | Hot Reload | Build & Upload | How |
React Native / Expo | Yes | Yes | Yes | JS bundled + Hermes bytecode compiled + pushed to native container. Full New Arch. |
Flutter | -- | Yes | Yes |
|
Vite | -- | Yes | -- | Dev server proxied through P2P. Web preview on phone. |
Next.js | -- | Yes | -- | Dev server proxied through P2P. Web preview on phone. |
Swift / Xcode | -- | -- | Yes |
|
Kotlin / Gradle | -- | -- | Yes | Gradle APK/AAB build + Play Store upload. Full native build each time. |
Why React Native is special: React Native apps are JavaScript at their core. Yaver compiles your JS into Hermes bytecode and loads it into a pre-built native container on the phone -- same principle as Expo Go. Other frameworks compile to machine code (Swift, Kotlin) or use their own VM (Flutter's Dart VM), so there's no way to "inject" your app into a container without building the entire binary.
How Push to Device Works (Under the Hood)
If you've never worked with React Native internals, here's what's happening when you run yaver push:
Your Code (JSX/TypeScript)
|
v
Metro Bundler ---- combines all your files into one big JS file
|
v
Hermes Compiler (hermesc) ---- converts JS into compact bytecode (like .class files in Java)
|
v
Hermes Bytecode (.jsbundle) ---- ~60% smaller, loads 2x faster than raw JS
|
v
HTTP push to phone (port 8347) ---- sent over Wi-Fi to Yaver app
|
v
Yaver app validates + loads ---- checks bytecode version, MD5, then hot-swaps the bridgeKey concepts:
Hermes is a JavaScript engine built by Meta specifically for React Native. Instead of parsing JavaScript text at runtime (slow), Hermes pre-compiles it into bytecode (fast). Think of it like the difference between running Python source code vs. a compiled .pyc file, or Java source vs. .class bytecode.
Hermes Bytecode (HBC) is the compiled output. The file starts with a magic number (0x1F1903C1) and a version number (currently BC96 for RN 0.81). If the version in your compiled bundle doesn't match the version compiled into the phone app, it will crash -- like trying to run Java 21 bytecode on a Java 8 JVM.
The Bridge is how JavaScript talks to native code (UIKit on iOS, Android Views on Android). When you write <View>, the JS side sends a message across the bridge saying "create a native view." The native side creates a real UIView or android.view.View. This is NOT a WebView -- every component is a real native component.
New Architecture (TurboModules + Fabric) is React Native's modern runtime. Old RN used an async JSON bridge (slow). New Architecture uses JSI (JavaScript Interface) for synchronous, direct communication between JS and native -- like calling a C function from JS instead of sending a message. TurboModules are native modules that use this fast path. Fabric is the new rendering system. Yaver's container supports both.
The Native Container is Yaver's phone app with 80+ native modules pre-compiled in. When you push your JS bundle, it runs inside this container using all the pre-installed native modules (cameras, maps, sensors, storage, lists, pickers, etc.). If your app uses a native module that isn't pre-installed, that specific feature won't work, but everything else will. This is the same concept as Expo Go, but Yaver supports New Architecture and more modules.
Safe Bridge Reload -- when a new bundle arrives, Yaver can't just swap the JS file. It needs to: (1) shut down the old JavaScript runtime, (2) wait for background threads (Hermes garbage collector) to finish, (3) create a fresh runtime with the new bundle. If step 2 is skipped, the GC thread touches freed memory and the app crashes. Yaver polls for actual deallocation before proceeding.
Git Providers — Clone Repos from Your Phone
Yaver auto-detects GitHub and GitLab credentials already on your dev machine — from gh CLI, glab CLI, macOS Keychain, git credential helpers, or environment variables. No tokens ever leave the machine.
Phone (Yaver app) Dev Machine
┌──────────────┐ ┌──────────────┐
│ Browse repos │──GET /git/repos────►│ Agent queries │
│ from GitHub │ │ GitHub/GitLab │
│ or GitLab │ │ API with │
│ │◄─repo list──────────│ local creds │
│ │ │ │
│ Tap "Clone" │──POST /git/clone───►│ git clone │
│ │ │ on machine │
└──────────────┘ └──────────────┘This is useful for headless dev machines (cloud VPS, Mac Mini) where you haven't cloned a repo yet. Browse your GitHub/GitLab repos from the app, tap clone, and the dev machine pulls it down using its own credentials. Then start coding from your phone immediately.
# Manual machine-side setup for a headless box:
yaver repo auth setup github --token <github-pat>
yaver repo auth setup gitlab --token <gitlab-pat>
yaver repo auth statusThat one-time setup saves the provider token in both places Yaver uses today:
local git credentials for private clone/pull
vault entries (
github-token/gitlab-token) for deploy and CI helpers
Email Connectors
Connect Office 365 or Gmail for AI-assisted email workflows.
# Setup
yaver email setup # Interactive — choose Office 365 or Gmail
yaver email test # Send a test email
yaver email sync # Sync emails to local SQLite database
# Available as MCP tools: email_list_inbox, email_get, email_send, email_sync, email_searchOffice 365
Requires Azure AD app registration with Microsoft Graph API permissions (Mail.Read, Mail.Send). Uses client credentials flow.
Gmail
Requires Google Cloud OAuth2 credentials with Gmail API scope. Uses refresh token flow.
Synced emails are stored locally in ~/.yaver/emails.db (SQLite) for fast search and retrieval.
ACL — Agent Communication Layer
Connect Yaver to other MCP servers for agent-to-agent workflows:
# Connect to local Ollama
yaver acl add ollama http://localhost:11434/mcp
# Connect to a filesystem MCP server (stdio)
yaver acl add files --stdio "npx -y @modelcontextprotocol/server-filesystem /home"
# Connect to a remote database
yaver acl add mydb https://db.example.com/mcp --auth token123
# List / manage peers
yaver acl list
yaver acl tools ollama
yaver acl health
yaver acl remove ollamaACL peers are also accessible via MCP tools (acl_list_peers, acl_call_peer_tool, etc.), enabling Claude to chain tools across multiple MCP servers.
Components
Piece | Directory | Install | What it does |
Mobile App |
| App Store / Play Store | Remote control for AI agents + native RN container + on-device HTTP server (port 8347) |
Desktop Agent |
|
| Native |
Unified NPM Bootstrap |
|
| Umbrella install. Installs the |
Feedback SDKs |
|
| Debug console + black box recorder embedded in your app. React Native, Flutter, Web. |
Programmatic SDKs |
|
| Automate Yaver from code — Go, Python, JS/TS, Flutter/Dart, C. |
Desktop Installer |
| GUI installer (DMG/EXE/DEB) — installs the Go agent binary | |
Relay Server |
| Docker / binary | QUIC relay for NAT traversal — self-hostable, pass-through only |
Backend |
| Managed (Convex) | Auth + peer discovery + platform config. No user data. |
Web |
| Managed (Cloudflare Workers) | Landing page at yaver.io |
Publish Runners
Yaver can now run package and store publishes directly on developer-owned
hardware. The source of truth is project-scoped config in .yaver/publish.yaml.
That same config is surfaced through CLI, web, mobile, and MCP.
Primary path: local/self-hosted execution on the developer's own machine.
Yaver-first upload/register: built artifacts are archived into Yaver's own blob storage first so the system dogfoods its own uploader before any external CI or store fallback path is used.
Optional fallback: self-hosted GitHub Actions
workflow_dispatch, only when the project allows it and the user explicitly requests it for that run.Secret sources: Yaver vault entries and/or environment variables already present on the machine or injected by GitHub secrets/vars.
Supported target kinds:
npm,pypi,pub.dev,testflight,playstore.
yaver publish init
yaver publish config
yaver publish run --target npm-cli
yaver publish run --target pypi-sdk-pythonThe repo includes .github/workflows/yaver-publish.yml for the GitHub fallback
path and exposes MCP tools publish_config_get, publish_run,
publish_submit, publish_upload, publish_ci_dispatch, publish_list, and
publish_status.
CLI Commands
yaver auth Sign in (opens browser — Apple, Google, or Microsoft)
yaver serve Start the agent
yaver mcp Start MCP server (--mode stdio|http)
yaver email Email connector (setup, test, sync, status)
yaver acl Agent Communication Layer (add, list, remove, tools, health)
yaver connect Connect to a remote agent
yaver code Terminal-first coding UX (local or remote workspace)
yaver attach Interactive terminal
yaver set-runner Set default AI agent (claude/codex/opencode/custom)
yaver relay Manage relay servers (add/remove/test — hot-reload, no restart)
yaver tunnel Manage Cloudflare Tunnels
yaver config Get/set configuration
yaver publish Project-scoped package/store publish runner
yaver status Show auth, agent, relay, and connection status
yaver doctor System health check (auth, runners, relay, network)
yaver devices List registered devices
yaver exec Execute a command on a remote device
yaver session Transfer AI agent sessions between machines
yaver build Build apps (Flutter, Gradle, Xcode, React Native)
yaver test Run tests (auto-detect framework)
yaver deploy Deploy to phone, TestFlight, Play Store, or CI
yaver debug Hot reload debug sessions
yaver repo Switch between projects
yaver vault P2P encrypted key management
yaver pipeline Build → test → deploy in one command
yaver feedback Visual bug reports (list/show/fix) — screen recording + voice from device
yaver stop Stop the agent
yaver restart Restart the agent
yaver logs View agent logs
yaver completion Generate shell completions (bash/zsh/fish)
yaver version Print versionTerminal Coding (yaver code)
yaver code is the terminal-first coding surface. It stays plain-text by default when you start from a terminal: no markdown layout, no mobile-style framing, and common terminal commands are handled locally instead of being forwarded to the runner.
# Local terminal + local repo/files on this machine
yaver code
yaver code --agent opencode --model openai/gpt-5.4
yaver code set byok openrouter --api-key $OPENROUTER_API_KEY --model openrouter/openai/gpt-5
yaver code get byok
yaver code "fix the failing tests"
# Local terminal + remote repo/files on another Yaver machine
yaver code --attach mac-mini
yaver code --attach mac-mini --username dev@example.com --agent codex --model gpt-5.4
yaver code --attach mac-mini "run tests, commit, push, and deploy the fix"
# Built-in help
yaver code helpTerminal semantics:
yaver codeandyaver code --agent ...edit the local machine's repo/files.yaver code --attach ...opens a terminal against the attached remote machine and edits that remote machine's repo/files.Local commands such as
help,tasks,agent,clear,exit,quit,/exit, and/quitare intercepted by Yaver locally.The plain-text terminal contract affects formatting only. The coding agent can still build, test, hot reload, commit, push, deploy, and run the normal dev loop if the target machine has the required tools and credentials.
If you want to keep the repo on one machine while borrowing runners or infra from another machine, use the yaver host-share ... borrowed-workspace flow (attach-repo, sync-repo) rather than yaver code --attach.
BYOK / OpenRouter in yaver code
yaver code can now persist a BYOK coding setup for OpenCode-backed runs instead of forcing the user to hand-edit opencode.json.
# Switch terminal coding to OpenCode + OpenRouter
yaver code set byok openrouter \
--api-key $OPENROUTER_API_KEY \
--model openrouter/openai/gpt-5
# Inspect the effective provider/model/base URL
yaver code get byok
yaver code get provider
yaver code get base-urlNotes:
BYOK settings are tied to the current
yaver codetarget, so the same commands work against an attached remote machine too.OpenRouter defaults to
https://openrouter.ai/api/v1.yaver code set model ...also updates the remembered provider when the model is namespaced likeopenrouter/openai/gpt-5.
Shared code control plane
The yaver code terminal is no longer the only surface that understands coding-session state.
HTTP now exposes
/code/status,/code/attach,/code/detach,/code/repos,/code/repo,/code/dev,/code/deploy, and/code/config.MCP exposes matching high-level tools:
code_statuscode_attachcode_detachcode_reposcode_repo_setcode_devcode_deploycode_config_getcode_config_set
Those surfaces all operate on the same machine-aware coding state:
current runner/model/provider
attached machine
active repo/workdir
orchestration mode
recent graph runs
OpenCode/BYOK config when relevant
That means another coding agent can use Yaver as the control plane for multi-machine coding instead of reimplementing attach/repo/dev/deploy logic itself.
Direct deploy first, CI optional
One of Yaver's main jobs is reducing CI cost for build/test/deploy loops.
code_deployand/code/deploynow support direct host deploys from the selected repo/machine to:testflightplaystoreconvexcloudflareall
You can override:
repo via
repo_queryorrepo_pathexecutor machine via
machineplacement via
machine=automulti-target fan-out via
distribute=true
CI is still available when you want it:
ci_provider=githubci_provider=gitlab
So the default path is "deploy from owned machines directly, use CI only when it adds value", not "burn CI minutes for every internal test or staging push".
Remote task video artifacts
Tasks can optionally capture a short demo clip after they finish. This is useful when the work happened on another machine and the user wants to watch what was actually built there.
create_tasksupportsvideo_enabledandvideo_source.create_task,list_tasks, andget_taskreturn structured task objects.When a clip exists, the task includes
videoClipId,videoStatus,videoClipUrl, andvideoPosterUrl.The clip URL is served by the producing Yaver machine, so clients can render a watch link or an inline
<video>player.
Graph resource modes (agent_graph_start, code_mesh_start)
The graph/mesh runtime can now carry explicit self-hosted resource intent per node instead of treating every step as a generic chat task.
MCP
agent_graph_startandcode_mesh_startaccept optional customnodes.Each node can request
resource_modeslikebuild,deploy,browser,sim-ios,sim-android,phone,proof-video,video-summary, ortest-video.Nodes can also carry
prior_device,prior_runner,sticky_device, andsticky_runnerso later rounds stay close to the machine/runner that already has the right repo state, build caches, devices, or credentials.Verification-oriented nodes can set
preferred_video_modeso proof/demo clips come from the right target (browser,sim-ios,sim-android,phone).Those fields are persisted on the graph run, shown by
agent_graph_show, and fed back into placement when the graph runs across local, remote, or borrowed shared machines.
Example:
{
"prompt": "ship the onboarding redesign",
"allowed_devices": ["mac-mini", "linux-builder"],
"nodes": [
{
"id": "build-ios",
"title": "Build iOS artifact",
"kind": "chat",
"prompt": "Implement the iOS slice and prepare a native build.",
"resource_modes": ["build", "sim-ios"],
"build_points": 1,
"prior_device": "mac-mini",
"sticky_device": true
},
{
"id": "proof",
"title": "Record proof clip",
"kind": "chat",
"depends_on": ["build-ios"],
"prompt": "Verify the flow and produce a short proof video.",
"resource_modes": ["proof-video", "video-summary", "browser"],
"preferred_video_mode": "browser",
"verify_points": 1
}
]
}Shell Completions
# Bash — add to ~/.bashrc
eval "$(yaver completion bash)"
# Zsh — add to ~/.zshrc
eval "$(yaver completion zsh)"
# Fish
yaver completion fish | sourceVoice Input & Text-to-Speech
Yaver supports voice input for both mobile and CLI — speak your tasks instead of typing.
Providers
Provider | Type | Cost | Quality |
On-device (Whisper) | Free, offline | $0 | Good (English) |
OpenAI | Cloud, API key | $0.003/min | Excellent |
Deepgram | Cloud, API key | $0.004/min | Excellent |
AssemblyAI | Cloud, API key | $0.002/min | Good |
Mobile
Configure in Settings > Voice or during onboarding. Tap the mic button in the task creation modal (WhatsApp-style). Supports TTS — have responses read aloud.
CLI
# Configure speech provider
yaver config set speech.provider whisper # Free, local (requires whisper-cpp)
yaver config set speech.provider openai # Cloud (bring your own key)
yaver config set speech.api_key sk-... # Set API key
# Use voice in interactive mode
yaver connect
yaver> voice # Records, transcribes, sends as taskFor local/free STT, install whisper.cpp on the host, then put the binary on PATH.
Response Verbosity
Control how detailed AI responses are (0-10 scale):
0-2: Minimal — "Done, no issues"
3-4: Brief — 2-3 sentence summary
5-6: Moderate — key changes + reasoning
7-8: Detailed — full code changes
9-10: Everything — diffs, alternatives, reasoning
Set via mobile app (Settings > Voice > Response detail) or passed per-task.
SDK — Embed Yaver in Your App
Yaver provides SDKs for Go, Python, and JavaScript/TypeScript. Connect to agents, create tasks, stream output, and use speech-to-text from your own code.
Go
import yaver "github.com/kivanccakmak/yaver.io/sdk/go/yaver"
client := yaver.NewClient("http://localhost:18080", token)
task, _ := client.CreateTask("Fix the login bug", nil)
for chunk := range client.StreamOutput(task.ID, 0) {
fmt.Print(chunk)
}Python
from yaver import YaverClient
client = YaverClient("http://localhost:18080", token)
task = client.create_task("Fix the login bug")
for chunk in client.stream_output(task["id"]):
print(chunk, end="")JavaScript / TypeScript
import { YaverClient } from 'yaver-sdk';
const client = new YaverClient('http://localhost:18080', token);
const task = await client.createTask('Fix the login bug');
for await (const chunk of client.streamOutput(task.id)) {
process.stdout.write(chunk);
}C/C++ (shared library)
Build the shared library, then link against it:
cd sdk/go/clib && go build -buildmode=c-shared -o libyaver.so .#include "libyaver.h"
int client = YaverNewClient("http://localhost:18080", token);
char* result = YaverCreateTask(client, "Fix the bug", NULL);Speech in SDK
All SDKs support speech-to-text:
# Python — transcribe audio
result = client.transcribe("recording.wav", provider="openai", api_key="sk-...")
print(result["text"])// Go — record and transcribe
audioPath, _ := yaver.RecordAudio()
tr := yaver.NewTranscriber(&yaver.SpeechConfig{Provider: "openai", APIKey: "sk-..."})
result, _ := tr.Transcribe(audioPath)
fmt.Println(result.Text)Feedback SDKs — Visual Bug Reports from Inside Your App
Embed in your app during development. Screen recording + voice + screenshots → sent to AI agent via P2P. Auto-disabled in production.
SDK | Install | Trigger Modes |
Web |
| Floating button, keyboard shortcut (Ctrl+Shift+F), manual |
React Native |
| Shake-to-report, floating button, manual |
Flutter |
| Shake, floating button, manual |
All SDKs include: auto device discovery, connection UI, screen recording, voice annotation, three runtime modes (Full Interactive / Semi Interactive / Post Mode), agent commentary, voice commands, and remote reload (trigger hot reload from the Yaver mobile app via the agent's command channel).
See Feedback SDK Examples for demos of each mode.
System Health Check
$ yaver doctor
Yaver Doctor
Version: 1.36.0
── Configuration ──
Config file ✓ ~/.yaver/config.json
── Authentication ──
Auth token ✓ Present
Token validation ✓ Valid
Device ID ✓ f5e857d3...
── AI Runners ──
Claude Code (claude) ✓ /usr/local/bin/claude (2.1.80)
OpenAI Codex (codex) ! Not installed — npm install -g @openai/codex
opencode (opencode) ! Not installed — npm install -g opencode
── Relay Servers ──
Relay: My VPS ✓ OK (89ms, password set)
── Network ──
Local IP ✓ 192.168.1.103
Internet connectivity ✓ OK
Doctor summary: 12 passed, 3 warnings, 0 failuresRelay Server — Hot Reload
Relay servers can be added, removed, or updated while the agent is running — no restart needed.
yaver relay add https://relay.example.com --password secret --label "My VPS"
# → Agent notified — relay will connect within seconds.
yaver relay remove a4ef61ac
# → Agent notified — relay tunnel will be stopped.
yaver relay set-password newsecret
# → Agent notified — new password will be used.
yaver relay list
yaver relay testThe agent polls config every 30s as a safety net, and responds instantly to SIGHUP when relay commands run.
Relay Health Monitoring
The agent pings each relay's /health endpoint every 60 seconds. Results are cached and shown in yaver status:
Relay:
Servers:
My VPS https://relay.example.com OK (89ms, 1 tunnel(s), v0.1.0) [password]
Last check: 22s agoToken Refresh & Re-Auth
Sessions last 30 days and auto-refresh:
CLI: Refreshes token on startup + weekly. Detects 401 in heartbeat → warns to re-auth.
Mobile: Refreshes on launch + every foreground resume. Auto-logouts if expired.
Backend:
POST /auth/refreshextends session by 30 more days.
Settings (relay servers, tunnels, preferences) are preserved across sign-out/sign-in on both CLI and mobile.
Networking
Three-layer stack — no Tailscale, no TUN/TAP, no VPN rights. Application-layer only.
1. LAN Beacon (direct) ── ~5ms ── same WiFi, instant discovery
2. Convex IP (direct) ── ~5ms ── known IP from device registry
3. QUIC Relay (proxied) ── ~50ms ── roaming, NAT traversalSee CLAUDE.md for detailed networking architecture.
Development
cd backend && npm install && npx convex dev # Convex dev server
cd web && npm install && npm run dev # Web (localhost:3000)
cd desktop/agent && go run . serve --debug # Desktop agent
cd relay && go run . serve --password secret # Relay server (local)Tests
# Unit tests (no external deps)
cd desktop/agent && go test -v ./...
cd relay && go test -v ./...
# Integration test suite
./scripts/test-suite.sh # Run all tests
./scripts/test-suite.sh --unit # Go unit tests only
./scripts/test-suite.sh --builds # Build verification (all platforms)
./scripts/test-suite.sh --lan # LAN direct connection (localhost)
./scripts/test-suite.sh --relay # Local relay server test
./scripts/test-suite.sh --relay-docker # Deploy relay via Docker to remote server, test, teardown
./scripts/test-suite.sh --relay-binary # Deploy relay binary to remote server, test, teardown
./scripts/test-suite.sh --tailscale # Tailscale cross-machine (local ↔ remote server)
./scripts/test-suite.sh --cloudflare # Cloudflare tunnel test
./scripts/test-suite.sh --help # Show all optionsNo credentials needed: --unit, --lan, and --relay work out of the box.
Remote server tests: --relay-docker, --relay-binary, and --tailscale SSH into a remote server (e.g., Hetzner VPS) to deploy relay/agent binaries, run them, test cross-network connectivity, then tear everything down.
Credentials: Set up via .env.test (gitignored) or ../talos/.env.test:
cp .env.test.example .env.test # fill in REMOTE_SERVER_IP, etc.For CI, store as GitHub Actions secrets. See .github/workflows/test-suite.yml.
Auth
Apple Sign-In, Google Sign-In, Microsoft/Office 365
yaver authopenshttps://yaver.io/auth?client=desktop→ OAuth → callback tohttp://127.0.0.1:19836/callback?token=<token>
Self-Hosting
Relay Server
The relay is a lightweight QUIC proxy for NAT traversal. It's pass-through only — no data is stored. Deploy on any VPS with a public IP.
Automated Setup (recommended)
The setup script handles everything: Docker, nginx, Let's Encrypt SSL, firewall, and relay deployment.
# Prerequisites: VPS with SSH access (root), DNS A record pointing to your VPS IP
./scripts/setup-relay.sh <server-ip> <domain> --password <relay-password>
# Example
./scripts/setup-relay.sh 1.2.3.4 relay.example.com --password mysecret
# Without a domain (testing / IP-only access)
./scripts/setup-relay.sh 1.2.3.4 --no-domain --password mysecret
# Custom ports
./scripts/setup-relay.sh 1.2.3.4 relay.example.com --password secret --quic-port 5433 --http-port 9443
# Show all options
./scripts/setup-relay.sh --helpThe script will:
Install Docker on the VPS (if not present)
Install nginx + certbot, obtain Let's Encrypt SSL certificate
Configure nginx as HTTPS reverse proxy with SSE/streaming support
Sparse-clone the relay directory to
/opt/yaver-relayBuild and start the relay Docker container
Configure firewall (UFW) — TCP 443, UDP 4433, TCP 80
Run a health check and print connection details
Manual Setup (Docker)
# On your VPS
git clone --depth 1 --filter=blob:none --sparse https://github.com/kivanccakmak/yaver.git /opt/yaver-relay
cd /opt/yaver-relay && git sparse-checkout set relay && cd relay
# Set password and start
echo "RELAY_PASSWORD=your-secret" > .env
docker compose up -d
# Verify
curl http://localhost:8443/health
# {"status":"ok"}Manual Setup (native binary, no Docker)
# Build the relay binary (requires Go 1.22+)
cd relay
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o yaver-relay .
# Copy to server
scp yaver-relay root@<server-ip>:/usr/local/bin/yaver-relay
# On the server: run directly
RELAY_PASSWORD=your-secret yaver-relay serve --quic-port 4433 --http-port 8443
# Or install as systemd service
scp relay/deploy/yaver-relay.service root@<server-ip>:/etc/systemd/system/
ssh root@<server-ip> 'systemctl daemon-reload && systemctl enable --now yaver-relay'HTTPS with nginx (for production)
If you set up manually (without the setup script), add nginx + Let's Encrypt for HTTPS:
# On your VPS — install nginx and certbot with your distro's standard package flow
# Get SSL certificate (point DNS A record to VPS IP first)
certbot certonly --standalone -d relay.example.com
# Copy nginx config template and edit domain
cp relay/deploy/nginx-relay.conf /etc/nginx/sites-available/yaver-relay
sed -i 's/DOMAIN/relay.example.com/g; s/HTTP_PORT/8443/g' /etc/nginx/sites-available/yaver-relay
ln -sf /etc/nginx/sites-available/yaver-relay /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
# Open firewall
ufw allow 443/tcp # HTTPS
ufw allow 4433/udp # QUIC
ufw allow 80/tcp # HTTP redirectConnect clients to your relay
# CLI — add relay to config
yaver relay add my-relay \
--quic-addr <server-ip>:4433 \
--http-url https://relay.example.com \
--password your-secret
# Or edit ~/.yaver/config.json directly{
"relay_servers": [
{
"id": "my-relay",
"quic_addr": "<server-ip>:4433",
"http_url": "https://relay.example.com"
}
],
"relay_password": "your-secret"
}Mobile app: Settings → Relay Servers → Add your relay URL and password.
Relay management
# Health check
curl https://relay.example.com/health
# View connected tunnels
curl https://relay.example.com/tunnels
# Logs
ssh root@<server-ip> 'cd /opt/yaver-relay/relay && docker compose logs -f' # Docker
ssh root@<server-ip> 'journalctl -u yaver-relay -f' # systemd
# Stop / remove
./relay/deploy/down.sh <server-ip> # Stop
./relay/deploy/down.sh <server-ip> --purge # Stop and remove everythingVPS requirements
CPU/RAM: 1 vCPU, 512 MB RAM minimum (relay is very lightweight)
Ports: TCP 443 (HTTPS), UDP 4433 (QUIC), TCP 8443 (HTTP fallback), TCP 80 (Let's Encrypt)
OS: Any Linux with Docker (Ubuntu 22.04+ recommended)
Providers: Hetzner, DigitalOcean, Linode, AWS Lightsail, Vultr — any VPS works
No Relay (Tailscale)
If both devices are on your Tailscale tailnet, no relay is needed:
yaver serve --no-relay # Connect directly via Tailscale IPTailscale client is open source (BSD 3-Clause). For a fully self-hosted alternative to the Tailscale coordination server, use Headscale.
Related Work
Projects and tools in the same problem space. Yaver is compatible with most of these and can be used alongside them. Items marked [OSS] are open-source software.
AI Coding Agents (Yaver's first-class runners)
Yaver supports exactly three coding runners. opencode wraps the long tail of providers (Anthropic / OpenAI / OpenRouter / Ollama / GLM / ZAI / …) via its own BYOK config, so anything you can reach from opencode you can reach from Yaver.
Claude Code — Anthropic's agentic coding tool
OpenAI Codex CLI
[OSS]— OpenAI's terminal coding agentopencode
[OSS]— open-source coding agent with BYOK provider config
Local LLMs & Inference
Ollama
[OSS]— run LLMs locally with one commandQwen — open-weight LLMs by Alibaba Cloud
GLM-4 — open-weight multilingual LLM
llama.cpp
[OSS]— LLM inference in C/C++vLLM
[OSS]— high-throughput LLM serving engine
Remote Development
code-server
[OSS]— VS Code in the browserCoder
[OSS]— self-hosted remote dev environmentstmate
[OSS]— instant terminal sharingsshx
[OSS]— collaborative terminal sharing over the webttyd
[OSS]— share your terminal over the web
Networking & NAT Traversal
Tailscale — mesh VPN built on WireGuard (client is open-source)
NetBird
[OSS]— network connectivity platformfrp
[OSS]— fast reverse proxy for NAT traversalCloudflare Tunnel — expose local services securely
Headscale
[OSS]— self-hosted Tailscale control server
Infrastructure & Protocols
Convex — reactive backend-as-a-service (runtime is open-source)
quic-go
[OSS]— QUIC protocol implementation in Gotmux
[OSS]— terminal multiplexerMCP
[Open Spec]— Model Context ProtocolQUIC (RFC 9000)
[Open Standard]— UDP-based transport protocolWireGuard
[OSS]— modern VPN protocol
Security
Reporting a vulnerability: email
kivanc.cakmak@simkab.com. 48-hour acknowledgement, 90-day disclosure window, good-faith safe harbour. Do not open a public GitHub issue for security bugs. Full policy:SECURITY.md.Production is protected by a 5-layer defence: required reviewer on the
Productionenvironment, branch + tag allowlist on that environment,mainbranch ruleset (no force-push, linear history, signed commits), release-tag ruleset (only admin can create/update),CODEOWNERSgating all CI / deploy / auth / vault code, and fork PRs are blocked from reading secrets. SeeSECURITY.md§"How production is protected" for the full breakdown.Contributors: sign off every commit with
git commit -s(DCO). Commits onmainfrom the repo owner are GPG-signed — unsigned commits by the owner name are a signal to investigate.
Legal
Developed by SIMKAB ELEKTRIK — Istanbul, Turkey
Contact: kivanc.cakmak@simkab.com
License
Yaver uses a split-license model — see LICENSING.md
for the full mapping and CONTRIBUTING.md for how
contributions are licensed.
Core (agent, relay, backend, web UI, mobile app, desktop app/installer, pi-image) —
FSL-1.1-Apache-2.0: Functional Source License. Free for any non-competing use; each release auto-transitions to Apache-2.0 two years after publication.Client SDKs & CLIs (
cli/,sdk/js,sdk/feedback/*,sdk/flutter,sdk/python,sdk/go/*,sdk/errors-js) — Apache-2.0 from day one, embed in closed-source apps freely.
Rule of thumb: does your app import / bundle / invoke this code? Yes → Apache-2.0. No, it's a network service → FSL-1.1-Apache-2.0.
A commercial license is available for organizations that need the core without the Competing Use restriction — contact kivanc.cakmak@simkab.com.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kivanccakmak/yaver.io'
If you have feedback or need assistance with the MCP directory API, please join our Discord server