- Added preprocessing to quote ambiguous plain scalars containing a colon-space sequence when standard YAML parsing fails.
- Preserves the parsed types of unaffected fields and prevents fallback warnings for common unquoted description strings.
- Added tests to verify successful recovery of unquoted values and continued fallback warning coverage for unrecoverable syntax.
- Restored the fetchWithRetry early return for Retry-After and quota hints larger than maxDelayMs.
- Added coverage so oversized provider retry hints do not sleep and retry internally.
- Introduced `isProbablyBinary` utility to sniff file headers for NUL bytes or invalid UTF-8 sequences.
- Updated `ReadTool` to use the binary sniffer, preventing mojibake corruption in output when reading non-text files.
- Refined `file-mentions` auto-reads to skip binary files and mark them as `binary` in the message transcript.
- Added comprehensive unit tests for binary detection logic, covering NUL bytes, truncated multibyte characters, and path-based file sniffing.
Rejoined split Windows extension module paths before launch parsing finishes and stripped extended-length Win32 prefixes before Bun import and worker spawn APIs see them.
Fixes#3804
- Introduced comprehensive support for multiple concurrent, independently-configured advisors via `WATCHDOG.yml` files.
- Implemented a full-screen TUI overlay for managing advisor rosters, models, tools, and instructions.
- Added session-wide advisor initialization, telemetry aggregation, and named transcript isolation.
- Enhanced advisor security and observability with secret redaction in tool results and secure XML attribute encoding.
Bun's `Response(stream).bytes()` returns the raw `ArrayBuffer` once the
body arrives in more than one chunk, which happens for subprocess stdout
past ~128 KB. The public contract of `ptree.ChildProcess.bytes()` is
`Promise<Uint8Array>`, and callers — most visibly the `ssh://` read
path's `decodeUtf8Text` — rely on `Uint8Array` methods such as `.indexOf`
and `.subarray`. On larger remote text files this surfaced as:
TypeError: bytes.indexOf is not a function
Normalize the result at the boundary: when `Response.bytes()` hands back
an `ArrayBuffer`, wrap it in a zero-copy `Uint8Array` view before
returning. Adds a regression test that drives a 256 KB stdout payload
through `ptree.spawn(...).bytes()` and asserts the contract.
Fixes#3712
- Added `rewrite-changelog.ts` and `fix-changelogs.ts` utilities to automate the consolidation of release notes using LLM-assisted processing.
- Updated multiple internal changelog files by consolidating redundant entries and improving phrasing for readability.
- Implemented `previewLine` utility in `coding-agent` to prevent visual spillover in status rows by managing text truncation and whitespace.
- Updated `package.json` with new workflow scripts for managing package-level change histories and documentation indexes.
- Renamed the `find` and `search` tools to `glob` and `grep` respectively across the codebase to improve command clarity.
- Implemented full-stack support for the renamed tools, including CLI arguments, system prompts, SDK exports, and tool registration.
- Added automated migration logic in `settings` to transform legacy `find` and `search` configuration keys to their new equivalents.
- Updated the `collab-web` renderer registry to ensure backwards compatibility with legacy tool outputs.
- Added a `worktree.base` setting to allow users to specify a custom directory for agent-managed git worktrees.
- Updated the `worktree` command to ensure settings are initialized before operations to respect the configured base path.
- Enhanced directory resolution logic to support `~` expansion and enforce absolute paths for worktree environments.
The #3348 change is a single retry-window constant (25->50ms); the test asserted
it via mock.module("node:fs") + process.platform/Bun.sleepSync mutation, which
AGENTS.md bans (leaks across the full suite). The retry-on-EBUSY loop already has
coverage; a config constant does not warrant a global-mutating test.
- Relocated json-parse (repairJson/parseJsonWithRepair/parseStreamingJson/
parseStreamingJsonThrottled) into @oh-my-pi/pi-utils; repointed all
ai/agent/coding-agent import sites to @oh-my-pi/pi-utils.
- readSseJson now recovers a truncated or lightly malformed final SSE event
through the shared streaming parser, removing the bespoke scanJsonState/
getClosingSuffix/isJsonTruncated scanner from stream.ts.
- Dropped the @oh-my-pi/pi-ai/utils/json-parse legacy bundled-plugin registry
entry; the symbols are exposed via the @oh-my-pi/pi-utils barrel.
- Moved json-parse tests into packages/utils/test.
- Centralized JSON parsing and stream processing logic by moving utilities from `packages/ai` to the shared `@oh-my-pi/pi-utils` package.
- Standardized import paths for JSON parsing and streaming across the agent, ai, and coding-agent packages.
- Refactored SSE stream handling to use consolidated `parseStreamingJson` logic and introduced robust error recovery for malformed container-shaped tail events.
- Cleaned up legacy bundled registry references and updated related module exports and tests to reflect the new utility structure.
The retry-on-EBUSY logic in removeSyncWithRetries/removeWithRetries
used 40 retries × 25ms = 1 second total. Windows can hold file locks
on SQLite databases for up to ~1.5s after close(), so tests that
already used removeSyncWithRetries (e.g. settings-manager.test.ts,
sdk-credential-disabled-bridge.test.ts) still failed with EBUSY.
Fix: increase the delay to 50ms (40 × 50ms = 2s total window). This
only affects Windows — the retry logic only runs on win32. Linux CI
is unaffected.
(cherry picked from commit ac67e96f1285ce0d80b2022c40c383b7ca262354)
- Set logger to silent mode when no transports are active to avoid "no transports" errors during log emission.
- Added a regression test to verify that disabling all transports suppresses warnings and that log output resumes after re-enabling transports.
- Added a check for empty transport arrays during logger initialization.
- Set the logger to silent mode if no transports exist to prevent unnecessary warning messages on every log emit.
- Corrected TTY property restoration to properly delete injected properties instead of redefining them as truthy values.
- Updated environment restoration to modify process.env keys individually to prevent breaking environment object reference bindings.
- Prevented pollution of TTY-gated code and environment variable state across test suites.