m4air 4057dd32f4 fix(crash-reporting): redact file:// URLs in crash reports
One lookbehind in the path redactor fails in opposite directions on the two
shapes a `file://` URL can take.

`PATH_PATTERNS` rule 5 is `(?<![A-Za-z0-9./])\/[A-Za-z0-9._-]+\/…`. Its
lookbehind rejects a slash preceded by a slash.

  - On POSIX a frame reads `file:///Users/alice/…`. The path's own leading slash
    sits behind the scheme's third slash, so the rule never fires and NOTHING is
    redacted — the account name and full filesystem layout ship in the report.

  - On Windows the same frame reads `file:///C:/Users/alice/…`. The drive letter
    interposes, the leading slash is preceded by `:`, and the rule fires.

So Windows file URLs were redacted and POSIX ones were not. Three payloads in a 326-file corpus carry a real account name: 25 occurrences,
13, and one with 48 path prefixes holding the name twice each — 96 literal
occurrences of a developer's account in a single submitted report, via
`/home/<name>/src/<name>/`.

Replaying those three payloads' actual leaking lines through both versions:
134 account-name occurrences before, 13 after. The 13 are payload C, whose
vector is a Vite dev-server URL this change does not address (below).

This adds two rules at the head of `PATH_PATTERNS`: a quoted `file://` URL, then
an unquoted one. Quoted first, so a URL holding spaces is taken whole rather
than truncated at the first one — that case previously leaked the entire path.

WHAT THIS DELIBERATELY DOES NOT DO

An earlier revision also preserved a stack frame's asset name and `:line:col`
while redacting its directory, because those offsets are the only axis a
minified React stack can be clustered on, and Windows loses all of them: across
17 minified React #185 payloads, darwin and linux kept 130 of 130 frames and
win32 kept 0 of 40.

That half is withdrawn. Gating on "ends in .js with a line and column" preserved
the basename of any user file with that shape. Gating instead on "carries a
bundler content hash" only narrowed it, because the shape it actually tests is
"the last 8 characters are not all lowercase letters" — which admits YYYYMMDD
dates, `_v2` suffixes, and every capitalised eight-letter dictionary word.
A grammar fuzz found 691,200 inputs where a user-identifying basename survived
the new code and did not survive the old, including
`tax-return-20241231.js` and `therapy-journal-20250101.js`. Against 5,000
ordinary basenames from this repo's node_modules, 99.3% become gate-passing once
one common date or version suffix is appended.

Two further defects went with it: running the frame pass first destroyed the
quoted-path rules' anchor, so a quoted region beginning with a frame fell
through to the unquoted rules and leaked from the first space onward; and its
two lookaheads made the regex quadratic on adversarial input — 4.1s at 50k
chars, 64s at 200k, on the unclamped breadcrumb path in the main process. With
the pass removed, 100k chars of the worst shape cost 0.10ms.

Preserving build frames is worth doing and needs a gate that constrains the
whole basename rather than its last 8 characters. It is not worth rushing into
the code path that decides what leaves a user's machine.

COST, STATED PLAINLY — AND IT IS SMALLER THAN IT FIRST LOOKS

darwin and linux stacks lose the frame `:line:col` offsets they currently keep,
because they were only keeping them by not being redacted at all. Windows is
byte-identical — it already lost them.

What survives on every platform: all 62 frame lines of an 8000-char stack, the
complete ordered minified function-name sequence (`_i, Ac, zv, Ll, kt, …`), the
component-stack component names, and `boundary_id` / `surface`. The function-name
sequence is the primary fingerprint crash aggregators group on; `line:col` is
the build-specific, weaker key. So these reports do not become unclusterable.

And redaction shortens the output enough to escape the 4000-char stack cap that
was silently truncating these. Measured on five real payloads (4 darwin, 1
linux) that previously shipped at exactly 4003 chars — the truncation marker:
they now ship at 899 / 1428 / 1476 / 1476 / 1499 chars, untruncated, with the
minified function-name sequence identical to the input in all five. Frame counts
come out equal rather than higher (37/37, 56/56, 57/57), because every over-cap
stack in the corpus is already one of the old code's truncated artifacts, so its
pre-truncation frame count is unrecoverable. The headroom gain is real and
measured; a frame-count gain is plausible but not demonstrable from this corpus.

A follow-up worth doing, and measured: preserving the `:line:col` alone — with
no basename — would restore the offset axis on every platform with no leak
surface at all, since digits carry nothing. Of the 17 payloads whose error_stack
holds the minified #185 string, 13 still carry offsets, and clustering those on
the INNERMOST THREE frames gives exactly 2 shapes (8 and 5). Stated precisely
because it matters: the full ordered offset sequence gives 9 clusters, since
outer frames drift per React build and the app-bundle frame moves every release.
The innermost frames are the stable part.

RESIDUALS — ONE OF THEM NEW

  - A Vite dev-server frame `http://localhost:5173/@fs/Users/<name>/…` still
    ships the account name. Not the `?v=` query or the `.tsx` extension, as an
    earlier draft of this message claimed: nothing anchors inside an `http://`
    URL at all, because every separator in `/@fs/Users/` is preceded by an
    alphanumeric. One corpus payload leaks a name 13 times this way.
  - `~user/…`, `.../Users/…` and `webpack:///Users/…` are unhandled.
  - An UNQUOTED path containing a literal space still stops at the space. Worst
    case is a Windows profile folder from a domain display name, leaving surname
    and employer. Quoted `file://` URLs holding spaces are now taken whole,
    which is new.
  - NEW, and the one thing here that is not pre-existing: redaction happens
    BEFORE truncation, so collapsing a long `file://` URL to `[redacted-path]`
    makes room under the length cap for content that previously fell past it. In
    a constructed dev-mode stack mixing `file://` frames with `/@fs/` frames, the
    old output truncated away all ten `/@fs/` frames and the new one ships all
    ten. Net leakage falls in every case measured this way (37→10, 34→10, 30→10,
    20→10 name occurrences) — but that does not generalise: a constructed input
    whose old output was name-sparse and whose newly-reachable tail is name-dense
    can raise the count, worst observed 5→515. Nothing newly exposed is content
    the old code redacted; it is unredacted residual whose reachability
    increased. No corpus payload contains both shapes.
  - Diagnostic BUNDLES, as opposed to crash payloads, are not sanitized by this
    code at all: roughly 274-282 of 321 expose 210-212 distinct home-directory
    usernames across some 800,000 occurrences (the range is definition-sensitive). That is a separate pipeline, and roughly four orders of
    magnitude larger than the payload leak this commit fixes.

No test covered a `file://` URL, which is how this shipped. There are now 49 in
this file: a per-platform frame case for darwin, linux, win32 URL and win32
backslash; nine document-shaped fixtures, each carrying a real `:line:col`, kept
so a future attempt to preserve frames has to clear the counterexamples that
killed this one; and three pinning the properties review found load-bearing but
untested — the `i` flag (an uppercase scheme was previously redacted by nothing
at all), the rule's inability to cross a newline, and quote-adjacency, which is
what stops it stealing an opening quote the way the withdrawn revision did.

One change post-dates the final review round and carries a round less scrutiny
than the rest: the unquoted rule was `file:\/\/\/?(?:[A-Za-z]:)?[\\/]…`, which
required a separator where an authority can appear, so `file://localhost/…`,
`file://host/share/…` and `file://Users/…` escaped every rule in the list. A
test added for those found it. It now takes everything after the scheme, which
is strictly more redaction; the `+` keeps the bare token in prose intact, and a
replay of all 31,497 payload lines leaves the same 13 residual account-name
prefixes, all Vite.

Review: four rounds. Round 1 found the frame pass preserved any `.js` basename;
round 2 found the hash gate meant to fix that was really a "last 8 characters are
not all lowercase" gate, with 691,200 leaking fuzz cases, and that the pass also
broke the quoted rules' anchor and made the regex quadratic. Removing the pass
was round 2's own recommendation. Round 3 fuzzed the remainder against the
pre-commit baseline over 604,800 grammar cases and 272,571 realistic cases and
found zero regressions, confirmed the anchor break is structurally impossible for
these two rules, and measured the worst adversarial shape at 2.9ms per 200k
chars against the removed pass's 64 seconds.
2026-09-15 08:45:49 -07:00
2026-09-15 06:20:16 +00:00
2026-05-04 20:42:03 -07:00
2026-03-16 22:27:51 -07:00
2026-03-28 10:19:14 -07:00

Orca Orca

GitHub stars Total downloads across all releases License: MIT Join the Orca Discord Follow Orca on X Supported platforms: macOS, Windows, and Linux

中文 · 日本語 · 한국어 · Español · Français · Português

The AI Orchestrator for 100x builders.
Run Codex, ClaudeCode, OpenCode or Pi side-by-side — each in its own worktree, tracked in one place.

Download Orca

Orca desktop app running agents in parallel worktrees, with the Orca mobile companion app in the corner

Features

Mobile Companion

Monitor and steer your agents from your phone — get notified when an agent finishes and send follow-ups from anywhere.

iOS App Store · TestFlight · Android APK 0.0.48 · Docs →

Orca desktop with the mobile companion app

Parallel Worktrees

Fan one prompt across five agents, each in its own isolated git worktree — compare the results and merge the winner.

Docs →

Parallel worktree orchestration

Terminal Splits

Ghostty-class terminals with WebGL rendering, infinite splits, and scrollback that survives restarts.

Docs →

Terminal splits

Design Mode

Click any UI element in a real Chromium window to send its HTML, CSS, and a cropped screenshot straight into your agent's prompt.

Docs →

Embedded browser and Design Mode

GitHub & Linear, Native

Browse PRs, issues, and project boards in-app — open a worktree from any task and review without a context switch.

Docs →

GitHub and Linear task workflows in Orca

SSH Worktrees

Run agents on a beefy remote box with full file editing, git, and terminals — auto-reconnect and port forwarding included.

Docs →

Remote worktrees over SSH

Annotate AI Diffs

Drop comments on any diff line and ship them back to the agent — review, edit, and commit without leaving Orca.

Docs →

Annotate AI-generated diffs

Drag Files to Agents

VS Code's editor with autosave everywhere — drag files or images straight into an agent prompt.

Docs →

Drag files and images into an agent prompt

Orca CLI

Agents drive Orca too — script every workflow with orca worktree create, snapshot, click, and fill.

Docs →

Script Orca from the CLI

Also in the box:

  • Quick open — Search across worktrees, files, agents, commands, and repo context without leaving your flow.
  • Account switcher & usage tracking — See Claude and Codex usage and rate-limit resets, and hot-swap accounts without re-logging in.
  • Rich repo previews — Preview Markdown, images, PDFs, and repo docs in the workspace.
  • Computer Use — Let agents operate desktop apps and visible UI when a workflow needs real interaction.
  • Notifications and unread state — Know when an agent finishes or needs attention, then mark threads unread to come back later.
  • And many, many more — we ship daily, so this list is perpetually behind. The changelog is the real feature list.

Supported Agents

Works with any CLI agent — if it runs in a terminal, it runs in Orca.

Claude Code logo Claude Code   Codex logo Codex   Grok logo Grok   Cursor logo Cursor   GitHub Copilot logo GitHub Copilot   OpenCode logo OpenCode   MiMo Code logo MiMo Code   Amp logo Amp   OpenClaude logo OpenClaude   Antigravity logo Antigravity   Pi logo Pi   oh-my-pi logo oh-my-pi   Hermes Agent logo Hermes Agent   Devin logo Devin   Goose logo Goose   Auggie logo Auggie   Autohand Code logo Autohand Code   Charm logo Charm   Cline logo Cline   Codebuff logo Codebuff   Command Code logo Command Code   Continue logo Continue   Droid logo Droid   Kilocode logo Kilocode   Kimi logo Kimi   Kiro logo Kiro   Mistral Vibe logo Mistral Vibe   Qwen Code logo Qwen Code   Rovo Dev logo Rovo Dev   + any CLI agent


Install

Desktop — macOS, Windows, Linux

Or via a package manager:

# macOS (Homebrew)
brew install --cask stablyai/orca/orca

# Arch Linux (AUR) — or stably-orca-git to build from source
yay -S stably-orca-bin

Mobile Companion — iOS, Android

Pair with your desktop app to monitor and steer your agents from your phone.


Community & Support

  • Discord: Join the community on Discord.

  • Twitter / X: Follow @orca_build for updates and announcements.

  • WeChat: Scan to join the Orca community WeChat group 8. Group 8 may be full; if so, scan the Group 9 QR code instead.

    WeChat group 8 QR code for the Orca community  WeChat group 9 QR code for the Orca community

  • Feedback & Ideas: We ship fast. Missing something? Request a new feature.

  • Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.

  • Show Support: Star this repo to follow along with our daily ships.


Developing

Want to contribute or run locally? See our CONTRIBUTING.md guide.

The relay that pairs the mobile app with a desktop host is also in this repository under cloud/, with a separate pnpm workspace and setup guide.

Orca contributors

GitHub star history chart for stablyai/orca

Signed Builds

Windows code signing sponored/provided by SignPath.io, certificate by SignPath Foundation.

License

Orca is free and open source under the MIT License.

S
Description
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.
Readme MIT
1.4 GiB
Languages
TypeScript 95.1%
JavaScript 4.1%
Swift 0.2%
HCL 0.2%
CSS 0.1%