* Prevent main-process crash on huge git status output
git status on a repo with an enormous un-ignored folder could emit a
listing large enough that buffering it into one string exceeded V8's
max string length, throwing an uncatchable RangeError inside Node's
execFile exit handler and crashing the main process (and blocking
mobile). The runner also forwarded an undefined maxBuffer straight to
execFile, which silently disabled the cap entirely.
- runner: apply a non-bypassable default maxBuffer so no git call can
buffer without a bound.
- status: stream porcelain-v2 output through an incremental parser and
kill git the moment the changed-entry count crosses a limit
(default 10,000); skip numstat/upstream probe when limited. Apply the
same limit to the relay/SSH status path.
- UX: surface a 'too many changes' state, pause auto status polling
while a repo is over the limit, and offer to .gitignore a detected
huge folder.
Co-authored-by: Orca <help@stably.ai>
* Address review: validate inputs, fix stream decoding, localize copy
- huge-folder-ignore: restrict folderName to the known-folder allowlist
before writing .gitignore (reject path-sep/newline injection).
- gitStreamStdout: decode stdout/stderr with StringDecoder so multibyte
UTF-8 split across chunk boundaries isn't corrupted; flush on cleanup.
- gitStreamStdout: wrap the onStdout callback in try/catch so a throwing
parser rejects the promise instead of crashing the main process.
- status/relay: validate the status limit as a non-negative integer.
- SourceControl: localize the 'too many changes' banner and the
.gitignore warning toast via translate() with placeholder params.
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>
- 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.
* Squashed commits
- WIP: uncommitted changes before rebase
- ci
- Show inline PR check details in task drawer
- Add a Checks tab that opens from the PR checks cell and expands runs inline
- Fetch check output, annotations, and workflow job steps through IPC/RPC
- Improve markdown/comment wrapping so long PR content stays within the drawer
* Use app-styled confirmations for PR actions (#2324)
Co-authored-by: Orca <help@stably.ai>
* fix: pr-bug-scan validated finding from #2274 (#2296)
Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
* fix: avoid optional git locks during status checks
---------
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
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>
* 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>
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>