@elpapi42/pi-fleet 0.1.0-beta.1 → 0.1.0-beta.13

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +180 -3
  2. package/README.md +118 -120
  3. package/bin/pifleet-runtime.mjs +1 -1
  4. package/dist/cli-meta.json +5555 -175
  5. package/dist/cli.mjs +4391 -471
  6. package/dist/cli.mjs.map +4 -4
  7. package/dist/client/agent-target.d.ts +33 -0
  8. package/dist/client/contracts.d.ts +81 -0
  9. package/dist/client/fleet-client.d.ts +118 -0
  10. package/dist/client/index.d.ts +4 -0
  11. package/dist/client/sdk-connector.d.ts +7 -0
  12. package/dist/client/sdk-facade.d.ts +84 -0
  13. package/dist/client/sdk-transport.d.ts +24 -0
  14. package/dist/client/shared-client.d.ts +18 -0
  15. package/dist/client/socket-fleet-client.d.ts +21 -0
  16. package/dist/client-meta.json +5736 -0
  17. package/dist/client.mjs +4434 -0
  18. package/dist/client.mjs.map +7 -0
  19. package/dist/installer-meta.json +87 -13
  20. package/dist/installer.mjs +589 -95
  21. package/dist/installer.mjs.map +4 -4
  22. package/dist/journal-sqlite-worker-meta.json +149 -0
  23. package/dist/journal-sqlite-worker.mjs +1110 -0
  24. package/dist/journal-sqlite-worker.mjs.map +7 -0
  25. package/dist/pi/external-installation.d.ts +23 -0
  26. package/dist/platform/client/start-runtime.d.ts +25 -0
  27. package/dist/platform/install/runtime-release.d.ts +8 -0
  28. package/dist/platform/install/tree-integrity.d.ts +7 -0
  29. package/dist/platform/shared/paths.d.ts +8 -0
  30. package/dist/platform/shared/runtime-ownership.d.ts +14 -0
  31. package/dist/protocol/jsonl.d.ts +3 -0
  32. package/dist/protocol/pi-identity.d.ts +16 -0
  33. package/dist/protocol/semantic-segmentation.d.ts +22 -0
  34. package/dist/protocol/version.d.ts +2 -0
  35. package/dist/runtime/semantic-events.d.ts +43 -0
  36. package/dist/runtime-manifest.json +167 -48
  37. package/dist/runtime-meta.json +3241 -2808
  38. package/dist/runtime.mjs +9290 -5641
  39. package/dist/runtime.mjs.map +4 -4
  40. package/dist/shared/result.d.ts +9 -0
  41. package/package.json +24 -5
  42. package/dist/sqlite-worker-meta.json +0 -84
  43. package/dist/sqlite-worker.mjs +0 -304
  44. package/dist/sqlite-worker.mjs.map +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,182 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-beta.13 — 2026-07-27
4
+
5
+ Makes local programs first-class pi-fleet clients: a supported TypeScript SDK plus continuous, replayable semantic receive over shared per-user agents. This beta replaces the previous receive and watch contracts and resets pi-fleet-owned state.
6
+
7
+ ### Added
8
+
9
+ - Added the side-effect-free `@elpapi42/pi-fleet/client` TypeScript SDK inside the existing package, with direct client methods, UUID-bound agent handles, steering and follow-up input, generated declarations, stable content-safe errors, and continuity-safe receive reconnection.
10
+ - Added durable semantic receive with initial and event cursors and exactly six lifecycle types: thinking, assistant-message, and tool-execution started/finished.
11
+ - Added byte-faithful durable Pi stdout journaling, bounded replay, content-free storage diagnostics, passive WAL checkpointing, and bounded incremental reclamation.
12
+
13
+ ### Changed
14
+
15
+ - Replaced idle-gated latest-response receive with a continuous passive semantic event stream. CLI `receive --until-idle` is now the explicit live one-off projection; historical replay uses `--after` or `--from-start`.
16
+ - Added `send --follow-up`; steering remains the default. Follow-up delivery is best effort: Pi queues
17
+ follow-up input only for a run already in flight, so idle follow-up input is delivered as an ordinary
18
+ prompt, and input accepted while a turn is ending may be queued against a run that never resumes.
19
+ - Bound every SDK handle, CLI invocation, durable operation, send, incarnation, cursor, and recovery path to the immutable agent creation UUID so same-name recreation cannot inherit stale work.
20
+ - Made durable recording fail closed and require explicit continuation after an unclean-runtime observation gap.
21
+ - Limited this release scope to Linux x64 with external Pi 0.82.1.
22
+
23
+ ### Removed
24
+
25
+ - Removed the public raw `watch` command and its protocol, limits, errors, and compatibility shims.
26
+ - Removed finite latest-assistant-response retrieval and the old latest-response storage model.
27
+
28
+ ### Upgrade note
29
+
30
+ - This beta transition transactionally resets all prior pi-fleet-owned agents, operations, responses, and journal state without deleting native Pi session files. Stop old supervision and prove the old runtime and Pi process trees absent before activation. After the reset, older binaries are not a supported rollback path.
31
+
32
+ ## 0.1.0-beta.10 — 2026-07-26
33
+
34
+ Corrects pi-fleet's execution-ownership boundary: pi-fleet now orchestrates the user's separately installed Pi executable instead of distributing a second managed Pi runtime.
35
+
36
+ ### Changed
37
+
38
+ - pi-fleet now requires a separately installed Pi and launches the exact Pi executable and Node interpreter selected by the invoking environment. It does not install, bundle, copy, or silently substitute Pi.
39
+ - A runtime whose persisted Pi is unavailable still serves passive inspection, response retrieval, watching, and cleanup; `create`, `send`, and `compact` fail before dispatch.
40
+ - Changed existing service Pi/Node selections fail closed as `runtime_upgrade_deferred` until users finish work and explicitly transition supervision. The beta.9 managed-Pi service follows the same manual transition: uninstall only pi-fleet supervision, then install from the intended Pi environment; state and native sessions remain.
41
+
42
+ ### Added
43
+
44
+ - Added `pifleet compact NAME [--human]`, backed by Pi's typed native compaction RPC. It restores an absent idle agent when capacity allows, checks authoritative state immediately before invocation, returns bounded token metrics, emits native compaction activity through raw RPC watchers, and never replays ambiguous compaction after a crash. Pi does not currently provide an atomic idle-only compact primitive, so a narrow trusted-extension activity race remains documented.
45
+
46
+ ### Changed
47
+
48
+ - Replaced `watch` session-file tailing with a live, unfiltered, byte-exact stream of one Pi RPC process incarnation's stdout. Stdout carries only Pi bytes; stderr reports subscription readiness and typed stream failures. Watching remains passive, bounded, and live-only, and never silently concatenates restored process streams.
49
+
50
+ ### Documentation
51
+
52
+ - Reframed pi-fleet as Pi-native, machine-first execution infrastructure for agent systems operating beyond terminal scale rather than a human-facing background terminal tool.
53
+ - Reworked the README and operator skill around programmatic lifecycle control, exact latest-response retrieval, live Pi RPC JSONL, orchestration boundaries, and user-owned sessions.
54
+ - Clarified that `create` creates an agent whose local name is its stable programmatic address, while its process residency and user-controlled native session remain separate concerns.
55
+ - Removed superseded internal implementation, testing, and release-planning documents to keep repository documentation focused on the README, operator skill, and changelog.
56
+
57
+ ### Reliability
58
+
59
+ - Added deterministic fault-injection coverage for receive timeout/cancellation, delivery recovery, runtime crashes, Pi RPC failures, SQLite worker/storage failures, protocol framing, command races, raw RPC byte boundaries, and public-error redaction.
60
+ - Serialized create, send, and destroy transitions per agent so cross-command races cannot orphan or resurrect an agent generation.
61
+ - Made SQLite-worker failures terminal for current and future calls and made send recovery safe when an operation exists but no send record was committed.
62
+ - Redacted Pi stderr and unexpected internal exceptions from public errors while retaining stable typed error codes.
63
+ - Contained asynchronous coordinator event/store failures by stopping the affected Pi process and rejecting waiters instead of producing unhandled promise rejections.
64
+ - Added a nightly reliability workflow and an isolated soak suite covering 500 concurrent ordered sends and 100 name lifecycle cycles.
65
+ - Reject invalid UTF-8 in stdin and Pi RPC stdout instead of silently replacing bytes at either protocol boundary.
66
+ - Keep idle agents `idle + absent` after pi-fleet-initiated orderly shutdown even when Pi reports a nonzero exit; active work remains `failed/runtime_interrupted`.
67
+ - Align explicit stdin input with the runtime's 512 KiB message limit and document credential-environment and receive-timeout behavior before the quick start.
68
+ - Install native services without forcing the default persistent state directory into `PIFLEET_STATE_ROOT`, preserving the default split between durable SQLite state and the private runtime socket.
69
+ - Validated systemd user lingering, idle reboot restoration, active reboot interruption without replay, single-writer restoration, and session preservation in a disposable privileged systemd container.
70
+ - Removed Pi from pi-fleet's production dependency and immutable runtime closure, restored a zero-exception production audit for what pi-fleet distributes, and moved real/process/package/CI validation to a separately installed Pi `0.82.1`. The audit does not certify the user's external Pi installation.
71
+
72
+ ## 0.1.0-beta.9 — 2026-07-20
73
+
74
+ Core product and Linux supervision validation after beta.8.
75
+
76
+ ### Fixed
77
+
78
+ - An orderly pi-fleet shutdown now leaves idle agents `idle + absent` even if Pi reports a nonzero exit; active interrupted work still becomes `failed/runtime_interrupted` without replay.
79
+ - A clean native-service install no longer forces the default persistent state directory into `PIFLEET_STATE_ROOT`, so the service and ordinary CLI agree on the private runtime socket while SQLite remains in durable state storage.
80
+ - Explicit stdin now uses the runtime's default 512 KiB message boundary instead of accepting a larger payload that the runtime later rejects.
81
+ - Onboarding now explains persistent credential environments before the first operational command and uses explicit receive timeout units.
82
+
83
+ ### Validated
84
+
85
+ - Reused one real Pi session through the same pi-fleet entry across a service restart and related follow-up assignment with less re-explanation.
86
+ - Proved user lingering, idle PID-1 restart without eager restoration, single-writer session restoration, active restart interruption without replay, explicit recovery, and session preservation in a disposable systemd container.
87
+
88
+ ### Security
89
+
90
+ - The production audit remains fail-closed except for one deliberate exact exception: managed Pi `0.80.10` currently pins `brace-expansion@5.0.6` affected by local glob-input denial-of-service advisory `GHSA-3jxr-9vmj-r5cp`. The policy verifies the advisory, package versions, and installed path and rejects every additional or changed vulnerability. Upstream tracking is `earendil-works/pi#6882`.
91
+
92
+ ## 0.1.0-beta.8 — 2026-07-20
93
+
94
+ Publishes the beta.7 manual-testing fixes after its immutable tag failed before npm publication.
95
+
96
+ ### Changed
97
+
98
+ - The process-tree fixture now waits for both parent and child SIGTERM handlers through an IPC readiness handshake before exposing their PIDs, removing a CI scheduling race while preserving the real escalation assertion.
99
+ - Includes the beta.7 `watch` EPIPE and pre-dispatch restoration-failure fixes; beta.7 itself was never published to npm.
100
+
101
+ ## 0.1.0-beta.7 — 2026-07-20
102
+
103
+ Continued direct CLI edge-case testing. No intentional command-surface change.
104
+
105
+ ### Fixed
106
+
107
+ - `watch` now treats downstream `EPIPE` as normal client disconnection, exiting successfully without misreporting a closed output pipe as `invalid_arguments`.
108
+ - A restoration failure proven to occur before prompt dispatch now returns `pi_start_failed`, marks the send definitively failed, leaves the agent `failed + absent`, and releases process capacity instead of claiming `delivery_uncertain` and leaving `restoring + starting` state.
109
+ - Restoration cleanup uncertainty remains fail-closed as `incarnation_cleanup_uncertain` with its process slot retained when pi-fleet cannot prove the spawned process is gone.
110
+
111
+ ### Manual validation
112
+
113
+ - Exercised active runtime death with held clients, hanging/HTTP-error/malformed providers, 19 MB watch backpressure, stdin limits, Unicode paths, extension UI cancellation, oversized session records, watch pipe closure, and missing-cwd restoration in isolated environments.
114
+
115
+ ## 0.1.0-beta.6 — 2026-07-20
116
+
117
+ Manual interruption-semantics correction. No intentional command-surface change.
118
+
119
+ ### Fixed
120
+
121
+ - `receive` now returns the agent's stored failure code when the agent is failed instead of returning an older assistant response as successful completion of interrupted work.
122
+ - Added regression coverage for the exact state observed during manual testing: a previous response exists, later work is interrupted, the Pi process is absent, and immediate receive reports `runtime_interrupted`.
123
+
124
+ ## 0.1.0-beta.5 — 2026-07-20
125
+
126
+ Release-pipeline reliability follow-up; includes the beta.4 receive and argument-validation fixes.
127
+
128
+ ### Fixed
129
+
130
+ - On Linux, process-group cleanup now treats zombie processes as exited by inspecting procfs instead of relying only on signal probes. This prevents conservative cleanup waits and CI failures when an orphaned descendant is awaiting reaping.
131
+ - Pi shutdown now waits for the child-process exit callback and coordinator transition before reporting completion, preventing a status read from briefly retaining `resident` after an idle release.
132
+ - Repeated the process-tree and real-Pi process suites five times locally before tagging after beta.4's publish workflow exposed the runner-specific zombie behavior.
133
+
134
+ ## 0.1.0-beta.4 — 2026-07-20
135
+
136
+ Manual edge-case testing fix. No intentional CLI contract change.
137
+
138
+ ### Fixed
139
+
140
+ - Prevented `receive --timeout 0` from rejecting an idle waiter before a handler was attached and terminating the runtime with an unhandled `Receive cancelled` rejection.
141
+ - Added explicit coordinator work tracking so promptless/repeated idle polling returns `no_response` or the latest response immediately, while managed work still waits for Pi settlement.
142
+ - Closed the abort-listener registration race and added regression coverage for timeout, disconnect, repeated receive, and settlement ordering.
143
+ - Return durable `invalid_arguments` errors for rejected Pi startup/positional arguments instead of a generic `internal_error`.
144
+
145
+ ### Manual validation
146
+
147
+ - Direct isolated lifecycle, timeout, repeated receive, raw watch, session mutation, concurrent startup/send, Pi/runtime crash recovery, capacity, and session-preservation scenarios passed against the beta.4 source build.
148
+ - Fresh-registry operational validation remains enforced by the tag workflow after publication.
149
+
150
+ ## 0.1.0-beta.3 — 2026-07-20
151
+
152
+ Reliability fix for fresh global npm installations. No intentional CLI or agent-lifecycle contract change.
153
+
154
+ ### Fixed
155
+
156
+ - Replaced the invalid assumption that npm recreates CI's byte-identical `node_modules` tree. Schema-3 runtime manifests retain exact hashes for pi-fleet-owned files, validate direct dependency name/version, derive the observed dependency-closure hash at materialization, and prove source-before, staged, and source-after closure equality before activation.
157
+ - Made immutable runtime release paths closure-specific, so different legitimate npm dependency layouts do not collide.
158
+ - Strengthened package testing to mutate a fresh installed dependency tree, require an operational `list`, remove the npm installation, stop the runtime, and restart through the materialized release.
159
+
160
+ ### Installation scope
161
+
162
+ - The documented global npm installation layout, where dependencies are package-local, is supported. Arbitrarily hoisted local-prefix, pnpm, and unusual `npx` dependency layouts are not yet supported.
163
+ - The tag workflow now performs a fresh registry-install operational `list` smoke after publishing. That smoke is a release gate and has not yet run for beta.3.
164
+
165
+ ## 0.1.0-beta.2 — 2026-07-20
166
+
167
+ Reliability-focused beta maintenance release. No intentional product-contract changes.
168
+
169
+ ### Reliability
170
+
171
+ - Added deterministic fault coverage and reproducible randomized lifecycle-race soak testing.
172
+ - Fixed timeout/cancellation classification, ambiguous-delivery recovery, no-replay behavior, and coordinator/store failure containment.
173
+ - Validated inbound protocol majors, strict and concurrent runtime materialization, and released beta.0/beta.1 CLI-runtime compatibility.
174
+ - Added unclean SQLite `quick_check` validation, redacted error handling, fatal UTF-8 checks, process cleanup coverage, and nightly resource-stability checks.
175
+
176
+ ### Validation limits
177
+
178
+ - Real disk exhaustion, host logout/reboot, macOS launchd/containment, and multi-hour platform resource soak remain unvalidated.
179
+
3
180
  ## 0.1.0-beta.1 — 2026-07-20
4
181
 
5
182
  Release-pipeline validation beta. No product-contract changes from `0.1.0-beta.0`.
@@ -11,13 +188,13 @@ Release-pipeline validation beta. No product-contract changes from `0.1.0-beta.0
11
188
 
12
189
  ## 0.1.0-beta.0 — 2026-07-20
13
190
 
14
- First public beta of Pi Fleet.
191
+ First public beta of pi-fleet.
15
192
 
16
193
  ### Included
17
194
 
18
195
  - Seven-command JSON-first CLI: `create`, `send`, `receive`, `status`, `list`, `watch`, and `destroy`.
19
- - Named resident Pi processes with restore-on-address from native Pi sessions.
20
- - Exact compatible Pi argument passthrough after `--` and Fleet-owned `--cwd`.
196
+ - Resident Pi processes with stable pi-fleet addresses and restore-on-address from native Pi sessions.
197
+ - Exact compatible Pi argument passthrough after `--` and pi-fleet-owned `--cwd`.
21
198
  - Ordered repeated steering input and idle-based latest-assistant response retrieval.
22
199
  - Raw live Pi session JSONL watching.
23
200
  - SQLite-backed names, latest responses, operation idempotency, and conservative crash recovery.
package/README.md CHANGED
@@ -1,201 +1,199 @@
1
- # Pi Fleet
1
+ # pi-fleet
2
2
 
3
- Pi Fleet is a local runtime and machine-first CLI for named, long-lived Pi agents.
3
+ **Pi orchestration beyond terminal scale.**
4
4
 
5
- ```text
6
- create · send · receive · status · list · watch · destroy
7
- ```
5
+ pi-fleet is local, Pi-native execution infrastructure for programs that coordinate long-lived Pi agents. It keeps one shared per-user pool reachable through a TypeScript SDK and a JSON-first CLI while every native Pi session remains under the user's control.
8
6
 
9
- Fleet keeps a Pi process resident when possible, restores it from the same native Pi session when absent, accepts repeated steering input, and returns the latest assistant message after Pi becomes idle. Pi sessions remain under your control: Fleet references them but never copies or deletes them.
7
+ **Control execution. Own the session. Build the orchestration above it.**
10
8
 
11
- > **Beta:** `0.1.0-beta.0` is release-validated on Linux x64 with Pi `0.80.10`. macOS, actual logout/reboot recovery, automatic upgrades, and public service-management UX are not yet release-validated.
9
+ ## Why pi-fleet exists
12
10
 
13
- ## Install
11
+ Terminal multiplexers such as tmux, cmux, and Herdr are useful for human-facing panes. Programmatic orchestration needs different primitives: stable agent addresses, immutable generation identity, ordered steering or follow-up input, process and recovery state, replayable high-level activity, and explicit uncertainty after a crash.
14
12
 
15
- Requirements:
13
+ pi-fleet supplies those execution primitives. It does not define roles, workflows, schedules, dashboards, semantic retries, memory policy, or autonomy. Agents act only on explicit instructions unless a higher layer implements its own bounded policy.
16
14
 
17
- - Linux x64
18
- - Node.js `^22.19.0 || ^24.0.0`
19
- - normal Pi provider credentials and configuration
15
+ ## Requirements and installation
20
16
 
21
- Install the beta globally:
17
+ The current support target is **Linux x64**, Node.js `^22.19.0 || ^24.0.0`, and a separately installed **Pi 0.82.1** executable. pi-fleet launches the Pi selected by the invoking environment; it never bundles, copies, or substitutes Pi.
22
18
 
23
19
  ```bash
20
+ command -v pi
21
+ pi --version # 0.82.1
24
22
  npm install --global @elpapi42/pi-fleet@beta
25
23
  pifleet --version
26
- pifleet list
27
24
  ```
28
25
 
29
- `npx @elpapi42/pi-fleet@beta` is suitable for evaluation, but a global installation is recommended for continued use. Fleet materializes a verified runtime independently of the npm installation/cache, and evaluation can leave that runtime and Fleet state behind intentionally.
26
+ pi-fleet resolves `pi` and `node` from the invoking `PATH` and persists their absolute selected paths for supervised startup. `PIFLEET_PI_EXECUTABLE=/absolute/path/to/pi` is an advanced override. Shell aliases and functions are unsupported.
30
27
 
31
- Pi Fleet includes the tested Pi coding-agent package. It uses your normal Pi configuration, provider credentials, extensions, skills, and project resources. **Do not put API keys or other secrets in CLI arguments:** Fleet persists accepted Pi arguments so it can restore the agent. Use Pi's credential configuration or provider environment variables instead.
28
+ Configure provider credentials before starting the persistent runtime. Environment variables added only to later commands do not change an already-running runtime.
32
29
 
33
- ## Quick start
30
+ ## TypeScript SDK
34
31
 
35
- Create a promptless named agent in the current project:
32
+ The SDK ships in the same npm package as the CLI and runtime:
36
33
 
37
- ```bash
38
- pifleet create reviewer --cwd "$PWD"
39
- ```
34
+ ```ts
35
+ import { connectPiFleet } from "@elpapi42/pi-fleet/client";
40
36
 
41
- Send work and retrieve the latest assistant message after Pi becomes idle:
37
+ const fleet = await connectPiFleet();
38
+ const reviewer = await fleet.create({
39
+ name: "reviewer",
40
+ cwd: process.cwd(),
41
+ instructions: "Review the current change.",
42
+ });
42
43
 
43
- ```bash
44
- pifleet send reviewer "Review the authentication changes"
45
- pifleet receive reviewer --human
46
- ```
44
+ const events = await reviewer.receive(); // live from attachment
45
+ console.log("attached at", events.cursor);
47
46
 
48
- Inspect and remove Fleet management:
47
+ await reviewer.send("Focus on lifecycle races."); // steering by default
48
+ await reviewer.send("Then check documentation.", { delivery: "followUp" });
49
49
 
50
- ```bash
51
- pifleet status reviewer
52
- pifleet list
53
- pifleet destroy reviewer
50
+ for await (const event of events) {
51
+ if (event.type === "assistant.message.finished") {
52
+ console.log(event.text);
53
+ }
54
+ }
54
55
  ```
55
56
 
56
- `destroy` stops Fleet's managed process and removes the Fleet name. It **never deletes the Pi session**.
57
+ `connectPiFleet()` connects to the shared per-user control plane; it does not create a private pool. Agents created through one SDK client are immediately addressable by other SDK clients and the CLI. `client.close()` closes only that client's local resources and receive streams—it never stops the runtime or shared agents.
57
58
 
58
- ## Commands
59
+ Use `connectPiFleet({ autoStartRuntime: false })` when another process owns control-plane startup; connecting still verifies the runtime is reachable and protocol-compatible, so it fails with `runtime_unavailable` when nothing is running and `protocol_incompatible` against an older runtime, which is left untouched. Imports are inert, and passive operations remain available when Pi is missing; Pi is validated only for `create`, `send`, and `compact`.
59
60
 
60
- ```text
61
- pifleet create NAME [INITIAL_INSTRUCTIONS] [--cwd PATH] [--human] [-- PI_OPTIONS...]
62
- pifleet send NAME MESSAGE [--human]
63
- pifleet receive NAME [--timeout DURATION] [--human]
64
- pifleet status NAME [--human]
65
- pifleet list [--human]
66
- pifleet watch NAME
67
- pifleet destroy NAME [--human]
68
- ```
61
+ ### Agent handles and input
69
62
 
70
- Finite commands emit JSON by default. Add `--human` for concise human output. `watch` has no human mode: stdout is only raw, complete records appended to the selected Pi session JSONL.
63
+ `client.create()` and `client.get()` return remote `Agent` handles; `client.list()` returns lightweight summaries for discovery. A handle carries both the reusable friendly name and the immutable creation UUID, so an old handle cannot retarget a later same-name recreation.
71
64
 
72
- Messages can be read explicitly from stdin with `-`:
65
+ `agent.send()` means durable acceptance and ordering, not task completion or one-send/one-response correlation.
73
66
 
74
- ```bash
75
- git diff | pifleet send reviewer -
76
- pifleet create researcher - < instructions.md
77
- ```
67
+ - `delivery: "steer"` is the default and matches ordinary Pi prompt/steering behavior.
68
+ - `delivery: "followUp"` asks Pi to queue input until it finishes current work. Pi only queues
69
+ follow-up input for a run that is already in flight, so pi-fleet delivers follow-up input to an
70
+ authoritatively idle session as an ordinary prompt instead. Follow-up delivery is therefore best
71
+ effort: input accepted in the narrow window while a turn is ending may be queued against a run
72
+ that never resumes, and no later turn will carry it. Use `steer` when delivery must be certain.
73
+ - Cancellation stops only the caller's wait; it does not cancel accepted remote work.
78
74
 
79
- ### Native Pi arguments
75
+ ### Continuous receive
80
76
 
81
- Fleet owns only its small command surface. `--cwd` belongs before the first literal `--`; native Pi options belong after it and retain their token order:
77
+ `agent.receive()` is a passive broadcast stream and never wakes or restores Pi. Any number of consumers may attach independently.
82
78
 
83
- ```bash
84
- pifleet create reviewer \
85
- --cwd /workspace/project \
86
- -- \
87
- --session /absolute/path/to/session.jsonl \
88
- --model anthropic/claude-sonnet-4 \
89
- --thinking high
79
+ ```ts
80
+ await agent.receive(); // live from invocation
81
+ await agent.receive({ after: cursor }); // replay strictly after a cursor, then follow live
82
+ await agent.receive({ fromStart: true });
90
83
  ```
91
84
 
92
- Supported native session selection includes:
85
+ The returned stream exposes its initial opaque `cursor` before its first event. Each event has its own stable ID and cursor; lifecycle pairs share an activity ID. Delivery is at-least-once after reconnect, so consumers should checkpoint cursors and deduplicate by event ID.
93
86
 
94
- ```bash
95
- pifleet create existing -- --session /path/to/session.jsonl
96
- pifleet create exact-id -- --session-id SESSION_ID
97
- pifleet create forked -- --fork /path/to/source.jsonl
98
- pifleet create latest -- --continue
99
- ```
87
+ The public event model contains exactly six types:
100
88
 
101
- Pi interprets these options directly. An existing or missing `--session` path follows native Pi behavior, and an exact `--session-id` remains exact. Fleet records the concrete selected session only so later process restoration reopens the same conversation. Headless `--resume` is not supported because it requires interactive selection before RPC mode.
89
+ - `assistant.thinking.started` / `assistant.thinking.finished`
90
+ - `assistant.message.started` / `assistant.message.finished`
91
+ - `tool.execution.started` / `tool.execution.finished`
102
92
 
103
- Positional Pi prompts and `@file` inputs after `--` are rejected; use Fleet's optional create instructions or `send` so input remains ordered.
93
+ There are no public deltas, raw RPC frames, turn events, retry events, or synthetic gap events. Starts mean pi-fleet durably observed meaningful activity begin. A crash may leave a start unmatched; pi-fleet never invents a finish.
104
94
 
105
- ## Communication semantics
95
+ After an unclean runtime death that may have left any Pi incarnation alive—even a logically idle one—old streams stop at their last safe cursor with `observation_uncertain`. The error provides the last-safe cursor and, when available, an explicit continuation cursor. Crossing that gap is a caller decision; pi-fleet never bridges it silently.
106
96
 
107
- `send` uses Pi's normal context-sensitive prompt operation with steering behavior:
97
+ ## CLI
108
98
 
109
- - while Pi is active, input is queued as steering;
110
- - while Pi is idle, input begins normal work;
111
- - repeated sends are accepted in order;
112
- - acknowledgement means Pi accepted/queued the input, not that it completed or produced a distinct response.
99
+ The CLI is a shell adapter over the same shared agents and semantic client contract:
113
100
 
114
- `receive` deliberately has no per-send response correlation:
101
+ ```text
102
+ pifleet create NAME [INITIAL_INSTRUCTIONS] [--cwd PATH] [--human] [-- PI_OPTIONS...]
103
+ pifleet send NAME MESSAGE [--follow-up] [--human]
104
+ pifleet receive NAME [--after CURSOR | --from-start] [--until-idle] [--human]
105
+ pifleet status NAME [--human]
106
+ pifleet list [--human]
107
+ pifleet compact NAME [--human]
108
+ pifleet destroy NAME [--human]
109
+ ```
110
+
111
+ Finite commands emit one compact JSON object on stdout. Expected failures emit one structured JSON error on stderr. `receive` emits semantic event JSONL on stdout and one readiness record with the initial cursor on stderr. Downstream EPIPE is a successful caller disconnect.
115
112
 
116
- - while Pi is busy or restoring, it waits for Pi to become idle;
117
- - once idle, it returns Pi's latest assistant message;
118
- - when already idle, it returns immediately;
119
- - with no assistant message, it returns `no_response`;
120
- - `--timeout 0` performs an immediate poll;
121
- - timing out does not cancel or change Pi.
113
+ Normal `receive` stays open across work, idle periods, absent Pi processes, and same-agent restorations. `--until-idle` is a CLI-only live convenience: it atomically attaches, emits subsequent events through the exact durable idle boundary, and exits. If the agent is already idle at attachment it exits successfully with no historical output. Historical modes cannot be combined with `--until-idle`.
122
114
 
123
- ## Sessions and `watch`
115
+ The former raw `watch` command and finite latest-response receive contract were removed during the beta cutover. Use semantic `receive`; inspect native Pi sessions directly when raw session history is required.
124
116
 
125
- Pi and you own session files, IDs, locations, creation, migration, and deletion. Fleet never copies, relocates, or deletes them.
117
+ ## Native sessions remain yours
118
+
119
+ `create` assigns a stable local address to a Pi agent and its native session. The process may be resident or absent; the logical agent remains addressable until `destroy`.
120
+
121
+ - Native selectors after the first literal `--` are passed to Pi in their original order.
122
+ - Exact `--session`, `--session-id`, `--session-dir`, `--fork`, and `--continue` choices remain authoritative.
123
+ - pi-fleet never copies, relocates, normalizes, wraps, or deletes session files.
124
+ - `destroy` stops execution ownership and logically deletes pi-fleet-owned control, journal, and semantic history for that agent UUID while preserving the native session; only a minimal content-free idempotency receipt may remain.
125
+ - Deliberate concurrent native-session writers remain possible at the user's risk.
126
126
 
127
127
  ```bash
128
- pifleet watch reviewer > live-session.jsonl
128
+ pifleet create reviewer --cwd /workspace/project -- --session /absolute/session.jsonl
129
129
  ```
130
130
 
131
- `watch` is live-only. For an existing file it begins at the current EOF; for a not-yet-materialized file it waits and begins at byte zero. It does not emit Fleet wrappers, history, or transient RPC events. Concurrent external rewrites can invalidate tailing; detectable replacement, truncation, lag, or runtime loss is reported on stderr.
131
+ `--cwd` is a pi-fleet option before `--`; Pi options come after it. Headless `--resume` and Pi positional prompts are unsupported.
132
132
 
133
- ## Runtime and local data
133
+ ## Persistence, privacy, and failure
134
134
 
135
- The short-lived CLI connects to one private per-user runtime. On first operational use, Fleet verifies and materializes an immutable runtime release, then starts it in the background. A registered native service is preferred when present; service management is experimental and is not part of the seven-command beta interface.
135
+ pi-fleet durably stores every complete LF-terminated Pi RPC stdout record byte-for-byte before parsing it or exposing derived receive events. This private journal can contain prompts, thinking, tool input/output, paths, extension data, and secrets emitted by Pi. It is retained for the logical agent's lifetime and removed by successful `destroy` as a logical SQLite deletion. pi-fleet does not claim immediate file shrinkage or forensic erasure from WAL files, freelist pages, backups, snapshots, or physical media.
136
136
 
137
- Linux defaults:
137
+ Storage failure is fail-closed: affected work stops, receive ends at the last durable cursor, committed history is preserved, and pi-fleet never bridges an unrecorded gap. Operational diagnostics contain counts, sizes, ages, health, and UUIDs—not retained payloads or paths.
138
138
 
139
- ```text
140
- Fleet state: ~/.local/state/pi-fleet/
141
- Materialized code: ~/.local/share/pi-fleet/releases/
142
- Runtime socket: $XDG_RUNTIME_DIR/pifleet-$UID/control.sock
143
- (or the system temporary directory when XDG_RUNTIME_DIR is absent)
144
- Pi sessions: Pi's normal ~/.pi storage or the exact path you selected
145
- ```
139
+ `status` and `list` are passive. An idle agent may be `resident` or `absent`; a later work operation restores an absent process from the concrete native session when safe. Treat `delivery_uncertain`, `compaction_uncertain`, `runtime_interrupted`, `incarnation_cleanup_uncertain`, and session failures conservatively. Semantic retry policy belongs to the orchestrator.
146
140
 
147
- `PIFLEET_STATE_ROOT` and `PIFLEET_APPLICATION_ROOT` can override Fleet-owned locations. A CLI invocation whose state root differs from an installed service fails immediately with repair guidance instead of connecting to the wrong database.
141
+ ## Destructive beta transition
148
142
 
149
- ## Uninstall and recovery
143
+ This release intentionally resets all prior pi-fleet-owned agent, operation, response, and journal state when upgrading the old schema. Native Pi session files are preserved. There is no compatibility alias for raw `watch` or finite receive.
150
144
 
151
- Before uninstalling, destroy agents you no longer want Fleet to manage:
145
+ Before the new runtime opens the old database:
152
146
 
153
- ```bash
154
- pifleet list --human
155
- pifleet destroy AGENT_NAME
156
- npm uninstall --global @elpapi42/pi-fleet
157
- ```
147
+ 1. Finish work on the old runtime.
148
+ 2. Stop and uninstall only pi-fleet supervision with `dist/installer.mjs uninstall`.
149
+ 3. Prove the old runtime and Pi process trees are absent.
150
+ 4. Install supervision from the environment selecting the intended Pi and Node with `dist/installer.mjs install`.
151
+ 5. Start the new runtime; no old agents are restored automatically.
158
152
 
159
- Removing the npm package does not delete Pi sessions, Fleet's SQLite state, materialized runtime releases, or an already-running runtime/service. This protects durable agents from package-manager changes. Reinstalling the same or a compatible version reconnects to the preserved state.
153
+ A responsive older runtime is never killed or replaced automatically. After the destructive schema reset, reinstalling beta.10 or another older binary is **not** rollback; use a forward fix or an externally managed pre-reset state backup. User-owned native sessions remain untouched throughout.
160
154
 
161
- There is intentionally no automatic self-update, telemetry, remote transport, or npm `postinstall` service registration. Database migrations are forward-only; installing an older binary after a newer schema migration is not a supported rollback strategy.
155
+ ## Runtime locations and service behavior
162
156
 
163
- For support, include:
157
+ Linux defaults:
164
158
 
165
- ```bash
166
- node --version
167
- pifleet --version
168
- pifleet list
169
- pifleet status AGENT_NAME
159
+ ```text
160
+ State: ~/.local/state/pi-fleet/
161
+ Releases: ~/.local/share/pi-fleet/releases/
162
+ Socket: $XDG_RUNTIME_DIR/pifleet-$UID/control.sock
163
+ Pi sessions: Pi's normal ~/.pi storage or the exact selected path
170
164
  ```
171
165
 
172
- Do not include API keys, message contents, session contents, or private paths unnecessarily. Report reproducible issues at <https://github.com/elpapi42/pi-fleet/issues>.
166
+ `PIFLEET_STATE_ROOT` and `PIFLEET_APPLICATION_ROOT` override pi-fleet-owned paths. State, database, WAL, SHM, socket, and immutable-release paths are private and fail closed on unsafe ownership, type, or symlink conditions.
167
+
168
+ A service whose selected Pi or Node differs from the terminal environment returns `pi_service_mismatch` or `runtime_upgrade_deferred`; it is not silently rewritten. Global installation is recommended for continued use; `npx` is suitable for evaluation only.
173
169
 
174
- ## Beta limitations
170
+ ## Scope and known limits
175
171
 
176
- - Release validation currently covers Linux x64 only.
177
- - Actual logout and host reboot recovery remain unvalidated.
178
- - launchd and macOS descendant containment remain unvalidated.
179
- - Native service install/repair/uninstall exists internally but has no supported public UX yet.
180
- - Runtime upgrades are not automatic; active runtimes are not silently replaced.
181
- - Session tails cannot promise exactly-once behavior under arbitrary external mutation.
182
- - A promptless missing session path may remain physically unmaterialized until Pi writes conversation content, following native Pi behavior.
172
+ - Linux x64 is the only current release target.
173
+ - Pi 0.82.1 is the current compatibility target.
174
+ - macOS, host logout/reboot, real disk exhaustion, and multi-hour resource behavior require separate validation.
175
+ - pi-fleet has no workflow engine, scheduler queue, idle-process eviction, remote transport, telemetry, automatic semantic retry, or automatic service upgrade.
176
+ - A promptless missing session path may remain unmaterialized until Pi writes conversation content.
177
+
178
+ For support, include `node --version`, `pi --version`, `pifleet --version`, `pifleet list`, and `pifleet status NAME`. Do not include credentials, messages, thinking, tool payloads, session contents, cursors, or private paths unnecessarily.
183
179
 
184
180
  ## Development
185
181
 
186
182
  ```bash
187
183
  npm ci
184
+ npm run audit:production
188
185
  npm run typecheck
189
186
  npm run lint
190
187
  npm run format:check
191
188
  npm test
189
+ npm run test:faults
192
190
  npm run build
193
191
  npm run test:package
192
+ npm run test:client-types
194
193
  npm run test:platform
194
+ npm run test:soak
195
195
  ```
196
196
 
197
- See [`IMPLEMENTATION_PLAN.md`](./IMPLEMENTATION_PLAN.md) for architecture, completed evidence, and remaining release gates.
198
-
199
197
  ## License
200
198
 
201
199
  MIT © elpapi42
@@ -6,7 +6,7 @@ const isSupported = (major === 22 && minor >= minimumNode22Minor) || major === 2
6
6
 
7
7
  if (!isSupported) {
8
8
  process.stderr.write(
9
- `Pi Fleet runtime requires Node ^22.19.0 or ^24.0.0; found ${process.versions.node}. Run the installer repair operation with a supported Node executable.\n`,
9
+ `pi-fleet runtime requires Node ^22.19.0 or ^24.0.0; found ${process.versions.node}. Run the installer repair operation with a supported Node executable.\n`,
10
10
  );
11
11
  process.exitCode = 1;
12
12
  } else {