pi-background-tasks 0.6.0 → 0.7.2

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
@@ -1,12 +1,13 @@
1
1
  # Publishing pi-background-tasks
2
2
 
3
- This package is ready for both npm publishing and standalone git publishing.
3
+ Release checklist for npm publishing and standalone git publishing. The current release candidate is 0.7.2; version 0.7.0 introduced the Fusion public surfaces (`/fusion`, `/fusion-models`, `fusion_brainstorm`) in addition to the background-task surfaces. Do not advertise the GitHub install target until the standalone repository has the exact release commit and tag.
4
4
 
5
5
  ## Preconditions
6
6
 
7
7
  - npm account with publish rights for `pi-background-tasks`.
8
8
  - Standalone GitHub repository, expected: `github.com/ismailsaleekh/pi-background-tasks`.
9
9
  - Clean worktree.
10
+ - Final repair commit present in the standalone package repository; do not push from automated repair runs unless the operator explicitly requests it.
10
11
 
11
12
  ## Verify
12
13
 
@@ -15,7 +16,8 @@ cd packages/pi-background-tasks
15
16
  npm run test
16
17
  npm run test:full
17
18
  npm run smoke
18
- npm pack --dry-run
19
+ npm run pack:dry-run
20
+ npm run test:compat
19
21
  npm view pi-background-tasks name version --json
20
22
  ```
21
23
 
@@ -32,8 +34,8 @@ npm publish --access public
32
34
  Pi install smoke after publish:
33
35
 
34
36
  ```bash
35
- pi -e npm:pi-background-tasks@0.6.0 --offline --no-tools --no-session -p "/jobs"
36
- pi install npm:pi-background-tasks@0.6.0
37
+ PI_CODING_AGENT_DIR=$(mktemp -d) pi -e npm:pi-background-tasks@0.7.2 --offline --no-tools --no-session -p "/jobs"
38
+ pi install npm:pi-background-tasks@0.7.2
37
39
  ```
38
40
 
39
41
  ## Publish to git
@@ -42,21 +44,19 @@ Because Pi git package installs treat the repository root as the package root, d
42
44
 
43
45
  ```bash
44
46
  cd packages/pi-background-tasks
45
- git init
46
- git add .
47
- git commit -m "Release pi-background-tasks"
48
- git branch -M main
49
- git remote add origin git@github.com:ismailsaleekh/pi-background-tasks.git
50
- git push -u origin main
51
- git tag v0.6.0
52
- git push origin v0.6.0
47
+ git status --short --branch
48
+ git log --oneline -3
49
+ git remote -v
50
+ git push origin main
51
+ git tag v0.7.2
52
+ git push origin v0.7.2
53
53
  ```
54
54
 
55
- Pi install smoke after git tag:
55
+ Pi install smoke after git tag, using an isolated Pi agent directory so no local checkout or user `~/.pi` state is involved:
56
56
 
57
57
  ```bash
58
- pi -e git:github.com/ismailsaleekh/pi-background-tasks@v0.6.0 --offline --no-tools --no-session -p "/jobs"
59
- pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.6.0
58
+ PI_CODING_AGENT_DIR=$(mktemp -d) pi -e git:github.com/ismailsaleekh/pi-background-tasks@v0.7.2 --offline --no-tools --no-session -p "/jobs"
59
+ pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.7.2
60
60
  ```
61
61
 
62
62
  ## pi.dev/packages
package/README.md CHANGED
@@ -2,26 +2,26 @@
2
2
 
3
3
  Claude-Code-like explicit background shell task manager for [Pi](https://pi.dev/).
4
4
 
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.
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. It also ships Fusion: a direct child-Pi five-call synthesis workflow exposed as `/fusion`, `/fusion-models`, and the always-active `fusion_brainstorm` tool. A terminal task status is published only after trailing wrapped-agent telemetry is consumed and final output plus terminal metadata have completed their durability writes.
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.6.0
12
+ pi install npm:pi-background-tasks@0.7.2
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.6.0
18
+ pi install git:github.com/ismailsaleekh/pi-background-tasks@v0.7.2
19
19
  ```
20
20
 
21
21
  For project-local install:
22
22
 
23
23
  ```bash
24
- pi install -l npm:pi-background-tasks@0.6.0
24
+ pi install -l npm:pi-background-tasks@0.7.2
25
25
  ```
26
26
 
27
27
  ## Commands
@@ -33,6 +33,8 @@ pi install -l npm:pi-background-tasks@0.6.0
33
33
  - `/tasks` or `/bg-tasks` — fallback command to open the task manager UI.
34
34
  - `/bg-clear` — clear finished background-task footer notices.
35
35
  - `/bg-update` — print update instructions when a newer published version exists (instruct-only; never self-installs).
36
+ - `/fusion <prompt>` — run three candidate child Pi final-text calls, one blind evaluator, and one merger, then append the merged answer directly as a visible `fusion-result` custom message without asking the parent model to rewrite it. Running `/fusion` without arguments opens a multiline editor in UI-capable modes; cancelling the editor does not spawn children.
37
+ - `/fusion-models` — TUI-only five-slot global model selector (`Candidate 1`, `Candidate 2`, `Candidate 3`, `Evaluator`, `Merger`). It supports duplicate selections, `$current` defaults, slash-containing model ids, atomic saves to `fusion-models.json`, and rejects non-TUI modes immediately.
36
38
 
37
39
  ## Footer dock UX
38
40
 
@@ -89,11 +91,61 @@ The lookup runs at most once per session on `session_start`, is time-boxed, and
89
91
  ## LLM tools
90
92
 
91
93
  - `bg_run` — start named long-running commands without blocking the conversation.
94
+ - `bg_run_pi_attested` — opt-in structured direct-spawn Pi agent task that emits a strict local attestation sidecar after successful completion.
92
95
  - `bg_status` — inspect one task or all recent tasks.
93
96
  - `bg_logs` — read bounded task output.
94
97
  - `bg_kill` — stop a running task.
98
+ - `fusion_brainstorm({prompt})` — always-active tool that runs the Fusion workflow and returns the exact merged text as the tool result for the parent agent to consume, with standard nested usage attached when the host Pi supports tool-result usage. Its closed public schema has exactly one required parameter, `prompt`; extra keys are rejected. It has no eligibility, quota, routine, or justification gate. Tool context capture excludes the current assistant tool-call leaf when Pi is executing that `fusion_brainstorm` call, so the nested children do not see the in-progress tool call or sibling calls.
95
99
 
96
- `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.
100
+ `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 both `notifyOnCompletion` and `triggerOnCompletion` to `true`. With those defaults, `bg_run` returns immediately, the agent continues only independent useful work or ends its current turn instead of sleeping or polling, and a durable `background-task-notification` for completed, failed, or killed state automatically starts a follow-up turn. The launch receipt states the effective notification/wake behavior explicitly. `bg_status` and `bg_logs` remain available for user-requested inspection, deliberately disabled completion delivery, concrete hang diagnosis, or reading output after the terminal event; they are not waiting primitives, and the terminal notification does not need status reconfirmation. Setting `triggerOnCompletion: false` keeps the notification but prevents it from starting an agent turn. Setting `notifyOnCompletion: false` suppresses both notification and wake-up even if `triggerOnCompletion` is true.
101
+
102
+ 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.
103
+
104
+ `bg_run_pi_attested` is separate from `bg_run` and never accepts a shell command. It takes structured `provider`, `model`, `prompt`, optional literal extra Pi argv, and a relative `reportPath`; launches exactly one direct `pi --mode json` child; records raw Pi JSON events, separate stderr, exact argv/cwd, prompt/report hashes, observed Pi session/provider/model, and `ModelRegistry.isUsingOAuth` credential class. It forbids direct API-key/auth-file launch arguments and emits no partial attestation: failures remain ordinary failed tasks with no sidecar.
105
+
106
+
107
+ ## Fusion workflow
108
+
109
+ Fusion runs direct child `pi --mode text` processes only; it never calls `pi-ai` completion APIs. Each child is launched with `--no-session`, `--no-tools`, `--no-extensions`, `--no-skills`, `--no-prompt-templates`, `--no-themes`, and `--no-context-files`, plus the resolved provider/model/thinking level and the package-owned private `extensions/fusion-child.ts` metadata extension. The prompt travels over stdin, not a shell or positional argument.
110
+
111
+ Pi text mode writes the final full answer exactly once instead of serializing cumulative reasoning/partial-message events on every token delta. The private child extension emits one compact, reasoning-free metadata record per finalized assistant message for provider/model, stop reason, usage, and response byte/hash validation. Fusion persists those compact records in `*.events.jsonl`; the complete answer remains in the stage response artifact. The 32 MiB child stdout cap therefore applies to one final response, not amplified JSON telemetry. Failed attempts keep the authoritative response artifact empty and, when any stdout was captured, persist it separately as an explicitly incomplete `*.response.partial.*` artifact.
112
+
113
+ Model configuration is global under the Pi agent directory:
114
+
115
+ ```text
116
+ fusion-models.json
117
+ ```
118
+
119
+ Missing config means all five slots are `$current`. Malformed config, stale explicit models, unavailable current models, and concurrent selector write conflicts fail loudly before child inference. Selector saves use an inter-process lock plus revision re-read before rename so simultaneous dialogs cannot silently overwrite each other. Candidate identities are anonymized before evaluation; provider/model metadata stays in local artifacts, not in evaluator prompts.
120
+
121
+ Progress is surfaced through `fusion` status updates, TUI cancellable loader UI for `/fusion`, and partial `fusion_brainstorm` tool updates. Session shutdown or reload tracks the whole invocation from entry, aborts live or initializing Fusion runs, and waits for cleanup. Captured conversation context is serialized as a full text transcript with no summarization-oriented 2,000-character tool-result truncation. Image bytes/base64 are not forwarded to Fusion children; user/tool-result image blocks are replaced in the transcript with `[Image omitted from fusion text transcript: <mime-type>]`, so visual information must be described in text if the children need it. Provider context-window failures remain loud child failures rather than hidden local truncation.
122
+
123
+ ## Extension EventBus API
124
+
125
+ Version `0.7.0` exposes a real extension-to-extension service over Pi's documented `pi.events` bus. This is not a `ctx` method and it does not call a second task manager: requests route to the same `BackgroundTaskRegistry` used by `bg_run`, `bg_status`, `bg_logs`, and `bg_kill`.
126
+
127
+ Public constants are exported from `src/core/extension-api.ts`:
128
+
129
+ | Purpose | Value |
130
+ |---|---|
131
+ | Request channel | `pi-background-tasks:request:v1` |
132
+ | Response channel | `pi-background-tasks:response:v1` |
133
+ | Terminal channel | `pi-background-tasks:terminal:v1` |
134
+ | Request schema | `pi-background-tasks.extension-request.v1` |
135
+ | Response schema | `pi-background-tasks.extension-response.v1` |
136
+ | Terminal schema | `pi-background-tasks.extension-terminal.v1` |
137
+
138
+ Requests are closed frames: `{ schema_version, request_id, operation, payload }`, where `operation` is one of `capabilities`, `run`, `status`, `logs`, or `kill`. Responses echo the same `request_id` and `operation`, set `ok`, and contain exactly one of `result` or bounded `error`. Malformed frames, unknown keys, duplicate request IDs, requests before `session_start`, and requests during shutdown receive `ok: false`; they are not silently dropped or rerouted to shell fallback behavior.
139
+
140
+ `capabilities` returns exactly:
141
+
142
+ ```json
143
+ {"api_version":1,"run":true,"run_is_agent":true,"run_completion_trigger":true,"status":true,"logs":true,"logs_bounded":true,"kill":true}
144
+ ```
145
+
146
+ `run.payload` is the strict `bg_run` launch object: `name`, `command`, `isAgent`, `notifyOnCompletion`, `triggerOnCompletion`, plus optional positive-integer `timeoutSeconds`. The result is a `BgTaskSnapshot`. `status` returns `{ tasks }`; `logs` returns the existing bounded log detail fields plus bounded `text`; `kill` returns `{ task, message }`. Task status vocabulary is exactly `running`, `completed`, `failed`, or `killed`.
147
+
148
+ Terminal events keep the strict paired-consumer frame `{ schema_version: "pi-background-tasks.extension-terminal.v1", task }`. They are correlated by `task.id`, published exactly once per task after final output and terminal metadata durability, and for EventBus `run`/`kill` requests they are held behind a response barrier so even an immediately exiting or immediately killed child cannot emit its terminal event until the correlated response has been delivered and one microtask turn has allowed consumers to bind the returned task id. Terminal EventBus delivery exceptions are logged loudly and retried; a task is marked terminal-published only after the EventBus emit returns successfully.
97
149
 
98
150
  ## Runtime files
99
151
 
@@ -104,11 +156,30 @@ Task output and metadata are written under the current project:
104
156
  .pi/tasks/<session-id>-<pid>/<task-id>.json
105
157
  ```
106
158
 
107
- These are runtime artifacts and should remain gitignored.
159
+ Fusion writes private debugging artifacts under:
160
+
161
+ ```text
162
+ .pi/fusion/<session-id>-<pid>/<run-id>/
163
+ ```
164
+
165
+ Each run contains `manifest.json`, `canonical-input.json`, candidate/evaluation/merge prompts, raw child JSONL events, stderr, responses, `blind-candidates.json`, `evaluation.json`, `merged.md`, and `error.json` for failed/cancelled runs. Artifact files are written by private temp-file/fsync/rename, and manifests persist cumulative child usage plus per-attempt observed usage/model data for successful, failed, and cancelled child attempts. These artifacts are local evidence only; they are not shown in `/jobs` or the background-task dock.
166
+
167
+ For attested Pi tasks only, the task id is `b` plus 32 random hex characters (128 bits) and additional flat siblings are written in the same directory:
168
+
169
+ ```text
170
+ .pi/tasks/<session-id>-<pid>/<task-id>.pi-events.jsonl
171
+ .pi/tasks/<session-id>-<pid>/<task-id>.stderr
172
+ .pi/tasks/<session-id>-<pid>/<task-id>.pi-telemetry-wrapper.cjs
173
+ .pi/tasks/<session-id>-<pid>/<task-id>.attestation.json
174
+ ```
175
+
176
+ The attestation sidecar uses `schema_version: "phase2.pi_task_attestation.v1"` and is written last, after metadata/output/events/stderr/wrapper/report bytes are closed and hashed. An attested task does not become externally visible as `completed` until final metadata and the sidecar are durable. These are local runtime artifacts and should remain gitignored.
108
177
 
109
178
  ## Safety model
110
179
 
111
180
  - Commands are spawned and tracked with `child_process.spawn`; the package does not rely on shell `&`.
181
+ - Fusion inference is isolated to direct child `pi --mode text` invocations with tools/skills/session/context files disabled and only the package-owned compact metadata extension explicitly loaded; no direct completion API, API-key argument, or model fallback is used.
182
+ - Attested Pi tasks are a local, unsigned, same-user-writable attestation path for downstream gates. They bind source bytes and observed Pi/ModelRegistry facts; they are not cryptographic proof against a malicious local user, compromised Pi binary, or compromised provider.
112
183
  - stdout/stderr are captured to task output files.
113
184
  - Model-visible logs are bounded and point to full output files.
114
185
  - POSIX process groups are used for process-tree kill where possible, with child-process fallback.
@@ -128,6 +199,7 @@ Smoke and release checks:
128
199
  ```bash
129
200
  npm run smoke
130
201
  npm run pack:dry-run
202
+ npm run test:compat
131
203
  ```
132
204
 
133
205
  Full interactive QA gate:
package/TESTING.md CHANGED
@@ -18,6 +18,7 @@ This runs:
18
18
 
19
19
  ```bash
20
20
  npm run typecheck
21
+ npm run test:type-safety
21
22
  npm run test:unit
22
23
  npm run test:sdk
23
24
  npm run test:rpc
@@ -43,15 +44,12 @@ Smoke/release checks:
43
44
  ```bash
44
45
  npm run smoke
45
46
  npm run pack:dry-run
47
+ npm run test:compat
46
48
  ```
47
49
 
48
- Current smoke:
50
+ Current smoke is `tsx scripts/smoke.ts`. It creates a temporary Pi agent/session directory, sets offline/telemetry-suppression environment variables, and runs the package entrypoint with `/jobs`.
49
51
 
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`.
52
+ Smoke proves loadability only; completion requires `npm run test`, `npm run test:full`, `npm run pack:dry-run`, and the release-only compatibility gate when preparing a release.
55
53
 
56
54
  ## Required isolated environment
57
55
 
@@ -66,19 +64,36 @@ CI=1
66
64
 
67
65
  Tests must not use the user's real `~/.pi/agent`.
68
66
 
67
+
68
+ Fusion-specific targeted gates:
69
+
70
+ ```bash
71
+ npm run typecheck
72
+ npm run test:type-safety
73
+ npm run test:unit
74
+ npm run test:component
75
+ npm run test:sdk
76
+ npm run test:rpc
77
+ npm run test:agent-loop
78
+ ```
79
+
80
+ The Fusion SDK/RPC/scripted-provider tests install a deterministic fake child `pi` in a temp `PATH` from `tests/helpers/fusion-fake-pi.ts`. Parent Pi remains the real SDK/RPC runtime; only direct child `pi --mode text` calls with the package-owned private compact metadata extension are intercepted. `PI_CODING_AGENT_DIR` is pointed at the temp agent directory so `fusion-models.json` is never read from the user's real global Pi directory. Fusion context coverage is intentionally text-transcript coverage: tests verify long text is not summarization-truncated and image-containing session entries are represented by `[Image omitted from fusion text transcript: <mime-type>]` markers without forwarding raw image bytes/base64 to child Pi prompts. The release-only `npm run test:compat` packs the package, installs exact supported Pi versions, runs `/jobs`, runs `/fusion` through the installed package entrypoint with the fake child Pi, verifies five child invocations, and verifies `/fusion-models` rejects non-TUI mode.
81
+
69
82
  ## Coverage summary
70
83
 
71
84
  Implemented coverage includes:
72
85
 
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`, `/bg-update` 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
86
+ - tools: `bg_run`, `bg_run_pi_attested`, `bg_status`, `bg_logs`, `bg_kill`, `fusion_brainstorm`, including required `isAgent` schema/runtime validation, the event-driven no-sleep/no-poll system-prompt contract, truthful launch receipts for all four notification/wake combinations, non-terminating `bg_run` compatibility, point-in-time status/log guidance, durable terminal-notification authority, attested direct Pi spawn validation, Fusion exact merged tool result delivery/progress/details/context exclusion, text-transcript image omission markers with raw image data excluded from child prompts, unknown/ambiguous IDs, completed-kill failure, legacy no-name preparation, head/tail truncation, and notification on/off behavior
87
+ - commands: `/bg`, `/jobs`, `/logs`, `/kill`, `/tasks`, `/bg-tasks`, `/bg-clear`, `/bg-update`, `/fusion`, `/fusion-models` discovery, happy paths, `/fusion` direct custom-message delivery, `/fusion` editor/cancel flow, `/fusion-models` TUI save and non-TUI rejection, `/bg --agent` parsing, finished-notice clearing, malformed `/bg`, unknown/ambiguous IDs, completed-task `/kill`, byte-limit normalization, and RPC no-hang fallback behavior
75
88
  - update-available notice: semver parse/compare/precedence, `formatUpdateSegment`, npm/`package.json` payload narrowing, and injected-fetch success/404/throw/timeout (unit); localhost-registry footer segment (idle + appended to an active footer), `/bg-update` non-installing instructions, and opt-out/offline/already-current/registry-failure no-segment-and-no-throw paths (SDK); `/bg-update` discovery and offline instructions (RPC). The check is one-shot on `session_start`, time-boxed, offline-safe, gated by `PI_OFFLINE`/`PI_BG_DISABLE_UPDATE_CHECK`, and `PI_BG_REGISTRY_URL` overrides the registry endpoint
76
89
  - shortcut/UI: component coverage for focused dock list/detail/key handling, detail output-tail scrolling (arrow/page scroll, follow-pause-on-scroll, `lines X–Y of N` position indicator, resume-follow-at-bottom, and no-scroll when output fits), 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
77
- - 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
90
+ - runtime files: output and metadata files under `.pi/tasks/`, Fusion private `.pi/fusion/<session-id>-<pid>/<run-id>/` artifacts plus global `fusion-models.json`, 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, attested Pi flat siblings (`.pi-events.jsonl`, `.stderr`, `.pi-telemetry-wrapper.cjs`, `.attestation.json`), real child `pi --mode json` tool-event parsing for background-agent telemetry, split/large telemetry ingestion, metadata after completion/failure, Fusion compact final-only child metadata and explicitly marked partial-response artifacts, Fusion manifest aggregate usage equal to the sum of successful plus observed failed/cancelled child attempt usage, local tarball install contents
91
+ - extension EventBus API: unit coverage for `pi-background-tasks:request:v1`/`response:v1` closed-frame validation, exact capability handshake, malformed payload rejection, unknown keys, unknown operations, duplicate request IDs, missing `session_start`, shutdown refusal, unsubscribe, strict terminal frame shape, and response-barrier ordering; registry coverage for exactly-one terminal publication after durable metadata plus loud/retriable terminal delivery failure; SDK coverage with a shared real `createEventBus()` loading the actual extension, starting `printf api-ok`, reading bounded logs, observing exactly one terminal event after the run response, and killing a real sleep task without model/provider calls
92
+ - attested Pi producer: unit/SDK coverage for 128-bit attested task ids, exact direct argv/cwd, ModelRegistry OAuth observation without secrets, raw Pi session/message events, separate stderr, prompt/report/source hashes, authority start/finish commit/tree/clean checks, atomic metadata serialization, completion visibility only after the sidecar is durable, malformed event rejection, and no attestation sidecar for ordinary tasks
78
93
  - agent activity transcript: pure `parseAgentActivity`/`formatAgentActivityLine` coverage (assistant text, reasoning, tool start with arg summary, silent successful tool end, `✗ tool failed` errors, truncation, invalid/non-activity narrowing); registry-unit coverage that wrapped-agent stdout is reconstructed across split chunks into the human-readable transcript while telemetry/activity control JSON is stripped from the output file (telemetry fields still updated), stderr passes through, and the trailing partial line is flushed on finalize; SDK coverage that fake and real child `pi --mode json` runs surface `→ tool`/`✗ tool failed`/assistant text in `bg_logs` with no control JSON leaking into the visible output
79
94
  - 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
80
- - 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
81
- - package: manifest, docs, `pi.extensions`, peer dependency/import parity, packed runtime files, tarball-install smoke, and artifact exclusion
95
+ - agent loop: deterministic scripted-provider coverage against `extensions/background-tasks.ts` for actual event-driven `bg_run` behavior. The provider observes the effective system prompt, public tool descriptions, and real launch receipt and deliberately emits the pre-fix `bg_status` poll if any contract layer is absent; the passing path proves one launch, no sleep/status/log polling, one durable terminal notification, and exactly one follow-up turn. It also covers notification-only `triggerOnCompletion:false`, `/bg` display-only behavior, `notifyOnCompletion:false`, failed-task notification error fields, and parent-model `fusion_brainstorm` tool use followed by normal parent response
96
+ - package: manifest, docs, `pi.extensions`, exported `src/core/extension-api.ts`, peer dependency/import parity, packed runtime files, tarball-install smoke, direct-completion import bans, test/helper/script/artifact exclusion, and isolated offline npm install environment for default package tests
82
97
 
83
98
  ## PTY notes
84
99
 
@@ -88,6 +103,7 @@ Implemented coverage includes:
88
103
  - A named `/bg` task appears in the dock when opened with xterm `Shift+Down` (`ESC [ 1 ; 2 B`).
89
104
  - 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.
90
105
  - Detail output-tail scrolling works with real arrow/page keys: opening a 60-line task's detail and pressing `↑` shows the `lines X–Y of N` position indicator and pauses the live tail.
106
+ - Fusion TUI surfaces work end to end: `/fusion <prompt>` renders the exact fake merged answer directly in the real TUI, and `/fusion-models` opens the five-slot selector.
91
107
 
92
108
  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.
93
109
 
@@ -116,4 +132,4 @@ Normalize volatile values before snapshotting: task IDs, session IDs, PIDs, time
116
132
 
117
133
  ## Remaining full exhaustive coverage work
118
134
 
119
- 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.
135
+ The Lane A residual hardening items, Fusion repair hardening, and the explicit `isAgent` agent-vs-script classification are covered by default unit/SDK/RPC/component/package 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 CHANGED
@@ -12,12 +12,13 @@ This package follows:
12
12
  |---|---|
13
13
  | Package | `pi-background-tasks` |
14
14
  | Extension entrypoint | `extensions/background-tasks.ts` |
15
- | Public commands | `/bg`, `/jobs`, `/logs`, `/kill`, `/tasks`, `/bg-tasks`, `/bg-clear`, `/bg-update` |
16
- | Public tools | `bg_run`, `bg_status`, `bg_logs`, `bg_kill` |
15
+ | Public commands | `/bg`, `/jobs`, `/logs`, `/kill`, `/tasks`, `/bg-tasks`, `/bg-clear`, `/bg-update`, `/fusion`, `/fusion-models` |
16
+ | Public tools | `bg_run`, `bg_run_pi_attested`, `bg_status`, `bg_logs`, `bg_kill`, `fusion_brainstorm` |
17
+ | Extension EventBus API | `pi-background-tasks:request:v1`, `pi-background-tasks:response:v1`, `pi-background-tasks:terminal:v1`; schemas exported from `src/core/extension-api.ts` |
17
18
  | Shortcuts | `Shift+Down`; optional fallback `Ctrl+Alt+C` |
18
19
  | Custom UI | footer status + focused bottom dock overlay |
19
20
  | Custom provider | no |
20
- | Runtime files/state | `.pi/tasks/<session-id>-<pid>/<task-id>.output`, `.pi/tasks/<session-id>-<pid>/<task-id>.json` |
21
+ | Runtime files/state | `.pi/tasks/<session-id>-<pid>/<task-id>.output`, `.pi/tasks/<session-id>-<pid>/<task-id>.json`; attested Pi opt-in adds `.pi-events.jsonl`, `.stderr`, `.pi-telemetry-wrapper.cjs`, `.attestation.json`; Fusion adds private `.pi/fusion/<session-id>-<pid>/<run-id>/` manifests/prompts/events/stderr/responses/evaluation/merged/error artifacts plus global `fusion-models.json` |
21
22
 
22
23
  ## Required gates
23
24
 
@@ -32,7 +33,8 @@ This package follows:
32
33
  | 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
34
  | Scripted provider | `npm run test:agent-loop` | full gate | implemented |
34
35
  | Pack dry run | `npm run pack:dry-run` | release gate | implemented |
35
- | Smoke | `npm run smoke` | no | implemented; load-only |
36
+ | Smoke | `npm run smoke` | no | implemented; isolated load-only |
37
+ | Compatibility | `npm run test:compat` | release gate | implemented; exact Pi `0.75.5`, `0.81.1`, `0.82.1` pack/install plus `/jobs`, `/fusion`, and `/fusion-models` surfaces |
36
38
 
37
39
  ## Feature coverage matrix
38
40
 
@@ -43,11 +45,18 @@ This package follows:
43
45
  | Show bounded logs | `/logs <id> [maxBytes]` | yes | | yes | | | | | Unit covers bounded reads; RPC verifies output/path. |
44
46
  | Kill running task | `/kill <id>` | | yes | yes | | | | | SDK tool and RPC slash command. |
45
47
  | 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. |
48
+ | Start background command from LLM tool | `bg_run` | yes | yes | | | | | yes | Unit derives all notification/wake modes from one typed helper. SDK exercises the registered tool's effective system prompt, descriptions, non-terminating behavior, and all four launch-receipt combinations. The scripted provider verifies a default launch yields without sleep/status/log polling before one terminal-event follow-up. |
49
+ | Attested direct Pi producer | `bg_run_pi_attested` | yes | yes | | | | type/schema | | Unit covers 128-bit ids, exact direct argv, raw events/stderr, provider/model/session capture from Pi JSON, OAuth observation via ModelRegistry, prompt/report/source hash laws, completion visibility only after durable sidecar creation, malformed-event rejection, and no sidecar for ordinary tasks. SDK runs a fake Pi CLI through the public tool and verifies one complete flat attestation. |
50
+ | Inspect task status | `bg_status` | | yes | | | | | yes | SDK uses exact IDs for deterministic lifecycle observations and verifies the model-facing contract calls status a point-in-time inspection rather than a wait primitive. Scripted-provider ordinary waiting makes zero status calls. |
51
+ | Read task logs | `bg_logs` | yes | yes | | | | | yes | SDK verifies bounded content and the model-facing no-wait-loop contract. Scripted-provider ordinary waiting makes zero log calls. |
49
52
  | 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. |
53
+ | Fusion command direct result | `/fusion`, `fusion-result` custom message | yes | yes | yes | | yes | yes | | Core unit covers deterministic full text-transcript context construction, explicit image omission markers without raw image data, direct final-text child argv/stdin/compact-metadata parsing, exact multi-block answer reconstruction, artifacts, pre-abort handling, and orchestration. SDK runs real `/fusion` against a fake child `pi`, verifies exactly five child text-mode invocations, hidden prompt persistence, visible exact merged custom message, no parent assistant rewrite, renderer output, progress/status behavior, no-argument editor flow, editor cancellation, and malformed config causing zero children. RPC verifies command discovery, `/fusion <prompt>` with U+2028/U+2029 content, custom-message result emission, no parent `agent_start`, no-argument editor protocol, malformed config/child failure visibility, and child isolation flags. PTY verifies `/fusion` renders the exact merged answer directly in a real TUI. Compatibility smoke runs `/fusion` through every supported Pi version with the installed package entrypoint. |
54
+ | Fusion tool result | `fusion_brainstorm({prompt})` | yes | yes | | | | yes | yes | Tool is registered at load and re-added on `session_start`; no eligibility/quota/routine/justification gates are implemented. Unit/SDK cover closed one-parameter schema, extra-key rejection, active tool-call leaf exclusion before asynchronous config/model work, sibling-call exclusion, exact merged text delivery, image-containing session context serialized as text omission markers with raw image bytes/base64 absent from child stdin, standard nested usage when supported, progress updates, final details with usage/artifact/model snapshot, and invalid config zero-child failure. Scripted-provider coverage proves a deterministic parent model calls `fusion_brainstorm`, receives the exact merged tool result, exercises one evaluator schema-repair child after invalid first evaluator JSON, then responds normally. |
55
+ | Fusion model selector | `/fusion-models`, `fusion-models.json`, `FusionModelSelector` | yes | yes | yes | yes | yes | yes | | Unit covers strict config parsing, duplicates, slash-containing model IDs, stale model failures, `$current`, atomic save, inter-process lock/revision compare-and-swap, and deterministic concurrent-save conflict. Component covers all five slots, duplicate selection, searchable model list, stale display, reset/save/cancel, persistence errors, and width safety. SDK drives the real command in a synthetic TUI context without `ctx.mode` to cover old Pi compatibility and verifies duplicate `$current`/explicit model persistence; SDK also verifies headless no-UI rejection. RPC verifies non-TUI notification without hanging, PTY verifies the real selector opens in a TUI, and compatibility smoke verifies print-mode rejection for every supported Pi version. |
56
+ | Fusion child isolation/lifecycle | child `pi --mode text`, private compact metadata extension, shutdown cleanup, `.pi/fusion` artifacts | yes | yes | yes | | | yes | | BUG-180 unit coverage proves reasoning and full response text are absent from compact metadata, text mode emits the complete final answer once, exact text-block byte/hash reconstruction preserves the unmodified answer, malformed metadata/model/stop/hash/newline states fail loudly, and the unchanged 32 MiB cap now bounds one semantic response. Unit coverage also covers argv, package-owned extension resolution, env cleanup, stdin failure, stdout/stderr caps, timeout/abort/process-group kill, abort-during-spawn race, cleanup failure surfacing, no-close-after-SIGKILL failure, manifest transitions, compact event artifacts, explicit incomplete partial-response artifacts, failed-run usage persistence, aggregate usage, transient spawn retry, sibling cancellation, concurrent workflows, and orchestrator cancellation. SDK/RPC verify actual public consumers launch direct child `pi` with all isolation flags. Session shutdown tracks initializing and live Fusion runs through the extension active-run set. |
57
+ | Extension request/response service | `pi-background-tasks:request:v1` → `pi-background-tasks:response:v1` | yes | yes | | | | yes | | Unit covers closed-frame validation, capability handshake, unknown keys, unknown operation, duplicate request IDs, missing `session_start`, shutdown refusal, strict `run.payload`, strict malformed frames, and unsubscribe. SDK loads the real extension with a shared `createEventBus()`, starts `printf api-ok`, reads bounded logs, lists status, starts and kills a real sleep task, and checks malformed/unknown/duplicate controls without model/provider calls. Package tests assert `src/core/extension-api.ts` ships. |
58
+ | Terminal EventBus publication | `pi-background-tasks:terminal:v1` | yes | yes | | | | yes | | Registry unit proves exactly-one terminal snapshot after durable metadata and loud/retriable EventBus delivery failure; extension API unit proves one strict terminal frame correlated by task id after the run response for immediate, normal, failed, timeout, and killed tasks; SDK observes one terminal event for a completed task and one for a killed task through the real extension service. |
59
+ | Completion notification | custom message `background-task-notification` | yes | yes | | renderer via typecheck | | | yes | BUG-181 unit/SDK coverage pins the durable-terminal guidance and truthful effective delivery receipts. Scripted provider loads the shipped extension, conditionally attempts the old `bg_status` poll when the real system prompt/descriptions/receipt are incomplete, and proves the fixed contract instead yields with exactly one `bg_run`, one terminal notification, and one default follow-up. Notification-only, notification-disabled, failed-task, and display-only `/bg` paths remain covered. |
51
60
  | 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
61
  | 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
62
  | 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. |
@@ -70,8 +79,8 @@ This package follows:
70
79
  | Output cap kills task | `PI_BG_MAX_OUTPUT_BYTES` | | | yes | | | | | RPC runs with a low cap and asserts failed status/log notice. |
71
80
  | Shutdown cleanup | `session_shutdown` | yes | yes | | | | | | SDK asserts multiple running tasks become killed; registry tests cover shared stop/wait behavior. |
72
81
  | 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, large telemetry records above the old 16KiB buffer, and wrapped-agent transcript/telemetry separation with split-chunk and trailing-partial flush; SDK/RPC cover runtime spawn/timeout/output-cap/shutdown; scripted provider covers wakeup integration. |
73
- | Package manifest | `package.json` | | | | | | yes | | Keywords, `pi.extensions`, files. |
74
- | Pack contents | `npm pack --dry-run` | | | | | | yes | | Runtime files included. |
82
+ | Package manifest | `package.json` | | | | | | yes | | Keywords, `pi.extensions`, files, local smoke/compat scripts, and direct-completion import bans. |
83
+ | Pack contents | `npm pack --dry-run` | | | | | | yes | | Runtime files included; tests, fake child helpers, release-only scripts, artifacts, nested tarballs, and `node_modules` excluded. Default tarball install test uses isolated HOME/XDG/npm cache and offline peer-ignore install from the local tarball. |
75
84
 
76
85
  ## Residual hardening coverage
77
86
 
@@ -84,7 +93,7 @@ Lane A residual hardening is now covered by automated tests. No remaining harden
84
93
  | 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. |
85
94
  | 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. |
86
95
  | Pruning | Unit tests cover oldest-finished pruning while preserving running tasks. |
87
- | 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. |
96
+ | Completion follow-up turns | `test:agent-loop` registers a deterministic scripted provider against the shipped extension path and verifies event-driven `bg_run` yielding with no sleep/status/log polling, exactly one default wakeup, notification-only `triggerOnCompletion:false`, `/bg` display-only behavior, `notifyOnCompletion:false`, and failed notification error fields. |
88
97
  | 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. |
89
98
  | Footer/status combinations | SDK tests cover failed/stopped/done/running combinations, explicit clear, and focused label. |
90
99
 
@@ -93,7 +102,7 @@ Lane A residual hardening is now covered by automated tests. No remaining harden
93
102
  - [x] `npm run test` passes offline in isolated temp dirs.
94
103
  - [x] `npm run test:full` validates baseline real TUI/PTY behavior.
95
104
  - [x] `npm run pack:dry-run` passes.
96
- - [x] README claims and all plausible edge cases are exhaustively mapped in this test plan.
105
+ - [x] README claims and all plausible edge cases are exhaustively mapped in this test plan, including Fusion command/tool/model-selector public surfaces and the text-only image omission limitation.
97
106
  - [x] Every listed edge case has automated coverage at the lowest reliable layer.
98
107
  - [x] No real LLM/API/network dependency in default tests.
99
108
  - [x] No dependency on user/global `~/.pi/agent` for SDK/RPC/PTY tests.
@@ -1 +1 @@
1
- export { default } from "../src/extension.ts";
1
+ export { default } from '../src/extension.js';
@@ -0,0 +1 @@
1
+ export { default } from '../src/fusion-child-extension.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-background-tasks",
3
- "version": "0.6.0",
4
- "description": "Claude-Code-like named background shell task manager for Pi: bg_run tools, /bg commands, Shift+Down footer dock, bounded logs, kill/timeout safety, and completion wakeups.",
3
+ "version": "0.7.2",
4
+ "description": "Pi extension package for background shell tasks plus five-model fusion brainstorming: bg_run tools, /bg commands, /fusion, fusion_brainstorm, model selector UI, bounded logs, kill/timeout safety, and completion wakeups.",
5
5
  "type": "module",
6
6
  "license": "ISC",
7
7
  "author": "Ismail <ismailsalikhodjaev@gmail.com>",
@@ -15,7 +15,10 @@
15
15
  "background-tasks",
16
16
  "coding-agent",
17
17
  "shell",
18
- "tasks"
18
+ "tasks",
19
+ "fusion",
20
+ "brainstorm",
21
+ "multi-model"
19
22
  ],
20
23
  "homepage": "https://github.com/ismailsaleekh/pi-background-tasks#readme",
21
24
  "repository": {
@@ -38,16 +41,19 @@
38
41
  "typecheck": "tsc --noEmit",
39
42
  "test:type-safety": "tsx --test tests/package/type-safety.test.ts",
40
43
  "test:unit": "tsx --test tests/unit/**/*.test.ts",
41
- "test:sdk": "tsx --test tests/sdk/**/*.test.ts",
44
+ "test:sdk": "tsx --test --test-concurrency=1 tests/sdk/**/*.test.ts",
42
45
  "test:rpc": "tsx --test tests/rpc/**/*.test.ts",
43
46
  "test:component": "tsx --test tests/component/**/*.test.ts",
44
47
  "test:package": "tsx --test tests/package/**/*.test.ts",
45
48
  "test": "npm run typecheck && npm run test:type-safety && npm run test:unit && npm run test:sdk && npm run test:rpc && npm run test:component && npm run test:package",
46
49
  "test:pty": "tsx --test tests/pty/**/*.test.ts",
47
- "test:agent-loop": "tsx --test tests/scripted-provider/**/*.test.ts",
50
+ "test:agent-loop": "tsx --test --test-concurrency=1 tests/scripted-provider/**/*.test.ts",
48
51
  "test:full": "npm run test && npm run test:pty && npm run test:agent-loop",
49
- "smoke": "pi --no-extensions -e ./extensions/background-tasks.ts --offline --no-tools --no-session -p \"/jobs\"",
50
- "pack:dry-run": "npm pack --dry-run"
52
+ "smoke": "tsx scripts/smoke.ts",
53
+ "pack:dry-run": "npm pack --dry-run",
54
+ "lint": "cd ../.. && npm run quality:ts:lint",
55
+ "format:check": "cd ../.. && npm run quality:ts:format",
56
+ "test:compat": "tsx scripts/test-compat.ts"
51
57
  },
52
58
  "pi": {
53
59
  "extensions": [
@@ -55,9 +61,9 @@
55
61
  ]
56
62
  },
57
63
  "peerDependencies": {
58
- "@earendil-works/pi-coding-agent": "*",
59
- "@earendil-works/pi-tui": "*",
60
- "typebox": "*"
64
+ "@earendil-works/pi-coding-agent": "^0.75.5 || ^0.81.1 || ^0.82.1",
65
+ "@earendil-works/pi-tui": "^0.75.5 || ^0.81.1 || ^0.82.1",
66
+ "typebox": "^1.1.38"
61
67
  },
62
68
  "devDependencies": {
63
69
  "@earendil-works/pi-ai": "^0.75.5",