Skip to main content

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 โ€” --json output 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 [!] errored in 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-counters to 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: /proc on Linux, ps -o stat= on macOS)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bgo_cli-0.2.0.tar.gz (35.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bgo_cli-0.2.0-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

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

Hashes for bgo_cli-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e17d36616872d3fa560accb13ee523e886a16f1dacbbb5bcf0d858c63b9bb70d
MD5 7c3980828698e01ec11723d78a6389be
BLAKE2b-256 1e3bdfe0530c37ec5b680abf4859a7bea69961d0cce68f6ec83a27dc58a9a4ae

See more details on using hashes here.

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

Hashes for bgo_cli-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2484a75b95460ccfd5790ac56d26ff3d7ea5fdd6a7fc9a8faeaf74251529c8e7
MD5 e3939c149ea46d3be49ddffd2743e50e
BLAKE2b-256 7e2bddc01e01799bcf0bca03f2bd3146105f42333677ee51b78ee271034fe306

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page