@viewportai/daemon
v0.29.0
Published
Viewport daemon — supervision and orchestration layer for AI coding agents
Readme
Viewport Daemon
Runtime supervision and orchestration layer for AI coding agents.
What it does
- Launches and manages agent sessions.
- Tracks lifecycle, permissions, and session state.
- Exposes local HTTP and WebSocket APIs for control and monitoring.
- Supports discovery and resume flows for existing sessions.
Requirements
- Node.js 20+
- npm 10+
One Command Install
curl -fsSL https://raw.githubusercontent.com/viewportai/viewport/main/packages/daemon/scripts/install.sh | bashThis installs @viewportai/daemon globally, then runs vpd setup.
Local development install (from this repo, no npm publish needed):
./scripts/install-dev.sh --yes --no-service --no-prereqs --no-hooksLocal development link mode:
./scripts/install-dev.sh --link --yes --no-service --no-prereqs --no-hooksLink mode is for active daemon development when you want the repo checkout to become the global vpd binary. For release-confidence validation, prefer the tarball path through npm run verify:install.
Local uninstall/reinstall:
npm run dev:uninstall # removes global package + launchd/systemd user service
npm run dev:uninstall:all # also removes daemon home/state
npm run dev:reinstallQuick start
npm ci
npm run build
npm run test
npm run checkFlag-driven test entry (single command surface):
npm run test # unit suite (default)
npm run test --verify # setup/service-focused verification suite
npm run test --e2e # protocol e2e suite
npm run test --fullstack # localhost fullstack CLI e2e
npm run test --env # local environment verification
npm run test --service # local environment + service verificationFirst-run onboarding:
vpd setupNon-interactive recommended defaults:
vpd setup --yesCustom choices:
vpd setup --chooseCLI
npm run build
node dist/index.js --helpBoot service setup (user-level):
vpd service install
vpd service statusLinux VPS note: For user-level systemd service auto-start after reboot, enable linger once:
sudo loginctl enable-linger "$USER"Profiles
Profiles isolate daemon environments on one machine. Use them when switching between local development and production, or when demoing multiple users from separate terminals.
Fresh managed installs create and select prod during vpd setup, so ordinary
users can install and pair without learning this command surface.
vpd profile create local --copy-current --server https://api.getviewport.test --app-url https://app.getviewport.test --relay wss://relay.getviewport.test:7781/ws
vpd profile create prod --server https://api.getviewport.com --app-url https://app.getviewport.com --relay wss://relay.getviewport.com/ws
vpd profile use prod
vpd profile statusProfile state lives in ~/.viewport/profiles/<name>. That includes the config,
auth token, pairing state, keys, relay identity, and runtime stores. The base
~/.viewport home keeps only the profile registry and current-profile pointer
once you move to named profiles.
vpd profile use <name> and vpd use <name> change the machine default for
future CLI commands. They do not move or retarget an already-running daemon. For
one terminal or one command, use scoped profile execution:
eval "$(vpd profile env prod)"
VPD_PROFILE=prod vpd status
vpd --profile prod status
vpd profile doctor prodvpd start --profile local|lan|relay still controls the daemon network
exposure mode. Put daemon profile flags before the command, or use
VPD_PROFILE, to avoid ambiguity.
Multiple daemons:
vpd profile create prod-user-1 --server https://api.getviewport.com --app-url https://app.getviewport.com --relay wss://relay.getviewport.com/ws --listen 127.0.0.1:7071
vpd profile create prod-user-2 --server https://api.getviewport.com --app-url https://app.getviewport.com --relay wss://relay.getviewport.com/ws --listen 127.0.0.1:7072
vpd profile start prod-user-1
vpd profile start prod-user-2
vpd profile psEach running profile owns a separate supervisor/owner process, worker process, state file, auth token, key store, and relay connection. The OS service manages the currently selected default profile; for multi-profile demos, start profiles explicitly.
Repo bindings include the active profile:
cd /path/to/repo
vpd bind .The generated .viewport/local.yaml is gitignored and includes
profile: <name>. Relay streaming is allowed only when both the organization
and the daemon's startup profile match. This prevents a repo bound in local
development from accidentally streaming to production after vpd profile use
prod, and it also prevents changing a shell default from silently rerouting a
running daemon.
Managed workers can also be operated from the daemon CLI:
vpd worker doctor --server https://api.getviewport.com --workspace <org-id> --executor <runner-id> --credential <vpexec-token> --runner-pool <pool> --json
vpd worker start --server https://api.getviewport.com --workspace <org-id> --executor <runner-id> --credential <vpexec-token> --runner-pool <pool>When the Viewport app creates or rotates a runner credential it also returns a registration profile. Save that JSON profile locally and start the worker with:
vpd worker doctor --registration-profile="$HOME/.viewport/managed-executors/<runner>.json" --json
vpd worker start --registration-profile="$HOME/.viewport/managed-executors/<runner>.json"--doctor checks the local daemon agent inventory and proves the platform
runner credential with heartbeat-only traffic. It does not claim workflow work.
The runner remains organization scoped; teams are preserved on workflow runs,
review packets, and exported artifacts.
Team Resource export bundles can be synced into a Git checkout without giving the API permission to clone or push remote repositories:
vpd team-resource sync --bundle /path/to/export-bundle.json --repo /path/to/team-resource-repo --json
vpd team-resource sync --server https://api.getviewport.com --workspace <org-id> --executor <runner-id> --credential <vpexec-token> --resource <team-resource-id> --repo /path/to/team-resource-repo --push --jsonThe command verifies each file hash, rejects paths outside .viewport/, writes
the bundle, and creates a Git commit. With server credentials it fetches the
bundle and reports the resulting commit back to Viewport. Pass --push to push
HEAD to origin for the selected branch. Use --no-commit to only
materialize the files for inspection.
Quality gates
npm run typecheck
npm run lint
npm run format:check
npm run test
npm run checkPackage operations
vpd upgrade --restart
vpd uninstall --yes
vpd uninstall --yes --purge-homeupgrade installs the latest global @viewportai/daemon package. uninstall
stops known profile daemons, removes the user service when present, and removes
the global package. It does not remove ~/.viewport unless --purge-home is
explicitly passed.
Testing Setup Flow
# fast setup-related tests
npm run test:setup
# full repository quality gate
npm run check
# manual verification test (no service or package installs)
VIEWPORT_HOME="$(mktemp -d)" vpd setup --yes --no-service --no-prereqs --no-hooks
# full local environment verification (temporary config dir + dedicated listen target)
npm run verify:env
# include OS service checks (launchd/systemd)
npm run verify:env:service
# package/install verification from local tarball in a temporary npm prefix
npm run verify:install
# one-command verification gate
npm run verify:repo
# CI-aligned Linux verification path
npm run verify:linux:ciRepository standards
- Semantic commits (
feat:,fix:,refactor:,test:,docs:,chore:). - One logical change per commit.
- Changes to protocol or runtime behavior require matching tests.
- Branch names use semantic prefixes with concise kebab-case descriptions (
feat/...,fix/...,docs/...). - PR titles use semantic commit format with an optional scope (
feat(runtime): ...,fix(daemon): ...). - Do not use roadmap labels or temporary agent labels in branches or PR titles.
Release
This package publishes as @viewportai/daemon.
Package release mechanics are maintainer-owned. Feature PRs should stay focused on code, tests, and docs unless the PR is explicitly intended to cut a package release.
When a release is intentionally being prepared, use the repo's current publish workflow from main and validate the built CLI before shipping.
Runtime config follows one simple rule:
- global defaults live in
~/.viewport/config.json - the nearest project
.viewport/config.jsoncan override selected daemon targets like server or relay vpd doctorwill tell you whether that override was chosen explicitly or simply because it was the nearest ancestor config- environment variables and CLI flags are temporary overrides, not the normal runtime model
See docs/releasing.md for setup and operations. See docs/testing.md and docs/developer-workflows.md for local validation workflows.
