config

package
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 Imports: 7 Imported by: 0

Documentation

Overview

Package config owns daemon paths, ports, and version metadata. All paths derive from a single base dir (default ~/.rmote/agent/) so the daemon and its installer can locate state without env drift.

Index

Constants

View Source
const (
	BackendAuto     = "auto"     // resolve from host capability (default)
	BackendAppleFM  = "applefm"  // on-device Apple Foundation Model (macOS 26+, free)
	BackendAgentCLI = "agentcli" // reuse an installed agent CLI in print mode
	BackendDisabled = "disabled" // no live summary / model title
)

Summarizer backend identifiers. Stored lower-case in config JSON.

View Source
const (
	AgentAuto   = "auto" // claude → pi → codex
	AgentClaude = "claude"
	AgentPi     = "pi"
	AgentCodex  = "codex"
)

SummarizerAgent identifies which agent CLI the agentcli backend shells out to. Validated against the catalog allowlist at the server layer (not here, to avoid an import cycle config→agents).

View Source
const DefaultPort = 17783

DefaultPort is the daemon's default localhost TCP port. Matches the iOS local-port-forward target. Overridable via RMOTE_AGENT_PORT for conflict cases (rare; default has been chosen to avoid common clashes).

Variables

View Source
var IsDarwin = func() bool { return runtime.GOOS == "darwin" }

IsDarwin is a tiny seam for test injection (production checks runtime.GOOS).

View Source
var Version = "0.1.0-dev"

Version is the daemon version reported by /api/health. Bumped per release. Overridden at build time via -ldflags="-X github.com/8ugustdev/rmoted/internal/config.Version=…".

Functions

func AgentDir

func AgentDir() (string, error)

AgentDir returns the daemon state directory. Override via RMOTE_AGENT_DIR (tests); default ~/.rmote/agent/.

func BindAddr

func BindAddr() string

BindAddr returns the address the daemon should bind. Default "127.0.0.1" (localhost-only — iOS reaches the daemon via SSH local-forward or Tailscale). Override via RMOTE_AGENT_BIND=0.0.0.0 for LAN-attached iOS (QR pairing to the host's LAN IP). Binding non-loopback exposes the daemon to the network — the bearer auth + rate limiting are the security boundary, but the exposure is wider than the SSH-tunnel path.

func ConfigPath

func ConfigPath() (string, error)

ConfigPath is the daemon config file (~/.rmote/agent/config.json). Respects RMOTE_AGENT_DIR like every other state path.

func EnsureDir

func EnsureDir() error

EnsureDir creates the state dir with mode 0700 if missing. Idempotent. Permissive enough for the user, tight enough that other local users can't read the daemon secret.

func LogPath

func LogPath() (string, error)

LogPath is the daemon's structured log sink (slog JSON, append-only). Rotated by the supervisor (launchd/systemd) — daemon itself does not rotate.

func PIDPath

func PIDPath() (string, error)

PIDPath is the pidfile written by `serve` and read by `status`/`stop`.

func Port

func Port() int

Port returns the configured TCP port (env override or default).

func SecretPath

func SecretPath() (string, error)

SecretPath is the file holding the per-install random auth secret (0600). Required on all daemon routes — local TCP bind is permissive, so the secret prevents any local process from subscribing to agent events.

Types

type DaemonConfig

type DaemonConfig struct {
	Summarizer SummarizerConfig `json:"summarizer,omitempty"`
}

DaemonConfig is the parsed ~/.rmote/agent/config.json. Today only the summarizer block is defined; future daemon-wide knobs land here. All fields are omitempty so an absent file yields a zero-value config resolved to safe defaults via ResolveBackend / Defaults().

func Load

func Load() (*DaemonConfig, error)

Load reads and validates ~/.rmote/agent/config.json. A missing file is not an error — it returns a zero-value config (resolved later to safe defaults). A present-but-unparseable file IS an error: per advisory (d), malformed JSON must never silently become defaults. The caller (server.New) treats a Load error as degraded mode: log + surface to /api/health, fall back to compiled defaults, never fatal.

Env overrides (RMOTE_SUMMARIZER_*) apply on every path — including the missing-file path — so a host can run purely from env with no file.

type HostCaps

type HostCaps struct {
	Darwin            bool // runtime.GOOS == "darwin"
	AppleFMAvailable  bool // rmoted-summarize helper resolves on disk
	AgentAvailable    bool // the configured/fallback agent CLI is on PATH
	AvailableAgentIDs []string
}

HostCaps summarizes what the host can actually run, computed once at startup by the server (which owns agent-binary probing + the Apple-FM helper path). ResolveBackend consults it to turn backend=auto into a concrete choice.

type SummarizerConfig

type SummarizerConfig struct {
	Backend             string `json:"backend,omitempty"`                // auto|applefm|agentcli|disabled
	Agent               string `json:"agent,omitempty"`                  // auto|claude|pi|codex (agentcli)
	ActivityIntervalSec int    `json:"activity_interval_sec,omitempty"`  // line-2 debounce floor
	TitleIdleSec        int    `json:"title_idle_sec,omitempty"`         // line-1 idle re-derive
	TitleLongIdleSec    int    `json:"title_long_idle_sec,omitempty"`    // line-1 long-idle re-derive
	TitleMinIntervalSec int    `json:"title_min_interval_sec,omitempty"` // no re-derive within this of last
	// ConsentOffdevice gates non-applefm backends. Hosted agent CLIs
	// (claude/codex/pi) ship PTY tail + hook content off-device to a third
	// party; Apple FM runs on-device and needs no consent. Default false →
	// agentcli refuses until the user opts in. See docs/system-architecture.
	ConsentOffdevice bool `json:"consent_offdevice,omitempty"`
}

SummarizerConfig drives the live-activity one-liner (Line 2) and the model-derived session title (Line 1). Intervals are seconds; the server converts to time.Duration. A zero-value config (no file) resolves to: backend=auto, agent=claude, activity=12s, title-idle=5m, long-idle=30m, min-title=5m, consent=false (non-applefm refuses until set true).

func (SummarizerConfig) ActivityInterval

func (s SummarizerConfig) ActivityInterval() time.Duration

ActivityInterval, TitleIdle, TitleLongIdle, TitleMinInterval are the convenience Duration views used by the server tickers/debouncers.

func (SummarizerConfig) Defaults

func (s SummarizerConfig) Defaults() SummarizerConfig

Defaults returns a fully-resolved SummarizerConfig with every zero field filled. The server calls this after Load so downstream code never sees a zero interval. These mirror the documented defaults in docs/ + the plan.

func (SummarizerConfig) ResolveBackend

func (s SummarizerConfig) ResolveBackend(caps HostCaps) string

ResolveBackend turns backend=auto into a concrete backend given host capability. Locked policy (user 2026-08-12):

  • macOS: Apple FM if available, else agentcli (claude).
  • Linux/other: agentcli (claude).
  • agentcli needs an agent on PATH; if none, disabled.

Explicit (non-auto) backends are returned as-is — no silent fallback. The server separately enforces consent for non-applefm backends.

func (SummarizerConfig) ResolvedAgent

func (s SummarizerConfig) ResolvedAgent(caps HostCaps) string

ResolvedAgent turns agent=auto into a concrete agent ID given what is installed. Preference (user): claude → pi → codex. An explicit agent is returned as-is even if absent — the server then errors+degrades (advisory: no silent fallback).

func (SummarizerConfig) TitleIdle

func (s SummarizerConfig) TitleIdle() time.Duration

func (SummarizerConfig) TitleLongIdle

func (s SummarizerConfig) TitleLongIdle() time.Duration

func (SummarizerConfig) TitleMinInterval

func (s SummarizerConfig) TitleMinInterval() time.Duration

Jump to

Keyboard shortcuts

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