pi-crew 0.9.42 → 0.9.46
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/CHANGELOG.md +223 -0
- package/README.md +35 -0
- package/dist/build-meta.json +4778 -11087
- package/dist/index.mjs +54648 -65435
- package/dist/index.mjs.map +4 -4
- package/package.json +1 -1
- package/scripts/build-bundle.mjs +2 -1
- package/src/agents/agent-config.ts +1 -1
- package/src/agents/discover-agents.ts +1 -1
- package/src/config/config.ts +1 -1
- package/src/config/types.ts +0 -2
- package/src/extension/crew-vibes/config.ts +1 -1
- package/src/extension/crew-vibes/font-detect.ts +16 -3
- package/src/extension/cross-extension-rpc.ts +8 -4
- package/src/extension/registration/commands.ts +5 -1
- package/src/extension/registration/foreground-run-controller.ts +28 -0
- package/src/extension/registration/lifecycle-handlers.ts +34 -3
- package/src/extension/registration/subagent-manager-setup.ts +178 -59
- package/src/extension/run-import.ts +21 -1
- package/src/extension/team-tool/api.ts +4 -2
- package/src/extension/team-tool.ts +5 -0
- package/src/prompt/prompt-runtime.ts +15 -0
- package/src/runtime/async-runner.ts +9 -1
- package/src/runtime/child-pi-constants.ts +42 -0
- package/src/runtime/child-pi-kill.ts +180 -0
- package/src/runtime/child-pi-spawn.ts +234 -0
- package/src/runtime/child-pi-steering.ts +128 -0
- package/src/runtime/child-pi-streams.ts +296 -0
- package/src/runtime/child-pi-transcript.ts +169 -0
- package/src/runtime/child-pi.ts +75 -837
- package/src/runtime/compact-stages/tail-capture-stage.ts +1 -1
- package/src/runtime/dwf-state-store.ts +5 -0
- package/src/runtime/dynamic-workflow-context.ts +78 -18
- package/src/runtime/dynamic-workflow-runner.ts +18 -2
- package/src/runtime/goal-evaluator.ts +59 -27
- package/src/runtime/goal-loop-runner.ts +40 -11
- package/src/runtime/live-agent-manager.ts +18 -0
- package/src/runtime/manifest-cache.ts +30 -0
- package/src/runtime/pi-json-output.ts +2 -1
- package/src/runtime/pi-spawn.ts +7 -1
- package/src/runtime/resilient-edit.ts +16 -15
- package/src/runtime/role-permission.ts +27 -2
- package/src/runtime/run-coalesced-task-group.ts +90 -25
- package/src/runtime/task-packet.ts +1 -1
- package/src/runtime/task-runner/prompt-builder.ts +2 -2
- package/src/runtime/team-runner.ts +6 -1
- package/src/state/event-log.ts +89 -34
- package/src/state/locks.ts +185 -49
- package/src/state/mailbox.ts +165 -4
- package/src/state/run-metrics.ts +40 -12
- package/src/state/worker-atomic-writer.ts +1 -0
- package/src/ui/live-run-sidebar.ts +1 -9
- package/src/ui/run-dashboard.ts +1 -9
- package/src/utils/incremental-reader.ts +105 -0
- package/src/utils/paths.ts +1 -1
- package/src/utils/visual.ts +27 -91
- package/src/worktree/worktree-manager.ts +47 -19
- package/src/runtime/auto-resume.ts +0 -100
- package/src/runtime/notebook-helpers.ts +0 -88
- package/src/runtime/orphan-sentinel.ts +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,229 @@
|
|
|
2
2
|
|
|
3
3
|
> **Note:** `atomic-write-v2.ts` / `AtomicWriter` mentioned in historical entries below was consolidated into `atomic-write.ts` as of v0.9.42. This changelog is preserved as historical record — the migration was completed (the v2 class was never adopted; v1 won on simplicity + symlink-safety + link+unlink atomicity). See `docs/migration/atomic-write-v2-migration.md` for the decision rationale.
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
## [0.9.46] — UI stability + notification coalescing (2026-07-20)
|
|
7
|
+
|
|
8
|
+
Three user-facing UI/notification fixes layered on top of the v0.9.45
|
|
9
|
+
remediation, plus CI hygiene. All verified live in a restarted Pi session.
|
|
10
|
+
|
|
11
|
+
### UI flicker — stop render-path snapshot-cache deletes
|
|
12
|
+
|
|
13
|
+
The run-snapshot cache has a deliberate stale-while-revalidate design so the
|
|
14
|
+
widget always shows a populated snapshot. That was defeated by three hot-path
|
|
15
|
+
call sites in `lifecycle-handlers.ts` that hard-deleted cache entries; the worst
|
|
16
|
+
ran `invalidate(undefined)` on every ~160ms fallback tick, wiping ALL entries
|
|
17
|
+
→ `activeWidgetRuns` dropped every run to "(loading…)" until the async preload
|
|
18
|
+
rebuilt the cache → continuous flicker across the widget, powerbar, and live
|
|
19
|
+
sidebar/dashboard. (`src/extension/registration/lifecycle-handlers.ts`)
|
|
20
|
+
|
|
21
|
+
**Fix:** never hard-delete from the render path. A no-runId tick is now a no-op;
|
|
22
|
+
a specific runId calls `refreshIfStale` (stale-while-revalidate); the two
|
|
23
|
+
`fs.watch` change handlers call `refresh` (rebuild-in-place). All three keep the
|
|
24
|
+
entry populated so `get()` never returns `undefined`.
|
|
25
|
+
|
|
26
|
+
### TUI width-overflow crash — delegate `visibleWidth` to pi-tui
|
|
27
|
+
|
|
28
|
+
`Rendered line N exceeds terminal width (160 > 159)` killed the host Pi process
|
|
29
|
+
whenever an agent emitted an emoji that pi-crew's hand-maintained `WIDE_RANGES`
|
|
30
|
+
table counted as 1 column but pi-tui (the renderer) counted as 2 (e.g. `⏳`
|
|
31
|
+
U+23F3). pi-crew truncated/padded to its own measure, pi-tui re-measured and
|
|
32
|
+
hard-aborted. This was patched twice before by adding individual codepoints —
|
|
33
|
+
whack-a-mole, since ANY emoji in agent output could trigger it.
|
|
34
|
+
(`src/utils/visual.ts`)
|
|
35
|
+
|
|
36
|
+
**Definitive fix:** `visibleWidth` now delegates to pi-tui's own `visibleWidth`
|
|
37
|
+
(the function that drives the crash assert). truncate/pad/wrap therefore always
|
|
38
|
+
agree with the renderer; an emoji-width mismatch is structurally impossible. The
|
|
39
|
+
hand-maintained `WIDE_RANGES`/`isWideCodePoint` table is removed.
|
|
40
|
+
|
|
41
|
+
### Notification coalescing — N drip → 1 consolidated wake-up
|
|
42
|
+
|
|
43
|
+
Launching N background subagents (no `batch_id`) produced N separate "changed
|
|
44
|
+
state" wake-ups, delivered one-per-turn at turn boundaries; after the leader
|
|
45
|
+
joined them all, redundant per-agent notices kept dripping in over later turns.
|
|
46
|
+
(`src/extension/registration/subagent-manager-setup.ts`)
|
|
47
|
+
|
|
48
|
+
**Fix (Rule 3):** a debounced coalescer for non-batch completions. Completions
|
|
49
|
+
within an 800ms window (reset on each new arrival) merge into ONE wake-up; each
|
|
50
|
+
is `resultConsumed`-re-checked before emit (Rule 2), so already-joined agents
|
|
51
|
+
are dropped and an all-consumed batch is suppressed entirely. Completions far
|
|
52
|
+
apart (>800ms) still flush separately. The explicit-`batch_id` path (Rule 1,
|
|
53
|
+
BatchBarrier) is unchanged.
|
|
54
|
+
|
|
55
|
+
### CI hygiene
|
|
56
|
+
|
|
57
|
+
`biome check --write` applied across the v0.9.45 remediation files (lint +
|
|
58
|
+
format), and two unused test imports were removed — the local remediation
|
|
59
|
+
commits had never been CI-checked; this brings lint + format:check green.
|
|
60
|
+
|
|
61
|
+
## [0.9.45] — Deep-review 2026-07-20 remediation (all 5 phases, 14 findings)
|
|
62
|
+
|
|
63
|
+
### ⚠️ BREAKING: custom agent roles default to read-only (FIND-12)
|
|
64
|
+
|
|
65
|
+
`permissionForRole()` now returns `"read_only"` for unknown/custom agent
|
|
66
|
+
roles instead of the previous permissive `"workspace_write"`. This is a
|
|
67
|
+
security hardening (default-deny) to prevent privilege escalation via
|
|
68
|
+
typo'd or unrecognized agent names.
|
|
69
|
+
|
|
70
|
+
**Migration:** write-capable roles are now an EXPLICIT allowlist
|
|
71
|
+
(`WRITE_ROLES` in `src/runtime/role-permission.ts`). All shipped
|
|
72
|
+
write-capable roles are listed: `executor`, `writer`, `verifier`,
|
|
73
|
+
`test-engineer`, `agent` (direct-agent default), `cold-verifier`,
|
|
74
|
+
`chain-executor` (chain workflow), and `worker` (goal-loop + dynamic
|
|
75
|
+
workflow). A custom agent role that needs workspace write access
|
|
76
|
+
must be added to `WRITE_ROLES`. Built-in read-only roles (`explorer`,
|
|
77
|
+
`reviewer`, `security-reviewer`, `analyst`, `critic`, `planner`) are
|
|
78
|
+
unaffected. (An earlier draft proposed a `permissions.workspaceWrite`
|
|
79
|
+
agent-config opt-in; it was dropped — unreachable from the call sites.)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## [0.9.44] — 3 flaky CI test fixes (2026-07-19)
|
|
83
|
+
|
|
84
|
+
Three pre-existing flaky tests in the CI suite have been fixed, completing
|
|
85
|
+
the CI green-light requirement. All three were verified by repeated
|
|
86
|
+
local runs (≥30 iterations each) and a green CI run on the merge commit
|
|
87
|
+
(ubuntu/macos/windows Node 22 all ✅, fallow audit ✅).
|
|
88
|
+
|
|
89
|
+
### Lock subsystem fixes (`src/state/locks.ts`)
|
|
90
|
+
|
|
91
|
+
- **ENOENT canSteal fix in `readLockSnapshot`** — previously returned
|
|
92
|
+
`canSteal: false` when the lock file was missing between the EEXIST
|
|
93
|
+
signal and the read, causing spurious "locked" errors in
|
|
94
|
+
`parallel-research-dynamic.test.ts` (9/10 local reproduction rate).
|
|
95
|
+
Now returns `canSteal: true` so the holder-released-mid-retry window
|
|
96
|
+
is handled correctly.
|
|
97
|
+
- **New `releaseOwnLock`** — unconditional `fs.rmSync` bypass of the
|
|
98
|
+
token-match check in `releaseLock`. Used by `withRunLockSync` /
|
|
99
|
+
`withRunLock` because same-process re-acquisition uses fresh
|
|
100
|
+
`randomUUID()` tokens that never match the stored token, so
|
|
101
|
+
`releaseLock` was silently never deleting lock files between calls
|
|
102
|
+
(strace showed many `openat(O_CREAT|O_EXCL)` calls but zero
|
|
103
|
+
`unlinkat` calls — lock file accumulation until EEXIST).
|
|
104
|
+
- **`treatOwnPidAsStealable` parameter on `readLockSnapshot`** — only
|
|
105
|
+
the run-lock async path passes `true`. The sync file-lock path
|
|
106
|
+
(`withFileLockSync`, used by `round26-file-locks.test.ts`) keeps
|
|
107
|
+
the default `false` to preserve the multi-process safety guarantee
|
|
108
|
+
("don't steal a fresh lock held by a live process — even if our own
|
|
109
|
+
pid"). Without this option split, the first fix attempt regressed
|
|
110
|
+
the existing `round26-file-locks` test which specifically tests that
|
|
111
|
+
behavior.
|
|
112
|
+
|
|
113
|
+
### Test fix (`test/unit/event-log-seq-uniqueness.test.ts`)
|
|
114
|
+
|
|
115
|
+
- **B7 test 3 uses `appendEventAsync` instead of `appendEventBuffered`**
|
|
116
|
+
— the 20ms buffered-event timer occasionally lost the race against
|
|
117
|
+
`--test-force-exit`'s suite-finalization deadline (~8ms cancellation
|
|
118
|
+
observed on CI), causing `cancelledByParent` failures with error
|
|
119
|
+
`'Promise resolution is still pending but the event loop has already
|
|
120
|
+
resolved'`. Tests 1 and 2 still cover the full sync/async/buffered
|
|
121
|
+
3-path seq-uniqueness contract; test 3 now focuses on the
|
|
122
|
+
explicit-vs-auto seq-assignment contract using only sync + async
|
|
123
|
+
paths. This avoids the buffered timer entirely while preserving the
|
|
124
|
+
original B7 invariant.
|
|
125
|
+
|
|
126
|
+
### Verification
|
|
127
|
+
|
|
128
|
+
- Local: 6184/6187 unit + 177/178 integration tests pass (3+1 skipped).
|
|
129
|
+
- CI: ubuntu/macos/windows Node 22 all ✅, fallow audit ✅.
|
|
130
|
+
- Three independent CI runs after each fix confirmed zero regressions.
|
|
131
|
+
|
|
132
|
+
## [0.9.43] — 4-wave upgrade + live LLM verification (2026-07-19)
|
|
133
|
+
|
|
134
|
+
A comprehensive upgrade pass was completed on top of v0.9.42: 4 implementation waves
|
|
135
|
+
plus H-1 (lock re-entrance) and H-7 step 1–6 (runChildPi decomposition), verified
|
|
136
|
+
end-to-end with real LLM calls on a real pi session (not mocked). All changes
|
|
137
|
+
were driven by an in-depth audit (`UPGRADE_REVIEW.md` — 647 lines, ~112 unique
|
|
138
|
+
findings) with cold-verification and live test feedback catching regressions
|
|
139
|
+
mock tests had missed.
|
|
140
|
+
|
|
141
|
+
### Wave 1 — Security + correctness (16 fixes)
|
|
142
|
+
|
|
143
|
+
- **H-3/H-4** `scripts/build-bundle.mjs` — bundle externalized `acorn` (~225 KB) and fixed `@sinclair/typebox` package name (~245 KB). Total **−481 KB** bundle.
|
|
144
|
+
- **M-23 / COAL-1** `prompt-builder.ts` + `run-coalesced-task-group.ts` — both prompt builders now `sanitizeTaskText` before injection (closes 2 prompt-injection bypasses).
|
|
145
|
+
- **M-22** `cross-extension-rpc.ts` — `pi-crew:live-control` event channel now wrapped with `withHmacVerification` (was the only state-mutating RPC channel without auth).
|
|
146
|
+
- **DISC-1** `dynamic-workflow-runner.ts` — `.dwf.ts` determinism check now transpiles TS→JS via `esbuild` before acorn parse. Restores the round-13 P0-2 enforcement that had been silently no-op'd by acorn's JS-only parser.
|
|
147
|
+
- **NEW-D1** `team-runner.ts` — merge path now calls `flushPendingAtomicWrites()` before `loadRunManifestById`. Closes the coalesced-write-cancellation lost-update window.
|
|
148
|
+
- **M-18 / M-19 / T-S1** — event-log buffered-timer `unref()`, dead-worker `worker = undefined` reset, and `handleSteer` terminal-status guard (rejects steer to completed/failed/cancelled tasks).
|
|
149
|
+
- **NEW-C1 / C5 / C7 / C13 / C17** — config dead-field deleted; token cap covers `max_completion_tokens`/`max_output_tokens`/`generationConfig.max_output_tokens`; tail-capture empty-tail slice fixed; `PI_CREW_HOME` alias added; doc comment env-var name fixed.
|
|
150
|
+
- **CV-NEW-1** `font-detect.ts` — `isWebTerminal()` cached (was 12 sync reads per render tick).
|
|
151
|
+
- **CMD-NEW-2** `commands.ts` — `--var` value split fixed (was `split("=", 2)` which lost values containing `=`).
|
|
152
|
+
|
|
153
|
+
### CP-1 — turn-limit hard-abort escalation
|
|
154
|
+
|
|
155
|
+
`child-pi.ts` turn-limit hard-abort now uses `killProcessTree` (same as abort/noResponseTimer paths) and sets a `hardAbortInitiated` flag so `onJsonEvent` stops restarting the no-response timer. Prevents SIGTERM-ignoring runaway children. `HB-003a` source-contract test updated to verify the new behavior.
|
|
156
|
+
|
|
157
|
+
### Wave 2 — Budget / Worker cap / Worktree / Coalesced (6 fixes)
|
|
158
|
+
|
|
159
|
+
- **BDG-1** `goal-evaluator.ts` — judge token usage now returned and accumulated into `budgetUsed` (was discarded, systematically undercounted budget by 20–30%).
|
|
160
|
+
- **GL-1** `goal-loop-runner.ts` — loop checks `turnResult.manifest.status` after each turn; stops early on `blocked`/`failed` instead of burning the full `maxTurns` budget on a dead-end.
|
|
161
|
+
- **DLOCK-1** `dynamic-workflow-context.ts` — `ctx.agent()` now goes through `withWorkerSlot`, finally respecting the global worker cap (`PI_CREW_MAX_WORKERS`). Docstring claim was previously false.
|
|
162
|
+
- **ERR-1** `dynamic-workflow-runner.ts` — script timeout now aborts a combined `AbortSignal`, so spawned `runChildPi` children are killed instead of leaking.
|
|
163
|
+
- **N-1** `worktree-manager.ts` — `snapshotDirtyWorktree` failure now causes the caller to skip the discard (preserves dirty work instead of losing it). The previous behavior would silently destroy work if the snapshot artifact write failed.
|
|
164
|
+
- **N-2** `live-agent-manager.ts` — `evictStaleLiveAgentHandles` no longer treats `session.pid === undefined` (the in-process case) as dead. Previously every in-process live agent was killed after 30 min idle.
|
|
165
|
+
- **COAL-2** `run-coalesced-task-group.ts` — coalesced dispatch wrapped in `executeWithRetry`. One transient failure no longer fails all N tasks.
|
|
166
|
+
|
|
167
|
+
### Wave 3 — Observability + Budget reserve + DWF resume (4 fixes)
|
|
168
|
+
|
|
169
|
+
- **OBS-NEW-1/2** `foreground-run-controller.ts` — emits per-task `crew.task.completed/failed/needs_attention` events at run completion with `durationMs` and `tokens`. Added `durationMs` to `crew.run.completed`. Fixes task-level metrics that were always zero.
|
|
170
|
+
- **BDG-2** `dynamic-workflow-context.ts` — reserve-then-adjust token budget. Before spawn, reserve estimate (4096 tokens); after spawn, adjust by `actualUsage − estimate`. Prevents N concurrent calls from each overspending by `perCallCost`.
|
|
171
|
+
- **PERS-1** `dynamic-workflow-context.ts` — per-agent-call idempotency cache stored in checkpoint (`completedAgentCalls`). On resume, cached calls are skipped (return cached result). Previously a DWF resume re-ran the entire script, duplicating artifacts/mailbox/tokens.
|
|
172
|
+
|
|
173
|
+
### H-1 — AsyncLocalStorage re-entrance guard (root-cause class)
|
|
174
|
+
|
|
175
|
+
`src/state/locks.ts` — `withRunLock`/`withRunLockSync` now track re-entrance via `AsyncLocalStorage<Set<string>>` instead of a module-global `Map<filePath, token>`. True nested calls in the same async context still bypass (no deadlock). Calls from a DIFFERENT async context (e.g. a child-stdout event handler firing while an async merge holder is awaiting) no longer bypass — they properly serialize against the on-disk lock.
|
|
176
|
+
|
|
177
|
+
### H-7 — `runChildPi` decomposition (6 steps, −572 lines / −31.1%)
|
|
178
|
+
|
|
179
|
+
`src/runtime/child-pi.ts` reduced from **1842 → 1270 lines**. Code extracted into 4 self-contained modules with zero behavior change verified by 147 tests + live LLM:
|
|
180
|
+
|
|
181
|
+
| Step | Module | Lines | Purpose |
|
|
182
|
+
|------|--------|-------|---------|
|
|
183
|
+
| 1 | `child-pi-transcript.ts` | 169 | Transcript batching (50 ms debounce) + compaction helpers |
|
|
184
|
+
| 2 | `child-pi-kill.ts` | 180 | `killProcessTree`, `appendBoundedTail`, active-children bookkeeping |
|
|
185
|
+
| 3 | `child-pi-constants.ts` | 42 | Shared timing/buffer constants |
|
|
186
|
+
| 4 | `child-pi-streams.ts` | 296 | `ChildPiLineObserver` + line-level compaction |
|
|
187
|
+
| 5 | `child-pi-steering.ts` | 128 | `ChildPiSteeringController` state machine (turn-limit, soft/hard abort) |
|
|
188
|
+
| 6 | `child-pi-spawn.ts` | 226 | `buildChildPiSpawnOptions`, `prepareSpawnContext`, env allowlist |
|
|
189
|
+
|
|
190
|
+
Steps 1–4 verified clean on first commit. Step 5 required updating the `HB-003a`
|
|
191
|
+
source-contract test (steering logic moved to its own module). Step 6 required
|
|
192
|
+
updating the assertion to check `builtEnv` (control vars only) rather than
|
|
193
|
+
`mergedEnv` (which includes process.env spread).
|
|
194
|
+
|
|
195
|
+
### Live-test-only bug fixes (caught by real pi binary, missed by mocks)
|
|
196
|
+
|
|
197
|
+
- **Token usage not captured** — `src/runtime/pi-json-output.ts` `extractUsage` now recursively looks into `obj.message.usage` (pi nests usage under `message` for `message_end`/`turn_end` events). Mock tests passed because `PI_TEAMS_MOCK_CHILD_PI` short-circuits the spawn path entirely; only real `--mode json` output exercises `extractUsage`.
|
|
198
|
+
- **child-pi spawns wrong binary** — `src/runtime/pi-spawn.ts` `resolvePiCliScript` previously trusted `process.argv[1]` unconditionally. When invoked from a standalone test script, `argv1` was the test script and child-pi spawned it as if it were pi. Fix: only trust `argv1` when `resolvePiPackageRoot()` succeeds (current process is running from the pi-coding-agent package).
|
|
199
|
+
- **Worktree mode blocked by own .gitignore** — `src/worktree/worktree-manager.ts` `assertCleanLeader` used `git status --porcelain` without `--untracked-files=no`. After pi-crew's `ensureCrewDirectory` auto-creates `.gitignore`, that file shows as untracked and blocks worktree mode. Fix: add `--untracked-files=no` so only tracked changes are checked. Applied to both sync (`assertCleanLeader`) and async (`assertCleanLeaderAsync`) variants.
|
|
200
|
+
|
|
201
|
+
### Live test coverage (real pi binary + real LLM, on session restart)
|
|
202
|
+
|
|
203
|
+
14 live tests run end-to-end across 3 waves — all green:
|
|
204
|
+
|
|
205
|
+
| Wave | Feature | Result |
|
|
206
|
+
|------|---------|--------|
|
|
207
|
+
| A1 | 3 concurrent runs, unique runIds, no state leakage | PASS |
|
|
208
|
+
| A2 | Steer to completed task → rejected with `T-S1` error | PASS |
|
|
209
|
+
| A3 | Long research run (5 key points + explanations) | PASS · 8,302 tokens / 124 s |
|
|
210
|
+
| A4 | Cancel completed run is safe no-op | PASS |
|
|
211
|
+
| A5 | Steer to nonexistent runId → graceful error | PASS |
|
|
212
|
+
| B3a | Invalid model → fallback to `zai/glm-5.2` agent default | PASS |
|
|
213
|
+
| B3b | Empty goal → graceful error | PASS |
|
|
214
|
+
| B3c | Long goal stress (multi-paragraph objective) | PASS · 5,247 tokens / 178 s |
|
|
215
|
+
| C1 | Worktree mode (clean git repo, after fix) | PASS |
|
|
216
|
+
| C2 | Original file preserved across worktree cleanup (N-1 fix) | PASS |
|
|
217
|
+
| C3 | `implementation` workflow creates `math.js` with `subtract` function | PASS |
|
|
218
|
+
| C4 | `plan` action returns 4-step plan | PASS |
|
|
219
|
+
|
|
220
|
+
Mock tests: 30/31 pass (1 pre-existing skip).
|
|
221
|
+
|
|
222
|
+
### Files
|
|
223
|
+
|
|
224
|
+
- `UPGRADE_REVIEW.md` — 647-line audit report (all findings + cold verification + live verification).
|
|
225
|
+
- `test/functional/pi-crew-live.test.ts` + `pi-crew-live-broad.test.ts` — 16 live integration tests run against the real pi binary + real LLM provider.
|
|
226
|
+
|
|
227
|
+
|
|
5
228
|
## [0.9.42] — 107-finding deep review + arch cleanup (2026-07-17)
|
|
6
229
|
|
|
7
230
|
### Deep Review Resolution
|
package/README.md
CHANGED
|
@@ -279,6 +279,41 @@ The advisory is **informational only** — there is no `force:true` flag needed
|
|
|
279
279
|
- `test/unit/topology-analyzer.test.ts` — 13 cases (each topology + edge cases)
|
|
280
280
|
- `test/unit/preflight-validator.test.ts` — 11 cases (each level + advisory contract)
|
|
281
281
|
|
|
282
|
+
|
|
283
|
+
- `test/functional/pi-crew-live.test.ts` + `test/functional/pi-crew-live-broad.test.ts` — 16 live integration tests run against the **real pi binary + real LLM provider** (verified after v0.9.42 audit, ~26 commits). Use these when you want to confirm end-to-end behavior, not just unit-level invariants.
|
|
284
|
+
|
|
285
|
+
## Recent changes
|
|
286
|
+
|
|
287
|
+
### v0.9.45 – v0.9.46 (2026-07-20): security + perf remediation, UI stability
|
|
288
|
+
|
|
289
|
+
- **Custom agent roles default to read-only (FIND-12, breaking):**
|
|
290
|
+
`permissionForRole()` returns `"read_only"` for unknown roles (was
|
|
291
|
+
permissive `"workspace_write"`). Write-capable roles are now an explicit
|
|
292
|
+
allowlist (`WRITE_ROLES`). See `CHANGELOG.md` for the migration.
|
|
293
|
+
- **Mailbox / snapshot-cache / scan perf:** delivery cache + async append
|
|
294
|
+
(FIND-01/02), `listActive` TTL + mtime-sort strict limit (FIND-03/04),
|
|
295
|
+
byte-bounded event-log tail-read (FIND-05).
|
|
296
|
+
- **Heartbeat race (FIND-06):** in-flight guard + drain + terminal-safety +
|
|
297
|
+
late-save repair in the coalesced task group.
|
|
298
|
+
- **UI flicker eliminated:** the render path no longer hard-deletes snapshot
|
|
299
|
+
entries, so the crew widget / powerbar / live sidebar stay stable (no more
|
|
300
|
+
"(loading…)" flashing every ~160ms).
|
|
301
|
+
- **Emoji width-overflow crash fixed for good:** `visibleWidth` delegates to
|
|
302
|
+
pi-tui's own measure, so agent-output emoji can never exceed terminal width.
|
|
303
|
+
- **Background-subagent notifications coalesce:** N near-simultaneous
|
|
304
|
+
completions now produce ONE consolidated wake-up instead of N drips.
|
|
305
|
+
|
|
306
|
+
### v0.9.42 – v0.9.44: 4-wave audit + flaky-CI fixes
|
|
307
|
+
|
|
308
|
+
A 4-wave audit + fix pass was completed (see `UPGRADE_REVIEW.md` for the full 647-line report and `CHANGELOG.md` for the diff):
|
|
309
|
+
|
|
310
|
+
- **−481 KB** bundle size (externalized `acorn` + fixed `@sinclair/typebox` name).
|
|
311
|
+
- **−31.1%** in `child-pi.ts` (1842 → 1270 lines via 6 decomposition steps).
|
|
312
|
+
- **~30 bug fixes** across security, correctness, budget enforcement, worker cap, observability, and worktree isolation.
|
|
313
|
+
- **Lock re-entrance guard** via `AsyncLocalStorage` (H-1) — fixes a root-cause mutual-exclusion violation.
|
|
314
|
+
- **Task-level metrics now functional** (OBS-NEW-1/2) — `crew.task.{count,duration_ms,tokens_total}` were always zero; now emit on every run completion.
|
|
315
|
+
- **Live-test-only bugs found** (mock tests had passed): token usage not captured (nested `obj.message.usage`), child-pi spawning wrong binary (`argv1` trust heuristic), worktree mode blocked by own `.gitignore`.
|
|
316
|
+
|
|
282
317
|
## Builtin Agents
|
|
283
318
|
|
|
284
319
|
```
|