@stablekernel/pi-background-run 0.3.0 → 0.5.0
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.
- package/README.md +108 -23
- package/extension/index.test.ts +1320 -50
- package/extension/index.ts +842 -230
- package/package.json +1 -1
- package/skill/run-bg/SKILL.md +32 -10
package/README.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Run long shell commands (test suites, builds, linters) as detached background jobs
|
|
4
4
|
so your pi agent session stays unblocked and its context stays clean. Output lands
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
on disk — the full log plus a trailing exit marker — so nothing large ever enters
|
|
6
|
+
the conversation; the command returns immediately. When the job finishes,
|
|
7
|
+
pi-background-run **wakes the live agent session** so it proactively reads a
|
|
8
|
+
condensed digest of the results and continues — no polling, no human intervention.
|
|
8
9
|
|
|
9
10
|
Built as a [pi](https://github.com/earendil-works/pi-coding-agent) extension. No
|
|
10
11
|
shell runner, no poller, no sidecar files — the extension spawns the job in-process,
|
|
@@ -18,9 +19,6 @@ the agent. The log file is self-describing (full output + a trailing
|
|
|
18
19
|
pi install npm:pi-background-run
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
> The npm package is `pi-background-run` — npm blocked the name `pi-bgrun`
|
|
22
|
-
> (too similar to the existing `pi-bg-run`).
|
|
23
|
-
|
|
24
22
|
Or the scoped alias (same code, permanent namespace claim):
|
|
25
23
|
|
|
26
24
|
```bash
|
|
@@ -35,17 +33,36 @@ Restart pi after install so the extension loads.
|
|
|
35
33
|
| ------ | --------- |
|
|
36
34
|
| `bgrun` | Launch a command detached in the background. Optional `name` gives the job a short human-readable label. Returns `started: <job-id>` immediately. Wakes the session automatically on completion. |
|
|
37
35
|
| `bgstatus` | Show job status. With an id: any job's state + exit code. Without: this session's running jobs (finished jobs hidden by default — pass `includeDone: true` or set `showCompletedJobs`). Jobs from other sessions are only listed when `adoptForeignJobs` is enabled. |
|
|
38
|
-
| `bgtail` |
|
|
39
|
-
| `
|
|
36
|
+
| `bgtail` | Read the newest lines of a job's log (default 40), **condensed for context**: ANSI escapes stripped, repeated lines collapsed, long lines and total size capped. First read = full last-N tail; repeat reads return **only lines appended since your last read** (delta tailing) — polling a running job never re-pays for lines already seen. Pass `raw: true` for the unprocessed last-N window (still advances the bookmark). |
|
|
37
|
+
| `bggrep` | Regex search over a job's log: line-numbered matches, optional `context` lines, capped (~50 matches, ~2KB/line, ~8KB) and condensed. Runs inside the extension, so it reaches **any** jobs dir — including global logs that project-sandboxed tools (`ctx_execute_file`) cannot. With no `pattern`, a generic failure-signature default is used (override it — convenience, not guarantee). |
|
|
38
|
+
| `bgclean` | Remove old job logs. **Default scope: this session's jobs only** — other sessions' logs are untouched. Pass `all: true` to sweep the whole shared jobs dir. Retention: `cleanupDays` config (7 days). Never removes a running job's log. |
|
|
39
|
+
|
|
40
|
+
## Slash commands
|
|
41
|
+
|
|
42
|
+
Human-facing mirrors of the read/clean tools, usable directly in the TUI
|
|
43
|
+
without asking the agent (registered via `pi.registerCommand` — a separate
|
|
44
|
+
registration from the agent tools above, which is why tools alone never show
|
|
45
|
+
up as `/` commands):
|
|
46
|
+
|
|
47
|
+
| Command | Purpose |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `/bgstatus [id] [done]` | One job's status by id, or the session listing (`done`/`all` includes finished jobs). |
|
|
50
|
+
| `/bgtail <id> [lines]` | Tail a job's log (condensed, same as the tool). |
|
|
51
|
+
| `/bgclean [days] [all]` | Remove old logs — session-scoped by default; `all` sweeps every session's. |
|
|
40
52
|
|
|
41
|
-
`
|
|
42
|
-
|
|
53
|
+
`/bgrun` is deliberately not a command — starting jobs (and reacting to their
|
|
54
|
+
wake messages) is the agent's workflow.
|
|
55
|
+
|
|
56
|
+
## Roadmap / not provided
|
|
57
|
+
|
|
58
|
+
- `bgkill` — not implemented; use `bash` with `kill` (job ids end in the child pid) if you ever need to stop a running job.
|
|
59
|
+
- `bgwait` — not implemented; the wake mechanism makes blocking on a job unnecessary in the normal flow.
|
|
43
60
|
|
|
44
61
|
## How it works
|
|
45
62
|
|
|
46
|
-
```
|
|
63
|
+
```text
|
|
47
64
|
agent calls bgrun(command: "make test-short", name: "unit-tests")
|
|
48
|
-
→ extension resolves log path:
|
|
65
|
+
→ extension resolves log path: <jobsDir>/<slug>-<ts>-<pid>.log (default ~/.pi-bgrun/jobs/)
|
|
49
66
|
→ spawn('sh', ['-c', '<cmd>; ec=$?; printf "\\n__BGRUN_EXIT__=%d\\n" "$ec"; exit $ec'],
|
|
50
67
|
{ stdio: ['ignore', logFd, logFd], detached: true }).unref()
|
|
51
68
|
→ records job in-memory + appends a bgrun-job entry to the session
|
|
@@ -66,14 +83,36 @@ exit code even after a restart.
|
|
|
66
83
|
|
|
67
84
|
## Reading results without flooding context
|
|
68
85
|
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
86
|
+
Two-tier read model — the log file stays complete on disk for deep analysis;
|
|
87
|
+
only bounded digests ever enter the conversation:
|
|
88
|
+
|
|
89
|
+
- **Quick peek:** `bgtail <id>` — condensed newest lines (ANSI stripped, repeats
|
|
90
|
+
collapsed, ~2KB/line and ~8KB caps). The first read is the last-40-lines tail; each later
|
|
91
|
+
read returns only what was appended since, so repeated polling is nearly
|
|
92
|
+
free. The wake message itself already carries the exit code and the log's
|
|
93
|
+
last line, so many turns need no follow-up read at all.
|
|
94
|
+
- **Pattern search:** `bggrep <id> [pattern] [context]` — line-numbered matches,
|
|
95
|
+
capped and condensed (~50 matches, ~2KB/line, ~8KB); works on global jobs dirs that `ctx_execute_file`
|
|
96
|
+
cannot reach. Pass your own pattern when you know the log's format.
|
|
97
|
+
- **Whole-log analysis:** `ctx_execute_file` on the job's log path (reachable
|
|
98
|
+
when logs are project-local) to extract only failure lines. Never `cat` or
|
|
99
|
+
`Read` a full bgrun log.
|
|
100
|
+
|
|
101
|
+
**Why `bggrep` instead of `bash grep` on the log?** A bash grep's output is
|
|
102
|
+
uncapped — a retry-storm log can dump thousands of matching lines straight
|
|
103
|
+
into context, and safety depends on remembering `| head` on every call.
|
|
104
|
+
`bggrep` is bounded by design (~50 matches, ~2KB/line, ~8KB), takes the job id instead of
|
|
105
|
+
a reconstructed log path (no shell-quoting of the regex), runs on any jobs
|
|
106
|
+
dir — including global logs that project-sandboxed tools like
|
|
107
|
+
`ctx_execute_file` cannot reach — and reports match counts, line numbers, and
|
|
108
|
+
skip markers. Plain `grep` is fine only for a one-off search you know is tiny.
|
|
72
109
|
|
|
73
110
|
## Configuration
|
|
74
111
|
|
|
75
|
-
The jobs dir (`~/.pi-bgrun/jobs
|
|
76
|
-
|
|
112
|
+
The jobs dir (default `~/.pi-bgrun/jobs`, overridable via `jobsDir` / `PI_BGRUN_DIR`)
|
|
113
|
+
is shared by **every pi session on the machine** — that sharing is what enables
|
|
114
|
+
cross-session job lookup, session-restart reconstruction, and machine-wide
|
|
115
|
+
cleanup. By default each session only *tracks its own jobs*: the widget and
|
|
77
116
|
`bgstatus` listings show this session's running jobs, and finished jobs are
|
|
78
117
|
hidden (ask for them explicitly with `bgstatus includeDone: true`). Jobs
|
|
79
118
|
started by other sessions can still be inspected by id, but they don't clutter
|
|
@@ -90,25 +129,71 @@ config file (trusted projects only) ← environment variables**.
|
|
|
90
129
|
"adoptForeignJobs": false,
|
|
91
130
|
"showCompletedJobs": false,
|
|
92
131
|
"cleanupDays": 7,
|
|
132
|
+
"globalAutoClean": true,
|
|
93
133
|
"jobsDir": "/some/other/dir"
|
|
94
134
|
}
|
|
95
135
|
```
|
|
96
136
|
|
|
137
|
+
### Project-local logs
|
|
138
|
+
|
|
139
|
+
A **relative** `jobsDir` (from any config layer, or `PI_BGRUN_DIR`) opts into
|
|
140
|
+
project-local logs: it resolves against the session's project root, so job logs
|
|
141
|
+
land inside the workspace — e.g. `"jobsDir": ".pi-bgrun/jobs"` in the project
|
|
142
|
+
config writes logs to `<project>/.pi-bgrun/jobs`.
|
|
143
|
+
|
|
144
|
+
Why you might want this:
|
|
145
|
+
|
|
146
|
+
- Logs sit inside the project sandbox, so project-confined analysis tools
|
|
147
|
+
(e.g. context-mode's `ctx_execute_file` / `ctx_index`) can process whole logs
|
|
148
|
+
without pulling raw bytes into the context window.
|
|
149
|
+
- Each checkout/worktree gets its own logs — no cross-project clutter in the
|
|
150
|
+
shared dir.
|
|
151
|
+
- The dir is auto-added to the repo's `.git/info/exclude` (local-only — the
|
|
152
|
+
tracked `.gitignore` is never touched), so logs never pollute `git status`.
|
|
153
|
+
Works in linked worktrees too (`.git` file → pointed git dir).
|
|
154
|
+
|
|
155
|
+
Rules and migration notes:
|
|
156
|
+
|
|
157
|
+
- Absolute `jobsDir` values behave exactly as in older versions — nothing
|
|
158
|
+
moves, nothing breaks on upgrade.
|
|
159
|
+
- If the session cwd is not a recognizable project root (no `.git`/`.pi`), a
|
|
160
|
+
relative path falls back to the global dir rather than scattering logs
|
|
161
|
+
across arbitrary directories.
|
|
162
|
+
- Tools resolve a job's log from the session's job record first, so jobs
|
|
163
|
+
started before a config change stay readable after it.
|
|
164
|
+
- Existing logs in the old global dir are not migrated (they're ephemeral,
|
|
165
|
+
`cleanupDays`-retained); `bgclean all` sweeps them once you've switched.
|
|
166
|
+
|
|
97
167
|
Environment variables (same knobs, handy for one-off overrides):
|
|
98
168
|
|
|
99
169
|
| Variable | Default | Description |
|
|
100
170
|
| --- | --- | --- |
|
|
101
|
-
| `PI_BGRUN_DIR` | `~/.pi-bgrun/jobs` | Override where job logs are stored. |
|
|
171
|
+
| `PI_BGRUN_DIR` | `~/.pi-bgrun/jobs` | Override where job logs are stored. An absolute path is used as-is; a **relative** path resolves against the project root (see [project-local logs](#project-local-logs)), falling back to the default when there is no project root. |
|
|
102
172
|
| `PI_BGRUN_FOREIGN_JOBS` | `false` | Adopt other sessions' running jobs into this session's widget and job list. Adopted jobs are polled so they leave the widget when they finish. |
|
|
103
173
|
| `PI_BGRUN_SHOW_COMPLETED` | `false` | Include finished jobs in `bgstatus` listings by default. |
|
|
104
|
-
| `PI_BGRUN_CLEANUP_DAYS` | `7` | Log retention for
|
|
174
|
+
| `PI_BGRUN_CLEANUP_DAYS` | `7` | Log retention for cleanup sweeps and the `bgclean` default. |
|
|
175
|
+
| `PI_BGRUN_GLOBAL_AUTO_CLEAN` | `true` | Set `0`/`false` to disable the automatic global orphan sweep (see below). |
|
|
105
176
|
|
|
106
177
|
### Log cleanup
|
|
107
178
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- **
|
|
179
|
+
Cleanup follows the same principle as everything else: **one session should
|
|
180
|
+
not delete another session's artifacts.**
|
|
181
|
+
|
|
182
|
+
- **Session-scoped auto-sweep (default)** runs at `session_start` and
|
|
183
|
+
`session_shutdown` and removes only *this session's* finished logs older
|
|
184
|
+
than `cleanupDays`. Cheap and unthrottled.
|
|
185
|
+
- **Global orphan sweep (default on; opt out with `globalAutoClean: false` /
|
|
186
|
+
`PI_BGRUN_GLOBAL_AUTO_CLEAN=0`)** — also sweeps the whole shared jobs dir at
|
|
187
|
+
session boundaries, removing *finished* logs (exit marker, or dead pid)
|
|
188
|
+
older than `cleanupDays`. This is what keeps orphans from sessions that
|
|
189
|
+
crashed or will never be resumed from accumulating: a week-old finished log
|
|
190
|
+
is garbage under the same retention its owning session would apply itself.
|
|
191
|
+
Throttled to once per `cleanupDays` via a `.last-clean` marker so
|
|
192
|
+
restart-heavy workflows don't re-sweep on every launch. Running jobs are
|
|
193
|
+
pid-protected, so live sessions are never affected.
|
|
194
|
+
- **Manual**: `bgclean` cleans this session's old logs; `bgclean` with
|
|
195
|
+
`all: true` sweeps every session's logs immediately (and refreshes the
|
|
196
|
+
marker).
|
|
112
197
|
- Running jobs are never swept while their pid is alive.
|
|
113
198
|
|
|
114
199
|
## Status
|