Commit Graph
11496 Commits
Author SHA1 Message Date
Jinwoo Hong 1ffe14986e chore: keep provider types within lint limit 2026-07-19 16:04:05 -07:00
Jinwoo Hong bbb54065e8 fix: preserve native PTY context on reattach 2026-07-19 16:04:05 -07:00
Jinwoo Hong 8281038d60 fix: refresh CWD after late WSL context 2026-07-19 16:04:05 -07:00
Jinwoo Hong 01ce6db168 test: make WSL cwd fixture cross-platform 2026-07-19 16:04:05 -07:00
Jinwoo Hong 3efc930908 fix: preserve WSL CWD across daemon sleep wake 2026-07-19 16:04:05 -07:00
Jinjing 08f446190a Standardize per-repo Source Control AI save UX (#9427)
* Standardize per-repo Source Control AI save UX with global recipe patter

Extract draft/save logic into `useRepositorySourceControlAiGlobalUx` hook and
serial persist queue, matching how global action recipes save: selects persist
immediately, CLI args and command template draft until per-action Save.

* Support draft/commit for per-repo custom-command input

- Drafts custom commands locally on keystroke without backend writes
- Commits to persistence only on blur or mode selection change
- Adds forceRepoMode local state to fix mode-select snapping with empty fields
- Mirrors existing pattern used for action recipe text editing
- Improves persist queue with repo-switch safety (returns boolean, pins repoId at schedule time)
- Adds comprehensive test coverage for settings hook and persist queue

* Fix forceRepoMode logic to preserve REPO intent mid-edit

Always set forceRepoMode based on field content instead of
only when a repo command is present. This preserves REPO
intent when the field is empty during editing, only exiting
when a value is explicitly entered. Add test for draft
discard and revert behavior.
2026-07-19 15:59:36 -07:00
Brennan Benson 624c8d4120 Make plain-text file:// links clickable in the terminal (#9467)
* Make plain-text file:// links clickable in the terminal

Printed file:// URIs (e.g. a report path echoed by a tool or agent) were
neither http links nor bare filesystem paths, so the terminal's URL and
local-path detectors both skipped them and the link was dead.

Orca already resolves and opens file:// URIs for OSC 8 hyperlinks. Reuse
that exact resolver for plain-text URIs so a printed file:// behaves the
same whether or not the emitter wrapped it in an escape sequence:

- Promote the (dependency-pure) file-url target resolver into src/shared
  so the OSC path and the new plain-text path share one implementation.
- Add a file:// detector that decodes the URI to a filesystem path and
  routes it through the existing file-link pipeline (existence probe +
  openDetectedFilePath), so line/col anchors, %20, Windows drive paths,
  html-in-browser, editor reveal, and SSH/runtime resolution all just work.

Lines without file:// are unchanged: the pass short-circuits to the prior
result, so only file://-bearing lines gain a link.

- Add unit + integration coverage for detection, decoding, and no-double-link.

* Harden plain-text file URI detection

* Split terminal file link detection modules
2026-07-19 15:21:06 -07:00
Brennan Benson 764cadafc7 fix(terminal): confirm the agent from ConPTY console presence to avoid false exits (#9258)
* fix(terminal): confirm the agent from ConPTY console presence to avoid false exits

On Windows the foreground scan is a whole-process-table PowerShell fork
that, under load, exceeds its timeout or returns an incomplete snapshot —
the completion coordinator then reads the shell as the foreground and
fires a false "agent done" while the agent is still working.

While a recognized agent is still active, confirm it with a cheap ConPTY
console-membership read instead: a child process still attached to the
console means the agent is working, so keep it without the whole-table
scan. Fall through to the authoritative scan only when the console is
shell-only (the agent likely exited). No-op off Windows, and never worse
than the existing degraded-scan fallback.

* fix(terminal): apply the ConPTY console-presence check on the daemon foreground path

Windows PTYs are hosted by the terminal daemon, whose foreground-identity
refresh (not the local provider) is what runs by default — it retired the
cached agent on a timed-out or incomplete CIM scan, so foreground reads fell
back to the shell and fired a false "agent done" while the agent was working.

Mirror the local-provider fix on the daemon path: a degraded scan
(available:false) no longer retires the identity; an authoritative scan that
resolves no agent is confirmed against a ConPTY console-membership read before
retiring (an incomplete snapshot with a child still attached keeps the agent);
and the sync foreground read serves the cached agent across a shell fallback on
Windows (an unreliable exit signal under load) until the background refresh
authoritatively retires it. The membership read stays off the sync path.

* fix(terminal): exclude the console-list helper's own process from ConPTY membership

The console-membership helper attaches to the console to read it, so
GetConsoleProcessList counts the helper's own forked process. A bare shell
therefore read as [helper, shell] and looked like it still had a child, so a
genuine shell-only console (an exited agent) was never detected — the foreground
refresh held the exited agent's identity indefinitely. Drop the helper's own pid
before judging membership; a remaining set of only the shell (or the
AttachConsole-failure fallback) is not child proof. Fixes real-exit detection on
both the daemon and local foreground paths.

* fix(terminal): require conclusive ConPTY exit evidence

* fix(terminal): absorb delayed ConPTY helper errors
2026-07-19 15:20:54 -07:00
Brennan Benson 9d262c98f6 Bump mobile app.json to 0.0.32 (#9466) 2026-07-19 14:43:07 -07:00
Brennan Benson ca4003a9e3 Keep Agent Session History from freezing the app on huge OpenCode databases (#8924)
* fix(agent-history): keep the app responsive while scanning huge OpenCode databases (#8864)

Opening or refreshing Agent Session History froze the entire app when
OpenCode's opencode.db had grown to multiple GB (reporter: 29 GB with
20+ live opencode writers). All OpenCode SQLite reads ran synchronously
(node:sqlite DatabaseSync) on the Electron main-process event loop, the
discovery query evaluated a COUNT+json_extract subquery for every
session before LIMIT, and the preview query JSON-parsed every part blob
of each session. Live writers bump session.time_updated continuously,
so the mtime parse cache missed every 15s/focus/manual refresh and the
multi-tens-of-seconds freeze repeated forever.

Fix:
- Run OpenCode SQLite discovery and per-session parsing on a persistent
  worker thread (lazy spawn, unref'd, idle teardown, FIFO dispatch,
  per-call timeouts, crash-loop cap). Faults surface as per-source scan
  issues instead of stalls; other providers' results always arrive.
- Fall back to the in-process reader when no worker bundle exists,
  surfacing a degraded-mode scan issue so a persistent fallback cannot
  silently reintroduce the hang.
- Bound the queries: sort+LIMIT sessions before computing message
  counts, and source previews from the newest 100 messages via the
  (session_id, time_created, id) index instead of scanning every part.

Measured on a 22 GB synthetic DB matching the reporter's shape: main-
process IPC RTT during a fully cache-invalidated scan went from a
32.8 s continuous block (UI click timeout) to 1 ms max, with the panel
populating normally (previews and message counts intact).

* fix(agent-history): drop the cached worker handle after a clean exit and document worker-client exports

A worker that exits cleanly on its own left this.worker pointing at the dead
thread; the next request would post into it and stall to its timeout instead
of respawning. Clean idle exits now drop the handle without counting as a
death. Also adds JSDoc to the new exported scan-worker surfaces.

* fix(agent-history): keep OpenCode scans off the main thread

* fix(agent-history): align OpenCode recency ordering
2026-07-19 14:40:54 -07:00
Brennan Benson fbe7780566 Fix diff editor flashing "Loading…" on every save (#9424)
* Fix diff editor flashing "Loading…" on every save

Saving a file open in a single-file diff tab blanked the editor to a centered "Loading…" for a frame on every content-changing save. The DiffViewer's React key embedded the modified-content signature, so each save changed the key and forced a full unmount/remount of the Monaco diff editor — which shows its built-in loading placeholder while re-initializing, and also discarded scroll position and undo history.

The modifiedModelKey → modifiedModelPath rotation already refreshes diff content in place without a remount, so the signature in the outer key was redundant. Drop it; keep the view-state scope and explicit reload nonce for a stable per-tab identity.

Adds a regression test asserting a save does not remount the diff editor.

* Harden in-place diff model refresh

* Preserve diff view state across model swaps

* Fix retained diff model disposal race
2026-07-19 14:30:59 -07:00
OrcaWinandBrennan Benson 37039cd095 fix(source-control): bound Create PR eligibility probe so it can't hang (#9292)
* fix(source-control): bound Create PR eligibility probe so it can't hang

The local Electron eligibility path had no renderer-side timeout, so a hung
main-process git/gh subprocess (plausible on Windows) left the Create PR header
stuck in its "Checking whether this branch can create a pull request..." loading
state with the button permanently disabled. The runtime-hosted path was already
bounded by callRuntimeRpc's 30s timeout; the local path was not.

- Wrap the local window.api.hostedReview.getCreationEligibility call in a 30s
  timeout so a never-settling probe rejects instead of hanging.
- On probe failure/timeout, synthesize a local-status blocker snapshot
  (dirty -> no_upstream -> needs_sync -> needs_push, mirroring the main-process
  ordering) so a dirty branch still offers the commit/preparation intent and a
  clean unpublished branch the publish intent, instead of an inert disabled
  button. Fall back to the retryable failed state only when local status can't
  determine a blocker.

Extracts the eligibility snapshot builders into their own module to stay under
the max-lines cap. Provider-aware copy and host-scoped (local/SSH/runtime)
behavior preserved; no git commands changed.

* fix(source-control): guard synthesized eligibility fallback (default branch, provider parity)

Mirror the main-process canReturnLocalBlocker guard in the renderer's
probe-failure fallback so a timed-out/failed probe can't synthesize a
'dirty'/commit blocker on the default branch or a detached HEAD — which
would have surfaced an enabled Create PR that commits onto the base
branch. The ahead-only needs_push case is likewise dropped to match main
(it won't offer a push it can't auth-check first).

Infer the provider from the repo remote host so a GitLab (etc.) repo with
no linked review shows its own review copy during loading and after a
failure instead of the GitHub default.

Also: assert the timeout error by type, and rename the snapshot test to
match its module.

* fix(source-control): keep eligibility timeout stable

* fix(source-control): keep eligibility timeout bounded

* test(source-control): assert eligibility effect dependencies

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-19 13:18:34 -07:00
Brennan Benson a833b5cba6 Clear a removed remote host's leftover repos and worktrees from the sidebar (#9463)
When a runtime host identity (runtime:<envId>) is removed from the saved
list, retire the repos, project host setups, and worktree rows it owned so
the same physical checkout stops duplicating in the sidebar.

setRuntimeEnvironments now diffs the previous in-memory saved list against
the new one and purges state owned by any environment that just left, routed
through the existing worktree purge cascade (tabs/PTY/browser/editor/agent
maps). Scoped to the removal diff, not an absolute keep-set, so a serving
instance's locally-persisted runtime-stamped repos (whose env id was never in
this instance's saved list) are never torn down.

A tombstone set (removedRuntimeEnvironmentIds) guards the three repo-catalog
merges so an in-flight fetch for a just-removed env can't re-add purged repos,
while a runtime env merely absent from a not-yet-hydrated saved list still
merges normally.

Refs #8881
2026-07-19 13:15:14 -07:00
Brennan Benson 37cd830192 Confirm before merging a PR/MR from the sidebar strategy dropdown (#8911)
The right-sidebar Checks panel merge control merged the PR/MR immediately when
a strategy was chosen from its dropdown, with no confirmation — so opening the
dropdown to switch strategies (e.g. Squash -> Merge commit) merged on the spot.
Every other PR/MR merge surface (PullRequestPage, GitHubItemDialog, TaskPage)
already confirms first, and the close/reopen path in this same hook confirms too;
only the hosted-review merge path was missing the gate.

Add the same confirmation dialog to the hosted-review handleMerge, provider-aware
so it reads "Squash and merge PR #N?" / "Squash and merge MR !N?". Selecting a
strategy now asks before merging; the merge still runs when explicitly confirmed.

Fixes #7943
2026-07-19 13:09:36 -07:00
Brennan Benson 500f0c50de Prevent adding the same Claude account twice (#8912)
* fix(claude-accounts): block adding a duplicate Claude account (#6616)

Adding the same Claude subscription via Settings -> AI Provider Accounts
appended a second managed account with an identical email/organization,
producing duplicate rows that confused account selection and rate-limit
tracking.

doAddAccount now checks the captured identity against existing accounts
before appending and rejects the add with a clear message when it matches.
Identity is keyed on email + organizationUuid scoped to the runtime
(host/WSL distro), so the same email can still be added under a different
organization, and both sides are normalized so a legacy account persisted
before the runtime fields existed still matches.

* fix(claude-accounts): skip rollback I/O for duplicates
2026-07-19 12:14:25 -07:00
Jinjing b4e85d95a6 feat(editor): add Toggle H5 to markdown editor (#9448) 2026-07-19 12:13:16 -07:00
github-actions[bot] b19dccd9b7 Update README downloads badge 2026-07-19 18:35:53 +00:00
OrcaWinandBrennan Benson 0b71f3bfba test(e2e): prove the terminal daemon survives a main-process crash on Windows (#7742) (#9311)
* test(e2e): prove the terminal daemon survives a main-process crash on Windows (#7742)

Add a win-crash-survival e2e harness (sibling to win-update-e2e) that
force-kills ONLY the packaged app's real Electron main (resolved via
app.evaluate -> process.pid, /F no /T) and asserts the detached
orca-terminal-daemon.exe plus its ConPTY shell survive with no pwsh
0xE9 FailFast, then that a relaunch re-adopts the SAME daemon and the
reattached UI binds to the SAME survivor shell (proved via a per-shell
env sentinel read back through the restored terminal).

This guards the #7742 fix (standalone relocated daemon that outlives
main death) against regression. A directional `--expect orphaned`
profile fails on a fixed build, keeping the survival assertions honest.

Windows-only; reuses win-update-e2e app-driver/daemon-process modules.

* test(e2e): harden Windows crash-survival proof

* test(ci): keep crash survival gate durable

* test(e2e): tolerate restart hydration navigation

* test(e2e): prove exact shell input after crash

* perf(ci): avoid crash harness installer rebuilds

* test(ci): harden crash survival evidence and cost

* test(e2e): fail closed on authoritative crash target

* test(e2e): fail closed on crash liveness evidence

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-19 11:27:29 -07:00
github-actions[bot] 80e632282c Update README downloads badge 2026-07-19 12:35:17 +00:00
NeilandOrca 5848550b5e fix(composer): show full worktree path on hover in Run on dropdown (#9398)
* fix(composer): show full worktree path on hover in Run on dropdown

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

* refactor(composer): use native title tooltip for Run on paths

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

* fix(composer): reliable native-style tooltip for Run on paths

The native title attribute won't re-trigger between adjacent rows in
Chromium, so the tooltip flickered/dropped as you moved down the list.
Use the shared (controlled) Tooltip instead, styled compact + arrowless
to read like an OS tooltip; the app-level provider's skip-delay makes
row-to-row hovers reliable.

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

* fix(composer): stop Run on path tooltip wedging shut

Radix's uncontrolled hover state could flash the tooltip open then
wedge it closed inside the cmdk list (shared pointer-transit state
getting stuck), so re-hovering never reopened it. Drive open state
with a controlled hover-intent handler (open after a delay, close
after a short grace) so re-entry always reopens and transient
enter/leave thrash debounces to a stable state.

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

* fix(composer): rebuild Run on path tooltip as a portal (no loop/wedge)

Both the native title and Radix Tooltip (controlled or not) misbehaved
inside the cmdk list: flashing, wedging shut, or opening/closing in a
loop. Replace with a self-contained tooltip that renders a fixed,
pointer-events-none portal on document.body and only changes state on
pointer enter/leave/down (never pointermove). Opening it cannot reflow
the list or become the hover target, so it structurally cannot create
the enter/leave feedback loop.

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

* fix(composer): trigger Run on path tooltip on the path line, always below

- Scope the hover trigger to the truncated path line itself (not the
  whole row), so only hovering the path reveals it.
- Always position the tooltip below the hovered line for predictable
  placement (was flipping above near the viewport bottom).

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

* fix(composer): anchor Run on path tooltip under the path line

The old placement anchored to the window's right half when the trigger
sat past viewport-center, which shoved the tooltip to the far right edge
of the window, disconnected from the dropdown. Always left-align it
directly under the hovered path line and cap max-width to the remaining
viewport width so long paths wrap instead of overflowing.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-19 02:34:39 -07:00
OrcaWin 8d5c674644 fix(win): launch Store-installed PowerShell 7 in terminals (#9437)
Resolve Microsoft Store PowerShell App Execution Aliases to their real package executable before ConPTY spawn, while preserving explicit PowerShell choices and the existing fail-safe fallback chain.
2026-07-19 01:19:46 -07:00
Jinjing e885cec154 Allow hiding Orca Mobile sidebar button once a device is paired (#5785)
* Allow hiding Orca Mobile sidebar button once a device is paired

Introduce a shared external store (`paired-mobile-devices.ts`) to cache
and synchronize the paired mobile device list across the sidebar,
Settings pane, and Mobile page. This prevents redundant backend IPC
requests when multiple surfaces mount simultaneously.

Using this shared pairing status, display an inline "Hide from sidebar"
control next to "Orca Mobile" in the navigation sidebar once a device
has been paired. This allows users to easily declutter their sidebar
after completing setup.

* Handle device load errors with recovery on focus/reconnect

- Add error flag to distinguish failed device loads from empty device lists
- Recover from transient startup IPC failures by retrying on window focus or online
- Validate revoke device success before routing or showing success toast
- Only show hide control after first device is actually paired
- Use snapshot getter to avoid manual device ref tracking in MobilePane

* Handle device load errors with recovery on focus/reconnect

- Shared module-level listeners for failed load recovery reduce IPC spam
  compared to per-consumer event listeners on every focus/online event.
- Optimistically remove revoked devices if post-revoke reload fails,
  keeping success toast and intro routing correct.
- Prevent repo/branch label overflow with CSS text truncation.
- Fix HTML entity rendering: use plain spaces instead of &nbsp; in
  translations so React text nodes render them correctly.
- Add comprehensive tests for the paired devices hook covering load,
  navigation, revoke, and error recovery paths.
2026-07-19 00:09:57 -07:00
Jinjing e074bc3f05 Gate certificate trust proceed action on runtime capability (#9070)
Only offer 'Proceed Anyway (Unsafe)' if the connected remote runtime
advertises browser.certificate-trust.v1 support. Older runtimes cannot
honor the request and would fail silently, creating a false affordance.

Centralize certificate error normalization to prevent divergence
between main and renderer certificate matching, and unify URL redaction
for Kagi session token stripping across load-error paths.
issue-assets-9432
2026-07-18 23:40:01 -07:00
gatsby74andJinjing 8ed8f0d109 feat(ssh): download folders from remote explorer (#7793)
* feat(ssh): download folders from remote explorer

* fix(ssh): harden remote folder downloads

* Add missing getRepo stub to worktree cwd test mock

Restoring headless mobile tabs looks up the repo for the active
worktree id; the mock lacked getRepo, so the test only passed
incidentally. Add it explicitly and return undefined since wt-1
is a worktree id, not a registered repo.

* Enable SSH folder downloads, gated for system-SSH connections

- Folder downloads require SFTP, unavailable on system SSH (which
  offers only raw file operations). Add supportsFolderDownload flag
  to gate the feature in the UI layer.
- Reject symlinks at directory-entry level, preventing tree escapes
  and eliminating unnecessary stat calls.
- Check abort signal before opening dialog for better responsiveness
  when renderer closes.
- Log cleanup errors without re-throwing to preserve underlying
  transfer failures.

* Gate SSH folder downloads to SFTP-capable connections

Enforce fail-closed gating and add Windows path traversal validation to
ensure downloads are only available when explicitly supported and safe.

* Gate SSH folder downloads to SFTP-capable connections

Enforce fail-closed gating and add Windows path traversal validation to
ensure downloads are only available when explicitly supported and safe.

* fix(ssh): keep provider types under max-lines after main merge

Move FolderDownloadOptions next to the SFTP download implementation and
narrow IFilesystemProvider.downloadFolder options to AbortSignal only so
types.ts stays within the 300-line oxlint budget when merged with main.

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-18 23:01:29 -07:00
Jinjing 99b59ad7be fix(floating-terminal): position panel at z-45 above notifications (#9420)
Raise the floating terminal panel from z-30 to z-45 so it sits above
notification cards (z-40) but below the modal layer (z-50), preventing
notifications from burying the terminal. Raise the toggle button to z-46
to keep it clickable where it overlaps the panel.
2026-07-18 22:29:26 -07:00
JinjingandOrca f7c2c1276c Add review note chord guards (#9412)
* Guard add-review-note chord to prevent remount (product B)

- Scoped guards consume chord at composer level to prevent remount and leakage
- Handle OS key-repeat: ignore when no draft, consume when one is mounted
- Clear stale block keys in markdown preview when content renumbers
- Flush pending selection before reading targets to fix timing races

* fix(editor): repair add-review-note guard tests and close remaining chord gaps

- Update the product-B guard tests to the Mod+Shift+A default binding
  (#9257 retired Mod+Alt+N as AltGr-unsafe); they asserted the old chord,
  so seven landed red and the rich-editor repeat test passed vacuously.
- Monaco: recompute the annotation target from the live selection at
  keydown instead of the render-lagged ref, so a chord right after a drag
  cannot open on the previous selection or miss a fresh one.
- Preview: key the stale-block-key cleanup on renderedContent (the DOM
  the block keys live in), which can lag content during external-edit
  section preservation.

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

* fix(editor): mirror shortcut-guard refs in effects instead of render body

CodeRabbit on #9412: render-body ref writes can leak from a render pass
React replays and discards. Move the state->ref mirrors for
commentPopoverRef / shouldShowMarkdownAnnotationsRef (MonacoEditor) and
activeAnnotationBlockKeyRef (MarkdownPreview) into effects; same-tick
keydown paths keep their eager event-handler writes.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-18 22:10:22 -07:00
Brennan Benson 02ff7c7465 Preserve agent chats and drafts through reconnects (#9242)
* fix(chat): preserve drafts through reconnects

* fix(terminal): bound stale handle reconnect polling

* refactor(chat): extract native view props

* fix(chat): harden reconnect lifecycle

* fix(terminal): replace stale reconnect identities atomically

* fix(terminal): recover mirrors after reconnect polling

* docs(reliability): record merged reconnect coverage

* fix(terminal): preserve reconnect lifecycle state

* fix(terminal): keep reconnect polling truly bounded
2026-07-18 20:31:14 -07:00
github-actions[bot] ae1c943da9 Update README downloads badge 2026-07-19 00:56:28 +00:00
Jinwoo-HandOrca 965a3f9a05 fix(terminal): keep setup split PTYs distinct
Co-authored-by: Orca <help@stably.ai>
2026-07-18 17:10:28 -07:00
NeilandOrca 6a573f376f fix(create-worktree): keep composer open when adding a project from the dialog (#9397)
Co-authored-by: Orca <help@stably.ai>
2026-07-18 16:36:52 -07:00
Neil 927ca9e94b perf(preflight): fs-based PATH resolution for agent detection (no where/which spawn) (#9297)
Resolve agent CLIs against PATH with fs instead of spawning one where/which subprocess per candidate (~34 at startup). Same found/not-found result (same env/PATH, faithful which/where semantics); subprocess spawns 34->0.

Fixes #9297.
2026-07-18 15:16:43 -07:00
Neilandgatsby74 4905b78282 fix(status-bar): show live session reset countdown in collapsed usage bar (#5399)
Derive the collapsed session limit label from resetsAt and tick it live via a shared boundary-scheduled countdown clock (no polling). Combines #6252/#6585.

Fixes #5399.

Co-authored-by: gatsby74 <166927047+gatsby74@users.noreply.github.com>
2026-07-18 15:16:10 -07:00
4930c87219 fix(github): load PR details on fork checkouts by preferring upstream (#9384)
On a fork checkout (origin=fork, upstream=parent) PR details failed to load because getOwnerRepo() resolved only the origin remote while GitHub PRs live on the upstream parent. Make getOwnerRepo() prefer upstream (mirroring getIssueOwnerRepo), and pin the call sites that genuinely need the checkout's own origin identity (getRepoSlug, getRepoUpstream, createGitHubPullRequest, resolvePrWorkItemSource) to the origin-only primitive.

Lands the fix community-identified in #7332 and hardened in #7513.

Closes #7331

Co-authored-by: fsdwen <1214772+fsdwen@users.noreply.github.com>
Co-authored-by: brennanb2025 <79079362+brennanb2025@users.noreply.github.com>
2026-07-18 14:53:22 -07:00
Neil 403d681d83 fix(terminal): re-linkify streamed URLs so links underline/click on first hover (#9320)
Invalidate xterm's linkifier hover cache (throttled) when output streams into a visible pane, so a URL printed under a stationary pointer underlines and becomes Cmd/Ctrl+clickable on the next pointer move instead of after several clicks. Skips while a link is hovered (no flicker) and re-arms so the reset is never dropped mid-hover. Reuses the visibility-resume primitive (#9061).
2026-07-18 14:27:34 -07:00
Jinjing b45a222f03 docs: remove terminal garble investigation notes
Scratch investigation doc is no longer needed on main.
2026-07-18 12:56:29 -07:00
Jinjing 4ae67e863a Merge branch 'docs/wechat-group-3-qr' 2026-07-18 12:47:18 -07:00
Jinjing 5cdf83be5e docs: rotate WeChat QR to group 3
Groups 1 and 2 are full; point readers at the new third-group QR in EN/ZH README.
2026-07-18 12:46:58 -07:00
github-actions[bot] 54cb772b9c release: v1.4.146-rc.0 v1.4.146-rc.0 2026-07-18 17:17:15 +00:00
Brennan Benson bb71a3a991 fix(terminal): bypass rejected macOS login sessions (#9301)
* fix(terminal): bypass rejected macOS login sessions

* fix(terminal): bound macOS login preflight

* test(terminal): isolate macOS login preflight

* fix(terminal): avoid blocking macOS login preflight

* fix(terminal): cancel pending PTY preparation

* fix(terminal): cancel preparation on daemon shutdown
2026-07-18 10:16:21 -07:00
github-actions[bot] d8629c41c8 Update README downloads badge 2026-07-18 12:35:43 +00:00
NeilandOrca 057a81493a fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1) (#9315)
* fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1)

Worktree.displayName is typed non-optional but arrives undefined at runtime for
persisted/discovered worktrees (crash 99657ab1). PR #8683 fixed the kanban board;
this extends the same guard to the five other sort sites that share those worktree
objects — including the Cmd+J switcher (order-empty-query-worktrees) — via one
shared compareWorktreeDisplayName helper in lib/. Behavior-neutral when names are
present; a missing name now sorts as '' instead of throwing.

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

* docs(agents): add over-commenting anti-pattern example to the comment rule

Anchors the existing 'document the why, briefly' rule with a concrete
before/after (the worktree-displayName guard) so agents stop dumping the
crash id, mechanism, file location, and every call site into a comment.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-18 01:55:00 -07:00
Jinho Choi 72d0a403a3 fix(editor): use Monaco's registered proto language id for .proto files (#9286) 2026-07-18 00:22:20 -07:00
Jinjing 45c4a1f61e refs/heads/create-pr-should-handle-sync (#8534) 2026-07-18 00:21:00 -07:00
NeilandOrca b8502b21bb perf(terminal): bound recent-PTY-output with a chunk deque (drop per-chunk 64KB concat) (#9291)
Co-authored-by: Orca <help@stably.ai>
2026-07-17 23:57:24 -07:00
NeilandOrca 2783f758df perf(persistence): compact JSON for durable-state save payload (drop pretty-print) (#9290)
Co-authored-by: Orca <help@stably.ai>
2026-07-17 23:56:05 -07:00
hanjoonchoe 0c73e3c33d fix(i18n): use full-sentence keys in RemoveFolderDialog description (#9296) 2026-07-17 23:55:12 -07:00
Brennan Benson 0532765b7f fix(pty): stop daemon reattach/kill race from orphaning restored terminals (#7742 sub-issue B) (#7836)
* fix(pty): stop daemon reattach/kill race from orphaning restored terminals

Two cold-start defects let a PTY kill silently orphan a live daemon session
after a renderer/app restart — the PTY-orphaning-on-restart half of #7742:

- DaemonPtyAdapter.shutdown() was the only session op that skipped
  ensureConnected(). The daemon client connects lazily, so a kill arriving
  before the first spawn (startup sleep/hibernation sweeps, closing a
  restored tab) threw "DaemonProtocolError: Not connected" against a
  HEALTHY daemon; the renderer swallows the rejection and the live session
  survives detached. Fix: connect first, like every other session op.

- pty:kill had no startup barrier while pty:spawn did. A kill issued before
  initDaemonPtyProvider swapped the provider resolved against the pre-daemon
  LocalPtyProvider, whose shutdown() silently no-ops on daemon ids; the
  handler then reported success and sent a synthetic pty:exit, permanently
  clearing the persisted tab->ptyId binding so the session never reattaches.
  Fix: pty:kill awaits the same getLocalPtyStartupPromise gate as spawn.

Both reproduced red-first (real DaemonServer socket rig for the adapter;
deferred-barrier IPC rig for the handler) and pass after the fix.

Scope: this restores the reattach/teardown invariant. It does NOT address
the renderer crash trigger or the daemon-process-death path that produces
the Windows PowerShell FailFast symptom (separate follow-ups).

* fix(pty): gate runtime shutdown on daemon startup

* fix(pty): keep shutdown independent of hook startup
2026-07-17 20:10:59 -07:00
Jinwoo-HandOrca ab0f220c60 fix(runtime): return authoritative visible TUI output
Co-authored-by: Orca <help@stably.ai>
2026-07-17 20:09:33 -07:00
OrcaWinandBrennan Benson cb9c42d605 fix(terminal): filter focus reports after Codex history resume (#9259)
* fix(terminal): filter focus reports after Codex history resume

* test(terminal): preserve focus reports outside Codex resume

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-17 19:25:13 -07:00
Brennan Benson bd7205684a test(pty-connection): drain async confirm reads between tests (#9260)
The connectPanePty suite intermittently fails in CI on
`clearAgentLaunchConfig` call-count assertions (e.g. expected exactly
once, received 5 with pane keys belonging to other tests).

Root cause is cross-test async leakage: pane foreground-agent trackers
kick off `confirmForegroundProcess` reads whose continuations settle on
the microtask queue, not on fake timers. A test that ends with one still
in flight leaks it into the next test, where it resolves against that
test's fresh store mock and calls clearAgentLaunchConfig with the prior
test's pane key.

Drain pending microtasks in afterEach (before tearing down fake timers,
while the test still owns its store mock) so each test absorbs its own
async fallout. No behavior change; full suite stays green (446/446).

Note: this is a CI-timing flake not reproducible locally in isolation
(ordered runs pass repeatedly, incl. under GC pressure); the fix targets
the confirmed leak mechanism and removes the timing dependence.
2026-07-17 19:17:33 -07:00