Lightweight, zero-dependency background process manager (pm2-style) with watch mode and auto-restart.
Project description
bgo - Background Go
Lightweight, zero-dep background process manager inspired by pm2. Detach any binary or script from your shell with one command.
Features
- ๐ Simple syntax โ
bgo <name> -- <command> - ๐ง Unix-style aliases โ
bgo open/kill/rm/ls - ๐ Status monitoring โ CPU, memory, uptime in plain / normal / fancy tables (auto-detect)
- ๐ Log management โ stdout / stderr / watcher logs with follow mode
- ๐ Lifecycle โ start, stop, restart, restart-stopped, restart-last, resurrect
- ๐ Watch mode โ auto-restart crashed processes with fast-crash backoff
- ๐งน Auto-cleanup โ clean stopped procs; keep logs on delete if desired
- ๐ค Scriptable โ
--jsonoutput for any pipeline - โก Zero runtime dependencies โ pure Python 3.9+
Installation
# Via PyPI
pip install bgo-cli
# or
pipx install bgo-cli
# or
uv tool install bgo-cli
# Via the install script (system-wide, needs sudo)
./install.sh
# User-local (~/.local/bin, no sudo)
./install.sh --local
# Or manually โ bgo is a single file
cp bgo ~/.local/bin/ # or /usr/local/bin/
ln -s "$(pwd)/bgo" ~/.local/bin/bgo
Run ./install.sh --help for --force and --uninstall options.
Quick Start
# Start a process
bgo myserver -- python3 -m http.server 8080
bgo open myserver -- python3 -m http.server 8080 # alias
# Check status
bgo status # full alias chain: status / ls / list
bgo ls
# Status detail for one proc (or: bgo <registered-name>)
bgo myserver
# View logs
bgo logs myserver
bgo logs myserver -f # follow (tail -f)
bgo follow myserver # alias for logs -f
# Stop / restart / delete
bgo stop myserver # or: bgo kill myserver
bgo restart myserver
bgo delete myserver # or: bgo rm myserver
bgo rm myserver --keep-logs # preserve log files
# Bare `bgo` prints help; `bgo <unknown>` errors out (never silently spawns)
bgo
Commands
Lifecycle
| Command | Description |
|---|---|
bgo start <name> -- <cmd> |
Start a process (alias: open) |
bgo <name> -- <cmd> |
Shorthand for start |
bgo stop <name> |
Stop (SIGTERM, alias: kill) |
bgo stop <name> -f |
Force kill (SIGKILL) |
bgo restart <name> |
Restart; preserves watch state and counters |
bgo restart <name> --reset-counters |
Also zero watch.restarts |
bgo restart-stopped |
Pick stopped procs to restart (interactive) |
bgo restart-stopped --all |
Restart every stopped proc |
bgo restart-stopped <name>... |
Restart named stopped procs |
bgo restart-last |
Menu sorted most-recent-first |
bgo restart-last --all |
Restart all not-running procs in recent order |
bgo resurrect |
Restart all procs that were running before shutdown |
bgo delete <name> |
Remove proc + logs (alias: rm) |
bgo delete <name> --keep-logs |
Remove proc, keep logs |
bgo clean |
Drop all stopped procs from the list |
Inspection
| Command | Description |
|---|---|
bgo status |
Process table (alias: ls, list) |
bgo status <name> |
Detail view for one proc |
bgo status -w |
Watch mode (auto-refresh every 2s) |
bgo status -w --interval N |
Custom refresh interval |
bgo status --json |
Machine-readable output |
bgo status --plain |
ASCII-only output (no color, no glyphs) |
bgo status --fancy |
Force Unicode box-drawing rendering |
bgo <registered-name> |
Shorthand for bgo status <name> |
bgo logs <name> |
Last 50 lines |
bgo logs <name> -f |
Follow logs |
bgo logs <name> -n 100 |
Last 100 lines |
bgo logs <name> --stderr |
Only stderr |
bgo logs <name> --watcher |
Watcher event log |
bgo follow <name> |
Alias for logs -f (also: tail) |
Watch mode
| Command | Description |
|---|---|
bgo start -w <name> -- <cmd> |
Start with watcher attached |
bgo -w <name> <cmd> |
Direct mode with watcher |
bgo watch <name> |
Attach watcher to a running proc |
bgo watch <name> --interval N --min-uptime N --on-fast-crash MODE |
Tune |
bgo unwatch <name> |
Detach watcher, keep proc |
Examples
# Python HTTP server
bgo web -- python3 -m http.server 8080
# Node.js app with watcher
bgo -w api -- npm start
# Custom binary with working directory
bgo start dashboard --cwd /opt/app -- node server.js
# Inspect one proc
bgo web
# Scripted: stop every online proc via JSON
bgo status --json | python3 -c '
import json, sys, subprocess
for p in json.load(sys.stdin):
if p["status"] == "online":
subprocess.run(["bgo", "stop", p["name"]])
'
Status Table
The table auto-detects terminal capabilities and picks the best rendering:
| Level | Trigger | What you get |
|---|---|---|
plain |
non-TTY (pipes, CI logs), TERM=dumb, or --plain |
ASCII only, no color, no glyphs |
normal |
TTY without UTF-8 locale | ANSI color + ASCII rules |
fancy |
TTY + UTF-8 locale (default) | ANSI color + Unicode box-drawing |
Override with --plain / --fancy or BGO_TABLE=plain|normal|fancy.
Sample (fancy):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NAME STATUS PID CPU MEM UPTIME WATCH COMMAND โ
โฃโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโซ
โ web โ online 12345 2.5 0.1 00:05 โ 0 python3 -m http.server 8080 โ
โ api โ online 12346 0.0 0.0 01:23 โ 3 node server.js โ
โ worker โ stopped - - - - โ errored python3 worker.py โ
โ batch โ online 12347 0.0 0.0 02:11 ยท ./batch โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Total: 4 | โ online: 3 | โ stopped: 1
โ 1 errored:
worker โ 4 consecutive fast-crashes
bgo logs worker --watcher | bgo restart worker
CPU / MEM / uptime are pulled in a single batched ps call regardless of how many procs are running.
Watch Mode
Watch mode runs a sidecar process per watched proc that polls the
target and restarts it on crash. State (restart count, error reason,
last stderr tail) is recorded in the proc JSON and surfaced via
bgo status.
Quick start
bgo start -w myapi -- node server.js # start with watcher
bgo -w myapi node server.js # direct-mode variant
bgo watch myapi # attach to a running proc
bgo watch myapi --interval 5 --min-uptime 3 --on-fast-crash backoff
bgo unwatch myapi # detach, keep proc
bgo logs myapi --watcher # inspect events
Fast-crash policy
If a process dies before --min-uptime (default 2s) it's a fast crash. Reaction depends on --on-fast-crash:
| Mode | Behavior |
|---|---|
backoff (default) |
Wait 2s, retry. Then 4s, then 8s. After 4 consecutive fast-crashes, mark errored and exit watcher. |
stop |
Mark errored on the first fast-crash. |
retry |
Retry indefinitely, capped at 8s backoff. |
When a proc enters errored:
- WATCH column shows
โ errored(or[!] erroredin plain). - Status footer summarizes errored procs and hints at the recovery commands.
bgo status <name>detail shows the error reason and last stderr tail.bgo restart <name>clears the errored flag and re-spawns the watcher. Restart counter is preserved by default โ use--reset-countersto zero it.
Tunables
| Flag | Default | Notes |
|---|---|---|
--interval N |
3 | Poll interval after the initial uptime window |
--min-uptime N |
2 | Crash threshold; sub-window polled at high frequency |
--on-fast-crash MODE |
backoff |
One of backoff, stop, retry |
--reset |
off | bgo watch only โ reset prior watch config to defaults |
Storage
- State:
~/.bgo/procs/<name>.jsonโ one file per process, written atomically (tmp +os.replace) - Logs:
~/.bgo/logs/<name>.out.log,<name>.err.log,<name>.watcher.log
Testing
python3 -m pytest tests/ -v
54 tests covering state I/O, atomic writes, command-shape detection, name derivation, liveness + zombie filtering, watch-config inheritance, and table rendering across all three levels.
Requirements
- Python 3.9+
- Linux or macOS (zombie detection is platform-aware:
/procon Linux,ps -o stat=on macOS)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bgo_cli-0.2.0.tar.gz.
File metadata
- Download URL: bgo_cli-0.2.0.tar.gz
- Upload date:
- Size: 35.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e17d36616872d3fa560accb13ee523e886a16f1dacbbb5bcf0d858c63b9bb70d
|
|
| MD5 |
7c3980828698e01ec11723d78a6389be
|
|
| BLAKE2b-256 |
1e3bdfe0530c37ec5b680abf4859a7bea69961d0cce68f6ec83a27dc58a9a4ae
|
File details
Details for the file bgo_cli-0.2.0-py3-none-any.whl.
File metadata
- Download URL: bgo_cli-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2484a75b95460ccfd5790ac56d26ff3d7ea5fdd6a7fc9a8faeaf74251529c8e7
|
|
| MD5 |
e3939c149ea46d3be49ddffd2743e50e
|
|
| BLAKE2b-256 |
7e2bddc01e01799bcf0bca03f2bd3146105f42333677ee51b78ee271034fe306
|