# Vibelet

`@vibelet/cli` is a cross-platform CLI that installs and manages the Vibelet daemon for remote coding sessions. The same package is also published as `vibelet`.

Official website: https://vibelet.icu

## Requirements

- macOS / Linux / Windows
- Node.js 20 or newer

## Install

```bash
npx @vibelet/cli
npx vibelet
```

Or install it globally:

```bash
npm install -g @vibelet/cli
npm install -g vibelet
vibelet
```

The CLI prints the official website on each run so users can always jump back to the main docs and download page.

## Commands

```bash
vibelet              # Install/start daemon, auto-enable remote access, and print pairing QR code
vibelet start        # Same as above
vibelet stop         # Stop the daemon
vibelet restart      # Restart the daemon
vibelet status       # Show service and daemon status
vibelet logs         # Print recent daemon logs
vibelet reset        # Clear pairings and saved device connections; print a fresh QR code
vibelet --help       # Show help
vibelet --version    # Show CLI version
```

`reset` clears this daemon's synced device profiles (including saved connection addresses),
revokes all pairings, and disconnects authenticated clients. Scan the fresh QR code to pair again.
It does not erase records stored on your phone; those can sync back after pairing,
so remove obsolete computers in the app as well when you want to discard them permanently.

The printed `Web UI` link uses `http://localhost:<port>` for a stable, browser-trusted
same-machine connection. When another advertised route is available, the CLI also
prints `Web UI (other devices)` for LAN or remote browsers.

## Options

```bash
vibelet --access=local                       # Disable Remote Direct and Cloudflare for this run
vibelet --access=remote --force              # Force a fresh tunnel URL
vibelet --access=https://<your-tunnel-url>   # Use your own tunnel URL
vibelet --access=<tailscale-or-lan-host>     # Use a direct private-network host
vibelet --access=<host>,<fallback1>          # Add fallback private-network hosts
vibelet --access=                            # Clear saved relay URL
vibelet --remote-direct                            # Enable account-free Remote Direct
vibelet --no-remote-direct                         # Disable previously enabled Remote Direct access
```

Remote Direct is enabled by default; Cloudflare is opt-in for `vibelet`, `vibelet start`, `vibelet restart`, and `vibelet reset`. Use `--access=local` when you want a LAN-only QR code for that run. This also disables Remote Direct for the current run, even if it was previously enabled; the saved Remote Direct choice is unchanged. Legacy aliases still work: `--local`, `--relay`, `--host`, `--fallback-hosts`, `--remote`, and `--tunnel`.

Managed Cloudflare Tunnels use cloudflared's `auto` transport so QUIC is preferred
when UDP is available and HTTP/2 remains the fallback. The CLI checks its bundled,
user-owned cloudflared binary for updates at most once every 24 hours. A failed
check does not prevent startup, and system package-manager binaries are never
modified. Versions older than 2026.5.2 temporarily stay on HTTP/2 because their
automatic QUIC fallback can delay tunnel readiness for minutes. Update metadata
is stored in `~/.vibelet/cloudflared-update.json`.

## Remote Direct

Run `npx vibelet` and scan the new QR with the current app. Remote Direct is enabled by default and requires no separate networking app or account. Vibelet attempts an encrypted direct path and falls back to an encrypted relay when needed.

Cloudflare is off by default. Add `--cloudflare` for an additional path, or use `--access=local` for LAN-only pairing. Internal forwarding addresses are managed automatically and are hidden from ordinary connection displays. Use `status` and `logs` for diagnostics; do not share connection credentials.

## Release

```bash
pnpm publish:dual:dry-run
pnpm publish:dual
```

The dual publish script builds once, then publishes the same CLI bundle to both `@vibelet/cli` and `vibelet`. The dry-run path stages both packages and validates them with `npm pack --dry-run` without touching the registry.

## Notes

- The npm package publishes the CLI plus a minified daemon runtime bundle.
- The package is intended for end users of the Vibelet host daemon, not for importing as a library.
- The daemon keeps `~/.vibelet/data/audit.jsonl` and `~/.vibelet/logs/daemon.*.log` size-bounded by trimming the oldest content in place.
- Environment variables:
  | Variable | Default | Description |
  |----------|---------|-------------|
  | `VIBE_PORT` | `9876` | Daemon listen port |
  | `VIBE_IDLE_TIMEOUT_MS` | `1800000` (30 min) | Idle timeout before a driver is released (0 = disabled) |
  | `VIBE_TURN_STALL_TIMEOUT_MS` | `300000` (5 min) | Soft inactivity threshold for suspecting an in-flight turn has stalled (0 = disabled) |
  | `VIBE_TURN_STALL_HARD_TIMEOUT_MS` | `900000` (15 min) | Stop threshold when both turn activity and verified execution-client presence are absent (0 = warn only; confirmed process death can still stop a turn) |
  | `VIBE_TEXT_DELTA_BATCH_MS` | `24` | Maximum delay for combining streaming text updates before WebSocket broadcast (0 = disabled) |
  | `VIBE_AUDIT_MAX_BYTES` | `8388608` (8 MB) | Max audit.jsonl size before trimming |
  | `VIBE_DAEMON_LOG_MAX_BYTES` | `16777216` (16 MB) | Max daemon log file size before trimming |
  | `VIBE_STORAGE_HOUSEKEEPING_INTERVAL_MS` | `300000` (5 min) | Log trimming check interval |
  | `CLAUDE_PATH` | auto-detect | Path to Claude binary |
  | `CODEX_PATH` | auto-detect | Path to Codex binary |

Execution-driver presence is checked locally every 2 seconds during a turn and
every 15 seconds while idle. These checks do not send prompts or consume model
tokens, and do not update the last actual activity time. A silent turn with
verified process presence produces a warning after the soft threshold but is
not stopped or subjected to tool-process recovery merely for silence. This
covers long commands, `sleep`, and polling without requiring a scheduling tool.
Presence means the execution process/connection is alive, not that its model or
tools are making progress; a live deadlock still needs explicit cancellation or
the tool's own timeout. If presence can no longer be verified, the hard timeout
also checks time since the last verified presence; a single missed check after a
long wait does not immediately terminate the turn. The existing idle-driver
release policy is independent and still applies after the turn finishes.

Remote Direct is enabled by default. Cloudflare is off unless explicitly requested with `npx vibelet --cloudflare`. Use `--access=local` for LAN-only pairing.
