Commit Graph
573 Commits
Author SHA1 Message Date
Brennan BensonandNeil a2aa4d449f Isolate worktree checkout admission and bound default workers
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-11-13 00:32:09 -08:00
OrcaWinandOrcaWin 6734880408 test: remove synthetic portal loop and static WSL move suites (#41895)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 00:08:35 -08:00
Neil 2050d9fbc6 refactor: group source-control modules by operation ownership (#41812) 2026-11-12 20:41:35 -08:00
OrcaWinandOrcaWin f5ab621250 test: remove low-value mobile and source control suites (#41811)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-12 20:31:27 -08:00
Brennan Benson e4fdb8db89 Attribute Git demand and make setup path discovery asynchronous (#41325)
* Attribute Git demand and resolve setup paths asynchronously

* Check detached attribution without requiring an exact span envelope

* Keep invalid setup repository fixtures inside disposable directories

* Retire setup runner synchronous launch allowance

* test: type the canonical Git executor mock import
2026-11-12 19:36:24 -08:00
Kelvin Amoaba 900d458c0c perf(workspace-cleanup): keep cleanup scans offline and about 4x faster (#41765)
Scan merge proofs run with lazy fetches and transports off, so partial
clones never download blobs; direct WSL reads forward those variables.
Base and coordinator refs resolve once per repo per scan, and the squash
search lists target commits once and only patch-ids commits that touch
the branch's exact file set.
2026-11-13 03:15:13 +00:00
Brennan Benson 91b3f12f03 perf(git): reuse branch snapshots across searches (#41558)
* perf(git): share branch snapshots across repository searches

* fix(git): read branch occupancy and current checkout live

* Preserve branch occupancy and unborn checkout parity

* Keep native searches for clients without qualified refs

* fix(git): preserve compiled branch option caching

* fix(git): derive selected source labels from branch identity

* test(git): resolve selected source fixture import

* fix(git): keep branch default menu translations reactive

* test(git): type mobile branch row mock parameters

* fix(git): keep branch metadata expiry bounded during streaming
2026-11-12 15:12:55 -08:00
Brennan Benson 0664f1c9bb fix: hide deleted workspaces while background cleanup finishes (#41483)
* Retire workspaces after durable removal acceptance

* Refuse plugin fallback into retiring workspaces

* Complete plugin workspace test fixture identity

* Restore removal helper bindings and complete test doubles

* Configure durable removal storage in runtime test fixtures

* Initialize durable removal fixtures before exercising cleanup

* Preserve descendants and explicit parent choices during removal

* Guard cached lineage traversal against catalog rescans

* Explain cleanup ownership before workspace name fallbacks

* Match automatic branch handling for empty overrides

* Use valid optional removal facts in traversal fixtures
2026-11-12 13:32:43 -08:00
mousepotato03andClaude Opus 5.5 b7bb1fb4e0 fix(gh): turn off gh telemetry for Orca's gh calls to stop Windows console flashes (#41608)
gh 2.91.0 and 2.92.0 start `gh send-telemetry` with DETACHED_PROCESS. Its
`tzutil /g` child then gets a new console, which shows a terminal window for
about 0.2s. Orca's background PR polling runs gh about once a minute, so
Windows users on those gh versions see the window every few minutes while
Orca sits idle. Default GH_TELEMETRY to false in the gh child env, next to
GH_PROMPT_DISABLED, and keep any value the user already set.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 20:05:36 +00:00
Brennan BensonandClaude Opus 5.5 5d34b135ab perf(worktrees): one owner for each repository's worktree list (#41480)
* perf(worktrees): give each repository's worktree list one owner

The sidebar and the runtime catalog each kept their own copy of a
repository's `git worktree list` result and their own staleness rule, so
the same change was often listed twice. One owner per repository, host
and Git runtime now holds the observation, its flight and invalidation;
each reader keeps its accepted age (sidebar 5 s, runtime 30 s plus the
admin-file verifier up to the 5-minute ceiling) and shares the scan.

Settled rows now go stale on Git-level mutations too, overtaken readers
follow one trailing scan, store hygiene uses the facts captured before
the scan that produced the rows (once per observation), and a cooled-
down watcher failure defers its catalog refresh instead of dropping it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): fence the catalog owner by runtime, single flight and hygiene claims

Sidebar reads age from scan start, so runtime verifications no longer
stretch them; probes only certify rows fingerprinted before their scan.
One flight per owner, with a single trailing scan after invalidation.
Switching a repo's Git runtime retires the old owner, and a reader whose
owner was retired mid-read returns non-authoritative rows. Only pruning
readers claim hygiene, failed scans keep the evidence gate's no-retry
claim, overflow invalidates at once, and the stopped-distro fallback
serves only current rows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): let only the live route own a repository's catalog

The catalog owner now asks the live registration which path and Git
runtime are current instead of trusting whichever request arrives last.
A request admitted for a replaced route runs no Git, retires nothing and
answers non-authoritatively; liveness is rechecked before a flight
starts and when it publishes. Route-changing writes retire obsolete
owners after they land. Adapters re-resolve the route after the WSL
admission check, a mismatching verification probe becomes the rescan's
fingerprint, and runtime scans share the strict true-empty-aware reader.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): bound live-route checks and recheck authority before pruning

Live-route checks read the repo registry once per synchronous pass
instead of hydrating every repo per check. WSL discovery answers that
change a repo's Git route retire obsolete owners like other route
writes, and desktop and headless pruning recheck the owner's authority
for the observation after their own awaits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): revision the live-route snapshot and carry owner authority to publication

Route checks use one registry and project pass per route-input revision,
which repo, project-membership and runtime-setting writes advance
synchronously; WSL discovery answers retire obsolete owners at once.
Repair-state and SSH routes never acquire local Git authority. Metadata
pruning rechecks owner authority after its path probes, fleet lineage
claims require a current observation, and final desktop and runtime
listings stay non-authoritative once the owner has retired their route.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): keep remote-owned repos out of local Git routes

Registrations owned by another host never get a local Git route, WSL
discovery notifies after the distro list is written and isolates its
listeners, and tests cover idle retirement on route-input and discovery
changes plus pruning that loses owner authority mid-helper.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(worktrees): cover catalog route authority at its production seams

Real repo-removal writer revokes the route at once, and desktop and
runtime listings never publish owner rows as authoritative after their
route was retired.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(worktrees): prove catalog authority at the pruning helper and Git conversion writer

The runtime listing loses route authority during its own metadata prune
and stays non-authoritative; a real held path probe deletes nothing once
the owner retires the route; a folder converted to Git is admitted as a
live route as soon as the write lands.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): keep strict true-empty listing behind the mockable lister

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(worktrees): start each worktree.ps case from an unobserved catalog owner

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* build(typecheck): list the WSL discovery change module in the web project

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(worktrees): withdraw catalog authority from a replaced observation

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-12 10:32:22 -08:00
Neil fb8d6f950b refactor(github): organize concrete feature owners (#41601) 2026-11-12 09:17:26 -08:00
OrcaWinandOrcaWin 0b6497cfc8 test: remove low-value plugin, mobile and shared suites (#41571)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-12 06:50:57 -08:00
Kelvin Amoaba 0b516b8a9d fix(workspace-cleanup): warn before deleting a workspace's ignored local files like .env (#41446)
* fix(workspace-cleanup): warn before deleting a workspace's ignored local files

git worktree remove deletes ignored files such as .env and local config,
and git status never reports them, so cleanup showed "Clean git" and the
delete dialog said nothing. Read them with a bounded ls-files listing,
skip regenerable output, symlinks and byte-identical copies of the main
checkout, and surface the rest as an approval-only cleanup blocker and a
warning in the delete confirmation.

* fix(workspace-cleanup): show an unchecked warning when the ignored-files check fails

* style(workspace-cleanup): format merged fact status list
2026-11-12 09:23:46 +00:00
Kelvin Amoaba 1ed47daf1f fix(workspace-cleanup): show merged and unchanged workspaces instead of flagging landed commits as unpushed (#41408)
* feat(workspace-cleanup): mark merged and unchanged workspaces from git evidence

Squash-merged branches whose remote was deleted were flagged as unpushed
and needed a forced delete. The scan now reads what HEAD holds beyond the
workspace's base (ancestor, Git's squash proof, or a cached merged PR) and
reports merged/unchanged reasons; landed commits no longer count as at risk.
A gone upstream no longer hides unpushed commits. Renames idle-clean to
inactive and drops the dead tier, selectedByDefault and volatile-local-context.

* fix(workspace-cleanup): read HEAD once, skip a reused branch as its own base

Merge evidence now compares the cached PR and the base against the HEAD it
reads, not the listing's possibly stale one; a workspace opened on an
existing branch no longer counts that branch as its base; the proof
wrapper settles the WSL route before building its caches; a visit keeps
merged/unchanged reasons; landed rows stop sorting as unpushed.

* fix(workspace-cleanup): qualify base refs and trust the branch proof only for HEAD

Base refs resolve through the worktree base-ref qualifier so a tag cannot
shadow them and only the branch's own family is skipped, including the
repo default; SHA-256 pinned commits are not bases; the squash proof runs
only while the branch ref is the HEAD just read; expanded details stop
counting landed commits as unpushed.

* test(workspace-cleanup): build the repo fixture without a cast

* fix(workspace-cleanup): never take a tag as a workspace's base
2026-11-12 08:14:14 +00:00
OrcaWinandOrcaWin affd908567 test: remove narrow parser, policy, and native projection tests (#41407)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 22:30:38 -08:00
OrcaWinandOrcaWin 86f23bbb6b test: remove low-value policy and parser samples (#41397)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 21:35:14 -08:00
Brennan Benson 042cb123aa Keep automatic Git maintenance opportunities pending (#41370) 2026-11-11 21:19:46 -08:00
Neil a0f1cb0ee2 refactor(git): group root modules by concrete domain owners (#41322)
* refactor(git): group root modules by concrete domain owners

* chore(git): reconcile retired-test metadata with owner cleanup
2026-11-11 18:02:15 -08:00
Neil 04158606b5 refactor(git): group command execution by concrete owners (#41316) 2026-11-11 17:05:03 -08:00
Dat 4f6d182dde feat(watcher): ignore mobile/monorepo build folders while keeping Pods live-watched (#28494) 2026-11-11 13:33:30 -08:00
OrcaWinandOrcaWin 9576e55773 test: remove 1,144 low-value declarations (#41177)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 09:11:06 -08:00
Neil bfd2bd7486 refactor: group CLI installation and crash lifecycle owners (#41142) 2026-11-11 04:02:20 -08:00
Neil e9e77a5962 refactor: organize GitLab and Linear implementation owners (#41130)
* refactor: organize GitLab and Linear implementation owners

* fix: package moved GitLab parser and consolidate owner import
2026-11-11 03:30:03 -08:00
OrcaWinandOrcaWin 2d2056b2d0 test: remove 117 low-value test definitions and orphaned fixtures (#41085)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 00:49:08 -08:00
OrcaWinandOrcaWin fce98d7d21 test: remove 167 low-value cases and 93 suites (#41057)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-10 23:17:08 -08:00
Brennan Benson bc1427f6ce Keep repositories on their known public forge (#40542)
* fix(git): keep public forge ownership ahead of auth evidence

* test(git): exercise forge admission with complete auth fixtures
2026-11-10 15:26:25 -08:00
Brennan Benson 8b1906a797 fix: register repositories before optional hosted metadata (#40050)
* fix: keep hosted metadata off repository registration

* test: update repository metadata ownership fixtures

* test: explain nested import runtime fixture cast

* fix: preserve explicit setup progress and metadata ownership

* fix: settle project links from the prospective saved row

* Keep explicit project choices stable after alias enrichment

* Keep project identity stable when opening repository settings
2026-11-10 13:15:49 -08:00
Brennan Benson c28414c10a fix: reclaim timed-out prepared checkouts without exceeding capacity (#40486)
* fix: retain prepared checkout cleanup ownership after timeout

* test: retain capacity for unregistered preparation leftovers

* fix: keep expired cleanup admission outside retry budget

* fix: verify original preparation registration before removal

* Retain preparation authority through bounded capacity recovery

* Exercise preparation cleanup failures through real filesystem fixtures

* Inject root mkdir failure without obstructing checkout absence proof

* Match the host filesystem path in preparation failure coverage

* Align preparation fixtures with physical cleanup ownership

* Await owned recovery in the fleet cleanup control

* Release abandoned preparation cleanup maintenance leases

* Match cleanup test identity paths on Windows

* Wait for completed preparation disposal in maintenance regression

* Await final cleanup state in maintenance controls
2026-11-09 22:02:16 -08:00
Kelvin Amoaba b41ab35b72 fix(clone): let a clone use its own folder when the repo's name is taken (#40066)
Cloning always went into <parent>/<repo name>, so a same-named repository
from another owner (or any non-empty folder of that name) could not be
cloned into the same parent. Before cloning, Orca now checks the target
on the clone host. If it is taken, the clone forms show a Folder name
field with a free suggestion (<repo>-<owner>, then <repo>-2...) and clone
into that instead. RPC repo.clone and `orca project setup-clone` accept
the folder name too.
2026-11-09 03:14:06 +00:00
OrcaWinandOrcaWin fcd356ad88 test: remove 6 low-value test cases (#39925)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 10:50:46 -08:00
Kelvin Amoaba f74bb65fa1 feat(runtime): tell phones when git status changes (#39672)
* feat(runtime): tell phones when git status changes

* fix(runtime): tell phones about HEAD and packed-refs moves too

* fix(runtime): don't let a phone's status re-read join a read begun before the change

* perf(runtime): limit status-read invalidation to the checkouts an outside change touched

* fix(runtime): match a checkout's status keys under any execution host

* fix(runtime): invalidate globally while a primary checkout is unread

* test(mobile): re-record the Changes and settings goldens on the rebased main

* fix(runtime): invalidate globally while a listed checkout has no cached path

* test: follow the moved paired-client harness

* refactor(mobile): let the host list's catalog read hold the event router
2026-11-08 18:36:13 +00:00
Neilandm4air dddc1260e5 chore(lint): oxlint 1.91, cheap perf/correctness rules, return-await fixes (#39730)
* chore(lint): bump oxlint to 1.91, add perf lint rules and perf audits

* fix(lint): await promises returned inside try/catch/finally for return-await

Prepare typescript/return-await with error-handling-correctness-only: await
returns whose catch or finally was meant to cover them, and suppress the eight
sites where the catch must not re-handle the returned promise.

* chore(lint): enable return-await (error-handling-correctness-only); exempt secondary-scan directives in the changed gate

* refactor(mobile): move file preview discard modal into its own module

Keeps MobileFilePreviewScreen under the 400-line limit after merging main.

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-11-08 06:21:54 -08:00
Neil 656a05de0d perf(main): overlap independent fs probes; skip per-entry copies (#39729)
* perf(main): overlap independent fs probes on git status, agent detection and orcad startup

* perf: skip per-entry copies in git change list and tab hydration; drop unused activity barrel
2026-11-08 05:05:19 -08:00
Brennan Benson d857e09615 Git Graph: commit actions (checkout, cherry-pick, revert) (#39069)
Adds commit actions to the Git Graph: check out a commit or branch, cherry-pick, revert, and create a branch from a commit. Conflicts hand off to Source Control with continue and abort. Works on local, WSL and remote hosts.
2026-11-08 03:43:30 -08:00
Brennan Benson 3fe350eaed Create a worktree per repository from an empty folder workspace (#39575)
A folder workspace with no worktrees now offers Create worktree for each repository, named after the folder workspace. If that branch name is already taken, the host refuses instead of picking another name, and the composer opens so you can choose.
2026-11-08 03:30:10 -08:00
Jinwoo Hong 4fabde28b1 feat(cli): one enclosing-workspace rule, --environment local, copyable addresses, and --parent-environment (#39733)
* feat(cli): one enclosing-workspace rule, --environment local, and copyable workspace addresses

current/active and cwd inference now pick the innermost workspace of either kind (worktree or
folder workspace); at equal depth the caller terminal's own workspace wins, otherwise the choice
is refused as ambiguous. --environment local names this machine's own Orca over an ambient
ORCA_ENVIRONMENT or pairing code. worktree ps/show/current print an environment: line and an
address: line (JSON environment, address, addressUnavailable, parent) that always carries its
--environment, and name a parent's environment only when it is verified.

* test: answer the folder catalog read in agent launch cwd tests

* feat(cli): worktree rm refuses current/active and names the selector to pass

Removal needs an explicit workspace, as git worktree remove needs a path. The refusal runs before
rm decides between a worktree and a folder workspace, and reports what current resolves to now
(one selector, the ambiguous choices, or none) in text and as invalid_argument data.

* fix(cli): keep the remote-environment guidance when rm refuses current

* fix(cli): surface folder-catalog failures for omitted targets; no address for a duplicated folder parent

* fix(cli): surface a worktree-list failure for omitted browser and terminal targets too

* test(cli): folder rm refuses current/active before the folder removal path

* fix(cli): refuse a cwd owner whose folder host can't be derived instead of skipping it

* fix(cli): compare cwd owners by filesystem identity, refuse every equal-path tie, surface worktree-list failures

Paths on the caller's own filesystem compare by realpath (reusing resolveRealPathSync), so /tmp
and /private/tmp aliases find the deeper owner in both the folder prefilter and ranking; other
hosts' paths stay lexical. Equal-depth owners with different repo registrations now refuse without
a caller instead of picking by catalog order. An omitted target no longer swallows worktree.list
method_not_found; only the optional folder reads fall back.

* fix(cli): read the realpath helper from shared so the packaged CLI ships it

* refactor(cli): move the catalog row type and unresolved-owner refusal out of the selection/catalog cycle

* fix(cli): resolve every caller-filesystem workspace path, not only basename matches

A workspace registered through a differently named symlink was skipped by the basename gate.
Containment now realpaths cwd and each row on the caller's own filesystem once per command,
shared by the folder prefilter and ranking; folder hosts are derived first so another host's
paths are never resolved locally.

* test: answer the folder catalog read in the ambiguous orchestration-check caller test

* feat(cli): --parent-environment names where a worktree's parent lives

worktree create and worktree set take --parent-environment <local|saved id|name>
next to --parent-worktree. The parent is resolved in that environment only, and
sent to the child as a verified cross-store ref after the child's cross-machine
capability check. Without the flag, the parent stays in the child's environment;
active/current always mean this machine's own Orca.

Preflight failures happen before any change: environment_not_paired,
environment_unavailable, LINEAGE_PARENT_NOT_FOUND / LINEAGE_PARENT_AMBIGUOUS
naming the searched environment, and incompatible_runtime with data.environment
and data.requires.

* fix(cli): parent lookup errors name and list the environment searched

LINEAGE_PARENT_AMBIGUOUS and LINEAGE_PARENT_NOT_FOUND now always carry
data.environment and a listing command for the environment the parent was
looked up in, for parents in another environment and in the child's own. Steps
inherited from the runtime listed the caller's default route instead.

* docs(cli): a local address names the Orca that printed it
2026-11-08 04:08:07 -05:00
Neil 83f8e6340d refactor(shared): organize file operations and storage owners (#39746) 2026-11-07 22:58:35 -08:00
Neil d406a22214 perf(git): reuse the branch-compare changed-files list while its inputs are unchanged (#39747)
* refactor(git): share the .gitattributes ancestor stamp paths

* perf(git): reuse the branch-compare changed-files list per commit pair

* perf(git): charge cached change lists for the stdout their paths retain

* perf(git): bound branch change-list reuse to five minutes for unstamped system attributes

* refactor(git): share the deadline-bounded stamp probe

* perf(git): bound branch change-list attribute stamps by a 2s deadline and 4096 paths
2026-11-07 21:42:01 -08:00
Neil 6d122f1eb5 perf(git): use git's untracked cache and reuse unchanged line stats in status reads (#39721)
* refactor(git): move porcelain status streaming into its own module

* perf(git): let status use the untracked cache and expand collapsed directories

-uall never matches the untracked cache's stored mode, so every poll rescanned the whole tree. Scan in the configured mode and list only the collapsed '? dir/' rows with ls-files, reapplying the entry cap so results match -uall exactly. Ignored reads and status.showUntrackedFiles=no keep -uall.

* refactor(git): let the settled diff cache and stamp serve multi-path reads

* perf(git): reuse status numstat passes while their stamped inputs are unchanged

Each poll re-ran up to two whole-worktree numstat diffs even when nothing changed. Cache each pass in a SettledDiffCache validated by the worktree diff stamp (HEAD, index, .gitmodules, plus every unstaged working file for the unstaged pass); racy writes, mutations and submodule rows still recompute.

* perf(git): defer status while index.lock is held

A status read during an agent's commit sees a half-written state and is immediately redone. Wait (up to 1s, abortable, inside the shared lease) for the lock in the worktree's own gitdir to go away; a lock that survives a full wait is remembered as stale so later reads skip waiting.

* perf(git): pick the untracked scan from config and fall back to -uall when expansion cannot win

Read status.showUntrackedFiles and core.untrackedCache in one config call, remember worktrees that need -uall so polls do not scan twice, and rescan with -uall when rows sit outside cwd, need more than one ls-files chunk, or list empty.

* refactor(git): keep numstat cache limits beside the file diff limits

* refactor(git): stamp host settings files and resolve the common gitdir

* perf(git): read untracked-scan config from a stamped snapshot, with a rollback switch

Cache 'git config --list --show-origin' per worktree while every config file it named (plus repo, worktree and global candidates) keeps its stamp, so steady-state polls spawn no config read. WSL and UNC checkouts keep -uall: their config cannot be stamped from the host and network mtimes cannot vouch for the untracked cache. ORCA_GIT_STATUS_UNTRACKED_EXPANSION=0 restores the plain -uall scan.

* fix(git): stamp config and attributes before reusing status numstat

Numstat output also depends on Git config (including includes) and on .gitattributes, info/attributes and core.attributesFile. Stamp all of them, plus every .gitattributes that can apply to a changed path, and skip reuse under WSL. ORCA_GIT_STATUS_NUMSTAT_REUSE=0 recomputes every pass.

* fix(git): stamp include targets and onbranch HEAD in the config snapshot, and share one read

Include and includeIf targets (and HEAD for onbranch conditions) are now stamped, so a branch switch or a filled-in include re-reads config. Concurrent cold reads coalesce, both numstat passes share one config read, folders without their own gitdir skip the snapshot, aborted reads keep the cached entry, and Windows HOME follows Git's HOMEDRIVE/HOMEPATH order.

* perf(git): expand untracked directories only when the untracked cache is opted in

Git's default core.untrackedCache=keep only reuses a cache someone already built, and fresh repos have none, so status plus ls-files cost more than one -uall scan. Expand only for core.untrackedCache=true or feature.manyFiles=true without an override.

* fix(git): bound config stamps on dead mounts and share commondir resolution

Config file stats run under the same 2s deadline as local-git-config-signature, coalesced per file set, so a hung home or network mount skips reuse instead of stalling status. readHeadComponent now uses resolveGitCommonDir.

* test(git): pin the -uall truncation contract of untracked directory expansion

* fix(git): treat an unreadable commondir as unstampable config

main's resolveGitCommonDir rethrows non-missing errors; the config snapshot must fall back to -uall rather than reject the status read.
2026-11-07 20:33:31 -08:00
OrcaWinandOrcaWin 331864e249 test: remove 259 low-value tests (#39701)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 19:53:07 -08:00
Neil d2506d05d6 perf(git): cache branch-compare merge-base and ahead/behind by commit pair (#39699)
* refactor(git): share common-dir resolution and stat stamps from worktree-diff-stamp

* perf(git): cache branch-compare merge-base and ahead/behind by commit OID pair

* fix(git): only store a commit-pair answer when its scope survived the walk

* refactor(git): type commit-pair stores per answer kind and pin test mtimes

* fix(git): skip the commit-pair cache whenever replace refs, grafts or relocating env could apply
2026-11-07 19:43:01 -08:00
Brennan Benson a7ba6a7cb1 Switch or create a branch in place from the Source Control header (#38836)
Adds a branch picker to the Source Control header for switching or creating a branch in place. Switching is disabled while an agent is working in the workspace, and results show as toasts.
2026-11-07 18:33:25 -08:00
OrcaWinandOrcaWin 5f226987f1 test: remove 279 low-value tests (#39527)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 07:58:19 -08:00
193dd5726f Git Graph tab: all branches, commit details and file changes (#6746)
* Add Git Graph view showing all branches and commit history

Adds a full-pane Git Graph tab that visualizes the whole repository —
all local branches, remote-tracking branches, tags, merges, and HEAD —
instead of only the current branch's linear history shown in the Source
Control sidebar today.

- Add an opt-in allRefs scope to the shared git-history loader so the
  graph query enumerates --branches --remotes --tags HEAD; the default
  current-branch path is unchanged. The flag is forwarded through the
  local IPC, SSH provider, and runtime RPC boundaries so it works in all
  environments.
- New git-graph tab content type with a full-pane GitGraphPane that
  reuses the existing graph SVG/row components, virtualizes rows, and
  opens a commit's combined diff on click. Wired into the tab strip as a
  chip (activate/close/keyboard-cycle) mirroring the simulator pattern.
- Entry point: an Open Git Graph button in the Source Control commits
  header (Cmd/Ctrl-click opens in a split).

Closes #4521

Co-authored-by: Orca <help@stably.ai>

* Address review: virtual-tab guards, nav-order, truncation copy

- Treat the Git Graph (and mobile emulator) tab chip as a virtual tab:
  add an isVirtual contract to EditorFileTab/EditorFileTabContextMenu so
  rename, copy-path, copy-relative-path, and reveal-in-finder are disabled
  for tabs whose filePath is a display label, not an on-disk path. Prevents
  a rename on the synthetic 'Git Graph' path running a real file operation.
- Forward gitGraphIds through the legacy reconcileTabOrder fallback in
  getActiveTabNavOrder so keyboard tab navigation does not drop git-graph
  tabs when no split-group layout exists yet.
- Make the truncation banner explicit: 'Showing first N commits across all
  branches' (was 'of many'), across all locales.
- Tests: virtual-tab hides path actions; git-graph survives the legacy
  nav-order fallback.

Co-authored-by: Orca <help@stably.ai>

* Forward allRefs over SSH relay and web runtime paths

Two boundaries re-destructured git.history params and dropped the new
allRefs flag, leaving the repo-wide Git Graph inert (linear default-branch
history) for SSH and web-runtime worktrees:

- src/relay/git-handler.ts: the relay host's git.history handler forwarded
  only { limit, baseRef }. Add allRefs so the SSH host enumerates all refs.
  Adds an end-to-end relay test (a feature-branch commit absent from linear
  history appears only when allRefs is forwarded).
- src/renderer/src/web/web-preload-api.ts: the web preload history shim
  destructured only { worktreePath, limit, baseRef }. Forward allRefs.

Also fix a request-id race in useGitGraphHistory: bump requestIdRef before
the null-context early return so an in-flight fetch from a prior worktree
can't resolve and overwrite the 'idle' state after the worktree clears.

Co-authored-by: Orca <help@stably.ai>

* Support filtered and pinned Git history

Resolve branch and tag roots on the host, keep paging tied to the chosen revision set, and echo the applied filter across Git transports.

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>

* Add the Git Graph tab and commit details

Open the all-branch view from Source Control or the command palette, preserve older clients' layouts, and keep the sidebar HEAD-only.

* Restore files the main merge left at stale versions

The earlier merge of origin/main kept older or missing copies of 61 files
unrelated to the Git Graph (CI script tests, reliability gates, shard
timings and five terminal runtime files). Take main's version of each so
the PR changes only its own files.

* Limit pinned history to explicit graph scopes

Keep All and HEAD snapshots free of redundant ref names, and filter ref searches before nested-tag peeling. Default history requests retain unpinned paging without evicting graph tokens.

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>

* Preserve canonical placement for older graph clients

Pass graph-free record deltas through without rebuilding layouts, retain existing empty groups, and translate content creation into canonical groups while preserving hidden graph tabs.

* Retain Git Graph browsing state for the tab lifetime

Own history retrieval, selection and scroll in one renderer controller that retires on close or owner/filter changes. Accumulate parent pages before publishing, share action-time workspace navigation, serialize ref searches, and scope refreshes to the workspace.

* Apply Git Graph branch selections on picker close

Keep checkbox changes local until dismissal, then normalize and apply one chosen ref set. Allow picker reads to use a qualified host scope.

* Keep Git Graph navigation bound to its tab owner

Retain the tab's qualified owner and Git connection across workspace focus changes. Newer selections and refreshes supersede pending parent navigation without losing fetched pages.

Report stale workspace switches and let the commit menu handle empty space in the Branch / Tag cell. Cover twin-owner retention, superseded navigation and picker apply-on-close with renderer regressions.

* Translate desktop layout commands against canonical state

Resolve older desktops' visible groups, tab gaps and split paths inside the canonical mutation, including detach and cross-partition moves. Keep initial admission visibility-aware and cache graph presence for binding-only frames.

* Refine Git Graph picker and owner transitions

Discard branch drafts on Escape or owner changes, follow updated tab ownership, and report workspace lookup failures for the current owner. Keep parent navigation queued behind pending history loads.

* Drop the redundant default from the exhaustive layout command switch

* Align Git Graph with changed-code quality rules

Use typed fixtures and an event guard, keep primitive styling on content wrappers, and prune loaded-commit bookkeeping after render.

* Route Git Graph opening through the existing editor action

Use workspace record selectors for stable owner inputs and remove two
loading labels orphaned by the graph changes from all locale catalogs.

* Preserve Git Graph selection and keep row content visible

Refresh and token recovery retain loaded depth and selection in one
accumulating operation. Keep the published view until it settles, and
only fall back to the first commit after history is exhausted.

Prioritize current and open-workspace refs, reserve their markers, clip
wide graphs and retain filenames when long paths need truncation.

* Bound Git Graph refresh and allow graph column resizing

Restore the loaded depth without searching for vanished selections, retain the published result on retrieval errors, and keep newer selections visible. Allow the bounded graph column to expand to every lane through the existing resize mechanism.

* Retain Git Graph history for errors without a message

Detect failed retrieval independently of its message and cover an empty-message rejection in the existing partial-failure regression.

* Retain Git Graph widths and preserve shifted selections

Separate committed and live resize widths, retaining the chosen width for the graph tab lifetime. Allow one bounded extra history page for selections shifted by new commits, and give the resize separator a translated label.

* Preserve nullable Git Graph owner fallback

* Fix Git Graph layout imports after the RPC method move

* Route the Git Graph owner connection through the source-control connection helper

* Keep the Git Graph button idle in hidden Source Control sections

* Re-probe Git Graph support when the owner's runtime status changes

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>
2026-11-06 19:59:47 -08:00
Brennan Bensonandlydiassssz 548ba48c32 Upload images before publishing GitHub drafts (#38928)
* Upload GitHub images when pasted or dropped

Keep image bytes out of issue and review bodies by uploading from the owning composer and inserting hosted attachment URLs.

Co-authored-by: lydiassssz <60514233+lydiassssz@users.noreply.github.com>

* Preserve GitHub image intake across editor and thread states

* Keep image placeholder boundaries and ordinary HTML paste intact

* Match the native replace overload in the image projection fixture

* Use typed element queries in the image intake fixture

* Narrow textarea elements at the fixture boundary

* Show failed GitHub draft images as filename links

* Keep GitHub draft attachment links current across updates

* Supply the repository address in the attachment preview fixture

---------

Co-authored-by: lydiassssz <60514233+lydiassssz@users.noreply.github.com>
2026-11-06 16:03:20 -08:00
Neil 4f1124d03d fix(hooks): ask before running a committed .orca/issue-command (#37931) 2026-11-06 02:22:12 -08:00
Brennan Benson 3659c0b787 Bound the lifetime of claimed worktree preparations (#38773)
* Keep a lifetime owner for claimed worktree preparation

* Record preparation ownership loss before retirement

* Type the preparation lock-write fixture without an assertion

* Revoke preparation cleanup when ownership changes
2026-11-06 02:15:14 -08:00
OrcaWinandOrcaWin a4cad3766b test: remove 1296 low-value mock and projection tests (#38837)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-05 21:39:35 -08:00
OrcaWinandOrcaWin 62eab0c434 test: remove 1148 low-value IPC and filesystem tests (#38817)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-05 20:45:38 -08:00
Brennan Benson b53db37643 Refuse unsafe branch switches and share one check across phone and desktop (#38744)
* fix(git): refuse unsafe branch switches in an existing workspace

The phone's Switch branch ran `git checkout` with no checks: uncommitted
files moved to the other branch, and a switch could land under a working
agent or mid-rebase. One host check now covers every client: it refuses,
with a plain reason, when files are uncommitted, a merge/rebase/
cherry-pick/revert is in progress, HEAD is detached or unborn, another
git action is running, or an agent in the checkout is working or waiting
for approval. Checks and the checkout run under a per-checkout lock.

After a switch the host clears the old branch's review links and push
target and tells every client, so a phone-only host stays correct, and
records that the user chose the branch so first-work naming never
renames it. The open Commits list follows the new branch.

* fix(git): review round 1 repairs for the guarded branch switch

- check out through the provider so the user's switch keeps the interactive git queue
- a landed switch that Windows left files behind on now tells the user instead of reporting success
- never let a Windows yes/no prompt hold the switch lock
- refuse submodule edits that submodule ignore config hides from status
- record the switch on the target host's metadata row and never fail a landed switch on bookkeeping
- read workspace paths from their ids instead of scanning the catalog on every switch
- admit agent rows like the sidebar roster (listed tab, or a live terminal by pane, tab or handle)
- move the host-side switch hooks into their own module

* test: type the new switch test fakes instead of casting them

* fix(git): second repair round for the guarded branch switch

- report files Windows left behind from git's own unlink warnings, not a status re-read, so
  ordinary branch differences and submodule commit changes are never called failures
- the phone refreshes its branch and files after a switch that landed with a warning
- refuse only edits inside a submodule its ignore config hides, never a commit mismatch alone,
  reading status without optional locks in the interactive queue
- read the agent process probe when a switch runs, not while the runtime is constructed
- check the agent's checkout path before terminal liveness and build the tab list once per switch
- the runtime wiring test no longer reaches real git

* fix(git): scope the switch's agent check to the checkout and keep landed-switch outcomes honest

- find candidate agents by checkout path first; build terminal liveness once, only from this
  checkout's terminals and its workspaces' saved tabs; probe candidates together and re-read
  the snapshot once; no work for unrelated workspaces (contract test at N and 10N)
- a checkout that fails after HEAD moved is recorded as landed; files left behind are named only
  when git reports it could not replace them, otherwise git's own error is shown
- parse git's unlink warnings for paths with apostrophes
- the phone keeps the refusal or warning visible while it reloads the branch
- cover a submodule that is only at another commit

* fix(git): name git's own error when a switch lands after a failing hook; use the shared unlink parser

* fix(git): keep the switch's agent check flat for unrelated folder workspaces

- read folder workspace directories once per switch instead of a linear search per row and terminal
- re-read each candidate's current status by pane key instead of rebuilding the whole snapshot
- skip the hidden-submodule status pass in repos without submodules
- the cost contract covers folder workspaces, many in-checkout agents and PTY passes
- a real-git test covers a switch that lands before a failing post-checkout hook

* fix(git): never quote git's progress line as a landed switch's error; fixed clock in the cost test

* fix(git): decide the hidden-submodule check from the index, not a visible .gitmodules

* perf(git): read only index modes for the submodule shortcut so large repos stay under the output cap
2026-11-05 20:16:50 -08:00