rmoted

module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: Apache-2.0

README

rmoted

Rmoted connects resumable terminal sessions across clients

Rmote Daemon — a Go daemon that hosts resumable, multi-agent terminal sessions and exposes them over a clean REST + WebSocket API. Run it on any macOS or Linux host; drive it from the bundled rmote CLI or any client that speaks the protocol.

Each session is a real PTY running your shell or AI coding agent (Claude Code, Codex, Grok, Gemini, and more via a pluggable catalog). Sessions survive client disconnects: reconnecting clients recover retained output through bounded ring-buffer replay and delta synchronization. PTY scrollback is held in memory and does not survive a daemon restart.

CI Latest release Apache-2.0 license

Highlights

  • Resumable agent sessions — PTY hosting with reconnect replay + delta sync.
  • Multi-agent, catalog-driven — detect/enable Claude, Codex, Grok, Gemini, and any future agent via agents.json + rmoted agents enable|disable <id> (a universal off-switch across every surface).
  • Hooks forwarder — agent lifecycle hooks (turn start/done, prompts, tool events) published to subscribers.
  • Skills — per-agent skill scanners exposed via REST.
  • Git, worktrees, usage/quota, plan-preview, orchestration events — first-class REST endpoints.
  • Single static binary, CGo-freedarwin/{arm64,amd64}, linux/{amd64,arm64}.
  • Apache-2.0.

Quick start

# Build + run in the foreground (listens on 127.0.0.1:17783 by default).
make run

# In another shell, drive it with the CLI:
rmote health       # version, port, detected agents
rmote sessions     # list live sessions
rmote              # attach to the active session (or create a shell)
rmote new claude   # start a Claude Code session and attach

Install rmoted and rmote

After the repository and a release are public, the curl installer verifies release checksums and places both binaries at ~/.rmote/bin/. The following setup command registers the user service and daemon hooks without touching unrelated hooks in the same config:

curl -fsSL https://raw.githubusercontent.com/8ugustdev/rmoted/main/scripts/install-rmoted.sh | sh

While the repository is private, clone it with an authorized GitHub account and run make build build-cli instead; unauthenticated curl and go install cannot read a private repository.

Then:

"$HOME/.rmote/bin/rmoted" install   # set up the user service + hooks
"$HOME/.rmote/bin/rmoted" health

Add ~/.rmote/bin to PATH to drop the absolute path. The generated service is loopback-only by default. To connect from another device, explicitly configure a private tunnel (recommended) or a trusted LAN bind, then print the pairing payload:

rmoted qrcode                    # print a pairing QR for LAN clients
rmoted qrcode --host 10.0.0.42   # override auto-detected host IP

Keep the pairing secret private. /api/health and /api/healthz are public; local-preview URLs use a short-lived HMAC token. Other HTTP routes require the bearer secret, and WebSockets authenticate in their first frame. Plain HTTP/WebSocket LAN traffic is not encrypted. Prefer SSH port forwarding or a private overlay network; use a host firewall for any non-loopback bind.

On macOS, rmoted install creates a loopback-only LaunchAgent. On Linux it installs a loopback-only systemd --user service; the user systemd session must be available. Running rmoted serve directly is also loopback-only unless --bind is supplied.

Uninstall
rmoted uninstall     # remove the user service + daemon-owned hooks (preserves state)

The rmote CLI

rmote is the terminal client for the daemon. It connects to a locally-running rmoted over loopback HTTP + WebSocket, bridging your terminal to a daemon-hosted PTY session. Auth uses the daemon's ~/.rmote/agent/secret, so it runs on the same host as rmoted; override with RMOTED_HOST / RMOTED_PORT.

Install after the repository is public:

go install github.com/8ugustdev/rmoted/cmd/rmote@latest
Command Action
rmote Attach to the active (or most-recent) session; create a shell if none.
rmote health Daemon version, port, detected agents, features.
rmote sessions List live sessions (id, active, agent, command, path).
rmote doctor Diagnose target resolution, local secret safety, connectivity, and authentication.
rmote new [command...] [-cwd DIR] Create a session (default $SHELL) and attach.
rmote attach <session-id> Attach to an existing session.
rmote <command...> Shorthand for rmote new <command...> (e.g. rmote claude).

Examples:

rmote                          # attach to the active session
rmote doctor                   # read-only connectivity/authentication checks
rmote new                      # a fresh shell
rmote new claude               # a Claude Code session
rmote new -cwd ~/src/proj vim  # vim in a specific directory
rmote attach bb0973ef-...      # attach by id (from `rmote sessions`)

Sample output:

$ rmote health
rmoted 0.1.0-dev on :17783
agents:  claude, codex, grok, pi
features: git, sessions, hooks, skills, usage, worktrees_v1

$ rmote sessions
SESSION     ACTIVE  AGENT      COMMAND       PATH
*bb0973ef   yes     pi         /bin/zsh      /Users/example/src/rmote
 2e33f69a   no      shell      /bin/zsh      /Users/example/src
(* = active)
30-second terminal demo

Terminal reconnect demonstration

$ rmote new codex
created session 7f2c1e5a (codex) in ~/src/project
connecting…

› Explain the failing test, then propose the smallest fix.
• Inspected the failing package and its direct callers.
• The cache is initialized before the test-specific state directory.
› _

# Network drops or the client closes; the PTY keeps running.
$ rmote attach 7f2c1e5a
reconnected — replayed retained terminal output
› _

The transcript is illustrative; exact agent output varies. The important bit is that the PTY belongs to rmoted, so reconnecting restores retained output.

Environment:

Var Default Purpose
RMOTED_HOST 127.0.0.1 Daemon host.
RMOTED_PORT rmoted's configured port Daemon port.

REST requests and WebSocket connection/authentication setup are bounded to five seconds. After attachment succeeds, the interactive session has no overall timeout and remains connected until the client, daemon, or hosted process exits. rmote doctor uses the same bounded transport for one authenticated read-only request; it never changes daemon or agent configuration and never prints the bearer secret.

During a session the terminal is raw (Ctrl-C, arrows, ESC pass through to the PTY); Ctrl-D or exiting the program detaches. Terminal resizes after attach aren't forwarded in this MVP — reconnect to pick up a new size.

rmote is also a readable reference client. See Protocol and API stability for the supported authentication and WebSocket contract, and copyable client examples for REST and WebSocket integrations.

Roadmap

The bundled rmote CLI is the reference client. Near-term work focuses on installer validation, protocol examples, reconnect/resize polish, diagnostics, and contributor workflows. See the public roadmap for shipped, next, 1.0, and exploratory work.

State

Path Purpose
~/.rmote/agent/secret Auth secret (mode 0600). Used by bearer, WebSocket, and derived preview authentication.
~/.rmote/agent/agent.pid Pidfile (managed by serve).
~/.rmote/agent/agent.log Structured log (JSON, append-only).
~/.rmote/agent/agents.json Desired enabled agent IDs (schema v1, mode 0600).

Inspect agent support without mutating config:

rmoted agents                # which agents are detected + enabled
rmoted agents list --json
rmoted agents doctor

agents doctor is read-only and reports a remediation for every catalog entry, including disabled selections, missing executables, unsupported runtimes, and hook configuration mismatches.

Environment overrides: RMOTE_AGENT_DIR (state dir), RMOTE_AGENT_PORT (port), RMOTE_AGENT_BIND (listener address, e.g. 0.0.0.0), or rmoted serve --bind 0.0.0.0.

Auth model

/api/health and /api/healthz are unauthenticated discovery/liveness routes. Local-preview paths use a short-lived HMAC token derived from the secret because browser subresources cannot attach a bearer header. Other HTTP routes require Authorization: Bearer <secret>, and WebSockets send the secret in their first binary frame. The secret is the actual auth boundary: loopback is reachable by any process on the shared host, and explicit LAN binds accept remote traffic.

Architecture and API

See Architecture for components, data flow, persistence, and trust boundaries. See Protocol and API stability for the HTTP endpoint groups and binary WebSocket frame contract.

Cross-compile

make dist
# → dist/rmoted-{darwin-arm64,darwin-amd64,linux-amd64,linux-arm64} + SHA256SUMS

Compatibility

This is a pre-1.0 project. The rmoted and rmote command names, documented environment variables, authentication model, and protocol frame values are compatibility-sensitive. HTTP response shapes and less common endpoints may still evolve between minor releases; release notes call out migrations.

Building from source requires Go 1.26 or newer. Release binaries target macOS and Linux on amd64 and arm64.

Contributing and security

See CONTRIBUTING.md for development and pull-request guidance. Report vulnerabilities privately as described in SECURITY.md.

License

Apache License 2.0. See LICENSE and NOTICE.

Directories

Path Synopsis
cmd
rmote command
Command rmote is the terminal client for the Rmote Daemon (rmoted).
Command rmote is the terminal client for the Rmote Daemon (rmoted).
rmoted command
Command rmoted is the Rmote Daemon: it hosts resumable, multi-agent terminal sessions over REST + WebSocket.
Command rmoted is the Rmote Daemon: it hosts resumable, multi-agent terminal sessions over REST + WebSocket.
examples
client command
Command client is a small, copyable reference for rmoted's authenticated REST and WebSocket protocols.
Command client is a small, copyable reference for rmoted's authenticated REST and WebSocket protocols.
internal
agents
Package agents owns the daemon's compile-time agent identity catalog.
Package agents owns the daemon's compile-time agent identity catalog.
agentsupport
Package agentsupport owns user-selected agent integrations and their reconciliation with Rmote-owned hook configuration.
Package agentsupport owns user-selected agent integrations and their reconciliation with Rmote-owned hook configuration.
auth
Package auth generates and validates the per-install daemon secret.
Package auth generates and validates the per-install daemon secret.
config
Package config owns daemon paths, ports, and version metadata.
Package config owns daemon paths, ports, and version metadata.
git
Package git implements the daemon's git operation surface — a thin shell- out wrapper around the system `git` binary with path allowlisting, timeout, and byte caps.
Package git implements the daemon's git operation surface — a thin shell- out wrapper around the system `git` binary with path allowlisting, timeout, and byte caps.
handoff
Package handoff linearizes a source agent's transcript into conversational turns so a DIFFERENT destination agent can summarize it.
Package handoff linearizes a source agent's transcript into conversational turns so a DIFFERENT destination agent can summarize it.
hooks
hook-forward subcommand implementation.
hook-forward subcommand implementation.
installer
Hook config installer — patches ~/.claude/settings.json (and codex/grok equivalents) with the hook entries that route agent events into the daemon via the `rmote-agent hook-forward` subcommand.
Hook config installer — patches ~/.claude/settings.json (and codex/grok equivalents) with the hook entries that route agent events into the daemon via the `rmote-agent hook-forward` subcommand.
osc
CompletionScanner detects OSC 133 prompt-mark sequences (shell integration) in PTY output.
CompletionScanner detects OSC 133 prompt-mark sequences (shell integration) in PTY output.
peermsg
docs.go writes the peer-messaging capability document (RMOTE.md) and ensures the global agent instruction files reference it.
docs.go writes the peer-messaging capability document (RMOTE.md) and ensures the global agent instruction files reference it.
profiles
Package profiles loads named agent profiles from ~/.rmote/agent-profiles.json.
Package profiles loads named agent profiles from ~/.rmote/agent-profiles.json.
pty
C1 — DSR/DA/XTWINOPS query stubber.
C1 — DSR/DA/XTWINOPS query stubber.
qrcode
Package qrcode generates a pairing QR code + connection info for the rmoted daemon.
Package qrcode generates a pairing QR code + connection info for the rmoted daemon.
security
Package security provides middleware for the daemon's HTTP surface: rate limiting, path allowlisting, and audit logging.
Package security provides middleware for the daemon's HTTP surface: rate limiting, path allowlisting, and audit logging.
server
Package server implements the daemon's HTTP and WebSocket surface.
Package server implements the daemon's HTTP and WebSocket surface.
sessions
Package sessions owns the daemon's tab-level session registry: the ordered list of live sessions, per-tab metadata (name, agent kind, cwd), the active pointer, and the maxSessions guard.
Package sessions owns the daemon's tab-level session registry: the ordered list of live sessions, per-tab metadata (name, agent kind, cwd), the active pointer, and the maxSessions guard.
skills
Claude scanner.
Claude scanner.
summarize
Package summarize produces one-line summaries of agent sessions: a live "what it's doing now" activity line (Line 2 of the session card) and a durable session title (Line 1).
Package summarize produces one-line summaries of agent sessions: a live "what it's doing now" activity line (Line 2 of the session card) and a durable session title (Line 1).
usage
Persistent cache for the rolling 30-day usage dashboard — the aggregate report AND the per-file incremental index, both on disk.
Persistent cache for the rolling 30-day usage dashboard — the aggregate report AND the per-file incremental index, both on disk.
worktrees
Package worktrees discovers Git worktrees without mutating repositories.
Package worktrees discovers Git worktrees without mutating repositories.
ws
Package ws implements the daemon's binary WebSocket protocol for PTY input, output, resizing, state updates, and bounded reconnect replay.
Package ws implements the daemon's binary WebSocket protocol for PTY input, output, resizing, state updates, and bounded reconnect replay.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL