bgo-cli 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ # Hindsight memory bank pointer (local)
2
+ .bank
3
+
4
+ # Serena MCP project state
5
+ .serena/
6
+
7
+ # PROJECT_INDEX (auto-generated)
8
+ PROJECT_INDEX.json
9
+ PROJECT_INDEX.md
10
+
11
+ # Hindsight migration markers
12
+ .hindsight-migrate-declined
13
+
14
+ # Python
15
+ __pycache__/
16
+ *.pyc
17
+ *.pyo
18
+ .pytest_cache/
19
+
20
+ # Build artifacts
21
+ build/
22
+ dist/
23
+ *.egg-info/
24
+ src/*.egg-info/
25
+
26
+ # Local virtualenvs
27
+ .venv/
28
+ venv/
29
+ .env
@@ -0,0 +1,191 @@
1
+ # Agent Instructions
2
+
3
+ <!-- TEAM_MODE:START -->
4
+ ## ⚡ Team Mode is ACTIVE
5
+ IMPORTANT: Read `TEAM.md` in the project root IN FULL before processing any task.
6
+ You are operating as Tech Lead of a multi-agent team, not as a solo developer.
7
+ If you don't remember Team Mode being activated, re-read `TEAM.md` NOW — it contains all instructions.
8
+ <!-- TEAM_MODE:END -->
9
+
10
+ <!-- myc:agents-start v=3 -->
11
+ ## Project Management with Mycelium
12
+
13
+ This project uses [Mycelium](https://github.com/tcsenpai/mycelium) (`myc`) for task and epic management.
14
+
15
+ ### Quick Reference
16
+
17
+ ```bash
18
+ # Initialize mycelium in this project (creates .mycelium/ directory)
19
+ myc init
20
+
21
+ # Create an epic (a large body of work)
22
+ myc epic create --title "Feature X" --description "Build feature X"
23
+
24
+ # Create tasks within an epic
25
+ myc task create --title "Implement Y" --description "Build the implementation for Y" --epic 1 --priority high --due 2025-12-31
26
+
27
+ # Task priorities: low, medium, high, critical
28
+ # Task status: open, closed
29
+
30
+ # List tasks
31
+ myc task list
32
+ myc task list --epic 1
33
+ myc task list --overdue
34
+ myc task list --blocked
35
+
36
+ # Manage dependencies (task 1 blocks task 2)
37
+ myc task link blocks --task 1 2
38
+ myc deps show 2
39
+
40
+ # Close tasks (blocked tasks cannot be closed without --force)
41
+ myc task close 1
42
+
43
+ # Assign tasks
44
+ myc assignee create --name "Alice" --github "alice"
45
+ myc task assign 1 1
46
+
47
+ # Link to external resources
48
+ myc task link github-issue --task 1 "owner/repo#123"
49
+ myc task link github-pr --task 1 "owner/repo#456"
50
+ myc task link url --task 1 "https://example.com"
51
+
52
+ # Project overview
53
+ myc summary
54
+
55
+ # Export data
56
+ myc export json
57
+ myc export csv
58
+ ```
59
+
60
+ ### Data Model
61
+
62
+ - **Epic**: A large body of work with a title and optional description (e.g., a feature or milestone)
63
+ - **Task**: A unit of work with a title and optional description, optionally linked to an epic
64
+ - **Dependency**: Task A blocks Task B (B cannot close until A is closed)
65
+ - **Assignee**: Person assigned to a task (can have GitHub username)
66
+ - **External Ref**: Link to GitHub issues/PRs or URLs
67
+
68
+ ### Git Tracking
69
+
70
+ The `.mycelium/` directory contains the SQLite database and should be committed to git:
71
+
72
+ ```bash
73
+ git add .mycelium/
74
+ git commit -m "Add mycelium project tracking"
75
+ ```
76
+
77
+ ### Follow-ups (`myc followup`, alias `myc fu`)
78
+
79
+ Lightweight scratch table for non-blocking "oh-by-the-way" items
80
+ captured mid-work — bugs, questions, ideas, things the user should look
81
+ at later. **Separate from tasks** (no epic/priority/deps/assignee). Most
82
+ follow-ups are resolved by the user, not the agent.
83
+
84
+ ```bash
85
+ myc followup add "body text" # capture (body required)
86
+ myc followup add "body text" --title "tag" # optional short title
87
+ myc fu add "short form alias works too"
88
+
89
+ myc followup list # all (default)
90
+ myc followup list -o # only active (open + in_progress)
91
+ myc followup list -c # only closed (done + wontfix)
92
+ myc followup list --status done # exact status
93
+
94
+ myc followup show <id> # full detail
95
+ myc followup next # lowest-ID active (agent loop)
96
+ myc followup count # JSON: {open, in_progress, done, wontfix}
97
+
98
+ myc followup start <id> # → in_progress
99
+ myc followup done <id> [--reason "..."] # → done
100
+ myc followup wontfix <id> [--reason "..."] # → wontfix
101
+ myc followup reopen <id> # → open
102
+
103
+ myc followup edit <id> --body "new body" [--title -|"new title"]
104
+ myc followup append <id> "more context" # timestamped, preserves existing
105
+ myc followup rm <id> [--force]
106
+ myc followup promote <id> [--epic N] [--priority high] # convert to task
107
+ ```
108
+
109
+ **Agent rule — end-of-task follow-up check** (MANDATORY)
110
+
111
+ At the end of every mycelium-tracked unit of work (closing a task,
112
+ finishing a user-requested change that touched myc state), the agent
113
+ MUST:
114
+
115
+ 1. Run `myc followup list --format json` (or `myc followup count
116
+ --format json`).
117
+ 2. If `active > 0`, surface them to the user before wrapping:
118
+ > "Before we wrap — N open follow-up(s): [titles/bodies]. Want me to
119
+ > handle any now, or leave for later?"
120
+ 3. **Never silently process them.** Always ask.
121
+
122
+ `myc task close` itself also prints a one-line reminder, but the agent
123
+ should still proactively check.
124
+
125
+ Use `myc followup add` during work to capture anything you notice but
126
+ shouldn't act on right now.
127
+
128
+ ### For AI Agents
129
+
130
+ When working on this project:
131
+
132
+ 1. Check existing tasks: `myc task list`
133
+ 2. Check blocked tasks: `myc task list --blocked`
134
+ 3. Create tasks for new work: `myc task create --title "..." --description "..." --epic N`
135
+ 4. Capture incidental observations as follow-ups: `myc followup add "..."`
136
+ 5. At end of task: `myc followup list` and surface open ones to the user
137
+ 6. Mark tasks complete when done: `myc task close N`
138
+ 7. Use `--format json` for machine-readable output: `myc task list --format json`
139
+
140
+ ## Mental Frameworks for Mycelium Usage
141
+
142
+ ### 1. INVEST — Task Quality Gate
143
+
144
+ Before creating or updating any task, validate it against these criteria.
145
+ A task that fails more than one is not ready to be written.
146
+
147
+ | Criterion | Rule |
148
+ |---|---|
149
+ | **Independent** | Can be completed without unblocking other tasks first |
150
+ | **Negotiable** | The *what* is fixed; the *how* remains open |
151
+ | **Valuable** | Produces a verifiable, concrete outcome |
152
+ | **Estimable** | If you cannot size it, it is too vague or too large |
153
+ | **Small** | If it spans more than one work cycle, split it |
154
+ | **Testable** | Has an explicit, binary done condition |
155
+
156
+ > If a task fails **Estimable** or **Testable**, convert it to an Epic and decompose.
157
+
158
+ ---
159
+
160
+ ### 2. DAG — Dependency Graph Thinking
161
+
162
+ Before scheduling or prioritizing, model the implicit dependency graph.
163
+
164
+ **Rules:**
165
+ - No task moves to `in_progress` if it has an unresolved upstream blocker
166
+ - Priority is a function of both urgency **and fan-out** (how many tasks does completing this one unlock?)
167
+ - Always work the **critical path** first — not the task that feels most urgent
168
+
169
+ **Prioritization heuristic:**
170
+ ```
171
+ score = urgency + (blocked_tasks_count × 1.5)
172
+ ```
173
+
174
+ When creating a task, explicitly ask: *"What does this block, and what blocks this?"*
175
+ Set dependency links in Mycelium before touching status.
176
+
177
+ ---
178
+
179
+ ### 3. Principle of Minimal Surprise (PMS)
180
+
181
+ Mycelium's state must remain predictable and auditable at all times.
182
+
183
+ **Rules:**
184
+ - **Prefer idempotent operations** — update before you create; never duplicate
185
+ - **Check before write** — search for an equivalent item before creating a new one
186
+ - **Always annotate mutations** — every status change, priority shift, or reassignment must carry an explicit `reason` field
187
+ - **No orphan tasks** — every task must be linked to an Epic; every Epic to a strategic goal
188
+ - Deletions are a last resort; prefer `cancelled` status with a reason
189
+
190
+ > The state of Mycelium after any operation must be explainable to another agent with zero context.
191
+ <!-- myc:agents-end -->
bgo_cli-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tcsenpai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bgo_cli-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: bgo-cli
3
+ Version: 0.2.0
4
+ Summary: Lightweight, zero-dependency background process manager (pm2-style) with watch mode and auto-restart.
5
+ Project-URL: Homepage, https://github.com/tcsenpai/bgo
6
+ Project-URL: Repository, https://github.com/tcsenpai/bgo
7
+ Project-URL: Issues, https://github.com/tcsenpai/bgo/issues
8
+ Project-URL: Changelog, https://github.com/tcsenpai/bgo/commits/main
9
+ Author-email: tcsenpai <tcsenpai@discus.sh>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: background,cli,daemon,pm2,process-manager,supervisor,watchdog
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: System Administrators
17
+ Classifier: Operating System :: MacOS :: MacOS X
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: System :: Systems Administration
27
+ Classifier: Topic :: Utilities
28
+ Requires-Python: >=3.9
29
+ Provides-Extra: dev
30
+ Requires-Dist: build>=1.0; extra == 'dev'
31
+ Requires-Dist: pytest>=7.0; extra == 'dev'
32
+ Requires-Dist: twine>=4.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # bgo - Background Go
36
+
37
+ Lightweight, zero-dep background process manager inspired by pm2.
38
+ Detach any binary or script from your shell with one command.
39
+
40
+ ## Features
41
+
42
+ - 🚀 **Simple syntax** — `bgo <name> -- <command>`
43
+ - 🐧 **Unix-style aliases** — `bgo open` / `kill` / `rm` / `ls`
44
+ - 📊 **Status monitoring** — CPU, memory, uptime in plain / normal / fancy tables (auto-detect)
45
+ - 📝 **Log management** — stdout / stderr / watcher logs with follow mode
46
+ - 🔄 **Lifecycle** — start, stop, restart, restart-stopped, restart-last, resurrect
47
+ - 👁 **Watch mode** — auto-restart crashed processes with fast-crash backoff
48
+ - 🧹 **Auto-cleanup** — clean stopped procs; keep logs on delete if desired
49
+ - 🤖 **Scriptable** — `--json` output for any pipeline
50
+ - ⚡ **Zero runtime dependencies** — pure Python 3.9+
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ # Via PyPI
56
+ pip install bgo-cli
57
+ # or
58
+ pipx install bgo-cli
59
+ # or
60
+ uv tool install bgo-cli
61
+
62
+ # Via the install script (system-wide, needs sudo)
63
+ ./install.sh
64
+
65
+ # User-local (~/.local/bin, no sudo)
66
+ ./install.sh --local
67
+
68
+ # Or manually — bgo is a single file
69
+ cp bgo ~/.local/bin/ # or /usr/local/bin/
70
+ ln -s "$(pwd)/bgo" ~/.local/bin/bgo
71
+ ```
72
+
73
+ Run `./install.sh --help` for `--force` and `--uninstall` options.
74
+
75
+ ## Quick Start
76
+
77
+ ```bash
78
+ # Start a process
79
+ bgo myserver -- python3 -m http.server 8080
80
+ bgo open myserver -- python3 -m http.server 8080 # alias
81
+
82
+ # Check status
83
+ bgo status # full alias chain: status / ls / list
84
+ bgo ls
85
+
86
+ # Status detail for one proc (or: bgo <registered-name>)
87
+ bgo myserver
88
+
89
+ # View logs
90
+ bgo logs myserver
91
+ bgo logs myserver -f # follow (tail -f)
92
+ bgo follow myserver # alias for logs -f
93
+
94
+ # Stop / restart / delete
95
+ bgo stop myserver # or: bgo kill myserver
96
+ bgo restart myserver
97
+ bgo delete myserver # or: bgo rm myserver
98
+ bgo rm myserver --keep-logs # preserve log files
99
+
100
+ # Bare `bgo` prints help; `bgo <unknown>` errors out (never silently spawns)
101
+ bgo
102
+ ```
103
+
104
+ ## Commands
105
+
106
+ ### Lifecycle
107
+
108
+ | Command | Description |
109
+ |---|---|
110
+ | `bgo start <name> -- <cmd>` | Start a process (alias: `open`) |
111
+ | `bgo <name> -- <cmd>` | Shorthand for start |
112
+ | `bgo stop <name>` | Stop (SIGTERM, alias: `kill`) |
113
+ | `bgo stop <name> -f` | Force kill (SIGKILL) |
114
+ | `bgo restart <name>` | Restart; preserves watch state and counters |
115
+ | `bgo restart <name> --reset-counters` | Also zero `watch.restarts` |
116
+ | `bgo restart-stopped` | Pick stopped procs to restart (interactive) |
117
+ | `bgo restart-stopped --all` | Restart every stopped proc |
118
+ | `bgo restart-stopped <name>...` | Restart named stopped procs |
119
+ | `bgo restart-last` | Menu sorted most-recent-first |
120
+ | `bgo restart-last --all` | Restart all not-running procs in recent order |
121
+ | `bgo resurrect` | Restart all procs that were running before shutdown |
122
+ | `bgo delete <name>` | Remove proc + logs (alias: `rm`) |
123
+ | `bgo delete <name> --keep-logs` | Remove proc, keep logs |
124
+ | `bgo clean` | Drop all stopped procs from the list |
125
+
126
+ ### Inspection
127
+
128
+ | Command | Description |
129
+ |---|---|
130
+ | `bgo status` | Process table (alias: `ls`, `list`) |
131
+ | `bgo status <name>` | Detail view for one proc |
132
+ | `bgo status -w` | Watch mode (auto-refresh every 2s) |
133
+ | `bgo status -w --interval N` | Custom refresh interval |
134
+ | `bgo status --json` | Machine-readable output |
135
+ | `bgo status --plain` | ASCII-only output (no color, no glyphs) |
136
+ | `bgo status --fancy` | Force Unicode box-drawing rendering |
137
+ | `bgo <registered-name>` | Shorthand for `bgo status <name>` |
138
+ | `bgo logs <name>` | Last 50 lines |
139
+ | `bgo logs <name> -f` | Follow logs |
140
+ | `bgo logs <name> -n 100` | Last 100 lines |
141
+ | `bgo logs <name> --stderr` | Only stderr |
142
+ | `bgo logs <name> --watcher` | Watcher event log |
143
+ | `bgo follow <name>` | Alias for `logs -f` (also: `tail`) |
144
+
145
+ ### Watch mode
146
+
147
+ | Command | Description |
148
+ |---|---|
149
+ | `bgo start -w <name> -- <cmd>` | Start with watcher attached |
150
+ | `bgo -w <name> <cmd>` | Direct mode with watcher |
151
+ | `bgo watch <name>` | Attach watcher to a running proc |
152
+ | `bgo watch <name> --interval N --min-uptime N --on-fast-crash MODE` | Tune |
153
+ | `bgo unwatch <name>` | Detach watcher, keep proc |
154
+
155
+ ## Examples
156
+
157
+ ```bash
158
+ # Python HTTP server
159
+ bgo web -- python3 -m http.server 8080
160
+
161
+ # Node.js app with watcher
162
+ bgo -w api -- npm start
163
+
164
+ # Custom binary with working directory
165
+ bgo start dashboard --cwd /opt/app -- node server.js
166
+
167
+ # Inspect one proc
168
+ bgo web
169
+
170
+ # Scripted: stop every online proc via JSON
171
+ bgo status --json | python3 -c '
172
+ import json, sys, subprocess
173
+ for p in json.load(sys.stdin):
174
+ if p["status"] == "online":
175
+ subprocess.run(["bgo", "stop", p["name"]])
176
+ '
177
+ ```
178
+
179
+ ## Status Table
180
+
181
+ The table auto-detects terminal capabilities and picks the best rendering:
182
+
183
+ | Level | Trigger | What you get |
184
+ |---|---|---|
185
+ | `plain` | non-TTY (pipes, CI logs), `TERM=dumb`, or `--plain` | ASCII only, no color, no glyphs |
186
+ | `normal` | TTY without UTF-8 locale | ANSI color + ASCII rules |
187
+ | `fancy` | TTY + UTF-8 locale (default) | ANSI color + Unicode box-drawing |
188
+
189
+ Override with `--plain` / `--fancy` or `BGO_TABLE=plain|normal|fancy`.
190
+
191
+ Sample (fancy):
192
+ ```
193
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
194
+ ┃ NAME STATUS PID CPU MEM UPTIME WATCH COMMAND ┃
195
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
196
+ ┃ web ● online 12345 2.5 0.1 00:05 ✓ 0 python3 -m http.server 8080 ┃
197
+ ┃ api ● online 12346 0.0 0.0 01:23 ✓ 3 node server.js ┃
198
+ ┃ worker ○ stopped - - - - ⚠ errored python3 worker.py ┃
199
+ ┃ batch ● online 12347 0.0 0.0 02:11 · ./batch ┃
200
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
201
+ Total: 4 | ● online: 3 | ○ stopped: 1
202
+
203
+ ⚠ 1 errored:
204
+ worker — 4 consecutive fast-crashes
205
+ bgo logs worker --watcher | bgo restart worker
206
+ ```
207
+
208
+ CPU / MEM / uptime are pulled in a single batched `ps` call regardless of how many procs are running.
209
+
210
+ ## Watch Mode
211
+
212
+ Watch mode runs a sidecar process per watched proc that polls the
213
+ target and restarts it on crash. State (restart count, error reason,
214
+ last stderr tail) is recorded in the proc JSON and surfaced via
215
+ `bgo status`.
216
+
217
+ ### Quick start
218
+
219
+ ```bash
220
+ bgo start -w myapi -- node server.js # start with watcher
221
+ bgo -w myapi node server.js # direct-mode variant
222
+ bgo watch myapi # attach to a running proc
223
+ bgo watch myapi --interval 5 --min-uptime 3 --on-fast-crash backoff
224
+ bgo unwatch myapi # detach, keep proc
225
+ bgo logs myapi --watcher # inspect events
226
+ ```
227
+
228
+ ### Fast-crash policy
229
+
230
+ If a process dies before `--min-uptime` (default 2s) it's a *fast crash*. Reaction depends on `--on-fast-crash`:
231
+
232
+ | Mode | Behavior |
233
+ |---|---|
234
+ | `backoff` (default) | Wait 2s, retry. Then 4s, then 8s. After 4 consecutive fast-crashes, mark `errored` and exit watcher. |
235
+ | `stop` | Mark `errored` on the first fast-crash. |
236
+ | `retry` | Retry indefinitely, capped at 8s backoff. |
237
+
238
+ When a proc enters `errored`:
239
+ - WATCH column shows `⚠ errored` (or `[!] errored` in plain).
240
+ - Status footer summarizes errored procs and hints at the recovery commands.
241
+ - `bgo status <name>` detail shows the error reason and last stderr tail.
242
+ - `bgo restart <name>` clears the errored flag and re-spawns the watcher. Restart counter is **preserved** by default — use `--reset-counters` to zero it.
243
+
244
+ ### Tunables
245
+
246
+ | Flag | Default | Notes |
247
+ |---|---|---|
248
+ | `--interval N` | 3 | Poll interval after the initial uptime window |
249
+ | `--min-uptime N` | 2 | Crash threshold; sub-window polled at high frequency |
250
+ | `--on-fast-crash MODE` | `backoff` | One of `backoff`, `stop`, `retry` |
251
+ | `--reset` | off | `bgo watch` only — reset prior watch config to defaults |
252
+
253
+ ## Storage
254
+
255
+ - State: `~/.bgo/procs/<name>.json` — one file per process, written atomically (tmp + `os.replace`)
256
+ - Logs: `~/.bgo/logs/<name>.out.log`, `<name>.err.log`, `<name>.watcher.log`
257
+
258
+ ## Testing
259
+
260
+ ```bash
261
+ python3 -m pytest tests/ -v
262
+ ```
263
+
264
+ 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.
265
+
266
+ ## Requirements
267
+
268
+ - Python 3.9+
269
+ - Linux or macOS (zombie detection is platform-aware: `/proc` on Linux, `ps -o stat=` on macOS)
270
+
271
+ ## License
272
+
273
+ MIT