- Added `ensureSharedBrowser` and shared browser acquisition to manage project-shared broker-owned Chromium instances.
- Implemented concurrent duplicate daemon start prevention and single-flight `pendingOpens` deduplication.
- Updated browser handle disposal to disconnect from shared daemons rather than closing them.
- Updated browser documentation and launch specifications to support shared and local headless runs.
Added the active Kitty Unicode placeholder overrides to the canonical environment-variable reference, including tmux placement behavior and the unsupported-terminal caveat.
Fixes#7172
Match interceptor regexes against conservative, raw shell command segments
in addition to the complete command, so anchored rules can detect commands
after &&, ||, ;, |, &, and newlines without treating quoted or escaped text
as commands.
Add extractFlatShellCommandSegments() to preserve source text for
user-configured regexes, unlike the token-based approval matcher.
Add skipShellWord() and environment-assignment stripping so rules can match
commands prefixed with NAME=value assignments. Preserve the original command
in interception errors after extracting a leading cd command.
html-to-markdown-rs 2.30 could recurse through pathological HTML until
a native stack overflow aborted the entire OMP process. Upstream 3.9.2
bounds those traversals and reports omitted subtrees as a
machine-readable DepthLimitExceeded warning.
Upgrade html-to-markdown-rs to 3.9.2. Upstream treats a depth-limited
conversion as a successful partial Markdown result plus a warning;
deliberately promote that warning to a rejected `htmlToMarkdown`
promise, allowing the Read tool to fall back without terminating OMP.
Normal conversions and unrelated warnings keep their existing behavior.
Add a rejection-contract test plus a child-process regression proving
OMP survives deeply nested and malformed input.
- Add the `app.live.toggle` keybinding defaulted to `Ctrl+L` to start or stop live voice mode.
- Remap the default display-reset action (`app.display.reset`) from `Ctrl+L` to `Alt+L`.
- Update the live visualizer to listen for stop keys so the toggle chord terminates active sessions.
- Added the coding-agent changelog entry the review flagged as missing.
- Updated docs/extensions.md: the ACP UI-context surface note still listed
editor among the stubbed no-op methods after it was wired through
elicitFromAcpClient.
Addresses PR review. The initial version put invokeTool on AgentToolContext
via ToolContextStore, but the extension execute path (RegisteredToolAdapter)
builds its own ExtensionContext and never saw it, so the documented
registerTool wrapper use case did not work. It also allowed arbitrary
cross-tool targets (bypassing the target's approval policy), used a
session-global recursion counter that tripped on concurrent independent
delegations, and missed discoverable built-ins that xdev partitioning moves
out of the tool array.
Rework:
- Move invokeTool onto ExtensionContext, and bind it in RegisteredToolAdapter
to the tool's own name, so a re-registered built-in actually receives it.
- Make delegation same-tool only: invokeTool takes just (params, options) and
runs the native built-in of the caller's own name. It cannot reach an
arbitrary target, so it cannot escalate past the approval already granted
for the call, and the native call is not re-gated.
- Track recursion depth per call chain (threaded through invokeNativeTool and
createContext) instead of session-global state, so concurrent delegations
do not interfere.
- Seed the native resolver from the xdev registry when present (it retains
discoverable built-ins like browser), else the built-in registry.
Replaces the ToolContextStore-level unit test with an end-to-end test that
registers a built-in wrapper through the extension/session path and asserts
the native tool runs the wrapper's delegated input.
A tool's execute context now carries invokeTool(name, params, options?),
which runs the native built-in of `name` and returns its result. A tool
that re-registers a built-in (e.g. wrapping write to add logging or a
policy check) can delegate to the original instead of reimplementing it.
The native implementation is captured before extension re-registration
replaces the registry entry and before the ExtensionToolWrapper pass, so
invokeTool reaches the unwrapped native execute: it does not recurse into
the caller's own wrapper, and it inherits the caller's already-granted
approval rather than re-running the gate. Delegation depth is guarded
against accidental self-recursion, and it resolves to undefined when no
native tool of that name exists.
Wired through ToolContextStore with a lazy native-tool resolver, so it is
coding-agent-only (no agent-loop change) and sees the fully-assembled
built-in set at call time.
Under a rootless XWayland session (the GNOME/KDE/sway default) the X11
root window has no backing pixmap, so core `GetImage` on the root returns
`BadMatch`. The computer tool advertised Wayland support yet failed every
screenshot with a raw X11 protocol dump, and coordinate actions stayed
gated behind a capture that could never succeed.
- `Monitor::all` now probes a 1x1 root `GetImage` at initialization and,
on a `Match`/`Drawable` error, fails fast with an actionable
`DESKTOP_BACKEND_UNAVAILABLE` message naming the rootless-XWayland
constraint via the new `root_capture_error` classifier.
- `capture_image` routes its `GetImage` failure through the same
classifier so any surviving path yields the actionable message rather
than a raw protocol dump; unrelated errors stay verbatim.
- Corrected the module doc premise and `docs/computer-use.md` to list
rootless XWayland as unsupported (capture needs a rooted/rootful X
server, which only exposes X11 clients).
Fixes#7085
- Extracted audio capture and playback implementations, along with the WebRTC peer engine, from `pi-natives` into a new `pi-voice` library crate.
- Updated `pi-natives` bindings to consume the extracted `pi_voice` audio streams and live peer core.
- Added release validation gate jobs, parallelized Linux binary builds, and introduced a concurrent macOS release build job in the CI workflow.
- Updated Bazel workspace configurations, Cargo manifests, and documentation to include the new `pi-voice` crate and its dependencies.
- Updated GitHub Actions workflows and custom actions to optimize caching strategies and runners.
- Configured separate restore and save steps for bun store caching with non-PR restrictions.
- Added darwin release bazel cache seeding and fallback keys for cache restore.
- Removed native-inputs workflow action and disabled PR-side Rust validation.
Anthropic's provider-scoped fastModeDisabled state was omitted from the session active predicate, and the unchanged-tier guard prevented explicit retries.
Attaching to a long-running browser (a signed-in profile, an Electron app kept
open for a session) meant repeating app.cdp_url on every browser call, and any
call that omitted it silently launched a fresh headless Chromium instead.
browser.cdpUrl supplies that endpoint once. It is a default rather than an
override: app.cdp_url and app.path still win, and an unset or blank value leaves
cmux and headless resolution exactly as before.
- Updated CI workflows and GitHub actions to enhance Bazel cache keying, credential masking, and validation checks.
- Migrated dependency locking from Cargo.Bazel.lock to MODULE.bazel.lock using rules_rust crate_universe.
- Updated build configuration, documentation, and tooling scripts to reflect the lockfile and cache changes.
The TTSR lifecycle doc called the edit/write match target the
"reconstructed source snapshot", which reads as the whole prospective
file. For edit that is wrong: every mode's matcherDigest returns only
the lines the call introduces (new_text / + body rows / added diff
lines). Only write passes whole content. Reworded lines 57 and 78 to
match the code contract in streaming.ts.
Fixes#6885