Commit Graph
79 Commits
Author SHA1 Message Date
Jinjing c548e85f57 Persist and repair target base branch for PR and MR worktrees (#5540)
* Resolve and fetch the review target branch (compareBaseRef) during PR and MR worktree creation.
* Persist this ref on worktree metadata instead of pinning the head SHA.
* Dynamically repair existing worktrees with stale commit SHA compare bases in the Source Control UI using linked review metadata.
2026-06-16 15:51:55 -07:00
Jinjing f6fec257eb Ignore merged pull requests found by implicit branch matches (#5524)
Merged pull requests are historical branch matches and should not be
treated as implicit review context unless the worktree has an explicit
PR link. Showing them as implicit review context leaves nothing
meaningful to unlink after the branch has been rebased or merged.
2026-06-16 15:39:57 -07:00
Jinjing d36782a4a8 Respect repository auto-merge setting and forward merge method (#5453)
- Retrieve and propagate `autoMergeAllowed` from GitHub repo metadata.
- Suppress auto-merge action in UI if disallowed by the repository.
- Support specifying the merge method (e.g., squash) when auto-merging.
2026-06-15 20:48:36 -07:00
Jinjing ac216d5727 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
2026-06-11 00:58:26 -07:00
KayleeandNeil 528a887ab5 Target the fork branch from fork-PR worktrees (#4394)
Creating a worktree from a cross-repository (fork) PR previously named the
local branch with the maintainer's branch prefix (e.g. `me/866`) and pushed to
origin instead of the contributor's fork, so maintainer edits never reached the
PR. Fork PRs now adopt the contributor's branch name (matching same-repo PRs)
and resolve a fork push target, with a non-blocking warning when the PR
disables maintainer edits and an indicator showing where a push will land.

- pr-start-point: return branchNameOverride/headSha/maintainerCanModify for
  cross-repo PRs (previously only same-repo PRs received these)
- github client: surface maintainer_can_modify alongside the fork push target
- composer: warn (but still allow) when "Allow edits from maintainers" is off
- source control: show the fork push target (owner:branch) before pushing
- extract fork-remote cleanup and setup into dedicated, unit-tested modules

Adds unit suites for the cleanup multi-fork matrix, fork-remote setup,
push-target resolution, the warning decision, and the push-target label.

Note: pre-commit react-doctor hook bypassed — its warnings in useComposerState
are pre-existing (identical count on base) and not enforced by CI.

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-06-07 19:51:36 -07:00
Trevin ChowandNeil abfe9bd329 Default repo avatars to the GitHub upstream owner and flag forks (#4522)
* Default repo avatars to the GitHub upstream owner and flag forks

Make the GitHub owner avatar the default repo icon and surface it as the
primary choice in the icon picker (the "Image" tab becomes "Avatar",
moves first, and opens by default). For forks, resolve the upstream/
parent owner so the avatar reflects the source repo instead of the
personal fork, and show a fork indicator (GitFork glyph + "Fork of
owner/repo" tooltip) next to the repo in the sidebar and settings.

Fork detection prefers the offline `upstream` remote, falling back to a
`gh repo view --json isFork,parent` lookup; the resolved upstream is
stored on the repo. Existing repos self-correct via a one-time startup
backfill (local repos) and a lazy backfill when their icon settings open
(SSH repos); new repos resolve at add-time. Reset now restores the
default (re-detecting the upstream) instead of clearing to the Folder
icon.

* Harden repo upstream avatar handling

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-06-02 20:55:35 -07:00
Jinjing 472a2a95be fix: address review findings (#4328) 2026-05-31 16:42:19 -07:00
Jinjing c5ba94ce96 fix: address review findings (#4327) 2026-05-31 16:17:30 -07:00
Neil 09d2227a04 fix: bound github merge metadata cache (#4154) 2026-05-31 06:12:38 -07:00
Jinwoo-HandOrca 1c1677eaad Hydrate task PR merge methods
Co-authored-by: Orca <help@stably.ai>
2026-05-31 02:43:16 -07:00
Neil e8b859118f Use GitHub merge method metadata for PR actions 2026-05-31 02:43:16 -07:00
Jinjing 1d9aefe021 fix: reopen pull requests with gh pr (#3980) 2026-05-30 21:14:08 -07:00
Jinjing 7686eaba2d fix: address review findings (#3968) 2026-05-30 18:33:31 -07:00
ef74c713ae Fix PR lookup for tracked upstream branches (#3484)
* Fix PR lookup for tracked upstream branches

* fix: handle upstream PR lookup over SSH

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

---------

Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-05-30 14:33:23 -04:00
7242b41698 Fix GitHub merge queue PR status (#2856)
* Fix GitHub merge queue PR status

* Fix merge queue GraphQL field encoding

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

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-05-29 20:22:41 -04:00
Jinwoo HongandOrca 153fd863c6 Refresh GitHub issues after creation (#3018)
Implements the no-cache GitHub issue list refresh path described in docs/refresh-github-issues-after-create.md.

Co-authored-by: Orca <help@stably.ai>
2026-05-28 21:14:58 -04:00
Brennan BensonandOrca a15b13b02d Customize Source Control AI prompts (#2916)
Co-authored-by: Orca <help@stably.ai>
2026-05-27 16:03:36 -07:00
Jinwoo HongandOrca b1973657ea Add mobile Tasks parity (#2452)
Co-authored-by: Orca <help@stably.ai>
2026-05-21 20:26:07 -07:00
Jinwoo HongandOrca a69ce28e1d Quiet expected SSH GitHub task skips (#2565)
Co-authored-by: Orca <help@stably.ai>
2026-05-21 16:01:29 -07:00
Jinjing c6043a6702 Show GitHub issue assignees in the task list (#2557) 2026-05-21 13:30:41 -07:00
Jinjing fca5f498db Keep PR refreshes anchored to cached review numbers (#2541)
- Use fallback PR numbers after branch lookup misses, including detached HEAD
- Preserve review cards for forked or deleted-head PRs across manual refreshes
- Clear stale GitHub PR cache entries when unlinking worktree review metadata
2026-05-21 12:12:10 -07:00
Jinwoo HongandOrca fbf53aa4cc Prevent unscoped GitHub task queries for SSH repos (#2506)
* fix: prevent unscoped ssh github task queries

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

* test: update worktree card context menu mock

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-21 04:23:59 -04:00
Jinjing 671f33a8c7 fix: address review findings (#2470) 2026-05-20 19:12:40 -07:00
Jinjing 38ccb999d4 fix: render PR review comments inline (#2382) 2026-05-19 18:24:51 -07:00
Jinjing 8321ea2e03 fix: address review findings (#2377) 2026-05-19 17:50:04 -07:00
Jinjing 9d5f27fa3c Fix PR check refresh and terminal tombstone test (#2375)
* Prefetch task PR checks by head SHA

* Fix terminal host tombstone cap test
2026-05-19 17:42:30 -07:00
Jinwoo HongandOrca fb4069be52 Improve GitHub PR status refresh freshness (#1716)
Co-authored-by: Orca <help@stably.ai>
2026-05-19 15:39:44 -07:00
Jinjing 9bbfb04a09 fix: address review findings (#2339) 2026-05-19 13:03:47 -07:00
63b11f11a4 Add PR automation CLI and mobile browser streaming (#2328)
* 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>

---------

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>
2026-05-19 11:36:24 -07:00
Jinjing a6ca940d0f Show GitHub PR reviewer names in task rows (#2309) 2026-05-18 23:06:54 -07:00
Jinjing 4ca26db06a fix: address PR checks fallback (#2303) 2026-05-18 21:09:15 -07:00
AnweshandNeil 95577ea9a0 Fix start-from PR failures for fork-backed PRs (#2233)
* Fix start-from PR failures for some fork PRs

* fix: limit PR fallback fetches to missing refs

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-05-18 00:36:34 -07:00
Jinjing c7ddfd17d1 Improve git remote selection (#2207) 2026-05-17 21:00:15 -07:00
Jinjing e4a794ec68 fix: address review findings (#2206) 2026-05-17 20:15:05 -07:00
Neil 4bfd1eb157 Prefer exact PR lookups and stale sidebar refresh
Prefer exact linked PR lookup when safe, add stale-while-revalidate for sidebar hosted review metadata, and preserve branch discovery correctness for stale linked PR metadata.
2026-05-15 22:42:17 -07:00
Neil 99df02b923 Add GitHub PR file viewed tracking (#1914) 2026-05-15 18:28:13 -07:00
Brennan BensonandOrca e5c394b09b Add pull request creation flow (#1960)
Co-authored-by: Orca <help@stably.ai>
2026-05-15 13:36:06 -07:00
Jinjing ac818caae5 Reduce GitHub GraphQL rate-limit spend (#1974) 2026-05-15 13:13:55 -07:00
Jinjing 9c601be199 Fix PR lookup during GitHub GraphQL limits (#1973) 2026-05-15 12:49:53 -07:00
Jinwoo HongandOrca 6c4bcf7ea6 feat(ssh): make remote workspaces first-class (#1876)
Co-authored-by: Orca <help@stably.ai>
2026-05-15 12:32:07 -07:00
Jinwoo Hong 31ab1560a7 Fix WSL gh fallback for task lists (#1879) 2026-05-14 22:42:11 -04:00
Jinjing 5a6b2994ea fix: address review findings (#1770) 2026-05-13 16:14:50 -07:00
3b0dda595d fix: pr-bug-scan findings from #1444 (#1466)
* fix: address pr-bug-scan findings from #1444

Threaded linkedPRNumber through all ChecksPanel force-refresh paths; gated useComposerState's PR-URL-from-name recovery on selected repo slug match; wrapped main-process linkedPR fallback gh pr view i

* fix: satisfy react-hooks/exhaustive-deps in selectedRepoSlug effect

Extract selectedRepo?.path into a const so the effect's only dep is
the path string, removing the missing-dependency warning.

---------

Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
Co-authored-by: Neil <neil@nousresearch.com>
2026-05-05 15:09:28 -07:00
JinjingandOrca 6a7cd2c9ae fix(github): link create-from-PR worktrees back to their PR (#1444)
When a worktree is created from a PR via the source picker, the new
local branch differs from the PR's head ref, so the branch-keyed PR
lookup misses and the worktree card shows no PR strip. Pass the
worktree's linkedPR number through the IPC call and fall back to a
number-based lookup in the main process. Also recover linkedPR from
a PR URL pasted into the workspace name when the user skips the
source picker. PR strip now wraps the whole row as the PR link.

Co-authored-by: Orca <help@stably.ai>
2026-05-05 11:43:13 -07:00
NeilandOrca 62e02a3b4c feat(new-workspace): unified source picker + non-submitted URL drafts for agents (#1426)
* Fix new workspace composer focus restore

* Unify new workspace source selection

* WIP: selected source pill in smart workspace name field

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

* fix(new-workspace): truncate source pill so it doesn't expand the dialog

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

* feat(new-workspace): add open-in-browser button to source pill, fix vertical alignment

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

* refactor(new-workspace): drop redundant kind suffix, distinct PR/issue icons, tooltips on pill actions

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

* fix(new-workspace): type linked URL into agent input without auto-submit

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

* fix(new-workspace): use bracketed-paste for draft URL injection so it actually appears in the agent input

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

* feat(agents): per-agent draft injection strategy (codex slow paste, pi/opencode type-chars)

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

* fix(agents): smarter TUI-ready heuristic + bracketed paste for codex/pi/opencode

Replaces per-agent strategy guesswork with a measured readiness check:
title-idle / non-shell-foreground stable for 1.5s / 2.5s minimum floor.
Verified against codex, pi, opencode, claude in a node-pty + xterm-headless
test rig — bracketed paste lands in the input buffer for all four.

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

* refactor(agents): drop unused per-agent draft strategy abstraction

The TUI-ready heuristic in agent-paste-draft.ts works for every tested
agent (claude/codex/pi/opencode), so the AgentDraftInjectionStrategy
field, type-chars + bracketed-paste-slow code paths, and per-agent
overrides are dead. Keep the `agent` arg on pasteDraftWhenAgentReady
for future per-agent escape hatches without touching every call site.

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

* feat(agents): skip draft URL injection for copilot + cursor-agent

Both TUIs open with a 'Do you trust this folder?' menu on first launch
that consumes keystrokes as menu input — pasting a URL there either
selects an arbitrary option or quits the session. Mark them with
skipDraftUrlInjection so the workspace still opens cleanly; the user
types/pastes the URL themselves once past the trust menu.

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

* feat(agents): native --prefill for claude, trust pre-write for cursor/copilot

Replaces the empirical TUI-ready waits with two deterministic mechanisms:

1) `claude --prefill <text>` flag — Claude launches with the URL already in
   its input box, no submit. Eliminates the readiness/paste race entirely
   for the most common agent.
2) DECSET 2004 (`\x1b[?2004h`) detection on the PTY data stream for every
   other agent. That escape is the protocol-level "input layer ready,
   accepting bracketed paste" handshake — emitted by claude/codex/pi/
   opencode/gemini/cursor-agent/copilot the moment the input box mounts.
   We tap it via a sidecar subscription on pty-dispatcher (no interference
   with the primary xterm handler) and paste as soon as it lands. The
   8s budget is now an upper bound, not a target.

Cursor-agent and Copilot's "Do you trust this folder?" menus are bypassed
by writing the same trust artifacts the CLIs themselves write after the
user accepts:
- Cursor: `~/.cursor/projects/<slug>/.workspace-trusted` (slug = abs path
  with leading `/` stripped, remaining `/` → `-`).
- Copilot: append cwd to `trustedFolders` in `~/.copilot/config.json`
  (the same array the bundled `addTrustedFolder` writes).

Verified against the cursor-agent CLI bundle (versions/2026.04.17-787b533/
index.js: `_=".workspace-trusted"`) and the @github/copilot 1.0.32 bundle
(`isFolderTrusted` / `addTrustedFolder` both read/write `trustedFolders`).
Both check via realpath() before string-comparing, so the trust preset
canonicalizes too.

skipDraftUrlInjection is dropped — both agents now get the draft URL
paste once the trust menu is pre-resolved.

Tests: 24 passing across tui-agent-startup, agent-trust-presets,
pty-dispatcher routing.

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

* fix(agents): wait for post-?2004h render burst to settle before paste

OpenCode emits DECSET 2004 at ~500ms during alt-screen setup, then runs
a 1.3s splash render with NO bytes on the PTY, then paints the actual
input box at ~1.85s. Pasting on the bare ?2004h signal lands during the
silent gap and the bytes are dropped.

The fix: take ?2004h as the necessary precondition, then wait for the
TUI's render burst to finish — defined as 1500ms of stream silence
after the most recent post-?2004h byte. This captures both the fast
TUIs (claude/pi/codex emit setup escapes in one burst then go quiet)
and the slow ones (opencode emits, sleeps for the splash, emits again,
then goes quiet).

Verified against opencode/claude/pi in a node-pty rig: paste lands on
the first try with the new strategy. The hard 8s timeout still caps
the wait when an agent fails to launch.

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

* fix(agents): guard agentTrust IPC so stale preload doesn't crash launch

If the preload bundle is older than the renderer (a real situation in
electron-vite dev because preload changes only apply on full restart,
not HMR), `window.api.agentTrust` is undefined and the launch crashes
with "Cannot read properties of undefined (reading 'markTrusted')"
before the worktree even opens.

Guard the call sites in launch-work-item-direct and useComposerState
to skip the trust pre-write when the IPC isn't exposed, and wrap the
invoke in try/catch so an IPC error never blocks the launch — the user
just sees the trust menu and accepts it manually, same as before this
feature shipped.

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

* feat(tasks): route 'Use' through the New Workspace dialog instead of yolo-create

The Use CTA on the Tasks page used to create+activate a worktree
synchronously, which surprised users — the worktree appeared in the
sidebar before they had a chance to confirm name / agent / setup. The
unified New Workspace dialog landed in this branch already supports
opening with a linked work item pre-filled (see openComposerForItem /
openComposerForLinearItem), so just route Use through it.

The launchWorkItemDirect helper stays exported for ProjectViewWrapper,
which has its own UX where the immediate-create flow is the right call.

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

* test(agents): include `agent` field in autohand startup-plan assertion

Merging main brought in the Autohand Code agent test (PR #1382), which
predated this branch's addition of `agent` to AgentStartupPlan.
Aligning the assertion fixes the lone CI test failure on this PR.

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

* refactor(agents): drop unused expectedProcess arg + snapshot sidecar set

Two minor follow-ups from self-review:

1. `pasteDraftWhenAgentReady` no longer reads `expectedProcess` — readiness
   is gated on DECSET 2004 alone now, not on PTY foreground process. Drop
   it from the signature and from the two callers (launch-work-item-direct,
   new-workspace).

2. The pty-dispatcher's sidecar fan-out iterates the live Set, which is
   safe against deleting the current element but not against a watcher
   that synchronously subscribes a sibling. Snapshot via Array.from
   before the loop. Cheap (Set is tiny) and removes the latent footgun.

No behavior change.

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

* test(e2e): match the unified smart-name input's new placeholder

The CreateFromTab refactor in this branch replaced the separate "Workspace
name" Input with a single SmartWorkspaceNameField whose default-mode
placeholder is "Type a name, #1234, branch, GitHub or Linear URL". The
worktree-create e2e test was still anchoring on the old "Workspace name"
text and could not find the input.

Update the placeholder regex to match the new copy. Free-form text typed
into smart mode is treated as a workspace name by submitQuick — same
contract the test used before.

Verified locally: targeted e2e passes in 2.2s.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-05 01:07:52 -07:00
Brennan BensonandOrca 70befde774 feat(github): per-repo issue-source selector (#1317)
Co-authored-by: Orca <help@stably.ai>
2026-05-01 21:48:51 -07:00
Brennan BensonandOrca 12858f37e3 feat(github): source-repo indicator + surface issue fetch errors (#1250)
Co-authored-by: Orca <help@stably.ai>
2026-04-30 22:53:37 -07:00
ed6c8755fe Prefer upstream remotes for GitHub issue tasks (#1076)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: brennanb2025 <brennankbenson@gmail.com>
2026-04-28 17:01:03 -07:00
6233b8e8a4 feat: Add GitHub PR review workflow to tasks (#1172)
* Render GitHub markdown safely

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

* Support PR line comment ranges in diffs

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

* Add GitHub item dialog review workflow

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

* Make attribution tests environment-safe

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

* Wire GitHubItemDialog for row clicks and bound file cache

Row clicks in the Tasks GitHub list now open the new GitHubItemDialog
instead of the legacy GitHubItemDrawer, making the PR review workflow
reachable from the main entry point. The unused drawer and its state
are removed.

Also bounds prFileContentCache at 64 entries with LRU eviction so the
module-level map can no longer grow without limit across many PR
openings in a session.

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

* Convert GitHubItemDialog to a right-side drawer

Replaces the centered Dialog modal with a Sheet drawer (side=right,
max-w 960/1100/1280 across breakpoints) so the review surface slides
in from the side instead of popping over the task list.

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

* Address review feedback on GitHub work-item details

- Restore full pagination in listAssignableUsers (REST /assignees --paginate)
  so repos with >100 assignees no longer silently drop users from the picker.
- Drop redundant REST /users/<login> fan-out in getMentionParticipants; the
  aliased GraphQL query already returns login/name/avatarUrl.
- Parallelize mention-participant lookup with checks/participants fetch.
- Avoid mutating caller-provided objects in mergeGitHubUsers.
- Type addIssueComment / addPRReviewComment(Reply) preload wrappers as
  Promise<GitHubCommentResult> instead of Promise<unknown>.
- Use typeof startLine === 'number' to harden the review-comment guard.

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

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-04-28 00:11:39 -07:00
fe6eecba0c feat(sidebar): improve PR checks and comments (#1134)
* feat(sidebar): improve PR checks and comments

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

* fix(sidebar): classify bot comments via GitHub user.type instead of login heuristic

Third-party review bots like qodo-ai-reviewer, coderabbitai, and sonarcloud
don't follow the [bot] suffix or "bot"/"automation" substring convention, so
the regex-based detector misclassified them as human. Plumb REST
`user.type === 'Bot'` and GraphQL `author.__typename === 'Bot'` through to the
renderer as an authoritative isBot flag; fall back to the login heuristic only
when the data source can't report it.

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

* fix(sidebar): allowlist AI review services that sign in as User accounts

qodo-ai-reviewer, coderabbitai, codium-ai and similar third-party review
services register as regular GitHub user accounts, so REST `user.type` is
"User" and their logins contain no "bot"/"automation" tokens. The previous
fix relied on the GitHub-reported type, which fails for these. Add an
explicit substring allowlist of known automation services so they still
land in the Bots tab.

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

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-04-26 13:28:09 -07:00