mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 00:02:10 +00:00
fix/execution-host-resolution
27
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b5a85890ac |
perf(git): bound git subprocess execution with an atomic admission scheduler (#16874)
* perf(git): bound git subprocess execution with an atomic admission scheduler Field traces (#16038, #11363) show Windows freeze storms driven by unbounded concurrent git children (12+ at once, 50-65s status convoys for 25+ minutes). Admit every main-process git child against atomic per-budget base+headroom counters (general / network / per-route), with reserved interactive capacity, ordering-only aging, close-bound permit release, a 120s fail-safe read timeout that feeds scheduler backoff, tier plumbing through every option carrier, and coalesced+jittered visibility pollers. Killswitch: ORCA_GIT_ADMISSION_DISABLED=1. Storm harness A/B: max concurrent children 65 -> 6, interactive p95 791ms -> 88ms; output-parity battery byte-identical with admission on vs off. * test(git): run the admission output-parity battery on every platform Parity needs real git, not the storm harness's PATH stub, so it must not share that file's POSIX gate - Windows is the platform where parity evidence matters. * fix(git): preserve interactive admission invariants * perf(git): keep admission queue drains linear * fix(git): close final admission gaps * perf(git): bound eligible route selection * fix(merge): remove unrelated stale snapshot changes * fix(git): preserve refresh lifecycle authority * test(git): align admission lifetime contracts * fix(git): harden admission across runtime paths * fix(git): restore freshness for bulk status reads * test(git): repoint delete-dialog source pins after admission plumbing The hydration effect now orders its targets through orderDeleteWorktreeStatusHydrationTargets and passes includeLineStats alongside the abort signal, so both literal anchors stopped matching. The invariants are unchanged and still pinned: dropping the signal, the main-worktree/folder filter, or getState-instead-of-subscribe each still reddens this test. * Fix git admission tier propagation and lock ordering Decode optional Git status tiers permissively and default runtime RPC status reads to the status lane while preserving renderer caller intent. Acquire the FETCH_HEAD mutex before atomic admission so same-repository fetch waiters hold no global or route permits. Preserve automatic pull-request refresh reasons, keep explicit hosted-review refreshes interactive, remove the dead candidate tier, and keep relay scheduling unchanged. Use tier-aware status lease keys because a shared lease cannot be safely promoted after its admission request is queued or granted. * test: align expectations with admission plumbing * refactor(child-process): move the process contract types to process-spec run-process.ts crossed its line cap after gaining the termination observer; the public types and defaults move out with re-exports so no caller changes. * chore: restore pnpm-lock.yaml to main (unintended local drift) --------- Co-authored-by: Merge Sim <sim@local> |
||
|
|
41ce4fadd9 |
Fix GitLab MR management menu in Checks sidebar (#16906)
* fix: add GitLab MR management menu * fix: restore GitLab menu typecheck * fix stale GitLab review relink updates * fix review relink guard lifecycle * test local owner scope for GitLab relinks * fix(gitlab): honor linked MR during review lookup * fix: reuse hosted review cache after relink * fix: avoid duplicate GitLab detail refresh |
||
|
|
77f23b013f |
refactor(shared): drop the shared/types barrel and import from the real modules (#14447)
#14397 split `shared/types.ts` into 46 per-domain modules but kept the path as a re-export barrel so the import sites did not have to change. This removes the barrel: every consumer now imports from the module that actually declares the type, and `src/shared/types.ts` is deleted. Barrels hide where a type lives, make every consumer look like it depends on the whole domain, and let an unrelated edit invalidate a module that ~2,000 files transitively import. 2,323 import declarations across 2,321 files. Rewritten mechanically: each specifier was resolved to an absolute path via the TypeScript AST and recomputed, rather than string-substituted, so alias forms (`@/../../shared/ types`) and per-specifier `type` modifiers survive. Four cases the mechanical pass had to handle, each found by a gate rather than by reading the diff: - Modules inside `src/shared` import the barrel as `./types`, not `shared/types`. A pre-filter on the latter string skipped 176 of them and left imports dangling at a deleted file, which surfaced as confusing `Property 'x' is optional in type 'Repo' but required in Pick<Repo, ...>` errors rather than "module not found". - The barrel RENAMED one type on the way through (`WorkspaceSource as WorkspaceCreateTelemetrySource`), so the original name in the owning module has to be re-aliased at each consumer. - Three test files put `;(globalThis as ...)` on the line after the import. TypeScript parses that `;` as the import statement's terminator, so replacing through `statement.getEnd()` deletes it and breaks ASI. The rewrite now stops at the module specifier. - A file that already imported directly from a module got a SECOND import from it, because the barrel re-exported those same names — which trips `import/no-duplicates` under `--deny-warnings`. A post-pass merges declarations sharing a specifier and type-only-ness; the `import type` plus `import` pair from one module is left alone, since that form is allowed. Splitting one barrel import into several genuinely adds lines, which pushed `terminal-layout-pty-ownership.ts` to 301 counted lines: its 107-character import must wrap, and neither local type collapses onto one line (101 and 116 characters). Rather than contort a type declaration to fit a line budget, `collectLeafIds` and `pruneLeaves` move to `terminal-pane-layout-tree.ts` — they are pure structural operations on the layout tree and independent of PTY ownership. `visible-worktrees.ts` similarly loses its own mini-barrel re-export of `isDefaultBranchWorkspace`, with the four real consumers repointed at the declaring module. No `max-lines` bypass added. Verified: cold `tsc --noEmit` green on node, cli, and web (buildinfo deleted first — these projects are `composite: true` and reuse stale caches); the full `pnpm lint` green, not just bare oxlint — the narrower local check is what let the duplicate imports reach CI; max-lines ratchet OK at 344. |
||
|
|
077f5a11cd |
feat(github): create stacked pull requests (#13750)
Adds GitHub stacked pull request creation: a contextual "Stack this PR above #N" option that appears only when the selected base branch has an open PR, plus the main-process stack preflight and registration. Also reworks the create-review composer for cohesion: shadcn Checkbox and Label primitives, base label above a full-width searchable combobox with attached results, keyboard navigation, and a unified field skin, spacing and typography scale. Verified end to end against real GitHub: extending an existing stack and creating a new one. |
||
|
|
63271a5933 |
feat(bitbucket): connect Bitbucket from Settings and create pull requests (#5832)
* feat(bitbucket): connect Bitbucket from Settings with encrypted credential storage Bitbucket Cloud was the only review provider with no in-app auth: GitHub and GitLab delegate to the gh/glab CLIs, but Bitbucket has no comparable first-party CLI, so the only option was ORCA_BITBUCKET_* env vars plus a restart (discussion #5364). Adds a Connect/Edit/Disconnect flow on the Bitbucket integration card, modeled on Linear and Jira: - Credentials are verified against /user before they are persisted, so a dead token is rejected inline instead of silently stored. - The secret is encrypted with safeStorage (0600 plaintext fallback when no OS keyring); non-secret metadata lives in a separate plaintext file so status reads render the connected account without decrypting. Opening Settings therefore never triggers a keychain prompt. - Env vars keep precedence over stored credentials, so existing headless and SSH setups are unaffected. Env-managed connections hide Disconnect. - connect/disconnect reset the preflight cache, so no relaunch is needed. The Bitbucket card moves to its own file to stay under the tsx max-lines cap. * feat(bitbucket): support creating pull requests from Orca Bitbucket was the only configured provider whose Create button reported "This repository provider does not support creating a pull request from Orca" — supportsReviewCreation was false and the forge provider had no createReview, so even a correctly authenticated setup was blocked. Adds createBitbucketPullRequest against POST /repositories/{ws}/{repo}/ pullrequests, using the same env-first / stored-credential resolution as PR lookups (extracted into resolve-auth.ts so both share one path). Bitbucket Cloud has no draft pull requests, so a draft request is rejected with a clear message rather than silently publishing a live PR. * fix(bitbucket): hide the draft toggle where drafts do not exist, plus review fixes Bitbucket Cloud has no draft pull requests, so the composer no longer offers the toggle for it and forces the flag off at submit — better than failing after the user has filled the form in. Review fixes: - writeFileSync's `mode` only applies when it creates the file, so rewriting a credential kept whatever permissions it already had. chmod after every write, for the secret and the metadata. - An explicit ORCA_BITBUCKET_API_BASE_URL now wins over a stored base URL. Env precedence is per-setting, not all-or-nothing. - Enter in the credentials dialog only submits from a text field, so it no longer hijacks Cancel and the docs link. - Replace the chmod-based delete-failure test with a mocked unlinkSync: file modes are not portable to Windows and elevated runners unlink anyway. * fix(bitbucket): stop a merged pull request from blocking the branch's next one Reported on #5832: with a merged PR on a branch, Create reported "Pull request already exists" and offered no way forward. The branch lookup queries every PR state and returns the most recently updated one, so a merged PR came back as the branch's current review and eligibility blocked on it. Bitbucket only discarded such a match on the repo default branch (#9171), while GitHub already drops any merged PR it matched by branch alone — "a merged PR without an explicit link is just a historical branch match, not implicit review context". Applies that rule to Bitbucket. An explicitly linked review still resolves through the linked-number fallback, so merging a PR Orca knows about keeps showing it. * fix(bitbucket): add bitbucket to the shared review-creation provider list Reported on #5832: on a Bitbucket repo with no existing PR, Create still said "This repository provider does not support creating a pull request from Orca", even after the forge provider gained createReview. There are two capability lists. Enabling supportsReviewCreation on the forge provider was necessary but not sufficient — the blocker and the whole renderer read the separate shared list, which never included bitbucket. Adds it, gives Bitbucket its own provider name so review copy stops saying "GitHub", and asserts the two lists agree so they cannot drift apart again. * fix(bitbucket): persist pull request links after creation * fix(bitbucket): fetch linked pull requests by number first * fix(i18n): use generated Bitbucket integration keys * test(bitbucket): cover forge creation delegation * fix(bitbucket): fall back when linked pull request is stale * docs(bitbucket): explain notFoundIsNull and fix a garbled permissions comment notFoundIsNull arrived without the rationale its sibling flag carries, and reads as a bare `true` at the only call site that opts in. * fix(bitbucket): address review findings before merge Two of these made the feature unusable in real setups: - Create PR checked GitHub authentication for Bitbucket. isProviderAuthenticated fell through to isGitHubAuthenticated, which was unreachable while Bitbucket could not create reviews at all. Anyone with Bitbucket connected but no `gh auth login` got auth_required with no way forward. - The draft flag was only gated in ChecksPanel, not the two SourceControl call sites. With "create as draft" saved as a default, the composer hides the toggle for Bitbucket, so the flag could not be cleared and creation failed every time. Bitbucket now ignores draft instead of rejecting it. Also: - Blocked-create copy said "GitHub is not authenticated. Run gh auth login" on Bitbucket repos, in both the main-process and renderer paths. - A decryption failure resolved to an anonymous config and queried anyway; a private repo answers 404, which reads as "no pull request" and offers Create for a branch that already has one. Requests now fail closed. - Hiding non-open implicit branch matches was too broad: a declined PR became permanently invisible off the default branch. Scoped to merged, restoring the default-branch rule (#9171) for the rest. - A failed disconnect rejected unhandled and the card silently re-rendered as connected; a partial delete left the secret live in memory for the session. - The credentials dialog refused to open on a remote runtime, so a local repo could never store a credential. Now only the storage note changes, matching the Jira dialog. --------- Co-authored-by: devatnull <59279509+devatnull@users.noreply.github.com> |
||
|
|
c1e75477f3 |
Fix static analysis page stuck in loading state (#13674)
* Fix static analysis page stuck in loading state - Bound check-details requests with 30s timeout, matching remote RPC budget - Track request IDs to discard stale responses when context changes - Propagate githubRepository through store and components for proper routing - Add retry button for failed check-details loads - Improve accessibility with ARIA labels for loading and error states * Fix static analysis page stuck in loading state When an open check-details tab's repository is removed, the loading state would continue indefinitely because the fetch was still being triggered. Prevent the fetch call in this scenario to unblock the UI. Also migrates translation keys to obfuscated identifiers. * Fix static analysis page stuck in loading state Add deadline-based timeouts and request ID tracking to prevent stale responses from freezing the checks panel. Include abort signal propagation throughout the request chain and provide retry UI for failed check details loads. * fix(checks): prevent loading state from getting stuck on retry - Consolidate mount checks into a helper function - Details now clear when a new request begins - Add i18n strings for retry status |
||
|
|
d19f511786 | refactor(reviews): remove retired queue foundation (#13500) | ||
|
|
73c5009b82 |
chore(dead-code): drop ~2k lines of unreachable exports and orphan modules (#12077)
* chore(dead-code): drop 2k lines of unreachable exports and orphan modules Ran knip across every build entry (main, preload, renderer, popout, web, cli, relay, workers, forked sidecars, config scripts) and removed what no entry graph can reach. - 11 orphan modules nothing imported, plus one test that only covered them - 159 unused exports/types, with their now-dead helpers, imports and tests Each candidate was verified against dynamic references before deletion. 42 knip hits were false positives and are kept: shared modules consumed by the mobile/ workspace, the src/shared/plugins/** public API, vendored shadcn primitives, and relay wire-protocol constants held for compatibility. Adds knip.json + `pnpm audit:dead-code` so this stays measurable. Verified: pnpm typecheck, pnpm lint, and 2081 tests across the 73 affected test files all pass. * chore(dead-code): move knip config under config/ Root-level additions are blocked by the root directory guard. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
2f104d8713 |
Tier GitHub PR lookup polling to prevent quota exhaustion (#12013)
* Tier GitHub PR lookup polling to prevent quota exhaustion The selected worktree (O(1)) checks per-minute; card list (O(N)) per-15-minutes. Introduce process-wide cache to collapse concurrent polling and gate lookups on available rate-limit budget with exponential backoff on failure. - Preserve last-known review during backoff - Invalidate cache when Orca opens a PR - Stop coordinator from double-charging * Tier GitHub PR lookup polling to prevent quota exhaustion - Return the latest reset time when both GitHub API buckets are rate-limited, preventing premature retries against still-blocked buckets. - Serve the last known review on transient lookup failures, preventing reviews from blinking out on temporary errors. - Discard in-flight lookups that predate an invalidation so stale answers cannot overwrite newly opened reviews. * fix: give rate-limit reset tests unique titles oxlint vitest/no-identical-title was failing static analysis because two cases shared the same describe title. |
||
|
|
d67ede1594 |
Implement confirm-only PR panel composer with classified error blocking (#9428)
* Clarify PR panel guidance: classify errors and confirm-only composer Replace the ambiguous GitHub hosted-review boolean with a four-state evidence model (found/positive_unresolved/not_found/unknown) so "No PR found" never appears without an accepted lookup result. Classify GitHub refresh failures into types (rate_limited, auth, network, permission, repo_unavailable, gh_unavailable, unknown) for stable, honest copy. Confirmed-only composer: preserve drafts across transient failures; hide Create during hard errors and positive-unresolved evidence. Hard errors clear only when an eligibility request starts after the error and returns an accepted outcome. Propagate error types and unified retry schedule through the store. Sync mobile parity with shouldOpenChecksPanelCreateComposer gating. Localize all new copy. * Clarify PR panel guidance: classify errors and confirm-only composer Add reviewLookupOutcome to hosted-review eligibility and thread it through the panel so it never claims "No PR found" without accepted evidence. A failed lookup is unavailable, not a settled no-PR. Fail closed on positive unresolved evidence, hard refresh errors, and unavailable lookups. Add structured GitHub refresh-error classification with Retry-After parsing. Implement confirmed-only composer gating based on fresh, matching-context eligibility with hard-error clearing. Mobile gates on reviewLookupOutcome to prevent false Create claims. Surface throwOnFailure variants for each provider so transport failures cross the RPC boundary instead of collapsing to null. (Design success criteria 1–4; invariant 8.) * Add exec-error helpers for subprocess error classification Extracts stderr/stdout parsing and Retry-After detection into a lightweight module that can be imported without pulling in the heavier runner machinery. Supports PR-refresh error classification and proper rate-limit handling for gh commands. * test(mobile): include reviewLookupOutcome in create eligibility fixtures Create / Push & Create now fails closed unless the lookup is not_found. Update mobile test fixtures so accepted-no-PR cases can still proceed. * Add OrThrow mock variants to forge-provider test mocks forge-provider resolves branch reviews via the OrThrow variant so lookup failures surface as unavailable instead of "no PR found". |
||
|
|
1ef0551bc1 |
Create pr not working for stacked worktree (#8651)
* Fix stacked-worktree PR creation targeting a local-only parent branch - Resolve the eligibility default base to a remote-tracking ref instead of blindly trusting the submitted parent branch, since a stacked worktree's base is often a local-only branch the remote can't resolve - Add a create-time hard block (base_not_on_remote) so a stale or unpushed submitted base fails with actionable copy instead of the provider's opaque error - Update the dialog's default-base resolution and blocked-action/ dropdown copy to match the new remote-validated default * Split hosted-review-creation.test.ts to fix max-lines lint error Moved getHostedReviewCreationEligibility tests to a separate file (hosted-review-creation-eligibility.test.ts) to reduce the original file size from 880 to 579 lines, satisfying the max-lines lint constraint. Co-authored-by: Orca <help@stably.ai> * Fix Create PR intent flow to use remote-validated eligibility default fo Prefer eligibilityDefaultBaseRef over the raw compare base when resolving the review base for the one-click Create PR intent flow, since eligibility is recomputed from the same compare base right before creation and already corrects a local-only stacked parent to the repo default. Falls back to the compare base only when eligibility supplies no default. * Simplify base-ref remote existence check into a single for-each-ref call Combine the wildcard and exact-tracking-ref lookups into one for-each-ref invocation with multiple patterns instead of two sequential git calls, removing the redundant rev-parse fallback path. --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
6883052a8f |
Fix push-target resolution missing queue-discovered PRs (#8351)
Include fallbackGitHubPR alongside linkedGitHubPR/linkedGitLabMR when determining whether a hosted review link resolves to a push target. Worktrees without persisted linkedPR metadata (e.g. child worktrees) were incorrectly blocked with "target unavailable" despite having a real matching upstream, since their PR was only known via the queue fallback. Also splits hasPositiveHostedReviewNumberLink to build on the resolvable subset so the two helpers can't drift. |
||
|
|
b099e27703 |
fix(checks): keep a merged PR visible when the worktree sits behind its own PR head (#7277)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
a71b865867 |
Show PR status for branch worktrees at a merged PR head (#6607)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
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. |
||
|
|
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. |
||
|
+3 |
36277801e4 |
Make remote hosts first class: concurrent multi-host workbench (#5071)
* 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> |
||
|
|
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> |
||
|
|
a15b13b02d |
Customize Source Control AI prompts (#2916)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
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 |
||
|
|
40e903d833 | fix: address review findings (#2138) | ||
|
|
64cf1d5d56 |
Add Azure DevOps Repos hosted review support
Add Azure DevOps Repos hosted review lookup, preflight, and shared hosted-review plumbing. |
||
|
|
c90b9f72ef |
Add PR review queue badge foundation
- Add provider-neutral review queue types, adapter, and checks-panel badges.\n- Keep the design doc out of the PR diff. |
||
|
|
e5c394b09b |
Add pull request creation flow (#1960)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
6c4bcf7ea6 |
feat(ssh): make remote workspaces first-class (#1876)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
f81b3f219f | Add Gitea hosted review support | ||
|
|
bca39bc928 |
Add GitLab and Bitbucket hosted review support (#1839)
* feat(gitlab): add foundational glab runner, types, and issue operations First slice of GitLab support, mirroring src/main/github/ structurally without refactoring the working GitHub path. - runner: add glabExecFileAsync parallel to ghExecFileAsync (same WSL routing and retry policy; HTTP-status / network classification is provider-agnostic so the existing helpers are reused). - types: GitLabProjectRef carries host alongside path so self-hosted instances and nested groups round-trip through the IPC layer. Mirror shapes for MR/issue/work-item/comment/file/assignable-user. - gitlab/gl-utils: concurrency limiter, error classification, project-ref resolution honoring upstream/origin preference, and known-host discovery via `glab auth status` so non-gitlab.com remotes are recognized after the user authenticates. - gitlab/mappers: pipeline-job → check-status mapping, MR state resolution (including draft inferred from `Draft:`/`WIP:` title prefix), and pipeline rollup. - gitlab/issues: full issue CRUD via `glab api` against URL-encoded project paths, with the same upstream/origin preference semantics as the GitHub side. 63 unit tests passing across gl-utils / mappers / issues. Both typecheck:node and typecheck:web clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): preflight glab auth check and URL parser - preflight: probe `glab --version` + `glab auth status` alongside the existing gh checks. PreflightStatus.glab is optional so renderer call sites that only render git/gh keep typechecking; consumers gating on GitLab affordances opt in via `glab?.authenticated`. - gitlab-links: parse GitLab issue and merge-request URLs honoring (a) arbitrary self-hosted hosts via the project-internal `/-/` separator rather than locking to gitlab.com, (b) nested group paths, and (c) GitLab's `!42` MR convention alongside `#42`. 26 unit tests added (5 new preflight cases, 21 URL-parser cases). Full typecheck (node + cli + web) clean. Pre-existing runtime/orchestration test failures unrelated to this branch — Node 25 vs the project's pinned Node 24 engine. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): MR list/get + paginated `glab api -i` helper Lean mirror of github/client.ts focused on the workspace-from-MR keystone. Adopts GitLab-native filter semantics (Open / Merged / Closed / All) instead of porting GitHub's search-DSL — that path is covered by the upcoming My Todos surface. - gl-utils: glabApiWithHeaders + parseGlabApiResponse for strict pagination via X-Total / X-Total-Pages on `glab api -i` output. CRLF / LF tolerant; status line never leaks into the headers map. - types: MRListState, GitLabPagedResult<T>, ListMergeRequestsResult. - mappers: mapMRToWorkItem + mapIssueToWorkItem produce the unified GitLabWorkItem shape the picker consumes. isCrossRepository derived from source_project_id !== target_project_id; deterministic id fallback when the per-MR detail endpoint omits global id. - client: getAuthenticatedViewer, getMergeRequest (with head pipeline rolled up), getMergeRequestForBranch (mirrors github/getPRForBranch semantics including refs/heads/ stripping and detached-HEAD guard), listMergeRequests (paginated), getWorkItemByProjectRef (paste-URL flow). Re-exports issues + projectRef helpers so callers don't have to know the gl-utils module split. 35 new tests (98 total in src/main/gitlab/), full typecheck clean. Tests split into client.test.ts + client-mr.test.ts to stay under the oxlint max-lines budget — matches github/client*.test.ts pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): worktrees:resolveMrBase IPC + linkedGitLab* persistence The workspace-from-MR keystone. Mirror of worktrees:resolvePrBase shape and semantics — caller passes mrIid (with optional source_branch / isCrossRepository hints), handler returns either a remote/branch ref (same-project MRs) or a SHA fetched from refs/merge-requests/<iid>/head (fork MRs). - types: linkedGitLabMR / linkedGitLabIssue on Worktree + WorktreeMeta. Marked optional so existing test fixtures and persisted older worktrees that pre-date these fields keep typechecking and loading without a migration. - persistence: getDefaultWorktreeMeta initializes both fields to null. - worktree-logic: mergeWorktree carries them through from meta. - worktrees IPC: resolveMrBase mirrors resolvePrBase. Resolves the GitLab project via getProjectRef + known-host discovery, fetches the MR work-item to derive source_branch + isCrossRepository when those hints aren't provided, and uses GitLab's refs/merge-requests/<iid>/head for fork MRs (parallel of GitHub's refs/pull/<N>/head). - tests: 6 fixture updates for the new optional fields. Full typecheck (node + cli + web) clean; 165 tests passing across src/main/gitlab/, preflight, worktree-logic, and gitlab-links. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): IPC channels + preload bindings (gl.*) Wire the GitLab backend to the renderer. Lean v1 surface — issues CRUD, MR list/get/getForBranch, viewer, project slug, paste-URL work-item lookup. Skips workItemDetails / listWorkItems-combined / listTodos until the matching backend pieces land. - main/ipc/gitlab.ts: thirteen handlers under the `gitlab:*` channel prefix with the same assertRegisteredRepo guard the gh handlers use. listIssues unwraps the structured result envelope to bare items[] to match window.api.gh.listIssues' shape; consumers that need the classified error can graduate to the envelope later. - main/ipc/register-core-handlers.ts: register alongside gh. - preload/api-types.ts: typed `gl: { ... }` block parallel to the existing `gh: { ... }`. Imports the new GitLab types so renderer code consuming the preload gets full inference. - preload/index.ts: runtime `gl: { ... }` exposes wired to ipcRenderer. Full typecheck (node + cli + web) clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): workspace-from-MR via paste-URL (keystone end-to-end) The first user-visible GitLab moment. Pasting a GitLab issue or MR URL into the workspace name field now resolves through the full pipeline to a created workspace with the right base ref and linkedGitLab* persisted. The dedicated GitLab tab + state-filter chips remain a follow-up; everything below it is wired. - shared/lib/new-workspace.ts: LinkedWorkItemSummary.type accepts `'mr'` alongside `'issue' | 'pr'`. Renderer code that switches on type explicitly handles each kind. - ui store slice: NewWorkspaceDraft mirrors the new linked slots so drafts persist GitLab selections across navigation. Optional fields for backward compatibility with drafts saved before this branch. - useComposerState: - linkedGitLabIssue / linkedGitLabMR state, draft persistence, repo-switch reset, applyWorktreeMeta wiring. - applyLinkedGitLabWorkItem mirrors applyLinkedWorkItem; reuses getLinkedWorkItemSuggestedName by structurally projecting the GitLab item onto the helper's input shape. - handleSmartGitLabItemSelect parallels handleSmartGitHubItemSelect: for picked MRs, calls window.api.worktrees.resolveMrBase to resolve the base ref (refs/merge-requests/<iid>/head for fork MRs) and threads it through handleBaseBranchMrSelect. - "was MR !N" reset hint when a repo switch wipes a GitLab selection — `!N` matches gitlab.com's MR-reference convention. - preload: window.api.worktrees.resolveMrBase + window.api.gl.* are already in. ComposerCardProps grows onSmartGitLabItemSelect (+ optional onBaseBranchMrSelect). - SmartWorkspaceNameField: - Paste-URL detection: parseGitLabIssueOrMRLink (host-agnostic via `/-/` separator) → window.api.gl.workItemByPath → row in the dropdown → click → forwarded to onGitLabItemSelect. - SmartWorkspaceNameSelection union, RowEntry union, RowIcon, RowLabel, SelectionIcon all carry the gitlab-mr / gitlab-issue kinds. MR rows show `!N` prefix; issue rows show `#N`. - Tab UI not added in this commit — paste-URL works in 'smart' mode, the dedicated tab + Open/Merged/Closed/All chips lands in a follow-up. - NewWorkspaceComposerCard: forwards onSmartGitLabItemSelect to the picker. Full typecheck (node + cli + web) clean. 165 unit tests passing in affected files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): GitLab tab in SmartWorkspaceNameField with state filter The discoverable demo path. The picker now has a "GitLab" tab — when selected it lists the project's MRs filtered by state via `gitlab:listMRs`, with an Open / Merged / Closed / All chip strip that mirrors gitlab.com's MR-page tab strip. Paste-URL detection in 'smart' mode is unchanged; the new tab simply makes the surface discoverable without requiring a URL. - SmartNameMode gains 'gitlab'; Gitlab icon (lucide) added to the MODES array between GitHub and Branch. - MrStateFilter / MR_STATE_FILTERS centralizes the four chip values so the labels stay GitLab-native (Open vs the GraphQL 'opened'). - listMRs effect: fires when mode === 'gitlab' and no GitLab URL is in the input, with the current state filter and a page-1 fetch bounded by RESULT_LIMIT. - Paste-URL effect now coexists with the list effect: it owns gitlabItems while a URL is in the input, the list effect owns it otherwise. Switching tabs no longer clears the list. - Chip strip rendered above the popover's CommandList only when mode === 'gitlab'. Buttons use the same Button component the rest of the picker uses for visual consistency. Full typecheck (node + cli + web) clean. 165 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): GitLab source on Tasks screen The Tasks screen now offers GitLab as a third source alongside GitHub and Linear. Selecting it surfaces MRs and issues for the primary selected repo with a state filter (Open / Merged / Closed / All) that mirrors gitlab.com's MR-page tab strip. Skips cross-repo aggregation, search DSL, and Projects mode for v1 — those layers are GitHub-API- shaped and would need a parallel store slice that is not worth porting ahead of the actual demand for them. - shared/types: GlobalSettings.defaultTaskSource accepts 'gitlab'. - TaskPage: - TaskSource union grows a 'gitlab' member; SOURCE_OPTIONS adds the Gitlab icon between GitHub and Linear so the toolbar order matches SmartWorkspaceNameField for cross-surface consistency. - GITLAB_TASK_FILTERS centralizes the four chip values. - Per-source state slim (matches Linear's pattern) — gitlabFilter, gitlabItems, gitlabLoading, gitlabError, gitlabRefreshNonce. - Data-fetch effect runs Promise.all over `window.api.gl.listMRs` and `window.api.gl.listIssues` for the primary repo, merges and sorts by updatedAt desc. 'merged' filter skips the issue fetch (GitLab issues are 'opened' / 'closed' only). - Filter bar block parallel to Linear's, with chips + a refresh icon-button. - List block: 5-column grid (ID / Title / Type+State / Updated / Open-link). Row click opens the web URL — the GitLabItemDialog is a follow-up commit, but the row affordance is enough for the Tasks-screen demo. - GitLab MRs render as `!N`; issues render as `#N` to match gitlab.com's reference convention. Full typecheck (node + cli + web) clean. 165 unit tests still passing in affected files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): GitLabItemDialog (minimal) + Tasks screen wiring Clicking a GitLab row on the Tasks screen now opens a side-sheet preview with the item's title, state, author, and description body rendered as markdown. "Open in browser" footer button stays as the escape hatch; opening from the row is dialog-first now (matching the GitHub side's row-click-to-dialog pattern). Files / comments / pipeline tabs are deferred — they mirror substantial GitHub-side surface area (work-item-details ~550 lines, GitHubItemDialog 2680 lines) and are not blocking the demo. - types: MRInfo and GitLabIssueInfo gain optional description / author / authorAvatarUrl. Optional because list endpoints strip them; populated on detail-endpoint reads (`getMR` / `getIssue`). - mappers: mapMRInfo and mapGitLabIssueInfo now pass description / author / avatar through when present. Skipped (rather than defaulted to '') so callers can distinguish "no body authored" from "this came from a list". - GitLabItemDialog: new ~200-line side sheet. Fetches the detail payload via `window.api.gl.mr` / `gl.issue` on open; renders CommentMarkdown for the description (reused from the GitHub side); falls back to "No description." when the body is blank. State badge tones picked locally — GitLab's MR state space is wider than GitHub's so coupling them buys nothing. - TaskPage: GitLab row now uses a div role=button with keyboard handling so the inner Open-in-browser <button> nests cleanly (HTML disallows nested <button>s, React would warn). Row click sets gitlabDialogItem; the small ExternalLink icon stops propagation so it still opens the URL. Full typecheck (node + cli + web) clean. 165 unit tests passing in affected files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): My Todos cross-project view on Tasks screen The GitLab tab now has a Project | My Todos sub-toggle. "My Todos" fetches gitlab.com/dashboard/todos via `glab api todos?state=pending` and surfaces them in a separate table — action / title / project / updated. This is the closest GitLab-native equivalent of GitHub's notifications/inbox and lands in lieu of porting GitHub's search-DSL which doesn't translate. - shared/types: GitLabTodo type with action_name, target_type/iid, target_url, project_path, author, updated_at. action_name kept as open-ended string because new GitLab versions extend the verb set. - gitlab/client.ts: listTodos uses `glab api --paginate todos?state= pending&per_page=50`. User-scoped — cwd doesn't matter, but the IPC path-validation guard still requires *some* registered repo path so we keep the signature consistent with the rest of gl.*. - IPC: `gitlab:todos` channel; preload `gl.todos`. - TaskPage: - gitlabView ('project' | 'todos') gates which list to render. - Sub-toggle row above the chip strip; chips are hidden on the Todos view since pending state has no Open/Merged/Closed axis. - Refresh button serves both views (uses gitlabRefreshNonce). - Todos table: 5-col grid, action verb (snake_case → spaces), target title, project path (mono font for repo-likeness), updated date, open-link icon. Row click opens target_url. Full typecheck (node + cli + web) clean. 165 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): gitlabProjects settings (recents auto-tracked) + tests Settings persistence for GitLab project preferences plus tests for the surface added since the last green run. - shared/types: GitLabProjectSettings { pinned, recent } and an optional GlobalSettings.gitlabProjects slot. Optional for backward compat with profiles saved before this branch — the persistence merge fills the empty default. - shared/gitlab-projects: pure helper computeNextGitLabRecents that prepends-and-dedupes by host+path, caps at GITLAB_RECENTS_MAX (10). Pulled out of the IPC handler so it tests without mocking Store. - gitlab IPC: workItemByPath handler now pushes the resolved project ref onto recents on success. 404 / auth-fail lookups do not pollute the list — recents reflects projects the user actually read. Tests added (12 new, 177 total passing in affected files): - gitlab-projects.test: prepend, dedupe, host-vs-host distinct, cap at max, no input mutation. - client.test: listTodos mapping, defensive state coercion, empty-on-error fallback, missing-target field defaults. - mappers.test: description / author / authorAvatarUrl pass- through on both mapMRInfo and mapGitLabIssueInfo, plus the "absent vs blank" distinguishing assertion. - mappers-workitem.test (split): mapMRToWorkItem + mapIssueToWorkItem cases moved out of mappers.test.ts to keep both files under the oxlint max-lines budget. Full typecheck (node + cli + web) clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): combined listWorkItems IPC + TaskPage refactor Centralize the MR + issue merge logic that TaskPage was doing inline into a single backend function and IPC channel. Future callers (the picker's GitLab tab, any new widget) get the merge / sort / state- mapping rule for free. The TaskPage effect drops from 60 lines of inline orchestration to a single call. - gitlab/issues: listIssues now accepts an IssueListState so the combined caller can ask for closed / all instead of always opened. CLI fallback path picks the right --opened / --closed / --all flag per glab version. Existing callers keep the 'opened' default. - gitlab/client: listWorkItems(state, page, perPage, preference) fans out listMergeRequests + a raw issues fetch in parallel, merges by updatedAt desc, returns a GitLabPagedResult<GitLabWorkItem>. Bypasses listIssues for the issues side because IssueInfo strips updated_at — the combined sort needs it. state='merged' skips the issues fetch entirely (issues don't have a merged lifecycle). - IPC: new gitlab:listWorkItems handler. - preload: gl.listWorkItems alongside gl.listMRs. - TaskPage: GitLab fetch effect now calls gl.listWorkItems and stops re-implementing the merge. Same UX, fewer moving parts. Tests added (8 new in client-work-items.test.ts; +1 fix to issues.test.ts for the new url-param order): - merge ordering by updatedAt desc - 'merged' state skips issues fetch - closed / all state pass-through - not_found envelope when project ref unresolved - mr-error vs issue-side success interleaving - combined error surfacing on either side failing Full typecheck (node + cli + web) clean. 117 unit tests passing in src/main/gitlab/ and src/shared/gitlab-projects.test.ts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): work-item-details + dialog Conversation/Pipeline tabs Task 3 lean version. The minimal description-only dialog grows two new tabs (Conversation / Pipeline) and four footer actions (close / reopen / merge / comment). Files-tab and inline review- comment positioning stay deferred — they mirror substantial GitHub- side surface (GitHubItemDialog is 2680 lines, work-item-details.ts is 551) and the v1 demo doesn't need them. - shared/types: GitLabPipelineJob (id, name, stage, status, webUrl, duration), GitLabWorkItemDetails (item + body + comments[] + pipelineJobs?[]). Mirrors GitHubWorkItemDetails layout. - main/gitlab/work-item-details: getWorkItemDetails(repoPath, iid, type) fans out parallel reads — issue: detail + discussions; MR: detail + discussions, then pipeline jobs follow-up keyed off head_pipeline.id. Discussion → MRComment flatten skips system notes (auto-generated activity entries) so the conversation tab shows only user content. Inline-review position carried through as `path` + `line` for v1.5 to consume. - main/gitlab/client: closeMR / reopenMR / mergeMR / addMRComment mutations. mergeMR accepts the same 'merge' | 'squash' | 'rebase' union as the GitHub side; close/reopen treat "already X" stderr as success since the desired state is reached. - IPC: gitlab:workItemDetails, closeMR, reopenMR, mergeMR, addMRComment channels; preload `gl.*` bindings parallel. - GitLabItemDialog rewrite: three Tabs (Description / Conversation / Pipeline-MRs-only) + footer with comment composer + state-aware Merge / Close / Reopen buttons. Cmd/Ctrl+Enter sends the comment to match gitlab.com's textarea shortcut. Refresh icon in the header re-fetches via a refreshNonce. eslint-disable max-lines on the dialog matches the GitHub-side equivalent's reasoning. Full typecheck (node + cli + web) clean. 184 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): sidebar icon, Smart-mix MRs, Integrations card, "Project MRs" rename Four follow-up fixes that surfaced from smoke-testing: - SidebarNav: GitLab icon next to GitHub / Linear in the Tasks-row shortcut strip; clicks open the Tasks page already filtered to the GitLab source. ui.ts taskPageData.taskSource union grows to accept 'gitlab' so the openTaskPage call typechecks. - SmartWorkspaceNameField: list-MRs effect now fires in 'smart' mode too, not just on the dedicated GitLab tab. The mixed picker surfaces the user's project MRs alongside GitHub items. Paste-URL effect still wins when a GitLab URL is in the input — the list effect bails on parsedGlLink !== null. - TaskPage: GitLab toggle relabels "Project" → "Project MRs" so the pairing with "My Todos" reads more clearly. - IntegrationsPane: new GitLab card mirroring the GitHub card — status badge (checking / connected / not-installed / not- authenticated), install link to gitlab.com/gitlab-org/cli, copy- ready `glab auth login` block, learn-more link to the auth/login doc, re-check button. Search-entry registered so settings search finds it. eslint-disable max-lines justified by the same pattern that already lives there for GitHub + Linear. - preload: PreflightStatus.glab is optional on the type so older payloads typecheck; consumers gate on the optional chain. Full typecheck (node + cli + web) clean. 184 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gitlab): multi-repo aggregation on Tasks screen Mirrors GitHub's cross-repo behavior. Previously the GitLab tab only queried the first selected repo; now it fans out to every eligible selected repo in parallel and merges results sorted by updatedAt desc. The repo selector at the top of Tasks is the project picker — it's the same one the GitHub tab uses, so the selection model is consistent across providers. - TaskPage gitlab fetch effect: Promise.allSettled across all selectedRepos that aren't SSH-relay (folder-mode repos and remote worktrees fall through). Each repo's project is resolved from its own git remote by the main process; non-GitLab repos return not_found which the renderer drops silently so a mixed selection (GitHub + GitLab repos) doesn't surface false errors on the GitLab tab. - Per-row repoId tagging stays correct — items keep their source repo's id through the merge, which matters for the dialog repoPath resolution below. - Banner display: only shown when EVERY eligible repo failed; partial failure is signaled by the row count being lower, not a banner that overshadows working repos. - GitLabItemDialog repoPath: derived from the clicked item's source repo (selectedRepos.find by repoId) instead of primaryRepo. Without this, clicking an item from a non-primary repo would route the detail fetch through the wrong repo's remote. Full typecheck (node + cli + web) clean. 117 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gitlab): swap MR icon to GitMerge for visual distinction GitPullRequest (curved-merge) reads similar to GitBranch (forking line) at the small sizes we use in the picker — feedback was that MR rows looked like branch rows. GitMerge (arrow-merge-into-line) reads as its own thing and matches gitlab.com's MR iconography, so users coming from the web UI find it familiar. GitHub PRs keep GitPullRequest — that matches github.com and keeps provider attribution distinct from GitLab MRs at a glance: GitHub PR: GitPullRequest (curved merge) GitLab MR: GitMerge (arrow merge) Branch: GitBranch (fork) Issue: CircleDot (provider-agnostic) - SmartWorkspaceNameField RowIcon + SelectionIcon: gitlab-mr → GitMerge. github-pr stays GitPullRequest. - GitLabItemDialog header icon: GitMerge for MRs. Full typecheck (node + cli + web) clean. 117 unit tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(gitlab): split shared types + preload into per-provider files Pre-emptive merge-conflict reduction. The two recent main syncs each surfaced ~5 conflicts, all in the same handful of central files where every provider lands code. Moving the GitLab footprint into provider-scoped files cuts the conflict surface roughly in half without changing any runtime behavior. - shared/gitlab-types.ts (new, 272 lines): every standalone GitLab type that previously lived in shared/types.ts — GitLabProjectRef / MRState / MRMergeableState / MRCheckDetail / MRInfo / GitLabReaction / MRComment / GitLabCommentResult / GitLabIssueInfo / GitLabViewer / GitLabAssignableUser / GitLabWorkItem / GitLabMRFile / GitLabProjectSettings / GitLabTodo[TargetType] / GitLabPipelineJob / GitLabWorkItemDetails / GitLabIssueUpdate / MRListState / GitLabPagedResult / ListMergeRequestsResult. - shared/types.ts: re-exports the GitLab types so existing call sites importing from '../shared/types' keep working unchanged. GitLabProjectSettings additionally imported locally for the GlobalSettings.gitlabProjects field. Worktree.linkedGitLabMR / WorktreeMeta.linkedGitLabIssue / GlobalSettings.defaultTaskSource union member stay here — they're entangled with non-GitLab structs and moving them out would just shuffle the conflict vector to a different file. - preload/gitlab.ts (new, 106 lines): the entire gl.* runtime binding block — viewer / projectSlug / mrForBranch / mr / listMRs / listWorkItems / issue / listIssues / createIssue / updateIssue / addIssueComment / listLabels / listAssignableUsers / todos / workItemDetails / closeMR / reopenMR / mergeMR / addMRComment / workItemByPath. Exported as `glApi`. - preload/index.ts: imports `glApi` and inlines as `gl: glApi`, shrinking the file by ~95 lines. Net: the two files most prone to conflict on upstream sync (shared/types.ts, preload/index.ts) lose ~360 lines of GitLab-specific code that now live in their own files where main's non-GitLab edits can't touch them. Full typecheck (node + cli + web) clean. 190 unit tests passing in src/main/gitlab/, src/shared/gitlab-projects.test.ts, src/main/ipc/{preflight,worktree-logic}.test.ts, src/renderer/src/lib/gitlab-links.test.ts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gitlab): satisfy pnpm pre-flight (lint + handler-registration test) - TaskPage: lift the selected-repos identity key into a useMemo so the GitLab fetch effect's dep array no longer holds a complex expression (oxlint exhaustive-deps). - register-core-handlers.test: mock ./gitlab alongside ./github / ./linear so registerGitLabHandlers doesn't try to call ipcMain.handle in a unit test that fakes only individual handler modules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(source-control): add Bitbucket hosted review support * fix(source-control): align hosted review lookup with provider model --------- Co-authored-by: Emilian Stoilkov <emilian.stoilkov@qaiware.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |