Viewport daemon, relay, and hosted runtime are available in alpha. Surfaces may change.
VIEWPORT
Reference

CLI

The vpd CLI reference, grouped by surface, with the flags the daemon actually accepts.

vpd ships with @viewportai/daemon (current local source: 0.2.1). The binary is wired at viewport/packages/daemon/bin/vpd.js; the source of truth for help text is cli/lifecycle-commands.ts:312-457.

npm i -g @viewportai/daemon
vpd --help

Group-by-surface below. Every command listed here is implemented in code as of the audit.

Lifecycle

vpd start

Launches the daemon. Two-process supervisor + worker model.

FlagDefaultWhat it does
--foreground(background)Run in current shell instead of detaching
--listen ADDR127.0.0.1:7070Listen address. Accepts host:port, just port, or a unix socket path.
--profile NAMElocalOne of local, lan, relay.
--allowed-hosts LISTnoneComma-separated Host header allow-list.
--allowed-origins LISTnoneCORS origins for the local API.
--authoffRequire token auth on the local API.
--home PATH~/.viewportDaemon home directory.

State files: ~/.viewport/runtime.json, plus pidfiles. Resolves VIEWPORT_HOME / VPD_HOME first.

vpd stop

Sends a graceful shutdown via the lifecycle channel. Optional --force to send SIGKILL to the process group. --timeout SECONDS controls how long to wait, --json for machine-readable output.

vpd restart

Stops, then re-launches with the previously persisted launch config.

vpd status

GET /health from the running daemon plus pidfile checks. Reports running / stopped / unresponsive. Pass --check-updates to also query npm for the latest CLI version. Output sections: Status, Runtime, Home, Listen, Owner PID, Worker PID, Profile, Server, Relay WS, Relay state, Node, npm, CLI, Latest CLI, Update, Sessions, Directories, Agents.

vpd doctor

Read-only environment check. Prints daemon identity (machineId, version, runtime kind, home, scope, profile), control-plane endpoints, relay state, config source path, and recovery hints.

vpd doctor does not repair anything. If something is wrong it tells you where to look.

vpd setup

First-run guided setup.

FlagWhat it does
--yesAccept recommended defaults
--chooseWalk through each choice

vpd install

Installs the local runtime files for vpd.

It does not silently install Claude/Codex hooks, skills, or MCP servers. Those are explicit opt-in setup steps for personal monitoring, not required for a self-hosted team worker.

vpd install

vpd update [--yes]

Updates the daemon npm package. With --yes, also restarts the running daemon to pick up the new binary.

vpd service install|uninstall|status

Manages a launchd (macOS) or systemd (Linux) unit so the daemon auto-starts on login / boot.

Pairing

vpd pair [CODE] [--worker] [--transport polling|relay] [--server URL] [--app-url URL] [--auto-unlock] [--no-auto-unlock] [--auto-unlock-ttl SECONDS]

The entry point.

  • No CODE: mints a fresh 8-char code via POST /api/pairing-codes, prints it, opens your browser to {appUrl}/pair?code=…, polls /api/pairing-codes/{code}/status until approval.
  • With CODE: claims a web-initiated code by calling POST /api/pairing-codes/{code}/claim.
  • With --worker: pairs a team worker profile for claiming governed execution leases. Hosted Viewport is the default server; use --server for a self-hosted or customer-internal control plane.
  • With --transport=polling: configures outbound polling, the recommended self-hosted worker default.

On approval the daemon receives relay_credentials, persists them to ~/.viewport/config.json, and auto-restarts.

--server and --app-url override the default Viewport URLs (useful for self-hosted relays pointed at your control plane).

Auto-unlock flags control whether the approved machine can satisfy short-lived web unlock sessions without you pasting a vpd unlock ... command every time:

  • --auto-unlock marks this paired install as trusted for automatic unlock.
  • --no-auto-unlock explicitly opts out.
  • --auto-unlock-ttl SECONDS sets the unlock session lifetime. Values are clamped between 300 and 3600 seconds. The default is 1800 seconds.

Web-generated pairing commands include --auto-unlock when the setup flow asks you to trust this device. Plain vpd pair stays manual unless you pass the flag.

vpd pair anchor

Prints the daemon's trust anchor fingerprint. Used when verifying a daemon's identity out-of-band.

vpd pair rotate-token

Rotates the on-disk daemon auth token via rotateAuthToken(). Restart the daemon to pick up the new token.

Note: vpd unpair is not implemented as a CLI command today. To detach a daemon, DELETE /api/workspaces/{workspace}/installs/{install} from the web UI under Settings → Machines.

Directories

vpd add PATH

Registers a directory in the global config and POSTs to /api/directories on the running daemon so it picks up the change live.

vpd remove PATH

Unregisters via DELETE /api/directories/:id.

vpd list

Lists registered directories and active sessions.

Sessions

vpd run [DIR] --prompt TEXT

Connects to the daemon over WebSocket, auto-registers the directory if needed, sends a launch request, and (optionally) streams session-update events back.

FlagWhat it does
--prompt TEXTInitial prompt (required)
--agent IDOverride agent (default: workspace policy)
--model IDOverride model
--waitBlock until the session ends
--attachFollow updates like vpd logs --follow
--timeout SECONDSTimeout for --wait
--jsonMachine-readable output

vpd send SID --prompt TEXT

Sends a prompt message to an existing session.

vpd logs SID [--follow]

Subscribes via WS, replays messages from --last-seq N if provided, renders text updates (agent-message, tool-call, etc.) or --json.

--follow is the canonical streaming mode. Without it, the CLI does a short flush and exits. Fine for interactive snapshots; not lossless replay.

vpd wait SID [--timeout]

Subscribes and blocks until session-ended arrives.

vpd attach SID

Equivalent to vpd logs --follow.

vpd ls

Lists sessions. Flags: --scope ALL|ACTIVE|DISCOVERED, --directory ID, --agent ID, --json or --format FMT.

vpd session stop SID

Sends a kill request for the session.

vpd session manifest --session SID

Prints the provider, workflow, and approval manifest for the session: what context was attached, which workflows applied.

vpd permit ls|allow|deny

Manages pending permission requests (Claude Code tool-use gates surfaced over the daemon hook bridge).

vpd agent mode SID [detect|bypass]

Reads or sets operator control mode for an active session.

Worktree

vpd worktree ls|diffs|summary|rollback|retry|squash

Operator-side worktree primitives backing the safe-edit model:

  • ls: list worktrees
  • diffs: show pending diffs vs HEAD
  • summary: short status overview
  • rollback: revert to a specific SHA (--to SHA)
  • retry: branch-retry from a SHA (--from SHA)
  • squash: squash-merge worktree into a target branch with a commit message

These map to the WS commands rollback, branch-retry, squash-merge (see API).

Workers

vpd worker

Starts or checks a customer-owned team worker from a paired profile. This is the preferred path for new self-hosted runners.

vpd pair PAIRING_CODE --worker --transport=polling --workdir "$HOME/.viewport/worktrees"
vpd worker doctor
vpd worker start --mode persistent --transport polling
vpd worker stop

Hosted Viewport is the default server. For a self-hosted compatible control plane, specify the server while pairing:

vpd pair PAIRING_CODE --worker --server https://viewport.customer.internal --transport=polling --workdir "$HOME/.viewport/worktrees"
vpd worker start --mode persistent --transport polling

Worker commands:

  • vpd worker start --mode persistent --transport polling|relay|inbound: keep heartbeating and claim multiple assignments over time.
  • vpd worker run-once --lease <lease-token> --transport polling|relay|inbound: run one ephemeral lease, emit cleanup, and exit.
  • vpd worker stop --json: send SIGTERM to the persistent worker for the paired profile, or clear the stale local lock if the recorded PID is gone.
  • vpd worker doctor --json: validate paired server, worker identity, workspace id, workspace root, transport, and detected capabilities without claiming work. The JSON includes vpdProfile (name, source, home, and baseHome) so operators can catch accidental profile switches before a worker claims work. If multiple local profiles exist and no profile is selected, doctor prints a warning before pairing or worker start. It also understands managed-executor registration profiles and explicit managed-worker flags, so support can diagnose the current proof path without starting a worker.
  • vpd worker reset --json: clear the local worker profile and identity before re-pairing.
  • vpd diagnostic --json: print a sanitized support snapshot with runtime, config, path, and support-packet metadata. It redacts secret-looking config fields, but you should still review local paths and workspace names before sharing.

Defaults:

  • hosted server: Viewport managed, unless --server or config overrides it;
  • transport: polling for self-hosted workers;
  • workspace root: ~/.viewport/profiles/local/workspace for the default local profile;
  • worker lifecycle: persistent for start, ephemeral for run-once.

--workdir is a pairing-time flag. Pass it to vpd pair --worker; vpd worker start reads the stored worker profile.

The runner credential only lets the worker claim scoped workflow leases and report evidence. It does not grant GitHub, Slack, Linear, model, repo, or context authority by itself.

If start says another worker is already running, use vpd worker stop for the paired profile, then start again. Use run-once for proof runs that should not hold the persistent worker lock.

For explicit managed-worker credentials, diagnose before starting:

vpd worker doctor --json \
  --server https://api.getviewport.com \
  --workspace WORKSPACE_ID \
  --executor EXECUTOR_ID \
  --credential-file ~/.viewport/profiles/local/runner/acme-runner-token \
  --runner-pool default \
  --workdir "$HOME/.viewport/worktrees"

The doctor output reports credentialSource (file, profile, or inline) but never prints the credential value. JSON output also includes a supportPacket block with the support-packet docs URL and the secret classes the command intentionally omits, so operators know what to review before sharing evidence. It also includes processLock, which reports whether a persistent worker lock is active, stale, or absent for the configured profile. For paired self-hosted workers, workspaceId should match the workspace shown in the app-generated pairing command, and vpdProfile.home should be the local profile directory you intended to use.

Doctor options:

  • --registration-profile PATH: load managed executor registration JSON written from the app.
  • --runner-pool NAME: advertise the runner pool for policy matching.

Agent capability checks are strict. If you pass --agents codex,claude, the connected daemon must actually have those adapters loaded. The worker checks the daemon before claiming work and exits before taking an assignment if an advertised agent is unavailable.

For a deterministic or custom runner, start the daemon with a PTY-backed custom agent:

VIEWPORT_CUSTOM_AGENT_COMMAND=/usr/local/bin/my-agent \
VIEWPORT_CUSTOM_AGENT_ID=my-agent \
VIEWPORT_CUSTOM_AGENT_ARGS_JSON='["--json"]' \
vpd start

Then advertise and use that same id in workflows:

vpd pair PAIRING_CODE --worker --transport=polling --workdir /path/to/repo
vpd worker start --mode persistent --transport polling

Custom command agents stream terminal output as session evidence. They do not provide SDK-level structured tool calls, token usage, or permission callbacks.

vpd team-resource sync

Writes a Team Resource export bundle into a Git checkout. Use this on a worker that has access to the team's configured repository. The API prepares the bundle; the worker performs the local filesystem write and Git commit.

vpd team-resource sync \
  --bundle /path/to/export-bundle.json \
  --repo /path/to/team-resource-repo \
  --commit-message "Sync Viewport Team Resource" \
  --json

Or let a managed worker fetch the bundle and report the commit with its runner credential:

vpd team-resource sync \
  --server https://api.getviewport.com \
  --workspace WORKSPACE_ID \
  --executor EXECUTOR_ID \
  --credential VP_EXECUTOR_TOKEN \
  --resource TEAM_RESOURCE_ID \
  --repo /path/to/team-resource-repo \
  --push \
  --json

The command verifies every file's SHA-256 before writing, rejects any path outside .viewport/, stages the exported files, and creates a commit using a Viewport worker identity. When server credentials are supplied, it reports the resulting commit SHA back to Viewport. Pass --push to push HEAD to origin for the selected branch, or --no-commit when you only want to inspect the materialized files.

Declarative GitOps

vpd check [PATH] [--json]

Validates committed .viewport/ policy and route files before you push them.

vpd check .
vpd check . --json

It checks:

  • .viewport/policy.yaml;
  • .viewport/routes/*.yaml;
  • .viewport/access.yaml structure when present.

It also warns when .viewport/ appears in .gitignore. Declarative GitOps requires policy and route files to be committed; ignored local config will never sync to the control plane.

Config

vpd config resolve

Resolves repo-local .viewport/config.yaml (or .viewport/config.json) and prints the resolved resources.

vpd validate [--path FILE]

Validates a repo-local Viewport config against viewport-config-v1.schema.json.

vpd contract resolve [--path FILE]

Resolves the contract manifest for a path.

vpd guard check --path FILE

Runs the policy guard against a specific file. Useful in pre-commit hooks.

Team Context

The vpd context family manages encrypted team memory (see Team Context).

vpd context init
vpd context status
vpd context add
vpd context propose
vpd context use-github
vpd context resolve
vpd context sync-push
vpd context sync-pull
vpd context sync-all
vpd context epoch-publish
vpd context epoch-rotate
vpd context recovery-backup
vpd context recovery-restore
vpd context rotations-process
vpd context grants-process
vpd context revokes-process
vpd context decisions
vpd context candidate-preview
vpd context device-enroll-request
vpd context device-enroll-approve
vpd context device-enroll-accept
vpd context device-enrollments
vpd context team-grant-create
vpd context team-grants-accept
vpd context dev-reset-crypto --i-understand

Some local-store commands accept --key-store file|macos-keychain.

The trusted-edge sync commands are the ones used for team sharing:

  • create and use can carry descriptor guidance with --use-when and --update-when. These fields are server-visible metadata, not encrypted body content. They tell agents when the vault is relevant and when a durable update is worth proposing.
  • use-github --repo <owner/repo|url> --provider <id> attaches a GitHub markdown repo as a provider. The trusted edge clones or pulls it with local Git auth. context propose --provider <id> pushes a branch and opens a PR when gh is available.
  • epoch-publish publishes public user/team epoch material. Private key material stays local.
  • epoch-rotate publishes a signed user/team epoch rotation after a revoke or manual rotation.
  • recovery-backup encrypts the active user epoch locally and uploads a ciphertext-only backup. Pass --recovery-key <key> or let the daemon print a new one once.
  • recovery-restore --recovery-key <key> fetches the latest encrypted backup, decrypts it locally, restores the user epoch, then immediately rotates and stores a fresh backup.
  • device-enroll-request, device-enroll-approve, and device-enroll-accept add a laptop, workstation, or VPS as decrypt-ready.
  • device-enrollments shows pending, approved, accepted, and revoked device enrollment state.
  • team-grant-create and team-grants-accept materialize team epoch access for team members.
  • grants-process lets a trusted edge wrap pending vault grants for active user/team epochs.
  • sync-pull imports encrypted events and reports grant materialization when this edge can unwrap a grant.
  • candidate-preview decrypts a candidate on the trusted edge and mints the proof required for approval.
  • revokes-process emits revoke and rotated-key events after access is removed.
  • dev-reset-crypto --i-understand clears local encrypted collaboration state for local/staging QA while preserving auth and daemon config.

Agent skills

vpd skills install [claude-code|cursor|all]

Writes per-agent contract markdown into a target path so the agent prompt-references vpd. Pass --force to overwrite. This is the magic that makes "Claude knows about vpd" work end-to-end.

Remote

vpd remote login|status|enable|disable|logout

Manages daemon-native relay transport options. Useful for switching between hosted relay, self-hosted relay, and disabled remote.

Hooks

vpd hook notify|plan|capabilities

Used by Claude Code hooks that vpd install writes into ~/.claude/settings.json. Not typically called by humans.

Internal

vpd __supervisor and vpd __worker are the daemon's two-process model. Don't invoke them directly.

What's persisted on disk

~/.viewport/
├── config.json              # daemon config (mode 0600)
├── runtime.json             # daemon runtime state (pid, listen address)
├── relay-identity.json      # daemon device identity for relay handshakes
├── plugins.json             # workflow plugins loaded at startup
├── replay/                  # session replay event store
├── sessions/                # per-session message logs (driven by directory + session id)
├── crypto/epochs.json       # local user/team epoch private material (mode 0600)
├── plans/trusted-edge-keys.json # local trusted-edge plan body keys (mode 0600)
├── pairing-*                # in-progress pairing identity / file stores
└── ...

Override the root path with VIEWPORT_HOME or VPD_HOME. Repo-scoped daemon overrides (separate from the repo's .viewport/config.yaml contract) can be opted into with VIEWPORT_RESOURCE_OVERRIDE_DIR.

On this page