Skip to content

Commit ce02a93

Browse files
authored
feat: add pi-bash-bg package (#29)
Co-authored-by: mgabor3141 <mgabor3141@users.noreply.github.com>
1 parent a9341df commit ce02a93

16 files changed

Lines changed: 1340 additions & 0 deletions

.changeset/add-bash-bg.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"pi-bash-bg": minor
3+
---
4+
5+
New package: pi-bash-bg. Makes `command &` work in pi's bash tool by intercepting bash tool calls, detecting background processes via AST parsing (@aliou/sh), and rewriting commands to redirect output to temp log files and disown. Compound commands (&&, ||, pipelines) are wrapped in braces so the redirect applies to the entire background subshell. The agent sees the PID, label, and log file path in the tool output.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"pi-bash-bg": patch
3+
---
4+
5+
Append background-job behavior guidance to the bash tool description so models see that background jobs keep running, output is captured to a log file, and the PID plus log path are returned.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"pi-bash-bg": patch
3+
---
4+
5+
Make background log file names human-readable by basing them on the detected command label and using a simple numeric suffix for uniqueness.

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Monorepo of extensions and libraries for [pi](https://pi.dev). Managed with Yarn
2222
| pi-budget-model | `packages/budget-model/` | library |
2323
| pi-no-soft-cursor | `packages/no-soft-cursor/` | pi extension |
2424
| pi-jujutsu | `packages/jujutsu/` | pi extension |
25+
| pi-bash-bg | `packages/bash-bg/` | pi extension |
2526

2627
## Workflow
2728

packages/bash-bg/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# pi-bash-bg
2+
3+
Makes `command &` work in pi's bash tool by detaching background processes from pipes.
4+
5+
## Problem
6+
7+
The bash tool pipes stdout/stderr from the spawned shell. When a command backgrounds a process with `&`, the background process inherits these pipe file descriptors and keeps them open. Node.js waits for all pipe readers to close, so the tool hangs until the background process exits.
8+
9+
## Solution
10+
11+
This extension intercepts bash tool calls, parses the command with [@aliou/sh](https://github.com/nicolo-ribaudo/sh) to detect background processes (`stmt.background === true`), appends background-job guidance to the bash tool description, and rewrites the command to:
12+
13+
1. **Redirect output** to temp log files with human-readable names based on the command label, so background processes release the pipes
14+
2. **Add `disown`** to detach from job control (if not already present)
15+
3. **Append echo** reporting PID, label, and log path
16+
17+
The agent sees something like:
18+
19+
```
20+
[bg] pid=12345 label=npm run dev log=/tmp/pi-bg-npm-run-dev-1.log
21+
```
22+
23+
It can then `cat` the log file or `kill` the PID.
24+
25+
## Install
26+
27+
```bash
28+
pi install pi-bash-bg
29+
```
30+
31+
## How it works
32+
33+
### Simple commands
34+
35+
```bash
36+
# Before:
37+
npm run dev &
38+
# After:
39+
npm run dev > /tmp/pi-bg-npm-run-dev-1.log 2>&1 & disown $!;
40+
echo "[bg] pid=$! label=npm run dev log=/tmp/pi-bg-npm-run-dev-1.log"
41+
```
42+
43+
### Compound commands (&&, ||, pipelines)
44+
45+
Compound commands are wrapped in braces so the redirect applies to the entire background subshell, not just the last command in the chain:
46+
47+
```bash
48+
# Before:
49+
cd /app && npm start &
50+
# After:
51+
{ cd /app && npm start; } > /tmp/pi-bg-npm-start-2.log 2>&1 & disown $!;
52+
echo "[bg] pid=$! label=npm start log=/tmp/pi-bg-npm-start-2.log"
53+
```
54+
55+
### Existing redirections
56+
57+
If a simple command already redirects both stdout and stderr, the extension only adds `disown` (no log file is created):
58+
59+
```bash
60+
# Before:
61+
node server.js > /dev/null 2>&1 &
62+
# After:
63+
node server.js > /dev/null 2>&1 & disown $!;
64+
echo "[bg] pid=$! label=node server.js"
65+
```
66+
67+
Compound commands are always wrapped in braces, even if their inner commands have redirections. This is necessary because the background subshell itself holds the pipe file descriptors open regardless of what its child commands do:
68+
69+
```bash
70+
# Before:
71+
cd /app && npm start > /dev/null 2>&1 &
72+
# After:
73+
{ cd /app && npm start > /dev/null 2>&1; } > /tmp/pi-bg-npm-start-3.log 2>&1 & disown $!;
74+
echo "[bg] pid=$! label=npm start log=/tmp/pi-bg-npm-start-3.log"
75+
```
76+
77+
### Existing disown
78+
79+
If the command already has `disown` after the `&`, no duplicate is added.
80+
81+
### Bash tool description
82+
83+
The extension appends a short background-job summary to the bash tool description, so the model sees it directly in tool metadata.
84+
85+
## Supported patterns
86+
87+
| Pattern | Handled |
88+
|---------|---------|
89+
| `npm run dev &` | Yes |
90+
| `cd /dir && npm start &` | Yes (wrapped in braces) |
91+
| `tail -f log \| grep error &` | Yes (wrapped in braces) |
92+
| `nohup node server.js &` | Yes |
93+
| `PORT=3000 node server.js &` | Yes |
94+
| `while true; do sleep 1; done &` | Yes (wrapped in braces) |
95+
| `(sleep 10 && echo done) &` | Yes (wrapped in braces) |
96+
| `cmd &> /dev/null &` | Yes (skips adding redirects for simple commands) |
97+
| `cmd & disown $!` | Yes (skips adding disown) |
98+
| `echo "foo & bar"` | Ignored (& inside string) |
99+
| `cmd1 && cmd2` | Ignored (no background) |

packages/bash-bg/package.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "pi-bash-bg",
3+
"version": "0.0.1",
4+
"description": "Makes command & work in pi's bash tool by detaching background processes from pipes · from yapp",
5+
"author": "mgabor3141",
6+
"license": "MIT",
7+
"repository": {
8+
"url": "git+https://github.com/mgabor3141/yapp.git",
9+
"directory": "packages/bash-bg"
10+
},
11+
"keywords": [
12+
"pi-package",
13+
"pi-extension",
14+
"yapp"
15+
],
16+
"type": "module",
17+
"main": "dist/index.js",
18+
"types": "dist/index.d.ts",
19+
"exports": {
20+
".": {
21+
"import": "./dist/index.js",
22+
"types": "./dist/index.d.ts"
23+
}
24+
},
25+
"files": [
26+
"dist",
27+
"README.md"
28+
],
29+
"scripts": {
30+
"build": "tsup"
31+
},
32+
"pi": {
33+
"extensions": [
34+
"dist/index.js"
35+
]
36+
},
37+
"dependencies": {
38+
"@aliou/sh": "^0.1.0",
39+
"valibot": "^1.2.0"
40+
},
41+
"peerDependencies": {
42+
"@mariozechner/pi-coding-agent": "*"
43+
},
44+
"devDependencies": {
45+
"@mariozechner/pi-coding-agent": "^0.57.0",
46+
"@types/node": "^25.3.5",
47+
"tsup": "^8.5.1",
48+
"typescript": "^5.9.3"
49+
}
50+
}

0 commit comments

Comments
 (0)