* Fix fork PR/MR worktree creation race via durable review-head refs
When creating a fork PR/MR worktree, concurrent `git fetch origin` operations
clobber the shared FETCH_HEAD, causing the wrong commit to be checked out.
Fetch PR/MR heads into dedicated per-review refs (`refs/orca/pull/<N>`,
`refs/orca/merge-requests/<N>`) that persist and isolate each head from other
fetches. Gracefully keep the compare-base when the fetch fails but the local
ref already exists, avoiding silent fallback to the wrong branch on transient
network errors.
* Bound PR/MR head fetches with 60s timeout
Prevent PR/MR creation from hanging when a remote is stalled or
unreachable. Both GitHub and GitLab head fetches now enforce a
60-second timeout, matching the bound used in the create-path
fetch. Durable refs (refs/orca/pull/*, refs/orca/merge-requests/*)
decouple the ref from FETCH_HEAD, preserving legacy client semantics.
* test: align CI expectations with main PowerShell/sparse regressions
PR checks merge into main, which recently changed PowerShell launch args
(cwd restore after profiles) and sparse-checkout detection (require
core.sparseCheckout). Derive PowerShell spawn args from the production
resolver, mock the sparse config flag, reset shared worktree list scan
cache between tests, and stop requiring floating polls to avoid getRepos
hydration.
* Address review follow-ups on durable review-head refs
- Unify PR review-head remote selection: local and SSH GitHub paths share
resolveGitHubReviewHeadRemote, which prefers the remote mapping to the
hosting GitHub project (upstream before origin, matching work-item/API
candidate order) so contributor clones fetch refs/pull from the repo
that actually hosts the PR.
- Soft-keep durable review heads: when the PR/MR head fetch fails but
refs/orca/pull/<N> / refs/orca/merge-requests/<iid> still resolves,
keep the pinned SHA (warn) instead of failing resolve, mirroring the
compare-base fallback. Extracted shared compare-base soft-keep into
compare-base-ref-fetch.ts.
- Extract fetchGitLabMergeRequestHeadRef (local + SSH) parallel to the
GitHub helper; bound its local fetch with the shared 60s timeout.
- Share relay-style fetch validation (positive safe-integer id, remote
not starting with "-") between relay and local helpers via
review-head-tracking-ref.ts; move REVIEW_HEAD_FETCH_TIMEOUT_MS there.
- Drop the githubPullRequestHeadLocalRef re-export; resolve head SHAs via
rev-parse --verify <ref>^{commit}.
- Add GitLab anti-FETCH_HEAD regression test plus durable-head soft-keep
and remote-selection unit tests.
Co-authored-by: Orca <help@stably.ai>
* test: supply live getRepos for terminal-retirement hydrates
Main's headless tab hydrate (#9343) skips worktree keys whose repo is not
in getRepos. Retirement tests that rebuild mobile tabs from a persisted
session now advertise the fixture repo as live so PR Checks merge stays green.
* fix(editor): extract RichMarkdownEditor props to stay under max-lines
Main's SSH external-image wiring (#10323) pushed RichMarkdownEditor.tsx over
the 400-line tsx budget, failing PR Checks lint on every merge into main.
Move the props type into a sibling module so the component stays under the
limit without disabling max-lines.
* Make durable review-head refs remote-identity scoped
Embed remote name + URL hash into refs/orca/pull|merge-requests refs to prevent soft-keep from serving wrong project's PR/MR when FETCH_HEAD is clobbered by concurrent fetch. Fetch functions now return the written ref path (writer-authoritative) so callers rev-parse exactly what was fetched, not re-derive identity. Soft-keep only applies to transient errors (timeout, network); fails hard on missing refs, auth failures, and stale relay. Relay returns localRef so client avoids re-hashing (URL normalization can disagree).
---------
Co-authored-by: Orca <help@stably.ai>
Collapse multi-line explanatory comment blocks into single-line "why" statements
per AGENTS.md ("Document the Why, Briefly"): drop restatements of the code and
mechanism narration; keep the non-obvious reason, external refs, and directives.
Comments-only — verified no code changed via a Babel/esbuild comment-strip
token-equality gate against origin/main; typecheck and oxlint clean.
Area: shared, cli, relay, preload. 26 files changed, 1039 insertions(+), 3300 deletions(-).
Co-authored-by: Orca <help@stably.ai>
* fix(runtime): retain watcher and PTY teardown ownership
* fix(runtime): restore watchers after interrupted cleanup
* fix(runtime): prevent stale watcher revival
* test(runtime): cover watcher shutdown ownership
* test(daemon): model physical PTY exit
* fix(daemon): keep shutdown terminating when disposal cannot prove exit
A rejecting host.dispose() (unreapable child past its exit deadline) left
the shutdown RPC without its process.nextTick(shutdown) and skipped socket
cleanup in shutdown(), stranding the daemon as an unreachable orphan after
the stale-daemon replacement flow unlinks its socket. Log and continue:
daemon exit reparents the child to init instead of blocking on it.
* fix(runtime): keep local watching alive after an idle-kill deadline miss
An idle child that outlived the exit deadline set shutdownRequested on the
shared desktop supervisor, which has no retire-and-replace path — every
later subscribe rejected supervisor_disposed and the roots were cached
unwatchable, silently ending local file watching for the session. The idle
path owns zero records, so there is no double-watch hazard; the zombie
keeps its capacity reservation until physical exit and the next subscribe
gets a fresh child.
* fix(renderer): resync replayed paired-web file watches
Transparent replay removed the implicit resync the old close-and-rebuild
path provided: a replayed files.watch only reports changes from its own
native setup, so changes during the reconnect gap were silently lost.
Deliver a conservative overflow to consumers once the replayed watch is
ready, matching the overflow-after-interruption contract everywhere else.
* fix(runtime): address teardown review findings
* fix(runtime): retry watches after teardown deadlines
* Fix PTY descendant leaks on forced teardown
* Fix jitter-sensitive terminal lifecycle test
* Improve workspace cleanup list
Co-authored-by: Orca <help@stably.ai>
* Address workspace cleanup review feedback
Co-authored-by: Orca <help@stably.ai>
* Fix workspace cleanup perf findings
Co-authored-by: Orca <help@stably.ai>
* Avoid stale cleanup progress cache
Co-authored-by: Orca <help@stably.ai>
* Complete workspace cleanup perf fixes
Co-authored-by: Orca <help@stably.ai>
* Fix worktree list option forwarding
Co-authored-by: Orca <help@stably.ai>
* Address workspace cleanup review nits
Co-authored-by: Orca <help@stably.ai>
* Fix workspace cleanup removal review findings
- Fail a queued removal that now needs a force the user never approved
(confirm-time approvedCandidates snapshot compared in preflight)
- Reword the 120s removal timeout to say removal continues in background
- Wire suppressPreservedBranchToast into cleanup removals
- Stop statting a repo after the first activity metadata timeout
- Document the WSL 9P best-effort stat gap; drop unused locale key
Co-authored-by: Orca <help@stably.ai>
* Split workspace-cleanup slice test to satisfy max-lines
Rebasing onto latest main pushed the combined store-slice test over the
800-line cap. Extract shared fixtures into a test harness and split the
suite into scan-progress and removal-preflight files instead of adding a
forbidden max-lines suppression.
---------
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules
Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day
minimum-release-age supply-chain guard; nothing here needs it). The
bump is a no-op on the existing config.
Enable 3 error rules (backlog autofixed to zero in this commit) and
4 warn rules (surface signal without gating CI):
error (autofixed, behavior-preserving):
- unicorn/prefer-node-protocol (~1531 sites: bare builtin -> node:)
- typescript/no-import-type-side-effects (~36: all-inline-type -> import type)
- unicorn/no-array-reverse (19: copy-then-reverse -> toReversed)
warn (real signal, current fires are test-only/correct):
- unicorn/no-array-fill-with-reference-type (aliasing footgun guard)
- typescript/no-unsafe-function-type (bans bare Function type)
- unicorn/prefer-array-flat-map (map().flat() -> flatMap())
- unicorn/prefer-regexp-test (.match() in bool ctx -> .test())
mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix
ran from root and covered mobile/ too.
Verification (all green): oxlint 0 errors (root+mobile+aux configs),
oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed,
builds (electron-vite + web + cli) succeed. node: rewrites confirmed to
skip embedded SSH/CLI string payloads (AST-only); all toReversed sites
verified to operate on fresh copies or write-once locals.
* chore(lint): bump mobile oxlint to 1.71 so inherited rules parse
mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which
lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since
mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile &&
oxlint' failed to parse the new rule. Bump mobile to match root (1.71).
Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit
pass, vitest 978 passed / 0 failed.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* feat(source-control): show submodule diffs with lazy expansion
Dirty submodules now expand inline in Source Control to reveal their
inner changes, with file-level diffs that are read-only from the parent
worktree. Inner status is fetched lazily only when a submodule is
expanded, so status polling never recurses into (possibly nested)
submodules. Adds a submodule-status path across local and SSH runtimes
and git providers.
* feat(source-control): add compare-against-current-branch setting
Adds a global setting (default off) that defaults the Source Control
compare base to the current branch's upstream so the panel prioritizes
local changes instead of the full delta versus the repository default
branch. When the branch has no upstream, the compare view falls back to
working-tree-only. This affects only the compare/diff view; the Pull
Request and rebase merge target are unchanged.
* refactor(source-control): extract submodule status hook and entry-action gates
Moves the lazy submodule-expansion state into a useSourceControlSubmoduleStatus
hook and centralizes per-row stage/unstage/discard eligibility into
source-control-entry-actions, shrinking SourceControl.tsx and keeping the
read-only submodule rules consistent across the row UI, bulk actions, and tests.
The hook adds a generation guard so a slow submodule-status response from a
previous worktree (common over SSH) can't write stale status into the current
panel. On the relay side, configured submodule paths are read through a
short-TTL per-instance cache so a burst of diff clicks does not re-read
.gitmodules over the SSH link. Adds tests for the new modules.
* fix(source-control): address submodule/compare review feedback
- Degrade git.submoduleStatus to an actionable reconnect hint when an older
SSH relay lacks the RPC, mirroring clone()/worktreeIsClean fallbacks.
- Keep the branch-compare summary while upstream status is still loading so
it no longer flickers when switching worktrees with prefer-upstream on.
- Mark the compare-base switch as type="button" to avoid form submission.
- Add diff base / source control keywords to the Git settings search catalog.
- Assert the compare-base toggle's own switch state and updateSettings call.
* fix(source-control): address second-round submodule/compare review feedback
- Route submodule inner diffs through resolveSubmoduleWorktreePath so a
crafted .gitmodules path can't escape the selected worktree
- Clear statusReadsInFlight alongside the diff dedupe on git mutations so a
post-mutation getStatus() can't join a stale in-flight read
- Clear the SSH diff dedupe in getSubmoduleStatus to mirror getStatus
- Derive list-view selection from the submodule-injected rows so expanded
submodule children are selectable
- Refresh commit history when the upstream compare base changes
* Support staged submodule expansion and refine default compare base
- Support expanding and diffing staged submodule changes (HEAD vs index) independently of unstaged changes (index vs worktree).
- Track submodule expansion states using a compound key of area and path to prevent conflicts between staged and unstaged listings.
- Update the compare-against-upstream setting to a segmented control for the "Default Compare Base" policy.
- Fall back to the repository default branch when comparing a branch with no upstream, preventing comparison views from unexpectedly disappearing.
* Fix submodule staging behavior, WSL caching, and double-click toggles
- Namespace submodule path cache per WSL distro to prevent cross-distro
collisions.
- Preserve the staged area of child entries when expanding unstaged
submodules so staged inner changes do not open empty diffs.
- Prefix oldPath with the submodule path for renamed inner entries.
- Ignore click events where detail > 1 to prevent double-clicks from
instantly collapsing newly expanded submodules.
* Secure submodule path resolution and prevent stale status updates
* Extract and centralize submodule path validation into a new
`resolveSubmoduleWorktreePath` helper to prevent path traversal
exploits when resolving paths from untrusted `.gitmodules` files.
* Invalidate submodule expansion state and increment the query
generation whenever the active runtime environment or connection
route changes, preventing out-of-order responses from writing
stale data.
* Set git identity via CLI config options in test commits
- Extract test email and name into constants.
- Use `-c` config flags to pass user identity to `git commit` dynamically.
- This ensures commits succeed in submodule checkouts or CI environments
where a local or global identity is not configured.
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* Limit large git diff payloads in main process before IPC transfer
Move the large diff rendering limit check to a shared module so that
the main process can evaluate diff sizes before transferring them. If
a diff exceeds the limits, its text content is dropped prior to IPC
serialization, and only the limit metadata is sent. This prevents the
application from freezing or crashing when loading massive diff files.
* Gracefully handle and prune oversized files in diff viewer
Prevent UI freezes and out-of-memory errors when viewing or editing
extremely large diffs or files. Working-tree files above 10MB and git
buffer overflows are treated as binary. Text diffs exceeding safe
rendering limits have their contents pruned before IPC transport, and
the UI is updated to show fallback states and disable invalid saves.
* Document save action check for large diffs and fix test import
Explain why saveContentAvailable is required for oversized diffs, as
stripped text bodies before IPC prevent complete saves. Also update the
large-diff-render-limit import in E2E tests to use the shared path.
* Restore the outlined server card for host headers
Feedback: the bordered card with the server glyph made it clearer that
a host section is a separate machine, not just another group. Bring
that back while keeping the recent quieting: no status dot when
healthy (marks only for connecting/blocked/error/disconnected), no
'This computer' detail on the local host, and collapse/menu/count
behavior unchanged.
Co-authored-by: Orca <help@stably.ai>
* Anchor host badge to its label, indent rows under host cards
Sidebar polish from review:
- The count badge sat in dead space between the label and the
hover-only chevron/menu; it now hugs the label like repo headers
- Rows under a host card get a left inset so projects and workspaces
visibly belong to the machine above them
- A host whose only visible row is a collapsed repo group counted 0
while the group badge said 9; host counts now fall back to header
counts for groups contributing no visible items
Co-authored-by: Orca <help@stably.ai>
* Two-tier sticky headers: pinned host card above pinned group header
When scrolling inside a host section, the host card now stays pinned at
the top (z-30) while project/status group headers hand off beneath it
(z-20, offset by the pinned card height). The host is the outer
hierarchy level, so it is the most persistent context — previously the
first repo header replaced it, losing 'which machine am I on' exactly
when it mattered. The pinned card keeps its collapse/menu/warning
affordances. Handoff rules: the next host card pushes the previous one
out at the viewport top; a group pins only once it reaches the slot
beneath the host card, and a previous host's group can never pin under
the next host. Without host sections the logic degrades to the original
single-tier behavior.
Co-authored-by: Orca <help@stably.ai>
* Revert host-section row indent
The two-tier sticky host card now provides continuous 'inside this
machine' context at any scroll depth, making the static indent
redundant — and it cost 12px of sidebar width on every row while
making multi-host layouts misalign with single-host ones. Host cards
bracketing their sections plus the pinned header carry the ownership
signal on their own.
Co-authored-by: Orca <help@stably.ai>
* Checkpoint multi-host sidebar and project-first notes
Co-authored-by: Orca <help@stably.ai>
* Add project-first compatibility persistence
Co-authored-by: Orca <help@stably.ai>
* Expose project host setup APIs
Co-authored-by: Orca <help@stably.ai>
* Group sidebar rows by project setup
Co-authored-by: Orca <help@stably.ai>
* Document project-first host model discussion
Co-authored-by: Orca <help@stably.ai>
* Resolve workspace creation through project host setups
Co-authored-by: Orca <help@stably.ai>
* Stamp workspace ownership with project host setup
Co-authored-by: Orca <help@stably.ai>
* Add project host setup existing folder API
Co-authored-by: Orca <help@stably.ai>
* Summarize project-first host model discussion
Co-authored-by: Orca <help@stably.ai>
* Add project host setup CLI commands
Co-authored-by: Orca <help@stably.ai>
* Allow CLI worktree creation by project host setup
Co-authored-by: Orca <help@stably.ai>
* Add workspace host setup picker
Co-authored-by: Orca <help@stably.ai>
* Add project host setup settings summary
Co-authored-by: Orca <help@stably.ai>
* Make project host setup settings navigable
Co-authored-by: Orca <help@stably.ai>
* Stabilize project host setup settings selector
Co-authored-by: Orca <help@stably.ai>
* Add project host existing-folder setup form
Co-authored-by: Orca <help@stably.ai>
* Update project host model implementation status
Co-authored-by: Orca <help@stably.ai>
* Keep projects outermost in default sidebar view
Co-authored-by: Orca <help@stably.ai>
* Update project-first sidebar status
Co-authored-by: Orca <help@stably.ai>
* Show host context in project sidebar groups
Co-authored-by: Orca <help@stably.ai>
* Show unavailable hosts in workspace run target
Co-authored-by: Orca <help@stably.ai>
* Import missing project host from composer
Co-authored-by: Orca <help@stably.ai>
* Clone project host setup from composer
Co-authored-by: Orca <help@stably.ai>
* Persist project host setup method
Co-authored-by: Orca <help@stably.ai>
* Clone project hosts over SSH
Co-authored-by: Orca <help@stably.ai>
* Improve SSH clone cancellation cleanup
Co-authored-by: Orca <help@stably.ai>
* Backfill workspace project host ownership
Co-authored-by: Orca <help@stably.ai>
* Gate project host setup runtime capability
Co-authored-by: Orca <help@stably.ai>
* Preserve independent project host setups
Co-authored-by: Orca <help@stably.ai>
* Add project host setup update API
Co-authored-by: Orca <help@stably.ai>
* Add project host setup delete API
Co-authored-by: Orca <help@stably.ai>
* Add project host setup create API
Co-authored-by: Orca <help@stably.ai>
* Expose project host setup lifecycle in renderer store
Co-authored-by: Orca <help@stably.ai>
* Handle independent project host setups in settings
Co-authored-by: Orca <help@stably.ai>
* Add pending host setup action in project settings
Co-authored-by: Orca <help@stably.ai>
* Show pending project host setup status in composer
Co-authored-by: Orca <help@stably.ai>
* Report pending setup state in workspace target resolution
Co-authored-by: Orca <help@stably.ai>
* Use shared host registry for project setup choices
Co-authored-by: Orca <help@stably.ai>
* Add settings clone flow for project host setups
Co-authored-by: Orca <help@stably.ai>
* Gate unavailable project host setup options
Co-authored-by: Orca <help@stably.ai>
* Gate unavailable project setup hosts in settings
Co-authored-by: Orca <help@stably.ai>
* Stream SSH clone progress to renderer
Co-authored-by: Orca <help@stably.ai>
* Update project host model status notes
Co-authored-by: Orca <help@stably.ai>
* Add CLI project host setup clone command
Co-authored-by: Orca <help@stably.ai>
* Make add project host aware
Co-authored-by: Orca <help@stably.ai>
* Complete project host setup validation
Co-authored-by: Orca <help@stably.ai>
* Recover floating workspace terminal WebGL atlas on reopen (#5069)
Co-authored-by: Orca <help@stably.ai>
* Fix stale terminal daemon spawn health (#5064)
Co-authored-by: Orca <help@stably.ai>
* Suspend floating workspace terminal WebGL while the panel is closed (#5073)
Co-authored-by: Orca <help@stably.ai>
* Fix source control branch compare base (#5074)
Co-authored-by: Orca <help@stably.ai>
* Fix workspace-creation tour panel clipped by the Create Worktree dialog (#5078)
* Fix workspace-creation tour panel clipped by the composer dialog
The tour panel portals into dialog/sheet content that clips overflow, but
its position was clamped against the window viewport. With the Project
field spanning nearly the dialog's full width, the panel landed past the
dialog's right edge and overflow-hidden cut it down to a sliver. Clamp
hosted panels within the host's bounds instead, so the panel flips below
the target and stays fully visible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add JSDoc docstrings to satisfy CodeRabbit docstring coverage check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Test hosted contextual tour overlay positioning
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
* release: v1.4.56
* Handle buffer overflows gracefully and truncate diffs fairly (#5083)
- Gracefully fall back to file-name summaries when staged diffs exceed
node/ssh execution maxBuffer limits, preventing generation failures.
- Split oversized diffs by file and allocate budget via water-filling,
ensuring single huge files do not starve smaller human changes.
- Clip truncated diff sections on line boundaries to avoid half-lines.
* Wrap AI generation controls with tooltips and clean i18n dependencies (#5087)
- Wrap the AI generation button in a tooltip so users can see the
disabled reason or the action description on hover.
- Add unit tests verifying tooltip triggers and aria-label safety.
- Simplify memo dependencies in settings metadata and worktree palette
by using 'useTranslation()' to handle language-change rerenders
directly without needing 'i18n.language'.
* fix: address review findings (#5088)
* Fix localization in repository hooks and base ref suggestion toast (#5089)
* Fix localization in base ref toast and custom hook description
- Localize the "commit"/"commits" plural nouns in the base ref toast.
- Translate missing suggestion toast strings for JA, KO, and ZH locales.
- Pass `{{artifact_url}}` as a literal template variable to translate
calls to prevent i18next from treating it as a dynamic placeholder.
* Fix localization reactivity in RepositoryHooksSection
Move static variables containing translation calls into helper functions
and subscribe to translation updates using useTranslation. This ensures
that localized options, descriptions, and error messages refresh
dynamically when the user changes the UI language.
* Fix task page labels after language changes (#5086)
Co-authored-by: Orca <help@stably.ai>
* release: v1.4.57
* Fix automation tabs showing a shell instead of the live agent (#5099)
* Fix automation tabs showing a shell instead of the live agent
Opening a background automation's terminal tab showed a bare shell while
the agent (Claude) kept running headless — the sidebar updated but the
pane was attached to the wrong PTY.
On first mount the restored ptyId equals the tab ptyId, and
isSessionOwnedByWorktree() returns true for it, so connectPanePty routed
the still-live eagerly-spawned PTY into the daemon-reattach branch
(transport.connect({ sessionId })), which spawns a fresh shell and
orphans the live agent PTY instead of adopting it via attach()+replay.
Part A: gate the deferred reattach on the absence of a live eager buffer.
A live eager buffer means the PTY is a still-running local session to
adopt (attach + replay), not a daemon session to re-connect. Daemon
reattach and remote PTYs are unaffected (gated on the eager buffer).
Part B: publish never-mounted background automation tabs into the runtime
graph (gated on a live eager buffer) so the live agent PTY binds to its
real tab instead of surfacing as an orphan `pty:<id>` terminal — fixing
`orca terminal list`, the CLI, and automation session-reuse.
Adds a characterization test (fails on the old code, passes now) and a
runtime-graph publish test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Harden eager PTY tab adoption
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
* Fix i18n label spacing in menus and settings (#5108)
* fix i18n label spacing
* Fix localized account runtime labels
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
* Improve localization catalog sync workflow (#5110)
Co-authored-by: Orca <help@stably.ai>
* Add Warp terminal theme import (#4714)
Co-authored-by: Orca <help@stably.ai>
* release: v1.4.58
* Tidy README badge layout
* Handle integration credential decrypt failures (#4683)
Co-authored-by: Orca <help@stably.ai>
* Fix git repo telemetry for repo adds (#5121)
Co-authored-by: Orca <help@stably.ai>
* Add feature interaction usage bucket telemetry (#5119)
Co-authored-by: Orca <help@stably.ai>
* Reset WebGL glyph atlases globally to stop cross-terminal glyph corruption (#5122)
Co-authored-by: Orca <help@stably.ai>
* perf(windows): fix 60s startup ACL walk and OpenCode streaming freeze, with benchmark harnesses (#5124)
* release: v1.4.59-rc.0
* Fix packaged shell PATH order (#5125)
Co-authored-by: Orca <help@stably.ai>
* Add Floating Workspace contextual tour (#5062)
* Add floating workspace contextual tour
Co-authored-by: Orca <help@stably.ai>
* Clarify floating workspace tour intro copy
Co-authored-by: Orca <help@stably.ai>
* Differentiate floating workspace tour steps instead of repeating examples
Co-authored-by: Orca <help@stably.ai>
* Lead floating workspace tour with the user benefit
Co-authored-by: Orca <help@stably.ai>
* Pitch floating workspace tour around cross-repo agents
Co-authored-by: Orca <help@stably.ai>
* Refine floating workspace tour step 1 copy
Co-authored-by: Orca <help@stably.ai>
* Anchor floating workspace tour step 2 on the minimize control
Co-authored-by: Orca <help@stably.ai>
* Restore floating workspace tour step 2
Co-authored-by: Orca <help@stably.ai>
* Anchor floating workspace tour steps on New Terminal and New Markdown Note
Co-authored-by: Orca <help@stably.ai>
* Retitle floating workspace tour step 2 as scratchpad
Co-authored-by: Orca <help@stably.ai>
* Add why-comments for tour selector fallback and placement flipping
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Fix source control compare base ambiguity (#5127)
Co-authored-by: Orca <help@stably.ai>
* release: v1.4.59-rc.1 [rc-slot:2026-06-10-15]
* release: v1.4.59
* Default-driven create-project flow: name-first form with sensible defaults (#5115)
Co-authored-by: Orca <help@stably.ai>
* Redesign Connect integrations (#4531)
Co-authored-by: Orca <help@stably.ai>
* Expose E2E store via build mode
* File search match counts (#5085)
* Add matchCount to SearchFileResult for accurate per-file hit counts
Co-authored-by: Orca <help@stably.ai>
* Add file search match count design
* rm design doc
---------
Co-authored-by: Orca <help@stably.ai>
* fix: address review findings (#5139)
* perf(windows): avoid blocking daemon pid checks (#5137)
* release: v1.4.60-rc.0
* release: v1.4.60
* Preserve core workflow terms in English and apply CJK spacing (#5141)
* Preserve core workflow and product terms in English across locales
Update translation policy to prevent localization of key terms such as
"Agent", "Commit", "Markdown", and "Terminal". This ensures consistent
jargon and product branding.
Introduce CJK-Latin term spacing to keep these Latin terms legible
when combined with CJK text, while adjusting Korean particle spacing.
Also add overrides to prevent network proxy settings from being
mistranslated as "Agent".
* Preserve repo terminology in English and localize source control labels
Treat "repo" and "repos" (and their capitalized forms) as brand terms
that should remain in English/Latin across CJK and Spanish locales.
Update translation files and policies to replace translated words like
"repositorio" or "リポジトリ" with "repo"/"repos", and fix an issue where
latin brand terms could be incorrectly matched as substrings in larger
words during cleanup.
Additionally, externalize and localize the "Staged Changes", "Changes",
and "Untracked Files" section labels in the source control sidebar.
* UX (#5143)
* UX/copy tweaks (#5142)
* UX/copy tweaks
* UX/copy tweaks
* Fix missed star UI translations (#5148)
* fix: make windows ssh relay deploy survive session teardown (#5136)
* Add option to remove child projects when deleting repo groups (#4702)
Co-authored-by: Orca <help@stably.ai>
* fix: remove checks panel response badge (#5147)
* Add read-only `orca linear` CLI with trusted launch-prompt pointer (V1) (#5126)
Co-authored-by: Orca <help@stably.ai>
* Add AI Vault session history
## Summary
- add AI Vault session scanning and resume command construction
- add the Agents sidebar panel with filtering, grouping, copy/open actions, and local resume launch
- support dragging saved sessions onto terminal split panes
## Validation
- pnpm run lint
- pnpm run typecheck
- pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/register-core-handlers.test.ts src/main/ai-vault/session-scanner.test.ts src/renderer/src/components/right-sidebar/ai-vault-session-filters.test.ts src/renderer/src/lib/ai-vault-session-drag.test.ts src/renderer/src/lib/launch-ai-vault-session.test.ts
* Default agent launches to yolo permissions mode (#5145)
* Default agent launches to yolo mode
* test: update launch default validations
* Fix Claude usage refresh error copy (#5155)
Co-authored-by: Orca <help@stably.ai>
* Move workspace board to sidebar bottom toolbar (#5146)
Co-authored-by: Orca <help@stably.ai>
* Rebuild contextual tour positioning on floating-ui; fix hosted dialog placement and arrow seam (#5154)
Co-authored-by: Orca <help@stably.ai>
* Fix missing spaces in cross-repo switch dialog (#5158)
* Fix Ctrl+Tab switcher selection on release (#5116)
* Fix additional i18n spacing regressions from #4995 (#5159)
* Refine add project selection styling (#5160)
Co-authored-by: Orca <help@stably.ai>
* improve chinese localization (#5162)
* Fix floating workspace needing two clicks after app switch (macOS) (#5128)
* Autofocus feedback textarea when Send Feedback dialog opens (#5164)
* fix: address pr-bug-scan validated finding from #4683 (#5151)
Isolated CredentialDecryptionError per-item in Linear getClients (client.ts:518) and Jira getClients (client.ts:373) on the 'all' selection so one bad credential no longer collapses healthy workspaces
Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
* fix: enable claude agent teams by default (#5168)
* Refresh Jira and Linear status after credential errors (#5169)
* fix: address pr-bug-scan validated finding from #4683
Isolated CredentialDecryptionError per-item in Linear getClients (client.ts:518) and Jira getClients (client.ts:373) on the 'all' selection so one bad credential no longer collapses healthy workspaces
* Refresh Jira and Linear status to clear stale credential errors
Ensure stale credential decryption errors are cleared from the store
status once a successful API read completes. By updating the check in
shouldRefreshStatusAfterRead to trigger when a credentialError is
currently set, successful issue or list fetches will trigger a status
check and remove stale error flags.
---------
Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
* Hide internal context from AI Vault titles (#5175)
* Fix detached HEAD publish actions (#5173)
* Keep freshly split terminal pane mounted if newborn PTY exits early (#5171)
Prevent a newly split pane from collapsing immediately if its PTY exits
during initial setup before any output is received or input is sent.
This ensures a failed startup session remains visible to the user.
* Route task PR queries by upstream source (#5176)
* Route task PR queries by upstream source
Implements the routing described in docs/tasks-pr-upstream-source.md so task PR and issue queries stay scoped to the selected source.
* rm design doc
* Prevent stale PR refreshes from restoring unlinked review state (#5180)
- Pass `worktreeId` to `fetchPRForBranch` to track active worktree context
- Ignore inflight or queued PR fetches if the worktree has been unlinked
- Include linked PR/MR metadata in the checks panel snapshot key to trigger updates immediately on link/unlink events
* Fix Claude agents management status detection (#5179)
Co-authored-by: Orca <help@stably.ai>
* fix: address review findings (#5177)
* Allow resolving selected review comments with AI (#5184)
* Allow resolving selected PR/MR review comments with AI
Users can now select specific unresolved review comments or threads in
the Checks panel sidebar, queue them, and trigger an AI agent to address
them, marking resolved threads on the host upon agent launch.
- Adds checkboxes and action/send buttons to select and queue comments.
- Builds a structured, robust prompt with sanitized comment metadata.
- Optimistically marks threads resolved on launch with rollback on error.
- Supports both GitHub PRs and GitLab MRs.
* Consolidate PR comment selection state and eliminate effects
Combine independent selection states and context-tracking into a single
state object. Derive active selection data and prune ineligible comments
during render using useMemo instead of relying on asynchronous
useEffect synchronization hooks.
* Improve source control action dialog layout and recipe saving UX (#5153)
* Improve source control agent action dialog layout and recipe UX
- Constrain dialog and scroll area heights to prevent viewport overflow.
- Add variable chips to easily insert the base prompt with tooltip previews.
- Keep the recipe save controls visible when a recipe is already saved, showing informational status text instead of hiding them.
- Update localized copy across multiple languages and reduce textarea rows.
- Add unit tests for the variable chip preview and save target visibility.
* Fix recipe-saved check in source control action dialog
* Evaluate only the selected save target instead of checking all available targets, as the action only writes to the selected target.
* Update daemon PTY adapter test fake PID to prevent collision with real host OS processes during runtime directory lookups.
* fix: remove unsupported agent launch defaults (#5185)
* Update Chinese and Japanese translations for worktrees and fixes (#5187)
- Correct awkward Chinese translation of "fix" ("使固定") to "修复" and "基本的" to "主工作树" (main worktree).
- Improve Japanese translation of "fix" from physical repair ("修理") to software correction ("修正").
* Embed hosted review creation composer directly in Checks panel (#5140)
* Embed hosted review creation composer directly in the Checks panel
- Replaces the modal pull request/merge request creation dialog with an
inline composer embedded in the empty state of the Checks sidebar.
- Extracts and moves pull request generation state to a dedicated store
slice so AI-generated details are persisted across sidebar unmounts.
* Fix hosted review composer feedback
* Combine file search and file explorer right sidebar tabs (#5182)
Unifies file discovery and tree navigation under a single Explorer domain, simplifying the right sidebar activity bar and reducing tab clutter.
* Replaces the standalone 'search' activity bar tab with a nested 'search' subview inside the File Explorer tab
* Introduces 'rightSidebarExplorerView' ('files' | 'search') state to manage the active subview inside the Explorer
* Adds a search button to the File Explorer toolbar and a back button to the search subview for seamless transition
* Exposes 'showRightSidebarFiles' and 'showRightSidebarSearch' store actions to route and seed search queries/include patterns
* Adapts file explorer keybindings, git status polling, and external workspace watchers to respect the active subview
* Maps legacy persisted search tab state to the new explorer search view for backward compatibility
* release: v1.4.61-rc.1
* Add multi-repo folder workspaces (v1) (#5172)
Co-authored-by: Orca <help@stably.ai>
* release: v1.4.61-rc.2
* Hide unavailable project hosts in worktree composer
Co-authored-by: Orca <help@stably.ai>
* Remove inline project host setup from composer
Co-authored-by: Orca <help@stably.ai>
* Mark imported project host setup methods
Co-authored-by: Orca <help@stably.ai>
* Fix rebase merge fallout
Co-authored-by: Orca <help@stably.ai>
* Disable unavailable Add Project hosts
Co-authored-by: Orca <help@stably.ai>
* Compact Add Project host selector
Co-authored-by: Orca <help@stably.ai>
* Hide redundant SSH target chooser
Co-authored-by: Orca <help@stably.ai>
* Browse SSH clone destinations
Co-authored-by: Orca <help@stably.ai>
* Avoid local clone defaults for SSH hosts
Co-authored-by: Orca <help@stably.ai>
* Polish host-aware Add Project flows
Co-authored-by: Orca <help@stably.ai>
* Polish remote host add project flows
Co-authored-by: Orca <help@stably.ai>
* Remove redundant host kind chips
Co-authored-by: Orca <help@stably.ai>
* Fix remote project setup UX gaps
Co-authored-by: Orca <help@stably.ai>
* Fix multihost workspace composer project identity
Co-authored-by: Orca <help@stably.ai>
* Finish host context merge repair
Co-authored-by: Orca <help@stably.ai>
* Continue host context checklist implementation
Co-authored-by: Orca <help@stably.ai>
* Route Linear and Jira tasks by source context
Co-authored-by: Orca <help@stably.ai>
* Preserve Linear task source context in history
Co-authored-by: Orca <help@stably.ai>
* Scope task retry state by source context
Co-authored-by: Orca <help@stably.ai>
* Route GitHub drawer reads by source context
Co-authored-by: Orca <help@stably.ai>
* Guard GitLab selectors with repo context
Co-authored-by: Orca <help@stably.ai>
* Guard GitHub metadata selectors
Co-authored-by: Orca <help@stably.ai>
* Route GitHub task row actions by source context
Co-authored-by: Orca <help@stably.ai>
* Update GitHub source-context checklist status
Co-authored-by: Orca <help@stably.ai>
* Show host ownership for CLI provider accounts
Co-authored-by: Orca <help@stably.ai>
* Persist GitLab task detail source context
Co-authored-by: Orca <help@stably.ai>
* Show host scope for provider API budgets
Co-authored-by: Orca <help@stably.ai>
* Preserve Jira task source context
Co-authored-by: Orca <help@stably.ai>
* Scope Jira optimistic task patches
Co-authored-by: Orca <help@stably.ai>
* Resolve task PR bases on run host
Co-authored-by: Orca <help@stably.ai>
* Record Jira task workspace usage
Co-authored-by: Orca <help@stably.ai>
* Scope Linear optimistic task patches
Co-authored-by: Orca <help@stably.ai>
* Scope GitHub optimistic task patches
Co-authored-by: Orca <help@stably.ai>
* Clean host copy in onboarding flows
Co-authored-by: Orca <help@stably.ai>
* Preserve automation CLI run context
Co-authored-by: Orca <help@stably.ai>
* Add automation CLI source context selector
Co-authored-by: Orca <help@stably.ai>
* Clarify unavailable task source hosts
Co-authored-by: Orca <help@stably.ai>
* Surface host model runtime capability skew
Co-authored-by: Orca <help@stably.ai>
* Use SSH host copy in reconnect dialog
Co-authored-by: Orca <help@stably.ai>
* Show host context in task source picker
Co-authored-by: Orca <help@stably.ai>
* Mark task source display complete
Co-authored-by: Orca <help@stably.ai>
* Clarify provider account host selection
Co-authored-by: Orca <help@stably.ai>
* Guard task source switching boundary
Co-authored-by: Orca <help@stably.ai>
* Mark task source diagnostics persisted
Co-authored-by: Orca <help@stably.ai>
* Mark base resolution host boundary
Co-authored-by: Orca <help@stably.ai>
* Clarify external automation source states
Co-authored-by: Orca <help@stably.ai>
* Harden project host compatibility projection
Co-authored-by: Orca <help@stably.ai>
* Finish host copy audit
Co-authored-by: Orca <help@stably.ai>
* Add provider host scope controls
Co-authored-by: Orca <help@stably.ai>
* Show task source account labels
Co-authored-by: Orca <help@stably.ai>
* Show automation run context in CLI
Co-authored-by: Orca <help@stably.ai>
* Scope Jira task cache lookups by source
Co-authored-by: Orca <help@stably.ai>
* Seed workspace creation from task source context
Co-authored-by: Orca <help@stably.ai>
* Explain disabled external automation actions
Co-authored-by: Orca <help@stably.ai>
* Surface task source runtime capability gaps
Co-authored-by: Orca <help@stably.ai>
* Persist automation run context from UI saves
Co-authored-by: Orca <help@stably.ai>
* Require workspace run capability for setup hosts
Co-authored-by: Orca <help@stably.ai>
* Disable automation runs for stale host setup
Co-authored-by: Orca <help@stably.ai>
* Route GitHub drawer metadata by source host
Co-authored-by: Orca <help@stably.ai>
* Guard runtime project setup mutations by host model
Co-authored-by: Orca <help@stably.ai>
* Route PR page metadata by repo host
Co-authored-by: Orca <help@stably.ai>
* Route PR mention metadata by repo host
Co-authored-by: Orca <help@stably.ai>
* Route GitHub Project edits by view source
Co-authored-by: Orca <help@stably.ai>
* Clarify runtime automation disabled states
Co-authored-by: Orca <help@stably.ai>
* Guard runtime automation backend dispatch
Co-authored-by: Orca <help@stably.ai>
* Preserve GitLab task source identity
Co-authored-by: Orca <help@stably.ai>
* Remove redundant SSH target row in add project
Co-authored-by: Orca <help@stably.ai>
* Add task source provider availability reasons
Co-authored-by: Orca <help@stably.ai>
* Surface task provider preflight availability
Co-authored-by: Orca <help@stably.ai>
* Record local GitHub task source verification
Co-authored-by: Orca <help@stably.ai>
* Record Linear task source verification
Co-authored-by: Orca <help@stably.ai>
* Show automation source context in details
Co-authored-by: Orca <help@stably.ai>
* Record remote capability negotiation coverage
Co-authored-by: Orca <help@stably.ai>
* Record local add project create verification
Co-authored-by: Orca <help@stably.ai>
* Scope Linear cached task reads by source
Co-authored-by: Orca <help@stably.ai>
* Preserve PR generation host ownership
Co-authored-by: Orca <help@stably.ai>
* Route git operations by owner host
Co-authored-by: Orca <help@stably.ai>
* Route delete warnings by worktree owner
Co-authored-by: Orca <help@stably.ai>
* Route editor drops by worktree owner
Co-authored-by: Orca <help@stably.ai>
* Route agent draft paste by tab owner
Co-authored-by: Orca <help@stably.ai>
* Route file explorer requests by worktree owner
Co-authored-by: Orca <help@stably.ai>
* Document remaining host context gaps
Co-authored-by: Orca <help@stably.ai>
* Check runtime task source provider auth
Co-authored-by: Orca <help@stably.ai>
* Validate automation source availability
Co-authored-by: Orca <help@stably.ai>
* Route remaining UI requests by owner host
Co-authored-by: Orca <help@stably.ai>
* Route quick open file listing by worktree owner
Co-authored-by: Orca <help@stably.ai>
* Route typed GitHub lookups by source host
Co-authored-by: Orca <help@stably.ai>
* Centralize automation run identity fallback
Co-authored-by: Orca <help@stably.ai>
* Surface unsupported task source providers
Co-authored-by: Orca <help@stably.ai>
* Document automation legacy repo compatibility
Co-authored-by: Orca <help@stably.ai>
* Record live host model verification
Co-authored-by: Orca <help@stably.ai>
* Quiet disconnected SSH polling
Co-authored-by: Orca <help@stably.ai>
* Verify task drawer source boundaries
Co-authored-by: Orca <help@stably.ai>
* Verify GitLab repo source selectors
Co-authored-by: Orca <help@stably.ai>
* Route automations through owning host
Co-authored-by: Orca <help@stably.ai>
* Update host context verification checklist
Co-authored-by: Orca <help@stably.ai>
* Run remote automations headlessly in serve mode
Co-authored-by: Orca <help@stably.ai>
* Keep setup guide entry stable during refresh
Co-authored-by: Orca <help@stably.ai>
* Keep setup script prompt stable during host switches
Co-authored-by: Orca <help@stably.ai>
* Deduplicate Tasks project picker sources
Co-authored-by: Orca <help@stably.ai>
* Use project identity for Tasks picker dedupe
Co-authored-by: Orca <help@stably.ai>
* Add Tasks source host switcher
Co-authored-by: Orca <help@stably.ai>
* Refine Tasks source picker disclosure
Co-authored-by: Orca <help@stably.ai>
* Polish Tasks source picker hover
Co-authored-by: Orca <help@stably.ai>
* Open Tasks source menu on hover
Co-authored-by: Orca <help@stably.ai>
* Match Tasks source submenu hover behavior
Co-authored-by: Orca <help@stably.ai>
* Open Tasks source submenu from project row hover
Co-authored-by: Orca <help@stably.ai>
* Group automation project hosts
Co-authored-by: Orca <help@stably.ai>
* Tighten automation project picker density
Co-authored-by: Orca <help@stably.ai>
* Show selected host in Tasks project picker
Co-authored-by: Orca <help@stably.ai>
* Hide host labels for single-host project pickers
Co-authored-by: Orca <help@stably.ai>
* Use saved remote server names in host pickers
Co-authored-by: Orca <help@stably.ai>
* Use standard add project start for remote servers
Co-authored-by: Orca <help@stably.ai>
* Use saved host labels in workspace surfaces
Co-authored-by: Orca <help@stably.ai>
* Route remote browser tabs through runtime hosts
Co-authored-by: Orca <help@stably.ai>
* Keep sidebar project-first across grouping modes
Co-authored-by: Orca <help@stably.ai>
* Polish multi-host remote runtime UX
Co-authored-by: Orca <help@stably.ai>
* Fix CI lint and remove design notes
Co-authored-by: Orca <help@stably.ai>
* Fix CI test failures
Co-authored-by: Orca <help@stably.ai>
* Fix Windows CLI path expectation
Co-authored-by: Orca <help@stably.ai>
* Fix CI renderer test expectations
Co-authored-by: Orca <help@stably.ai>
* Fix remaining verify test failures
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Bryant Ung <bryant.ung@outlook.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Borja <3930245+BorjaLL@users.noreply.github.com>
Co-authored-by: Parker Rex <me@parkerrex.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
Co-authored-by: Trevin Chow <trevin@trevinchow.com>
Co-authored-by: buf0-bot[bot] <252831055+buf0-bot[bot]@users.noreply.github.com>
Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
* Suggest enabling local-main freshness when a new workspace finds it stale
Adds a "Keep Local Main Up to Date" suggestion path: when the setting is
off and a new workspace's local base branch is behind its remote, Orca
surfaces a one-time, dismissible toast nudging the user to enable it. The
toast is sticky (no auto-expire) so it can't be missed, with explicit
Turn On / Dismiss actions; dismissing (button, close X, or swipe) persists
localBaseRefSuggestionDismissed so the nudge — and its backend probe —
never runs again.
Also refactors the refresh logic so the advisory and mutating paths share
one fast-forward-safety evaluator, adds an SSH relay RPC for the ref
mutation, and fixes remote-tracking base parsing for fully-qualified refs.
Co-authored-by: Orca <help@stably.ai>
* fix: restore update-ref fast-forward for un-checked-out local base ref
The refactor that split refresh into evaluate + mutate dropped the
non-owner case: a local base branch checked out in no worktree was left
stale (return undefined) instead of fast-forwarded. Restore it across all
three layers — local evaluator/mutator, SSH evaluator, and relay handler
(which also removes the dead duplicated throw) — using the expected-old-OID
compare-and-swap form of update-ref so a concurrent ref move is a no-op.
The suggestion toast now also fires for this case.
Co-authored-by: Orca <help@stably.ai>
* refactor: restore resultBase spread in local-base-ref mutators
The evaluate/mutate split spelled out { baseRef, localBranch, status }
literally in the mutating paths; main used a resultBase spread. Restore
that pattern in both the local and SSH mutators — behavior-preserving,
collapses two identical skipped_error returns.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Add per-file line counts to the source control sidebar
Show +N/-N (green/red) next to each file in the Changes, Untracked, and
Committed-on-branch sections so the magnitude of a change is visible at a
glance. Counts are computed per staging area via `git diff --numstat`;
untracked/new files count their full contents as additions and binary
files show no count.
Consolidate numstat parsing and binary-buffer detection into shared
modules reused by the local status path, the SSH/relay path, and the
existing branch-compare code. Include added/removed in the status-entry
equality check so the sidebar doesn't re-render on unchanged polls.
* fix: harden source control line counts
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
- Add a narrow SSH relay RPC for refreshing remote-tracking refs without
reopening generic fetch execution
- Resolve SSH connection context from composite worktree IDs during startup
before worktree discovery completes
- Make the sleeping workspace filter negative-form and reset to the new visible
default
- Tolerate transient xterm scroll restoration failures during layout
- Restore macOS Electron framework symlinks after copying the dev app
- Resolve an effective upstream so legacy branches tracking origin/main use
origin/<branch> when that remote branch exists.
- Pull, sync, and ahead/behind status now operate on the same branch the UI
reports, including after non-fast-forward push rejections.
- Treat new remote worktrees without a HEAD commit as an empty compare when
the base ref exists, avoiding a broken source-control compare state
- Keep the existing unborn-head error for cases where the base cannot resolve
* feat(file-explorer): show gitignored files with dimmed italic decoration
Surfaces `.gitignore`d files in the right-sidebar file explorer with an
italicised, dimmed filename and a CircleSlash icon in the same trailing
slot used by the git status letter. A tracked change always wins — the
ignored decoration only applies when no other git status is present.
Gated behind a new `showGitIgnoredFiles` global setting (default on) so
heavy SSH workspaces can keep the smaller payload by skipping
`--ignored=matching` on `git status`.
`ignoredPaths` lives as a peer field on GitStatusResult rather than an
extension of GitFileStatus/GitStagingArea, so Source Control's
staging-area grouping is untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(file-explorer): trim redundant comments from gitignored decoration
Removes duplicated "Why:" explanations that ended up restating the same
backward-compat rationale across five files (relay, ssh provider, runtime
git commands, RPC handler, renderer git client) plus a few comments that
narrated the mechanism the code already shows.
Net: -39 lines of comment across 10 files; no behavior change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(file-explorer): drop remaining comments from gitignored decoration
The code reads well without them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* review: harden gitignored file decorations
- clear ignored decoration cache when ignored status is disabled or omitted
- keep ignored decoration state scoped across worktree and runtime cleanup
- add coverage for local, SSH, runtime, relay, and Explorer precedence
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* fix(worktree): preserve user push.autoSetupRemote, include path in warn
- Probe push.autoSetupRemote with `git config --get` before writing so a
deliberate user value at any scope (local/global/system) is preserved.
- Include worktree path in the warn log for failed config writes.
- Add test pinning the preserve-existing-value behavior.
- Remove stray 00-review-context.md committed during review tooling.
Co-authored-by: Orca <help@stably.ai>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* fix(worktree): narrow config --get error handling, tighten test asserts
Treat only exit code 1 from `git config --get push.autoSetupRemote`
as "key unset". Other read failures (corrupt config, locked file,
parse error) now re-throw to the outer warn handler instead of being
silently treated as unset and overwriting whatever value the user
actually has.
Also: add test for the non-unset read-error path; convert the
"preserves existing value" test from `.some()` predicates to a
full-array `toEqual` matching sibling-test style; explicitly mock
`config --get` (with code: 1) in the sparse-failure rollback test
so it exercises the intended branch instead of the helper's empty-
stdout fallthrough; document in the design notes that
addSparseWorktree's rollback intentionally does not unset
push.autoSetupRemote.
Co-authored-by: Orca <help@stably.ai>
* test(worktree): pin --get-empty-stdout and worktree-add-fail invariants
Why: addWorktree's post-create config probe has two ordering
invariants worth pinning so a future refactor can't silently
regress them: (1) `git config --get` succeeding with empty stdout
still counts as "already set" so we don't overwrite an explicit
empty value, and (2) the entire config block is skipped when
`worktree add` itself rejects.
Co-authored-by: Orca <help@stably.ai>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* docs(worktree): cross-ref local↔SSH addWorktree, clarify SSH-host git version, add empty-stdout parity test
JSDoc on local addWorktree now flags the push.autoSetupRemote side
effect; both paths cross-reference each other so the next change keeps
them in lockstep. Relay comment clarifies that the git version that
matters is the SSH host's, not the client's. Adds the missing
empty-stdout-as-already-set parity test on the relay side.
Co-authored-by: Orca <help@stably.ai>
* chore: remove 00-review-context.md from PR
Stray file from local review workflow; should not ship in this PR.
Co-authored-by: Orca <help@stably.ai>
* chore: remove worktree-ssh-no-track-parity.md from PR
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
When a remote SSH workspace contains a symlink whose target lies outside
the registered repo/worktree roots, file reads failed with 'Path outside
authorized workspace'. This silently broke common workflows: HPC dataset
mounts, multi-checkout repos, dotfile editing, and any cross-mount
symlink.
Drop `RelayContext.authorizedRoots`, `validatePath`, and
`validatePathResolved` along with all ~33 call sites in fs-handler.ts
and git-handler.ts. The relay's threat model becomes 'the relay runs as
the SSH user and trusts the renderer.'
Why this is acceptable: `pty.spawn` and `git.exec` already concede the
same threat. A renderer that wants to reach `/etc/passwd` can spawn a
shell or run `git -C /etc cat-file`; the FS allowlist was friction, not
a security boundary. Intra-worktree path checks in `getDiff` and
`discard` are intentionally preserved.
Back-compat preserved: `session.registerRoot` (notification + request)
remains a valid RPC, retained as no-ops on new relays. Old main + new
relay and new main + old relay both keep working through the upgrade
window. `registerRelayRoots` is also kept for the same reason. A
narrowed error-translation block in `worktree-remote.ts` handles old
relays still surfacing the legacy error string to users.
Tests: removed two negative-allowlist tests; added a positive control
('reads files outside any registered root') and a direct regression
test for #1661 ('reads files via symlinks resolving outside the
workspace'). All 469 relay/SSH/IPC tests pass.
See docs/relay-fs-allowlist-removal.md for the full rationale,
back-compat matrix, alternatives considered, and follow-up cleanup
plan.
Closes#1661
Co-authored-by: Orca <help@stably.ai>