@tduyng/pi-shell 0.0.3 → 0.0.4
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 +27 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,64 +1,39 @@
|
|
|
1
1
|
# @tduyng/pi-shell
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Background processes with one tool: start, read new bytes, kill, list. The turn moves on, and an exiting process wakes the session instead of being polled.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`bg` is 197 tokens a request for the whole lifecycle, where four tools would have cost four schemas.
|
|
8
|
-
|
|
9
|
-
The saving is in the wait, not the schema. A test suite, a build, or a dev server run for minutes and then return a log nobody reads whole. This tool holds the bytes and hands the model the tail it asked for, so a five minute build does not become a five minute stall in the transcript.
|
|
5
|
+
A foreground command blocks the turn. `&` plus `sleep` is a guess, and the log has to be read from the top to find one line.
|
|
10
6
|
|
|
11
7
|
## The tool
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
### output
|
|
20
|
-
|
|
21
|
-
Reads new bytes since the last read, through a byte cursor.
|
|
22
|
-
|
|
23
|
-
| `wait` | Behaviour |
|
|
24
|
-
| --- | --- |
|
|
25
|
-
| `now` | Return whatever is available |
|
|
26
|
-
| `next_write` | Park the agent until the first new byte, then wake it |
|
|
27
|
-
| `exit` | Park the agent until the process ends, then deliver the verdict and the unread tail |
|
|
28
|
-
|
|
29
|
-
A wake read does not advance the cursor, so a later `output` still sees every byte from the stored offset.
|
|
30
|
-
|
|
31
|
-
### kill
|
|
32
|
-
|
|
33
|
-
SIGTERM to the process group, polled every 50ms for up to a second, then SIGKILL. Takes a `task_id`, a raw `pid`, or a `port` resolved through `lsof -ti`.
|
|
34
|
-
|
|
35
|
-
### status
|
|
36
|
-
|
|
37
|
-
Every task with id, pid, state (running, exited, killed), cursor offset, and the first 80 characters of the command.
|
|
38
|
-
|
|
39
|
-
## Waking only when asked
|
|
40
|
-
|
|
41
|
-
Only a task the model parked on, through `wait: "exit"` or `wait: "next_write"`, injects a message when it finishes. A burst of exits coalesces into one message on a byte budget: 8 KB total by default, at least 1 KB per task. The wake carries the exit verdict, the unread tail, and the log path, so the model gets the result without a read-back.
|
|
9
|
+
```text
|
|
10
|
+
bg({action: "start", command: "bun run dev"})
|
|
11
|
+
bg({action: "output", task_id: "t1", wait: "next_write"})
|
|
12
|
+
bg({action: "kill", port: 3000})
|
|
13
|
+
bg({action: "status"})
|
|
14
|
+
```
|
|
42
15
|
|
|
43
|
-
|
|
16
|
+
`output` waits three ways: `now` returns what is there, `next_write` returns on the next line written, and `exit` returns when the process ends. `kill` takes a `task_id`, a `pid`, or a `port`, whichever is known. Logs land in `<agent-dir>/shell-logs/`, and the start result names the path.
|
|
44
17
|
|
|
45
|
-
|
|
18
|
+
One tool with an action field instead of four tools, because four tools would cost four schemas in every request.
|
|
46
19
|
|
|
47
|
-
##
|
|
20
|
+
## Cursor reads
|
|
48
21
|
|
|
49
|
-
|
|
22
|
+
`output` takes a byte offset and returns only new bytes. A build that prints 200,000 lines costs the 40 that matter, and a line already read is never re-billed.
|
|
50
23
|
|
|
51
|
-
|
|
24
|
+
The task list is rebuilt from session entries after a reload, so a task whose pid is gone is reported as gone.
|
|
52
25
|
|
|
53
|
-
|
|
26
|
+
## The exit code pi reports wrong
|
|
54
27
|
|
|
55
|
-
|
|
28
|
+
A `tool_result` handler patches pi's silent signal-death bug. A child killed by a signal reports `code === null`, which pi reads as success, so a command that was killed looks like a command that passed. The handler reports `128+n` and adds a note for a benign exit.
|
|
56
29
|
|
|
57
|
-
|
|
30
|
+
## Settings
|
|
58
31
|
|
|
59
|
-
|
|
32
|
+
| Variable | Default | Effect |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `SHELL` | unset | `0`, `false`, `no` or `off` disables the extension |
|
|
60
35
|
|
|
61
|
-
|
|
36
|
+
`SHELL` is the variable a login shell sets to its own path, so the switch only fires on the four falsey spellings. The name is a compromise: any other name would break profiles that already set it.
|
|
62
37
|
|
|
63
38
|
## Install
|
|
64
39
|
|
|
@@ -68,6 +43,11 @@ pi install npm:@tduyng/pi-shell
|
|
|
68
43
|
|
|
69
44
|
Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-shell`
|
|
70
45
|
|
|
71
|
-
|
|
46
|
+
`kill` by port uses `lsof`, which is on macOS and most Linux images. Kill by id or pid needs nothing.
|
|
47
|
+
|
|
48
|
+
## Limits
|
|
72
49
|
|
|
73
|
-
|
|
50
|
+
- A start can set a timeout up to 600 seconds. The default is no timeout.
|
|
51
|
+
- Logs are kept 7 days, with a 512 MB cap across the log directory.
|
|
52
|
+
- The `output` view returns at most 8 KB per call. Use `from_offset` to continue.
|
|
53
|
+
- A wake is sent only when the session is idle, so a process that exits mid-turn shows up at the next settle.
|