Skip to main content

CLI reference

omnitron <command> is the single binary. It is a thin Netron client — every command opens a connection to ~/.omnitron/daemon.sock, makes an RPC call, and exits. The daemon does the real work.

Verified against src/cli/omnitron.ts and src/commands/*.

Global options

Option / EnvEffect
--json / OMNITRON_OUTPUT=jsonMachine-readable JSON; suppresses spinners and styling
--versionPrint CLI version
--helpPer-command help

The --json flag is honoured by every command. Use it from CI / scripts / agent bots so output is parseable.

Command index

GroupCommands
Daemon lifecycleup, down, ping, kill
Projectproject add, project list, project remove, project scan
Stackstack list, stack create, stack delete, stack status, stack start, stack stop, stack runtime
App lifecyclestart, stop, restart, reload
Informationlist (alias ls), status, config, init
Monitoringlogs, monit, health, metrics, health-check, discover
Scalingscale
Diagnosticsdoctor, inspect, exec, env
Remoteremote add, remote remove, remote list, remote status
Fleetfleet status, fleet health, fleet metrics
Clustercluster status, cluster step-down
Secretssecret set, secret get, secret list, secret delete
Deploymentdeploy app, deploy build, rollback
Infrastructureinfra up, infra down, infra status (ps), infra logs, infra psql, infra redis-cli, infra migrate, infra reset
Pipelinespipeline list, pipeline run, pipeline status
Backupbackup create, backup list, backup restore
Kubernetesk8s pods, k8s deploy scale
Nodesnode list, node add, node update, node remove, node check, node ssh-keys
Webappwebapp build, webapp start, webapp stop, webapp status, webapp open
Tortor
Knowledge basekb mcp, kb index, kb status, kb query

Daemon lifecycle

omnitron up

Start the daemon in the background. Auto-detects omnitron.config.ts at the current working directory or any ancestor.

OptionEffect
-c, --config <path>Explicit path to omnitron.config.ts
-p, --project <name>Initial project name (default: auto-detect from CWD)
-f, --foregroundBlock the terminal — useful for tail -F style use
--no-infraSkip Docker infrastructure provisioning
--no-watchDisable file watching daemon-wide
--masterFirst-run: configure as master in a cluster
--slave [host:port]First-run: configure as slave; optional master address
--webapp / --no-webappToggle automatic console UI start

omnitron down

Stop the daemon — gracefully stops every project, stack, and infrastructure container.

omnitron ping

Probe whether the daemon is alive. Exit code 0 = up, non-zero = down.

omnitron kill

Force-kill the daemon process. Use only when down doesn't respond.

omnitron service install|uninstall|status

Hand supervision of the daemon itself to the operating system. Omnitron supervises apps and infrastructure; without this, nothing supervises the daemon, so a daemon crash — disk full, a load spike, a container-runtime hiccup — leaves every managed app down until someone runs omnitron up by hand.

CommandEffect
omnitron service installRegister and start the OS service
omnitron service uninstallStop the supervised daemon and remove the service
omnitron service statusWhether the OS is supervising, and what it reports
PlatformWhat is written
macOSLaunchAgent at ~/Library/LaunchAgents/dev.omnitron.daemon.plist
Linuxsystemd user unit at ~/.config/systemd/user/omnitron-daemon.service

Restarts are crash-only, so up and down keep meaning what they meant. A graceful omnitron down exits 0 and stays down; a crash or a SIGKILL exits abnormally and is respawned (KeepAlive={SuccessfulExit:false} on launchd, Restart=on-failure on systemd). Installing the service does not take down away from you.

The supervisor runs the same daemon-entry.js that omnitron up forks — one daemon codepath with two launchers — and that entry point holds a single-instance pid guard, so the two can never both bind.

Project management

A project is a named directory containing an omnitron.config.ts. Register many projects to one daemon; operate on them by name.

CommandEffect
omnitron project add <name> <path>Register a seed project
omnitron project list (alias proj list)List registered projects
omnitron project remove <name>Unregister (does not delete files)
omnitron project scanScan app bootstraps and report their infrastructure requirements

Aliases: omnitron proj works the same as omnitron project.

Stack management

A stack is a named environment within a project (typical values: dev, staging, prod). Stacks scope deployments and infrastructure to a subset of the project's apps.

CommandEffect
omnitron stack list [-p project] (alias stacks list)All stacks across all projects (filter with -p, --project)
omnitron stack create <project> <stack> [-t type] [-a apps]Create a new stack (-t, --type local|remote|cluster, default local; -a, --apps comma-separated names or all, default all)
omnitron stack delete <project> <stack>Drop a stack
omnitron stack status <project> <stack>Per-app status within the stack
omnitron stack start <project> <stack>Start everything in the stack
omnitron stack stop <project> <stack>Stop everything in the stack
omnitron stack runtime <project> <stack>Show runtime details (containers, ports)

App lifecycle

These commands accept an [app] argument. With no app, they operate on all managed apps.

CommandEffect
omnitron start [app]Start app(s); auto-starts the daemon if needed
omnitron stop [app] [-f]Graceful stop; -f/--force to SIGKILL
omnitron restart [app]Stop + start
omnitron reload [app]Zero-downtime reload — workers cycle one at a time

Information

CommandEffect
omnitron list (alias ls)One row per app, then one per topology process
omnitron statusDaemon-wide overview (apps, uptime, leader, infra)
omnitron config [--json]Print the resolved ecosystem config
omnitron initScaffold omnitron.config.ts in the CWD

Reading the child rows of omnitron list. Each indented row is one entry of the app's process topology, and two of its columns say something a single number cannot.

A pool entry — one declaring instances > 1 — runs several processes and the row prints one of their pids, so it also prints its live worker count: transform (worker) ×2. When that count has drifted from what the topology declares it is shown as ×1/2 in yellow; doctor reports the same drift as a finding.

RST shows -, not 0, when nothing counts that row's restarts. The supervisor keeps a restart count per child, and a pool is not a supervisor child, so for a pool row the honest answer is that it is not tracked. 0 would leave "never restarted" and "not counted" looking identical.

UPTIME is the uptime of the process whose pid the row prints — not the app's. A child that restarted an hour ago under an app that has been up for a week reads one hour.

Monitoring

omnitron logs [app]

Tail logs. Omit [app] to read the daemon's own log.

OptionEffect
-f, --followStream new entries
-n, --lines <N>Show last N entries (default 50)
-l, --level <lvl>Min level: `trace
-g, --grep <pattern>Filter by message regex
--fileRead from log files (auto-fallback when daemon offline)

omnitron monit

Live TUI dashboard — terminal app showing per-process CPU / RSS / restart counts in real time. Quit with q.

omnitron health [app]

Composite health report from titan-health indicators.

omnitron metrics [app]

Snapshot of current CPU / memory / latency / RPC counters.

omnitron health-check [app]

Detailed composable health report — runs HTTP/TCP probes against declared endpoints.

omnitron discover

Scan Docker + SSH on known hosts for Omnitron-managed processes not yet in the registry. Useful when migrating in an existing fleet.

Scaling

omnitron scale <app> <count>

Scale an app's worker pool to <count> instances. The pool respects the app's IProcessEntry.scaling constraints (maxInstances, targetCPU, etc.).

Diagnostics

omnitron doctor

One pass over the whole installation, reporting problems with the evidence that identifies them and the command that fixes them.

It reads the database directly rather than through the daemon, because a daemon whose schema has gone missing still answers RPCs perfectly well.

What it examines. Every finding's id begins with the area it came from, so this table is the same list the output uses:

AreaWhat it looks at
daemonWhether it answers, how fast, whether it restarted recently, whether it is aggregating metrics
appManaged apps and their sub-processes, and the ports they claim against the ports they answer on
infraInfrastructure containers, their health, their published ports, and containers detached from the stack
dbReachability, the tables the daemon needs, pending migrations, and a table that is bloated rather than merely large
buildSources newer than their build output, sources never built, and a daemon older than the build it is running
webappWhether the console is being served and whether its proxy reaches the daemon
logsOne message dominating the day's errors; repetition dominating while no single message does; lines stored twice; an operation being retried without limit
alertsEnabled alert rules whose expression can never fire
metricsWhether any CPU or memory reading is arriving at all
projectEvery registered project's config, read from the file rather than from the daemon
authWhich RPC methods answer without credentials, and whether the daemon is reachable off this host
doctorA check that failed on its own account, so a gap is never silent
OptionEffect
--jsonMachine-readable output (see below)

Exit code is 1 when any finding has severity error, so it works as a CI gate.

What "no problems found" means. A check that cannot run is reported separately from one that ran and found nothing:

[?] 5 area(s) not examined:
db.pending-migrations — not checked: whether every migration
has been applied — the database stopped answering
...

An unreachable database takes five checks down with it and a daemon that is not answering takes seven. Without that section a silent gap and a clean result print identically, and they point an operator in opposite directions.

In --json the same distinction is two fields:

{
"ok": false,
"complete": false,
"worst": "error",
"findings": [ { "id": "db.unreachable", "severity": "error", "title": "…",
"evidence": ["…"], "remedy": "…" } ],
"skipped": [ { "id": "logs.*", "reason": "not checked: … — the database stopped answering" } ]
}

ok is "nothing was found"; complete is "everything was looked at". A gate that reads only ok cannot tell a healthy installation from an unexamined one.

Findings carry a stable iddb.unreachable, app.port-unreachable, infra.detached, build.stale-sources, auth.anonymous-surface, logs.retry-loop, project.config-unloadable and so on. A skipped entry names the id its check would have reported under, or prefix.* where a check reports several.

project.config-unloadable is worth knowing about before you need it: the daemon refuses to start against a config it cannot load, rather than starting with no apps, so this finding is what a failed omnitron up in that project's directory would have told you. The check reads the files rather than asking the daemon, because a daemon holding a config it loaded hours ago cannot tell you the file has been edited since.

omnitron inspect <app>

Deep diagnostics for an app — services exposed, memory breakdown, pending requests.

OptionEffect
--graphRender live DI dependency graph instead of memory/services
`--format <mermaiddot
--focus <token>Restrict the graph to one token + its closure
`--direction <ancestorsdescendants

omnitron exec <app> <service> <method> [args...]

Invoke an RPC method on a managed app:

omnitron exec api users findById u_42

Arguments are parsed as JSON when they look like JSON, otherwise strings.

omnitron env <app>

Show resolved environment variables for an app (after merging project / stack / per-app overrides).

Remote daemons

Register remote daemons as named aliases and address them via omnitron remote <alias>.

CommandEffect
omnitron remote add <alias> <host> [-p port] [-t tags]Register a remote (default port 9700)
omnitron remote remove <alias>Unregister
omnitron remote listList registered remotes
omnitron remote status <alias>Check connectivity

Fleet operations

Aggregate across all remotes (and the local daemon).

CommandEffect
omnitron fleet statusStatus across the fleet
omnitron fleet healthHealth across the fleet
omnitron fleet metricsAggregated metrics across the fleet

Cluster (leader election)

CommandEffect
omnitron cluster statusCurrent leader, follower list, election term
omnitron cluster step-downForce the current leader to step down

Cluster operations require cluster.enabled: true in the daemon config.

Secrets (encrypted at rest)

CommandEffect
omnitron secret set <key> <value>Store an encrypted secret
omnitron secret get <key>Read a decrypted secret
omnitron secret listList all keys (values hidden)
omnitron secret delete <key>Delete a secret

Backed by ~/.omnitron/secrets.enc (file provider) or an external secret manager when configured.

Deployment

omnitron deploy app <app>

Deploy an app with a strategy.

OptionEffect
-s, --strategy <strategy>`rolling
-v, --version <version>Version label (git SHA / tag)
-t, --target <server>Target server alias or tag

omnitron deploy build <app>

Build a deployment artifact: a tarball of the app + its workspace dependencies, suitable for shipping to remote nodes.

omnitron rollback <app>

Rollback an app to its previous deployed version.

OptionEffect
-t, --target <server>Target server alias or tag

Tor

omnitron tor

Show the Tor hidden-service onion addresses for the running stack. Top-level command; no flags.

Infrastructure

Manage infrastructure containers (Postgres / Redis / MinIO / custom) provisioned per app's omnitronConfig.infrastructure.

CommandEffect
omnitron infra upProvision and start all infra services
omnitron infra down [--volumes]Stop containers; --volumes also removes data
omnitron infra status (alias infra ps)Container status
omnitron infra logs [service] [-f] [-n N]View logs for one or all infra services
omnitron infra psql [database]Open psql shell
omnitron infra redis-cliOpen redis-cli shell
omnitron infra migrate [app]Run database migrations
omnitron infra reset [--yes]DESTRUCTIVE — drop and recreate all data

Pipelines (CI/CD)

CommandEffect
omnitron pipeline listList all pipelines
omnitron pipeline run <id>Execute a pipeline by ID
omnitron pipeline status <runId>Check a run's status

Backups

CommandEffect
omnitron backup create [database]Back up one database, or every running-stack database with no argument
omnitron backup fullEverything: all stack databases plus MinIO storage, Tor keys and the daemon's own state
omnitron backup listList available backups
omnitron backup restore <id>Restore from a backup
omnitron backup schedule <target> <cron>Schedule a backup; <target> may be all
omnitron backup schedulesList configured schedules
omnitron backup unschedule <target>Remove a schedule

full is not a bigger create. create backs up databases; full also takes the object storage, the Tor keys and the daemon state — the three things that are not in any database and that a restored stack is useless without. It reports per target, so a partial result is visible rather than aggregated into one success or failure, and it says so plainly when there is nothing to back up because no stack is running.

Schedules live in the daemon and survive its restarts, so schedule is not a substitute for host cron in one respect only: nothing runs while the daemon is down. <target> takes all to mean every database of every running stack.

Kubernetes

CommandEffect
omnitron k8s pods [namespace]List Kubernetes pods
omnitron k8s deploy scale <name> <replicas> [-n namespace]Scale a deployment

Nodes (infrastructure machines)

Register physical / virtual machines for fleet operations and remote deploys. Different from remote daemons — nodes are SSH targets that may or may not run a daemon.

CommandEffect
omnitron node list (alias ls)All registered nodes
omnitron node add ...Register a node (see flags below)
omnitron node update <id> ...Update a node
omnitron node remove <id> (alias rm)Remove a node
omnitron node check [id]Connectivity check (all nodes if omitted)
omnitron node ssh-keysList available SSH keys from ~/.ssh/

omnitron node add flags

FlagRequiredDefault
--name <name>yes
--host <host>yes
--ssh-port <port>22
--ssh-user <user>root
--ssh-auth <method>key (or password)
--ssh-key <path>
`--runtime <nodebun>`
--daemon-port <port>9700
--tags <a,b,c>

Webapp (console UI)

CommandEffect
omnitron webapp buildBuild the React + Vite bundle
omnitron webapp start [-f]Start nginx container serving static + gateway (-f, --force recreates a running container)
omnitron webapp stopStop the webapp nginx container
omnitron webapp statusShow webapp status
omnitron webapp openOpen the webapp in the system browser

Knowledge base (MCP)

CommandEffect
omnitron kb mcpStart MCP stdio server for AI assistants
omnitron kb index [--full] [--watch]Reindex the knowledge base
omnitron kb statusKB index health and statistics
omnitron kb query <question>Test a query against the KB

Exit codes

CodeMeaning
0Success
1General failure (RPC error, config error, etc.)
2Daemon not reachable
3Authorization failed

Combined with --json output, this is enough to drive any CI or agent pipeline.

Tips

  • omnitron --json status | jq ... — pipe to jq for any scriptable check.
  • omnitron logs my-app -f --grep error — narrow follow on a hot pattern.
  • omnitron exec my-app users findById '"u_42"' — note the quoted JSON string for the arg.
  • omnitron status before up — checking what's already running prevents accidental double-start.
  • omnitron --json in agent workflows — never parse the styled output; it's not stable.

See also