systemg

Search docs

/
Install

Examples

Units

A unit is the shortest path from an ad-hoc command to systemg supervision. Use one when you want systemg to manage a database tunnel, development server, watcher, script, or other command without writing a project manifest first.

$ sysg start --daemonize --name db-tunnel -- sh db-tunnel.sh

When --name is omitted, systemg generates a unit name from the command.

Info

Staging is translation. systemg writes your command as a generated version 2 manifest—the format its central supervisor understands for every service and project. The generated unit is project-less, so the supervisor manages it in the __loose__ bundle. Its command runs from the directory where it was staged, even though the generated manifest lives elsewhere.

From command to running unit

sysg start -- <command...> always stages the command first. What happens next depends on whether a supervisor already exists:

  • No supervisor is running: the staged manifest starts a new supervisor and the unit runs immediately.
  • A supervisor is already running: systemg writes the manifest but leaves the live supervisor unchanged. The unit has been staged, but it is not yet registered and no process has started for it.

Info

The explicit apply step protects the supervisor's live topology. An ad-hoc command cannot silently add work while the supervisor is managing other services and projects. Applying the staged manifest gives systemg a clear point to validate it and reconcile it into the live state.

For a resident supervisor, systemg prints the exact command required to apply the unit:

Unit staged at ~/.local/share/systemg/units/db-tunnel-<hash>.yaml.
Run `sysg start --daemonize --config ~/.local/share/systemg/units/db-tunnel-<hash>.yaml` to apply it.

Run that printed command, then inspect the unit normally:

$ sysg start --daemonize --config ~/.local/share/systemg/units/db-tunnel-<hash>.yaml
$ sysg status
$ sysg logs --service db-tunnel
$ sysg stop --service db-tunnel

Common examples

Run a shell script under supervision.

$ sysg start --daemonize -- sh foo.sh

Keep a lightweight HTTP server alive.

$ sysg start --daemonize -- python3 -m http.server 8080

Tail application logs under supervision.

$ sysg start --daemonize -- tail -F ./logs/app.log

Run a frontend development server.

$ sysg start --daemonize -- npm run dev

Run a backend API in reload mode.

$ sysg start --daemonize -- uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

Run a worker with explicit queue and concurrency settings.

$ sysg start --daemonize -- sh -lc 'QUEUE=critical CONCURRENCY=4 ./bin/worker'

Run a live TypeScript watcher and build loop.

$ sysg start --daemonize -- sh -lc 'pnpm install && pnpm run dev:watch'

Run a periodic heartbeat loop.

$ sysg start --daemonize -- sh -lc 'while true; do date; sleep 30; done'

Run a composed multi-step local pipeline.

$ sysg start --daemonize -- sh -lc 'pnpm db:migrate && pnpm run seed && pnpm run start:prod'

Where staged units are stored

Generated unit manifests are saved under:

~/.local/share/systemg/units/*.yaml

systemg prunes manifests older than 30 days and retains the newest 200 files when it stages new units.

Warning

Treat this directory as staging space. For a long-lived unit, copy its generated manifest to a durable path before applying it, then pass that path to sysg start --config. The registered path becomes the supervisor's source of truth for later restarts.

Once applied, a unit's runtime state—PIDs and service lifecycle state—persists under ~/.local/share/systemg/projects/__loose__/. See State.

CRUD ApplicationOrchestrator