pi-background-tasks 0.1.0 → 0.3.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/PUBLISHING.md CHANGED
@@ -12,12 +12,14 @@ This package is ready for both npm publishing and standalone git publishing.
12
12
 
13
13
  ```bash
14
14
  cd packages/pi-background-tasks
15
+ npm run test
16
+ npm run test:full
15
17
  npm run smoke
16
18
  npm pack --dry-run
17
19
  npm view pi-background-tasks name version --json
18
20
  ```
19
21
 
20
- At creation time, `npm view pi-background-tasks` returned 404, so the unscoped name appeared available.
22
+ `pi-background-tasks` is already published; bump `package.json` before each npm publish.
21
23
 
22
24
  ## Publish to npm
23
25
 
@@ -30,8 +32,8 @@ npm publish --access public
30
32
  Pi install smoke after publish:
31
33
 
32
34
  ```bash
33
- pi -e npm:pi-background-tasks@0.1.0 --offline --no-tools --no-session -p "/jobs"
34
- pi install npm:pi-background-tasks@0.1.0
35
+ pi -e npm:pi-background-tasks@0.3.0 --offline --no-tools --no-session -p "/jobs"
36
+ pi install npm:pi-background-tasks@0.3.0
35
37
  ```
36
38
 
37
39
  ## Publish to git
@@ -42,19 +44,19 @@ Because Pi git package installs treat the repository root as the package root, d
42
44
  cd packages/pi-background-tasks
43
45
  git init
44
46
  git add .
45
- git commit -m "Initial pi-background-tasks package"
47
+ git commit -m "Release pi-background-tasks"
46
48
  git branch -M main
47
49
  git remote add origin git@github.com:ismailsaleekh/pi-background-tasks.git
48
50
  git push -u origin main
49
- git tag v0.1.0
50
- git push origin v0.1.0
51
+ git tag v0.3.0
52
+ git push origin v0.3.0
51
53
  ```
52
54
 
53
55
  Pi install smoke after git tag:
54
56
 
55
57
  ```bash
56
- pi -e git:github.com/ismailsaleekh/pi-background-tasks@v0.1.0 --offline --no-tools --no-session -p "/jobs"
57
- pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.1.0
58
+ pi -e git:github.com/ismailsaleekh/pi-background-tasks@v0.3.0 --offline --no-tools --no-session -p "/jobs"
59
+ pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.3.0
58
60
  ```
59
61
 
60
62
  ## pi.dev/packages
package/README.md CHANGED
@@ -2,44 +2,78 @@
2
2
 
3
3
  Claude-Code-like explicit background shell task manager for [Pi](https://pi.dev/).
4
4
 
5
- This package adds tracked background shell jobs with durable output files, bounded log reads, kill/timeout safety, a `/tasks` manager UI, and completion notifications that can wake the agent when LLM-launched work finishes.
5
+ This package adds named, tracked background shell jobs with durable output files, bounded log reads, kill/timeout safety, task-owned context-window/token/tool-use/model telemetry, explicit Pi-agent telemetry wrapping for tasks marked as agents, a focused footer-dock task manager, `/tasks` fallback UI, and completion notifications that can wake the agent when LLM-launched work finishes.
6
6
 
7
7
  ## Install
8
8
 
9
9
  From npm after publish:
10
10
 
11
11
  ```bash
12
- pi install npm:pi-background-tasks@0.1.0
12
+ pi install npm:pi-background-tasks@0.3.0
13
13
  ```
14
14
 
15
15
  From git after pushing this package to its standalone repository and tagging:
16
16
 
17
17
  ```bash
18
- pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.1.0
18
+ pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.3.0
19
19
  ```
20
20
 
21
21
  For project-local install:
22
22
 
23
23
  ```bash
24
- pi install -l npm:pi-background-tasks@0.1.0
24
+ pi install -l npm:pi-background-tasks@0.3.0
25
25
  ```
26
26
 
27
27
  ## Commands
28
28
 
29
- - `/bg <command>` — start a tracked background shell command.
29
+ - `/bg [--agent] [--name "Task name"] <command>` — start a named tracked background shell command. Use `--agent` only when the command launches an LLM/agent.
30
30
  - `/jobs` — list running and recent completed/failed/killed tasks.
31
31
  - `/logs <id> [maxBytes]` — show bounded tail output and full output path.
32
32
  - `/kill <id>` — stop a running task.
33
- - `/tasks` or `/bg-tasks` — open the interactive task manager UI.
33
+ - `/tasks` or `/bg-tasks` — fallback command to open the task manager UI.
34
+ - `/bg-clear` — clear finished background-task footer notices.
35
+
36
+ ## Footer dock UX
37
+
38
+ When tasks are active or unseen completions/failures exist, Pi shows a compact footer status:
39
+
40
+ ```text
41
+ bg 2 running · Shift↓
42
+ bg 1 running · 1 failed · Shift↓ · /bg-clear
43
+ bg 2 done · Shift↓ · /bg-clear
44
+ ```
45
+
46
+ Press `Shift+Down` to open the focused bottom dock. Arrow keys are captured only while the dock is focused. Each task row shows the latest context-window usage reported by that specific background task, for example `ctx 21.0%/200k`; tasks that do not report their own context show `ctx —` rather than the parent Pi session's usage. Background Pi-agent tasks also surface the LLM model they ran (`model gpt-5.5` in the compact row, fully-qualified such as `openai-codex/gpt-5.5` in the detail view), cumulative token usage (`tok 1.6k`), and tool-use counts (`tools 2/1 failed`) in the dock and detail view; missing model/token/tool telemetry is omitted in rows and shown as “not reported by this background task” in details. When a background command is explicitly marked as an agent and invokes a print/json child agent such as `pi -p ...` through the normal shell command name, the extension wraps that child Pi process with `--mode json`, parses real assistant usage/tool execution events, and emits task-owned telemetry automatically — including the model reported by the child assistant turns.
47
+
48
+ Finished-task badges intentionally remain visible until acknowledged. The reliable clear path is `/bg-clear`, which works in every terminal and clears finished background-task footer notices without opening the dock. `Ctrl+Alt+C` is still registered as an optional terminal-dependent fallback shortcut, but the footer advertises `/bg-clear` because some macOS terminals do not transmit `Ctrl+Alt+C` distinctly.
49
+
50
+ Dock controls:
51
+
52
+ | Key | Action |
53
+ |---|---|
54
+ | `Shift+Down` | Open focused background-task dock |
55
+ | `/bg-clear` | Clear finished-task footer notices from the main UI |
56
+ | `Ctrl+Alt+C` | Optional terminal-dependent shortcut for `/bg-clear` |
57
+ | `↑` / `↓` | Select task |
58
+ | `PageUp` / `PageDown` | Page task list |
59
+ | `Enter` / `→` | Inspect logs/details |
60
+ | `←` | Return from details to list |
61
+ | `h` | Toggle recent history |
62
+ | `k` | Stop selected running task |
63
+ | `a` / `K` | Stop all running tasks, with confirmation |
64
+ | `r` | Refresh detail tail |
65
+ | `R` | Rerun selected command |
66
+ | `c` | Show copyable output path |
67
+ | `x` / `Esc` / `q` | Close dock |
34
68
 
35
69
  ## LLM tools
36
70
 
37
- - `bg_run` — start long-running commands without blocking the conversation.
71
+ - `bg_run` — start named long-running commands without blocking the conversation.
38
72
  - `bg_status` — inspect one task or all recent tasks.
39
73
  - `bg_logs` — read bounded task output.
40
74
  - `bg_kill` — stop a running task.
41
75
 
42
- `bg_run` defaults to `triggerOnCompletion: true`, so completion notifications trigger a follow-up agent turn. User-launched `/bg` jobs are display-only by default.
76
+ `bg_run` requires a concise `name` for the footer dock, the shell `command`, and required `isAgent: boolean`. Set `isAgent: true` only when the background task launches an LLM/agent process (for example `pi -p ...` or `pi --mode json ...`); set `isAgent: false` for scripts, tests, dev servers, sleeps, and ordinary shell commands. It defaults to `triggerOnCompletion: true`, so completion notifications trigger a follow-up agent turn. Tasks marked with `isAgent: true` that launch print/json child Pi agents through the normal shell command name are telemetry-wrapped; set `PI_BG_DISABLE_PI_TELEMETRY=1` only when raw Pi stdout is required. The task snapshot and metadata expose `isAgent`, `contextUsage` (latest reported child assistant turn), cumulative `tokenUsage` (`input`, `output`, `cacheRead`, `cacheWrite`, `totalTokens`), cumulative `toolUsage` (`total`, `failed`, `byName`), and `model` (the LLM identifier reported by the child assistant turns, preferring the fully-qualified `provider/model` form) when reported by the child task. User-launched `/bg` jobs are display-only by default unless `--agent` is provided; UI reruns preserve the original task's `isAgent` value.
43
77
 
44
78
  ## Runtime files
45
79
 
@@ -61,9 +95,34 @@ These are runtime artifacts and should remain gitignored.
61
95
  - Running tasks are cleaned up on Pi session shutdown/reload.
62
96
  - Cross-Pi-restart process reattachment and Ctrl+B backgrounding of already-running foreground tools are intentionally out of scope.
63
97
 
64
- ## Development smoke
98
+ ## Development and QA
99
+
100
+ Default QA gate:
101
+
102
+ ```bash
103
+ npm run test
104
+ ```
105
+
106
+ Smoke and release checks:
65
107
 
66
108
  ```bash
67
109
  npm run smoke
68
110
  npm run pack:dry-run
69
111
  ```
112
+
113
+ Full interactive QA gate:
114
+
115
+ ```bash
116
+ npm run test:full
117
+ ```
118
+
119
+ The suite includes typecheck, unit, SDK, RPC, component, package, PTY/TUI, and scripted-provider coverage for the focused dock, lifecycle safety, and completion follow-up behavior.
120
+
121
+ Note: the repo QA standard requires exhaustive coverage of every public behavior and plausible edge case. `TEST_PLAN.md` tracks the current coverage matrix and any future edge-case additions.
122
+
123
+ This package follows the repo-wide Pi extension QA standard documented in:
124
+
125
+ - [`../EXTENSION_QA_STANDARD.md`](../EXTENSION_QA_STANDARD.md)
126
+ - [`../EXTENSION_TESTING_PLAYBOOK.md`](../EXTENSION_TESTING_PLAYBOOK.md)
127
+ - [`TEST_PLAN.md`](TEST_PLAN.md)
128
+ - [`TESTING.md`](TESTING.md)
package/TESTING.md ADDED
@@ -0,0 +1,116 @@
1
+ # pi-background-tasks Testing
2
+
3
+ This package follows the repo-wide Pi extension QA standard:
4
+
5
+ - [`../EXTENSION_QA_STANDARD.md`](../EXTENSION_QA_STANDARD.md)
6
+ - [`../EXTENSION_TESTING_PLAYBOOK.md`](../EXTENSION_TESTING_PLAYBOOK.md)
7
+ - [`TEST_PLAN.md`](TEST_PLAN.md)
8
+
9
+ ## Current commands
10
+
11
+ Default gate:
12
+
13
+ ```bash
14
+ npm run test
15
+ ```
16
+
17
+ This runs:
18
+
19
+ ```bash
20
+ npm run typecheck
21
+ npm run test:unit
22
+ npm run test:sdk
23
+ npm run test:rpc
24
+ npm run test:component
25
+ npm run test:package
26
+ ```
27
+
28
+ Full interactive gate:
29
+
30
+ ```bash
31
+ npm run test:full
32
+ ```
33
+
34
+ This runs the default gate plus:
35
+
36
+ ```bash
37
+ npm run test:pty
38
+ npm run test:agent-loop
39
+ ```
40
+
41
+ Smoke/release checks:
42
+
43
+ ```bash
44
+ npm run smoke
45
+ npm run pack:dry-run
46
+ ```
47
+
48
+ Current smoke:
49
+
50
+ ```bash
51
+ pi --no-extensions -e ./extensions/background-tasks.ts --offline --no-tools --no-session -p "/jobs"
52
+ ```
53
+
54
+ Smoke proves loadability only; completion requires `npm run test`, `npm run test:full`, and `npm run pack:dry-run`.
55
+
56
+ ## Required isolated environment
57
+
58
+ Automated tests run with isolated temp project/agent/session directories and should use:
59
+
60
+ ```bash
61
+ PI_OFFLINE=1
62
+ PI_SKIP_VERSION_CHECK=1
63
+ PI_TELEMETRY=0
64
+ CI=1
65
+ ```
66
+
67
+ Tests must not use the user's real `~/.pi/agent`.
68
+
69
+ ## Coverage summary
70
+
71
+ Implemented coverage includes:
72
+
73
+ - tools: `bg_run`, `bg_status`, `bg_logs`, `bg_kill`, including required `isAgent` schema/runtime validation, unknown/ambiguous IDs, completed-kill failure, legacy no-name preparation, head/tail truncation, and notification on/off behavior
74
+ - commands: `/bg`, `/jobs`, `/logs`, `/kill`, `/tasks`, `/bg-tasks`, `/bg-clear` discovery, happy paths, `/bg --agent` parsing, finished-notice clearing, malformed `/bg`, unknown/ambiguous IDs, completed-task `/kill`, byte-limit normalization, and RPC no-hang fallback behavior
75
+ - shortcut/UI: component coverage for focused dock list/detail/key handling, empty/history/unread states, paging, close aliases, stop/stop-all/rerun/path actions, missing output files; SDK coverage for explicit `/bg-clear` finished-notice clearing, `/bg-clear` footer hinting, optional `Ctrl+Alt+C` fallback shortcut registration, and mixed failed/stopped/done/focused footer status; RPC coverage that `/bg-clear` works as a terminal-independent clear path; and PTY coverage for `/tasks`, `/bg-tasks`, real `Shift+Down`, arrows, page keys, detail/back/history/stop/stop-all/rerun/path/close, failed unread badges, and running/completed/failed/killed rerun paths
76
+ - runtime files: output and metadata files under `.pi/tasks/`, persisted `isAgent` classification, task-owned context-window telemetry snapshots, cumulative background Pi-agent token usage, tool-use counts, agent model identifier (preferring the fully-qualified `provider/model` form), explicit `isAgent:true` telemetry wrapping for background `pi` agents, `isAgent:false` non-wrapping for scripts, real child `pi --mode json` tool-event parsing, split/large telemetry ingestion, metadata after completion/failure, local tarball install contents
77
+ - safety: kill, already-finished kill failure, timeout failure, spawn failure, low output-cap failure, multi-task shutdown cleanup, process-group kill fallback, Windows child-kill behavior, SIGKILL escalation, duplicate finalization/notification races, metadata/notification failure handling, and pruning
78
+ - agent loop: deterministic scripted-provider coverage for actual `bg_run` completion follow-up turns, `/bg` display-only behavior, `notifyOnCompletion:false`, and failed-task notification error fields
79
+ - package: manifest, docs, `pi.extensions`, peer dependency/import parity, packed runtime files, tarball-install smoke, and artifact exclusion
80
+
81
+ ## PTY notes
82
+
83
+ `test:pty` uses `/usr/bin/expect` to drive a real pseudo-terminal. It verifies:
84
+
85
+ - `/tasks` and `/bg-tasks` open the focused dock and close with `x`.
86
+ - A named `/bg` task appears in the dock when opened with xterm `Shift+Down` (`ESC [ 1 ; 2 B`).
87
+ - Secondary dock keys work in a real TUI: arrows, page keys, detail/back, history, stop selected, stop-all confirmation, rerun, output path, and failed/unread history surfacing.
88
+
89
+ The detail-view `Model:` line and the compact `model <id>` dock row are also exercised deterministically by the component layer (`tests/component/background-tasks-manager.test.ts`), which is the lowest reliable layer for dock rendering.
90
+
91
+ ### Terminal keyboard-protocol negotiation
92
+
93
+ `pi` enables the Kitty keyboard protocol at startup by emitting `ESC[>7u ESC[?u ESC[c` and briefly intercepts stdin until that negotiation completes. The expect harness therefore must not key on a bare `>` (which matches the `ESC[>7u` push instantly and fires input before pi is listening); instead it waits for the steady-state status marker `(auto)`, answers the keyboard-protocol query (`ESC[?0u`, i.e. legacy keyboard) and the device-attributes query (`ESC[?1;2c`), and settles briefly before sending keys. This makes legacy keystrokes reach pi deterministically rather than racing the 150 ms negotiation fallback.
94
+
95
+ ### Interactive-stdin capability probe
96
+
97
+ `test:pty` begins with a one-shot probe (`ptyInputSupported()`) that spawns a minimal raw-mode Node stdin reader under the same `/usr/bin/expect` driver and checks that a sent byte is received. Some hosts cannot deliver stdin to a raw-mode Node TUI through expect (a plain `cat` receives input but Node `process.stdin` does not). On such hosts every PTY case is skipped with a loud reason instead of failing; where stdin is deliverable the full interactive dock scenarios run for real. The deterministic SDK/RPC/component layers remain the authoritative gates in `npm run test` either way.
98
+
99
+ ## Artifact policy
100
+
101
+ Use package-local or repo-level artifacts if future snapshot/log persistence is needed:
102
+
103
+ ```text
104
+ artifacts/pi-extension-tests/pi-background-tasks/
105
+ ├── summary.json
106
+ ├── rpc-events.jsonl
107
+ ├── tui-ansi.log
108
+ ├── screen.normalized.txt
109
+ └── snapshots/
110
+ ```
111
+
112
+ Normalize volatile values before snapshotting: task IDs, session IDs, PIDs, timestamps, durations, temp paths, and `.pi/tasks/<session-pid>/...` run directories.
113
+
114
+ ## Remaining full exhaustive coverage work
115
+
116
+ The Lane A residual hardening items and the explicit `isAgent` agent-vs-script classification are now covered by default unit/SDK gates plus full PTY and scripted-provider gates. `TEST_PLAN.md` remains the source of truth for future edge-case additions, especially any new telemetry surfaces added after this baseline.
package/TEST_PLAN.md ADDED
@@ -0,0 +1,98 @@
1
+ # pi-background-tasks Test Plan
2
+
3
+ This package follows:
4
+
5
+ - [`../EXTENSION_PACKAGE_STANDARD.md`](../EXTENSION_PACKAGE_STANDARD.md)
6
+ - [`../EXTENSION_QA_STANDARD.md`](../EXTENSION_QA_STANDARD.md)
7
+ - [`../EXTENSION_TESTING_PLAYBOOK.md`](../EXTENSION_TESTING_PLAYBOOK.md)
8
+
9
+ ## Package
10
+
11
+ | Field | Value |
12
+ |---|---|
13
+ | Package | `pi-background-tasks` |
14
+ | Extension entrypoint | `extensions/background-tasks.ts` |
15
+ | Public commands | `/bg`, `/jobs`, `/logs`, `/kill`, `/tasks`, `/bg-tasks`, `/bg-clear` |
16
+ | Public tools | `bg_run`, `bg_status`, `bg_logs`, `bg_kill` |
17
+ | Shortcuts | `Shift+Down`; optional fallback `Ctrl+Alt+C` |
18
+ | Custom UI | footer status + focused bottom dock overlay |
19
+ | Custom provider | no |
20
+ | Runtime files/state | `.pi/tasks/<session-id>-<pid>/<task-id>.output`, `.pi/tasks/<session-id>-<pid>/<task-id>.json` |
21
+
22
+ ## Required gates
23
+
24
+ | Gate | Command | Required in default `npm run test`? | Status |
25
+ |---|---|---:|---|
26
+ | Typecheck | `npm run typecheck` | yes | implemented |
27
+ | Unit | `npm run test:unit` | yes | implemented |
28
+ | SDK | `npm run test:sdk` | yes | implemented |
29
+ | RPC | `npm run test:rpc` | yes | implemented |
30
+ | Component | `npm run test:component` | yes | implemented |
31
+ | Package | `npm run test:package` | yes | implemented |
32
+ | PTY/TUI | `npm run test:pty` | full gate | implemented (answers pi's Kitty keyboard-protocol negotiation; auto-skips with a loud reason on hosts that cannot deliver raw-mode Node stdin via `/usr/bin/expect`) |
33
+ | Scripted provider | `npm run test:agent-loop` | full gate | implemented |
34
+ | Pack dry run | `npm run pack:dry-run` | release gate | implemented |
35
+ | Smoke | `npm run smoke` | no | implemented; load-only |
36
+
37
+ ## Feature coverage matrix
38
+
39
+ | Feature | Public surface | Unit | SDK | RPC | Component | PTY | Package | Scripted provider | Notes |
40
+ |---|---|---:|---:|---:|---:|---:|---:|---:|---|
41
+ | Start background command from UI command | `/bg` | yes | | yes | | yes | | | Unit covers `--name` and `--agent`; RPC/PTY start real processes. |
42
+ | List tasks | `/jobs` | | | yes | | | | | RPC asserts running and killed task rows. |
43
+ | Show bounded logs | `/logs <id> [maxBytes]` | yes | | yes | | | | | Unit covers bounded reads; RPC verifies output/path. |
44
+ | Kill running task | `/kill <id>` | | yes | yes | | | | | SDK tool and RPC slash command. |
45
+ | Open task manager fallback | `/tasks`, `/bg-tasks` | | | discovery | yes | yes | | | Component covers dock; PTY covers `/tasks` and `/bg-tasks`. |
46
+ | Start background command from LLM tool | `bg_run` | yes | yes | | | | | yes | SDK starts named commands, verifies required `isAgent` schema/runtime behavior, and scripted provider verifies agent-loop tool calls with `isAgent:false` for scripts. |
47
+ | Inspect task status | `bg_status` | | yes | | | | | | SDK polls exact IDs and validates shutdown state. |
48
+ | Read task logs | `bg_logs` | yes | yes | | | | | | SDK verifies content. |
49
+ | Stop task from LLM tool | `bg_kill` | | yes | | | | | | Covers running kill and already-finished loud failure. |
50
+ | Completion notification | custom message `background-task-notification` | yes | yes | | renderer via typecheck | | | yes | Unit covers duplicate/failing notification paths; SDK verifies XML/details; scripted provider verifies real follow-up turns, display-only `/bg`, `notifyOnCompletion:false`, and failed-task error fields. |
51
+ | Footer status | `ctx.ui.setStatus` | | load path + clear command/shortcut + mixed states/focused label | | render semantics | yes | | | SDK verifies `/bg-clear` hint, failed/stopped/done combinations, running combinations, and focused label; PTY verifies Shift+Down dock path after footer-visible task. |
52
+ | Explicit agent classification | required `bg_run.isAgent`, `/bg --agent`, task metadata | yes | yes | | | | | yes | `isAgent:true` is required only for LLM/agent tasks and enables Pi-agent telemetry wrapping when the command invokes plain `pi`; `isAgent:false` is required for scripts/non-agents and prevents wrapping even if the command text looks like `pi -p ...`. |
53
+ | Per-task context usage | task row/detail + `bg_status`/metadata/notification snapshots | yes | yes | | yes | | | | SDK verifies task-owned telemetry is captured, explicitly marked background `pi` invocations are wrapped to emit telemetry, and parent `ctx.getContextUsage()` is not used; component verifies list/detail rendering plus `ctx —` placeholder. |
54
+ | Per-task token usage | background Pi-agent telemetry + `bg_status`/metadata/dock row/detail | yes | yes | | yes | | | | SDK verifies cumulative input/output/cache read/cache write/total token usage from explicit telemetry, fake `isAgent:true` wrapped child events, and real child `pi --mode json` with scripted provider; component verifies row/detail rendering. |
55
+ | Per-task tool-use counts | background Pi-agent telemetry + `bg_status`/metadata/dock row/detail | yes | yes | | yes | | | | SDK verifies total/failed/by-name tool counts from fake and real child Pi `tool_execution_start/end` events, including failed tools; component verifies row/detail rendering. |
56
+ | Per-task agent model | background Pi-agent telemetry + `bg_status`/metadata/dock row/detail | yes | yes | | yes | | | | Unit verifies `formatModelSummary`/snapshot-list rendering and telemetry ingestion of `model`; SDK verifies the model is captured from explicit telemetry, fake `isAgent:true` wrapped child `message_end` events (qualified `provider/model`), and a real child `pi --mode json` run (bare child model re-qualified from `--model`), plus that non-agent tasks report no model; component verifies compact `model <id>` row, fully-qualified `Model:` detail, and the “not reported by this background task” placeholder. |
57
+ | Focused dock list | overlay component | | | | yes | yes | | | Selection/actions/history tested; PTY covers arrows, page keys, ordering with multiple tasks, failed/unread badges, and `/bg-tasks` fallback. |
58
+ | Focused dock detail | overlay component | | | | yes | | | | Tail read, output box, return-to-list tested. |
59
+ | Dock stop selected | `k` | | | | yes | | | | Component. |
60
+ | Dock stop all | `a`/`K` | | | | yes | yes | | | Component and PTY confirmation. |
61
+ | Dock rerun | `R` | | | | yes | yes | | | Component plus PTY running/completed/failed/killed rerun paths. |
62
+ | Dock close | `x`/`Esc`/`q` | | | | yes | yes | | | Component + PTY. |
63
+ | Shortcut opens dock | `Shift+Down` | | registration | | | yes | | | PTY sends xterm `ESC [ 1 ; 2 B`. |
64
+ | Clear finished notices | `/bg-clear`, optional `Ctrl+Alt+C` fallback | | yes | yes | | | | | `/bg-clear` is the canonical terminal-independent path and is advertised in the footer. SDK invokes the slash-command handler and verifies fallback shortcut registration; RPC verifies `/bg-clear` clears finished notices; finished notices remain until explicit clear. |
65
+ | Runtime output files | `.pi/tasks/...output` | yes | yes | | | | | | SDK asserts existence. |
66
+ | Runtime metadata files | `.pi/tasks/...json` | yes | yes | | | | | | SDK asserts shape/status/name/context usage; registry unit tests cover metadata failure/update ordering. |
67
+ | Timeout kills task | `timeoutSeconds` | | yes | | | | | | SDK. |
68
+ | Output cap kills task | `PI_BG_MAX_OUTPUT_BYTES` | | | yes | | | | | RPC runs with a low cap and asserts failed status/log notice. |
69
+ | Shutdown cleanup | `session_shutdown` | yes | yes | | | | | | SDK asserts multiple running tasks become killed; registry tests cover shared stop/wait behavior. |
70
+ | Process lifecycle/races | registry core | yes | yes | yes | | yes | | yes | Unit tests cover process-group fallback, Windows fallback, SIGKILL escalation, duplicate finalization/notification races, notification/metadata failures, pruning, malformed telemetry, split telemetry chunks, and large telemetry records above the old 16KiB buffer; SDK/RPC cover runtime spawn/timeout/output-cap/shutdown; scripted provider covers wakeup integration. |
71
+ | Package manifest | `package.json` | | | | | | yes | | Keywords, `pi.extensions`, files. |
72
+ | Pack contents | `npm pack --dry-run` | | | | | | yes | | Runtime files included. |
73
+
74
+ ## Residual hardening coverage
75
+
76
+ Lane A residual hardening is now covered by automated tests. No remaining hardening-only gaps are intentionally left open in this plan. Future feature work should add new rows instead of weakening these gates.
77
+
78
+ | Hardened area | Coverage |
79
+ |---|---|
80
+ | Extracted process registry | `src/core/registry.ts` has direct unit coverage for state transitions and injected spawn/kill/platform behavior. |
81
+ | Agent/script classification | Unit tests cover `isAgent:true` wrapping, `isAgent:false` non-wrapping, `PI_BG_DISABLE_PI_TELEMETRY`, and non-interceptable path-qualified `pi`; SDK verifies required tool schema/runtime validation and real marked Pi telemetry. |
82
+ | Process lifecycle/races | Unit tests cover duplicate error/close finalization, output-cap races, duplicate-notification prevention, waiter resolution via stop paths, metadata failure logging, and notification failure reset. |
83
+ | Process-tree kill safety | Unit tests cover POSIX process-group kill, child fallback, both-fail loud errors, SIGTERM idempotency, SIGKILL escalation, and Windows child-kill/shell invocation. |
84
+ | Pruning | Unit tests cover oldest-finished pruning while preserving running tasks. |
85
+ | Completion follow-up turns | `test:agent-loop` registers a deterministic scripted provider and verifies `bg_run` wakeup default, `/bg` display-only default, `notifyOnCompletion:false`, failed notification error fields, and real follow-up provider calls. |
86
+ | PTY secondary keys | `test:pty` covers arrows, page keys, `a`/`K`, `R`, `c`, `/bg-tasks`, failed/unread badges, multiple-task ordering, and rerun paths for running/completed/failed/killed tasks. |
87
+ | Footer/status combinations | SDK tests cover failed/stopped/done/running combinations, explicit clear, and focused label. |
88
+
89
+ ## Acceptance checklist
90
+
91
+ - [x] `npm run test` passes offline in isolated temp dirs.
92
+ - [x] `npm run test:full` validates baseline real TUI/PTY behavior.
93
+ - [x] `npm run pack:dry-run` passes.
94
+ - [x] README claims and all plausible edge cases are exhaustively mapped in this test plan.
95
+ - [x] Every listed edge case has automated coverage at the lowest reliable layer.
96
+ - [x] No real LLM/API/network dependency in default tests.
97
+ - [x] No dependency on user/global `~/.pi/agent` for SDK/RPC/PTY tests.
98
+ - [x] Volatile output is normalized in snapshot-style assertions where applicable.