- Preserved escaped control characters for the downstream reinterpretation safety decision.
- Covered the backslash-escaped git inline shell-alias bypass.
Fixes#7552
- Treated double-quoted shell-control chars like single-quoted ones so a -c/-e reinterpretation option still gates them.
- Covered the double-quoted git inline shell-alias bypass.
Fixes#7552
- Replaced the raw character guard with quote-aware scanning while retaining command substitution and unquoted shell-control protections.
- Added regression coverage for the reported Cargo benchmark filter.
Fixes#7552
- Introduce `@oh-my-pi/omptype` as a new ArkType-compatible schema validation package featuring a lazy JIT runtime, JSON Schema emission, and compatibility adapters.
- Replace `arktype` across workspace packages and test utilities with `@oh-my-pi/omptype`.
- Add benchmark suites, tests, and documentation for the new validation engine and adapters.
- Update workspace build, test runner, and release configurations to include the new package.
- Split the Python bridge signal: the raw abort reaches tools (so
subagents die with the turn) while a shielded signal governs how long
the host waits, so a cancel can no longer settle a cell on top of a
still-running isolation merge.
- Mirrored the contract in the JS runtime: abort in-flight tool calls
immediately, then drain any deferExternalAbort phase before killing
the worker, and refuse new bridge calls once cancelled.
- Held a finished worker result until the run's tool calls drain. A
floated agent() previously settled the cell at once, dropping the
run's abort listener and leaving the subagent running with nothing
able to cancel it.
- Added regression coverage for all three, each verified to fail
without its fix.
Load project Codex MCP entries before user entries so a disabled project server claims its dedupe key before a same-named user server can survive.
Added regression coverage for project-over-user disable precedence.
Fixes#7538
Carry enabled = false through discovery so loadAllMCPConfigs' suppress
path can claim the dedupe key (keeping a same-named lower-priority
source disabled) and honor the user force-enable allowlist. Dropping the
entry outright defeated both.
Fixes#7538
- Rejected local model discovery at the configured deadline even when fetch ignored abort.
- Covered pending-transport behavior with deterministic fake timers.
Fixes#7482
- Added native `FileLock` bindings supporting cross-process advisory locking on Linux, Unix, and Windows.
- Replaced directory-based file locking and custom stale-lock reclamation with OS-backed native locks.
- Updated TypeScript declarations, native bindings, and package documentation for the new API.
- Added comprehensive unit tests and fixtures validating single-owner constraints and process death handoff.
- Moved the coding-agent lock-directory primitive to @oh-my-pi/pi-utils/file-lock
and migrated settings, MCP config-writer, and security store imports.
- Replaced the stats aggregator's parallel ~200-line token/breaker lock protocol
with the shared primitive: dead owners reclaimed immediately, live-but-wedged
owners after STATS_SYNC_LOCK_STALE_MS, unstamped acquisitions after the new
acquireStaleMs grace (10s).
- Shared primitive now treats EPERM kill probes as live owners.
- Rewrote the stats lock-reclamation regressions against the shared protocol
and moved the file-lock contract test into pi-utils.
Reserve the plain b shortcut only after /btw has a completed answer or a branch is already pending. Running, empty, aborted, and failed panels now leave the key for the composer, while completed-but-refused branches still consume it with an explanation.
Fixes#7474
Branched session files preserve entry ids, so leaf-id equality alone let a stale /btw answer promote into a different loaded session. Capture the originating session id at /btw start and require it to match at both the controller gate and every branchFromBtw checkpoint.
Fixes#7474
- Passed the authorized leaf through the branch executor and revalidated it before rewriting history.
- Refused promotion during active turns and bounded post-prompt drains.
- Consumed unavailable branch keys while showing pending and refusal state in the panel.
Fixes#7474
Publish terminal daemon completions to the session that started the
process so idle agents can resume without polling hub status.
Persist every unacknowledged generation with a stable completion ID and
immutable snapshot. Replay the collection after reconnect or broker
recovery, and clear each event only after the owning client acknowledges
it.
Signed-off-by: Christian Stewart <christian@aperture.us>
- The 'N tool calls elided' replay placeholder leaked tool activity while
display.hideToolActivity was on; it is now a visibility-aware component
wired into both the hotkey and /settings toggle paths.
- Added replay + live-reveal regression coverage.
- A reload that drops a module's last require() edge leaves the permanent
hooks serving it from the synchronous snapshot map, which was only
refreshed while the path stayed flagged; an edit after the downgrade
replayed stale bytes. Ensure now re-rewrites and refreshes the snapshot
for every ever-synchronous path on each graph walk.
- Added the mirror reload regression (require edge dropped + source edited).
- A reload that adds a require() edge to an already-hooked ESM module never
re-registers hooks, and the original async onLoad filter keeps matching;
require() rejects async onLoad results, so the async hook now serves the
pre-rewritten synchronous source inline when one exists.
- Added a same-process reload regression covering the async-to-sync upgrade.
inspect_image resolved @vision with resolveModelFromString, which dropped the
:high thinking selector, and passed no reasoning to the oneshot. The
google-gemini-cli mapper then emitted thinkingBudget: 0, which thinking-only
Gemini models reject with HTTP 400. Resolve the role's explicit thinking
selector, clamp it to the model's supported efforts, and forward it as the
oneshot reasoning.
Fixes#7448
- Added shared Python call and literal serialization utilities with multiline verbatim support.
- Standardized tool inventories to format as an OpenAI-Harmony functions namespace using TypeScript declarations.
- Updated tool normalization and rendering functions to accept options objects and default to Python-syntax examples.
- Refactored Gemini dialect rendering to leverage shared serialization functions directly.
Completed transcript entries now write through to the OS page cache on
append instead of microtask-batching, supersede in-flight atomic rewrites
with a synchronous full-body publish, and land on the live moveTo path
(source pre-rename, destination post-rename) so a software crash no longer
drops finished user/assistant/tool events. Streaming text remains durable
only at message_end; no fsync/power-loss guarantee is claimed.