- Update isActionableDisable in usage-cli.ts to accept active accounts and check identity matches.
- Suppress credential disable tombstones when an active account exists for the same provider and identity.
- Add test coverage for suppressing tombstones when active accounts share the same identity.
downloadVerifiedBinary only wrapped isTimeoutError around the fetch()
catch, so a 15-minute timeout firing while pipeline() streamed the
response body re-threw the raw "TimeoutError: The operation timed out."
Mirror the wrap into the pipeline catch after cleaning up the partial
file, matching the connection-phase message.
Fixes#6822
- Native (non-mcp://) resource URIs now pass through byte-for-byte via
rawHref; slash elision applies only to the legacy mcp:// wrapper, so
catalog://root/ style URIs match exact-equality server lookups.
- resources/templates/list failure no longer discards a successful
resources/list (Promise.allSettled; templates retried later).
- Opaque RFC 3986 URIs (urn:doc, custom:item) are recognized by both
the router and read-cli discovery gates, with drive-path and
read-selector false positives guarded.
- Review follow-up for PR #6790.
The setup window between writeIsolationOwner and isoStart left the base
dir holding only the marker file and no `m` mount, so classifyDir
returned null and scanWorktrees classified it as a stray — which a
non-`--all` clear removes, defeating the ownership guard mid-setup.
classifyDir now treats the presence of the ownership marker as a
task-isolation signal (in addition to the mount dir), so an in-progress
sandbox with a live owner is preserved throughout backend setup.
Fixes#6761
`omp worktree clear` (without `--all`) removed every task-isolation dir
under the worktree base, including sandboxes owned by subagents running
right now, and the "no live task owns it" reason was asserted from the
mere presence of the `m` mount dir with no ownership check.
`ensureIsolation` now stamps each sandbox base dir with a pid-bearing
ownership marker before the backend materialises `m`, and the worktree
scanner classifies a sandbox as live while its owning process is alive,
so `clear` reclaims only crashed leftovers.
Fixes#6761
- Treated missing files separately from malformed or unreadable configs.
- Backed up malformed YAML and wrote settings atomically without dropping pending changes.
- Reported success only after saving, with regression tests for global and project configs.
Bun's global bin entry on Windows is a regular-file .exe shim, not a
symlink, so the standalone-binary override would have rerouted a
legitimate bun-managed install to in-place binary replacement and
clobbered the shim. Gate the override on POSIX, where package-manager
bin entries are always symlinks; add a regression test.
The settings panel persists "" when a credential is cleared and renders
that as unset; config list now uses the same semantics instead of
masking the empty string as a configured credential.
The credential pass marked `hindsight.apiUrl` secret instead of
`hindsight.apiToken`: both share `condition: "hindsightActive"` and the flag
landed on the wrong one, so the settings panel masked an ordinary endpoint. The
token keeps its masking through the `credential` marker.
`config list` also redacted on classification alone, so a fresh configuration
reported every unset credential as though one were stored. Redaction now
depends on a value being present.
The suite asserted classification and panel metadata only, so both output
branches could be deleted while every test passed, which is how the wrong flag
shipped. It now drives `runConfigCommand` and reads the real human and JSON
output.
omp config list printed every configured value, including auth.broker.token,
searxng.token, searxng.basicPassword and dev.autoqaPush.token, in both the
human and --json output. Nobody asked for those specific credentials; the
command dumps everything.
Credentials are marked with a top-level credential flag rather than ui.secret,
because four of them have no settings-panel entry and so have nowhere to put a
UI-level flag. isCredential is the single accessor both the CLI and the panel
consult, so the two spellings cannot produce different behaviour on different
surfaces.
Human output shows dots. JSON omits value and marks the entry redacted instead
of substituting a placeholder, which a consumer could not distinguish from a
real value and might write back.
config get <path> is deliberately unchanged: that is an explicit request for a
single value, and masking it would break a retrieval API with no way to read
your own token back.
- Added `listDisabledCredentials` and `refreshSnapshot` methods to credential stores along with API endpoints and wire schemas.
- Added `authorizedAt` timestamps and Anthropic OAuth grant TTL constants to track credential lifecycles.
- Updated the usage CLI to render auto-disabled credential tombstones and grant expiration warnings.
- Added comprehensive unit and broker integration tests covering the new credential management features.
The pi-native-only filter still let any non-pi-native models.yml provider override (baseUrl/apiKey/headers) reach the broker-backed gateway: config keys shadowed broker credentials (bypassing account pooling, refresh, and accounting) and a custom baseUrl redirected the broker bearer to a configured endpoint. Generalized the flag to ignoreLocalModelConfig, which short-circuits loadCustomModels so the gateway serves bundled plus broker-discovered catalog metadata only, applying no local overrides, config API keys, custom models, or custom discovery.
Fixes#6615
Gateway catalog construction now ignores models.yml provider entries whose transport is pi-native. This keeps the registry's bundled, cached, and upstream-discovered models while preventing client-side gateway base URLs and bearer keys from being applied to server-side dispatch.
Added a regression test proving a normal client registry retains pi-native routing while the gateway registry restores the bundled provider route before indexing the model.
Fixes#6615
runServe built /v1/models and the resolveModel behind /v1/chat/completions from getBundledModels only, freezing the gateway catalog on the compiled-in snapshot. Every discovery-only model omp itself reaches (ids released after the build date) was unroutable through the gateway while the same broker credential answered it in the TUI.
Source the catalog from ModelRegistry (bundled + cached + discovered) like every other omp surface, via a shared indexModelsByRequestId helper that preserves the credential scoping and qualified/bare-id registration. Rebuild it every 15m so a long-lived serve tracks newly discovered models without a restart; a failed refresh keeps serving the previous catalog.
Fixes#6615
resolveUpdateMethod classified the install purely by directory containment,
so a standalone binary placed where `npm prefix -g` / `bun pm bin -g` also
points (e.g. ~/.local/bin) was misrouted to `npm install -g`, which then
aborted with EEXIST refusing to overwrite the existing regular file. Now a
plain executable (not a symlink) inside a package-manager bin dir is treated
as the standalone binary and self-updated in place.
- Implemented a structured web-search query parsing module supporting directives, tokenization, date parsing, and syntax serialization.
- Updated search providers to map query directives and date bounds to native provider parameters and filters.
- Added lenient result constraint post-filtering and configuration settings for enhanced engine routing.
- Added comprehensive unit and integration tests covering query parsing, constraint filtering, and provider-specific request mapping.
Required CLI model registries to expose getAvailable() and used that authenticated
set whenever callers omit availableModels. Deferred SDK and bench/dry-balance
resolution now lets configured roles beat unauthenticated catalog id collisions.
Updated resolver test registries and made the #6508 regression omit the explicit
availableModels option, covering the deferred-caller path from the review.
Fixes#6508
- Switched from `miniaudio` to `maudio` Rust crate and added `AudioCapture` and `AudioPlayback` native classes.
- Removed browser-side audio infrastructure including Web Audio API, audio worklet processor, and WebRTC runtime.
- Migrated STT recorder and transcriber modules to use native `AudioCapture` with callback-based streaming.
- Replaced streaming audio player with native `AudioPlayback` that writes PCM directly without TypeScript intermediaries.
- Removed ffmpeg, wav, and platform-specific playback commands from the audio toolchain.
parseBlobRef sliced the blob:sha256: suffix and returned it unvalidated;
get/getSync then fed it into path.join(this.dir, hash), so a crafted ref
like blob:sha256:../../../etc/passwd escaped the blob directory and read
arbitrary files into resolved image history (base64, raw UTF-8, and the ACP
sync path).
Reject any suffix that is not a canonical 64-char lowercase hex hash in
parseBlobRef, the single choke point for every resolution entry point. Reuse
the shared BLOB_HASH_RE in gc-cli instead of its duplicate HASH_RE.
Fixes#4088
/usage and omp usage now report Synthetic (synthetic.new) quota state
via GET /v2/quotas (free, does not consume quota): the rolling 5-hour
request limit with per-tick regeneration rate, and the weekly credit
quota in USD. Applies to API-key credentials for the synthetic
provider; every payload section is parsed defensively since only
subscription is documented.
- omp update's getBinaryName now detects a musl Linux host (Alpine release file or /lib/ld-musl-* loader, mirroring scripts/install.sh) and downloads omp-linux-musl-<arch>, so self-update no longer replaces a musl install with the glibc build.
- Updated musl-release dry-run assertions to the Bun.build output format the binaries script now emits; promoted the musl changelog entry to [Unreleased].
Emitted session_shutdown after model rendering and centralized managed timer cleanup across one-shot listings and agent sessions.
Added regression coverage for the extension shutdown lifecycle.
Fixes#6297
A session now carries an ordered list of workspace directories beyond cwd,
managed live from the terminal. New /add-dir, /remove-dir, and /dirs slash
commands let you add and remove folders mid-session; the repeatable --add-dir
CLI flag seeds them at launch, and the workspace.additionalDirectories
setting persists defaults per project. Additional roots are persisted in the
session header, survive reopen/fork/move, and are surfaced to the agent in the
system prompt so it knows they exist and can read/grep/glob them by absolute
path. Design aligns with the endorsed community implementation on
feature/session-workspace.
Co-authored-by: oh-my-pi <https://omp.sh>
- Treated ZIP-based .jar/.war/.ear/.apk as zip archives in archiveFormatFromPath and parseArchivePathCandidates so read/write member access works.
- Shared one archive-extension alternation between format detection and path splitting to stop them drifting.
- Derived the markit convertible-extension set from a single source of truth (utils/markit) matching the registered converters (pdf/docx/pptx/xlsx/epub), dropping legacy .doc/.ppt/.xls/.rtf that had no converter and only produced Unsupported format errors.
- Updated read/write tool prompts to document the zip-family extensions.
Fixes#5808
The `omp grep` subcommand resolved its path argument with a bare
`path.resolve` in `runGrepCommand`, bypassing `expandPath`. The
leading-colon strip from #5529 never fired, so `:/abs/path` was
mangled into `<cwd>/:/abs/path` and failed to resolve.
Route the path arg through `expandPath` so it inherits the leading-`:`
strip plus `@`-prefix, tilde, and unicode-space normalizations, matching
`read`/`edit`/in-agent `grep`.
Fixes#5624