mirror of
https://github.com/stablyai/orca.git
synced 2026-10-22 00:03:47 +00:00
aab112933e7bacd1d7c49edd1669cbb2bded5907
38
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aab112933e |
Revert "fix(memory): bound OOM-prone accumulators (#10179)" (#10255)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
8f40ddf328 | fix(memory): bound OOM-prone accumulators (#10179) | ||
|
|
971b167548 |
fix(github): load PR diffs for Enterprise remotes (#8932)
* fix(github): load PR diffs for Enterprise remotes * fix(github): encode PR content paths by segment * Fix PR review actions failing on GitHub Enterprise remotes - Threads GitHub host identity (not just owner/repo) through the client, work-item-details, issues, and RPC layers so gh commands target the correct Enterprise server instead of silently falling back to github.com - Adds a shared github-api-repository helper to resolve/host-qualify repo identity consistently across REST, GraphQL, and CLI shorthand calls - Scopes the gh rate-limit breaker and singleton rate-limit snapshot by host/runtime so a github.com block or probe can't affect GHES or WSL - Coalesces concurrent host-auth probes and paginates PR file fetching beyond 100 results - Propagates `host` through renderer PR caches, checks-panel keys, and preload IPC types so Enterprise and github.com data never collide * Route gh host qualification through runner options instead of argv sniff Move GHES/GH_HOST resolution from parsing --hostname/--repo out of gh argv to an explicit options.host passed through ghExecFileAsync, since SSH-backed repos spawn gh with no cwd and argv sniffing couldn't reliably detect the target host. The runner now injects --hostname and qualifies --repo/-R at spawn time from options.host, and rate-limit scoping/guards use the same explicit host instead of inferring it. Also adds a shared githubRepoIdentityKey helper to keep cache/store keys consistent with the new host-aware repository identity. * Fix gh CLI GHES host pinning and rate-limit scope leaks - Pin `--host` on every gh call site so a process-level GH_HOST can't silently redirect requests, and qualify `-R`/`-R=` repo shorthand alongside the existing `--repo=` handling. - Check the target scope for an active rate-limit block before each WSL/native or host fallback retry, not just on the initial attempt, so a blocked scope can't be hit again through a fallback path. - Compute idempotency once per call instead of re-deriving it after fallback reassigns args. * Fix GitHub Enterprise host identity loss across PR/work-item paths - Thread `host` through mobile PR RPC params, IPC work-item lookups, and RPC schemas so GHES identity survives the renderer/mobile/main boundary instead of silently falling back to a same-named github.com repo. - Qualify `--repo`/`-R` args for github.com too (not just GHES), since gh resolves bare shorthand against a process-level GH_HOST that can redirect pinned github.com commands. - Cache `getOriginGitHubApiRepository` to avoid a per-call uncached `git remote get-url` round trip on connection-backed repos. - Add a local-fork fallback in `getWorkItemDetails` so PRs living on a base repo (not visible via the origin slug) still resolve via cwd. - Centralize the github.com-vs-GHES host predicate in `isDefaultGitHubHost` so cache keys, quota scoping, and identity checks can't drift out of sync. * Make repository identity host-aware across all GitHub surfaces Generalize the auth-gated enterprise resolver to any remote and build a cached hosted-identity family (origin/issue/candidates/source) on top of it, then migrate every github.com-only consumer: Tasks listing/counting, branch-to-PR discovery, push targets, fork upstream, issue operations, Projects, web links, avatars, and PR-link facts. Scope the rate-limit breaker probe per runtime:host and classify WSL UNC cwds correctly. Co-authored-by: Orca <help@stably.ai> * Fix expected slug to include host field in GitHub PR link test Updates the smart-source paste-intent test fixture to match the repository slug shape that now carries a `host` field, keeping GHES host identity intact through the paste-intent parsing path. * Surface per-host gh auth state for GitHub Enterprise diagnoseGhAuth accepts the host a surface needs credentials for, scopes the account/scope diagnosis to that host, and reports whether gh has any login there; GhAuthErrorHelp renders host-qualified login/refresh commands so an unauthenticated GHES host stops masquerading as a github.com scope problem. Also fixes the mobile paste-intent expectation for host-carrying parsed links. Co-authored-by: Orca <help@stably.ai> * Bound GHES identity caches and preserve non-default ports in host identity Cap the origin-repo and host-auth caches like ownerRepoCache; keep ports from remote/link URLs so GHES on a non-default port is a distinct identity; make positional github.com slugs explicit against GH_HOST; compare work-item sources by host-aware identity key; bail cwd-less branch lookups when no repository candidate resolved; thread host through the renderer work-item slug lookup. Co-authored-by: Orca <help@stably.ai> * Thread GitHub host through issue detail requests Incorporates ghes-issue-host-support (ed6bb96ef): one hosted issue repository identity is resolved before the details fan-out so comments, timeline, participants, and mention lookups cannot drift across hosts, with SSH guards so unresolved issue/PR repositories never fall through to gh's default host. Co-authored-by: Orca <help@stably.ai> * Scope remaining GitHub rate-limit accounting * Resolve typed PR lookups across hosted repository candidates getWorkItem's PR path probes upstream-then-origin hosted candidates instead of origin alone, so fork checkouts resolve the base repo's PR with the right host; issue detail resolution reuses the up-front hosted identity and keeps the SSH unresolved-host guards. Co-authored-by: Orca <help@stably.ai> * Refactor GitHub repository execution setup * Carry host on smart-submit link intents Co-authored-by: Orca <help@stably.ai> * Carry the project host on GitHub item dialog origins Co-authored-by: Orca <help@stably.ai> * Keep GHES web ports but drop SSH transport ports in host identity Supersedes PR #9118 on this branch: http(s) remote ports identify the Enterprise web/API endpoint and are preserved, while ssh/git transport ports (including ssh.github.com:443) never leak into gh's host identity. Replaces the ssh.github.com:443 special case with the structural protocol split and ports the PR's parsing test suite. Co-authored-by: Orca <help@stably.ai> * Support GitHub Enterprise diffs and mutations with host-scoped caches Parse GitHub host identity from work-item URLs and carry it through PR/issue mutations, labels, and assignments. Bound rate-limit and scope-probe caches (1024 and 512 entries) to prevent unbounded growth when interacting with multiple GHES instances. Normalize repository identity keys to include host so github.com and GHES slugs don't collide in cache and equality checks. * Support GitHub Enterprise diffs and mutations with host-scoped caches - Carry host identity through PR mutations and reads so fork PRs on different GHES instances don't collide in cache or state tracking. - Validate host authentication before routing requests to unconfigured Enterprise servers; ambient credentials must never reach untrusted hosts. - Scope rate-limit guards and spend tracking per host so GHES quota stays independent from github.com quota. - Respect explicit --hostname arguments in gh CLI calls ahead of GH_HOST or ambient defaults, so breaker state follows the actual request target. - Detect implicit WSL runtimes from UNC paths for consistent host auth and execution-options scoping across mobile and desktop clients. * Support GitHub Enterprise work-item diffs with host-scoped execution Enterprise PRs must use their selected host consistently across diff, comments, and file-content loads. Validate repository slugs before authenticated execution to prevent path-injection via renderer overrides. Scope project browsing cache and rate-limit tracking by host to prevent cross-host pollution. Use parsed URLs as authoritative over ambient hosts for project resolution. * Support GitHub Enterprise work-item diffs with host-scoped execution Preserve host identity on PR/issue work items throughout the mutation and diff pipeline so Enterprise instances (including ported endpoints like github.acme.test:8443) can execute mutations without ambiguity. Rate-limit gh commands by the pre-qualified --repo host, cache auth state per ported host, and surface Enterprise hosts in project metadata and error messages. * fix(review): drop dead rateLimitGuard/noteRateLimitSpend re-export Both callers (project-view.ts, mutations.ts) moved to the host-scoped repositoryRateLimitGuard/noteRepositoryRateLimitSpend; the bucket-only re-export in internals.ts had zero importers left. Co-authored-by: Orca <help@stably.ai> * fix(ci): split Enterprise host work-item tests under max-lines Move GHES/SSH host-routing cases out of work-item-details.test.ts so the suite stays within the 800-line test max-lines budget. * test(github): align mocks with host-scoped repository resolution - Route origin repository resolution through getOwnerRepoForRemote, not getOwnerRepo, to match production path - Pin github.com host on origin results so host-less fixtures pass host gate in resolveGitHubApiRepository - Add generation-based invalidation to prevent stale slug-cache writes from in-flight resolutions - Fix ref-sync race in ProjectPicker: use useLayoutEffect so committed tree owns browse cache key - Defer handledCrossRepoUrlRef assignment in SmartWorkspaceNameField until resolution succeeds - Update Enterprise host routing: found work items must not silently fall back to default host when unresolved - Normalize GHES avatar URLs: accept explicit port 443 as canonical form, not a fallback trigger --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Co-authored-by: Orca <help@stably.ai> |
||
|
|
e109e78ebf |
fix(source-control): keep huge change sets responsive (#9477)
* fix(source-control): keep huge change sets responsive * Fix cancellation and retry handling for capped status * Harden capped status for conflict-heavy repositories * Harden capped status recovery and cancellation * fix(source-control): preserve capped status correctness * fix(source-control): translate submodule status at render time --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> |
||
|
|
190de8223e |
refactor(comments): slim verbose comments in main integrations (git/providers/…) (#9543)
Collapse multi-line explanatory comment blocks into single-line "why" statements
per AGENTS.md ("Document the Why, Briefly"): drop restatements of the code and
mechanism narration; keep the non-obvious reason, external refs, and directives.
Comments-only — verified no code changed via a Babel/esbuild comment-strip
token-equality gate against origin/main; typecheck and oxlint clean.
Area: main — git, source-control, providers & integrations. 40 files changed, 1432 insertions(+), 4473 deletions(-).
Co-authored-by: Orca <help@stably.ai>
|
||
|
|
b320bcb374 | fix(gitlab): bound and coalesce auth probes (#9476) | ||
|
|
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". |
||
|
|
1a6abc87d1 |
Suppress Git Credential Manager OAuth popup loop in Orca-run git — clone, terminals/agents, setup hooks (fixes #7652) (#7986)
* Suppress Git Credential Manager OAuth popup on git clone (fixes #7652)
Orca's git runner disables the interactive credential prompt on every git
call that goes through gitExecFileAsync/gitStreamStdout, but the two raw
'git clone' spawns (desktop repos:clone and the runtime clone path) passed
no env, so they inherited process.env with no guard. On Windows a clone
that needs GitHub auth then makes Git Credential Manager pop its
'Connect to GitHub' OAuth window, and in a network-restricted intranet the
browser/device flow never completes while git's credential retry re-pops it.
Apply nonInteractiveGitEnv() to both clone spawns so the prompt is
suppressed (GCM_INTERACTIVE=never, credential.interactive=false,
GIT_TERMINAL_PROMPT=0). The credential *helper* is kept, so cached-token
clones for private repos still work; only the interactive fallback popup is
disabled and the clone fails fast with a clear error instead.
* Suppress GCM OAuth popup in agent terminals and setup hooks too (#7652)
The clone-spawn fix stopped Orca's own managed git from popping Git
Credential Manager, but git run in terminals and setup scripts inherited
process.env with no guard. That is the more likely source of the reported
loop: agents are told to run 'git pull --rebase'/'git fetch'/retry 'git
push' (preamble + conflict/push-failure prompts), and each retry re-pops
GCM's 'Connect to GitHub' window in a network-restricted intranet.
Apply the credential-prompt guard to:
- setup/archive/hook scripts (hooks.ts non-WSL exec env), which run
unattended on worktree create/archive.
- the shared PTY host env (buildPtyHostEnv), via a small
applyTerminalGitCredentialPromptGuard helper. Agent terminals are
guarded unconditionally (they cannot dismiss a GUI popup); user
terminals are guarded by default via the new
terminalSuppressGitCredentialPrompt setting so power users can opt out.
The credential helper is kept, so cached gh auth still works; only the
interactive fallback prompt is disabled. Verified end-to-end in a real
Orca terminal (GIT_TERMINAL_PROMPT=0 + GCM_INTERACTIVE=never by default;
absent when the opt-out is set).
* Scope user-terminal credential guard to Windows, add settings toggle, forward guard into WSL (#7652)
* Retrigger PR checks (Actions dropped the synchronize dispatch for
|
||
|
|
3d3e0ea0b1 | perf(file-explorer): batch and debounce ignored checks (#8103) | ||
|
|
b7e84aea3c |
Fix automatic branch rename for non-English git locales (#8012)
* Fix automatic branch rename for non-English git locales A gettext-enabled git (Homebrew git, most Linux distro gits) under a non-English locale translates every diagnostic, including the `fatal:` prefix, so Orca's stderr phrase parsers stop matching. The first-message branch auto-rename was the headline casualty: isNoUpstreamError missed the translated no-upstream error, branchHasUpstream failed closed to "has upstream", and the rename settled silently and permanently. - Force LC_ALL=C on all Orca-spawned machine-parsed git: the local prompt-guard env chokepoint, the three relay git spawn sites, and both local clone spawns (progress + failure-message parsing). User terminals are untouched. - Replace the boolean upstream check with a tri-state probe: rename proceeds only on a proven missing upstream; an unreadable probe now raises the rename-failed badge and retries instead of settling. Fixes #7808 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * Consolidate untranslated-git-locale into runner and relay primitives Replace the five per-site LC_ALL=C patches with one shared UNTRANSLATED_GIT_OUTPUT_ENV (LANGUAGE=en LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8) injected inside the git runner primitives (promptGuardGitEnv, gitSpawn, gitExecFileSync, gitExecFileAsyncBuffer) and a relay buildRelayGitEnv() helper, so every current and future machine-parsed git spawn is covered by construction — including the fs-handler-git-fallback sites the per-site approach missed. The UTF-8 English locale keeps a UTF-8 LC_CTYPE for hooks git spawns; LANGUAGE is pinned because gettext consults it before LC_ALL. WSL-routed git gets the same values as a shell assignment prefix built in resolveCommand, since spawn env cannot cross the wsl.exe boundary — closing the WSL gap the first pass accepted. Also scrub credential-bearing remote URLs from the probe-failed message surfaced on the worktree card. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * Scrub credential-bearing URLs from clone failure messages --------- Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e537953d8f | Fix GitLab auth diagnostic waking WSL (#7967) | ||
|
|
417723411e |
perf(source-control): stop gh rate-limit storms and idle git-status spawn churn (#7595)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
ac8d365296 |
Fix STA-1292: prevent Windows worktree-create hang (disable interactive credential prompt + timeout create-path git) (#7301)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
2f3c7e8660 | Fix Windows slow startup and multi-minute UI freezes (#7225) (#7266) | ||
|
|
a10e1d7584 |
fix(gitlab): recognize self-hosted GitLab on non-default ports over SSH connections; stop one project failing the whole issues panel (#5400)
* fix(gitlab): port-aware self-hosted host recognition
Use the URL host (including a non-default web/API port) as the GitLab
host identity instead of the port-less hostname, and match known hosts
port-aware:
- A known-host entry without a port matches any port of the same
hostname (preserves legacy bare-host and gitlab.com recognition).
- A known-host entry WITH a port matches only that exact host:port, so
two services sharing a hostname on different ports (e.g. a GitLab and
a Gitea) are no longer conflated.
- For ssh/git remotes the port is a transport port (e.g. ssh :2222) and
is dropped; for http(s) remotes the port is the endpoint and kept.
- Also capture an optional :port in parseGlabAuthStatusHosts so a
self-hosted GitLab on a non-default port is discovered correctly.
* fix(gitlab): per-connection known-hosts cache + port-aware auth-status parsing
getGlabKnownHosts() was connection-blind and cached process-globally,
and on any failure it cached [gitlab.com] forever — so a repo on an SSH
connection never discovered its self-hosted host once a probe failed
before the tunnel was ready.
- getGlabKnownHosts(connectionId?) now caches per connection so a
connected repo's authenticated hosts don't leak into the local
context (or vice versa).
- The failure fallback (canonical default) is no longer cached, so a
later probe can re-discover the real host once auth/tunnel is ready.
- parseGlabAuthStatusHosts captures an optional :port on both the
'Logged in to <host>' and header-style lines, keeping two services on
the same hostname distinct by port.
* fix(gitlab): isolate unresolvable projects instead of cwd-fallback that hits exit 128
listIssues/getIssue fell back to an unscoped 'glab issue list' / 'glab
issue view' that infers the project from cwd. For a repo on an SSH
connection cwd is not the repo dir, so glab runs git resolution in a
non-repo dir and fails with 'git: exit status 128'. In an 'All projects'
aggregate one such failure could sink the whole issues panel.
When a projectRef cannot be resolved, return a structured, isolated
per-project result (listIssues: { items: [], error: not_found };
getIssue: null) and spawn no glab subprocess. Behavior is unchanged when
a projectRef IS resolved (the scoped '-R' / 'api projects/...' path).
* fix(gitlab): recognize modern /-/work_items/<iid> issue URLs
Modern GitLab emits issue URLs as /-/work_items/<iid> in addition to the
legacy /-/issues/<iid>. The URL classifiers only matched /-/issues/, so
work-item-form issue links went unrecognized.
Extend the gitlab-links parsers (parseGitLabIssueOrMRNumber /
parseGitLabIssueOrMRLink, which also backs isWorkItemLookupText) and
isGitLabIssueUrl to accept /-/work_items/<iid>, mapping it to an issue
work item with the same project-path + iid extraction.
* fix(gitlab): thread connectionId into getGlabKnownHosts call sites
Follow the existing connectionId-threading pattern: pass the repo's
connectionId into every getGlabKnownHosts() call (client.ts,
work-item-details.ts, orca-runtime.ts) so the per-connection known-hosts
cache is keyed correctly and self-hosted hosts are discovered against
the right glab context.
* docs(gitlab): use generic example hosts in comments
* fix(gitlab): pass self-hosted host:port via GITLAB_HOST (glab --hostname rejects ports)
* polish: satisfy oxlint curly + oxfmt on merged gitlab port-recognition code
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Ptah-CT <auctor@xinfty.space>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
|
||
|
|
46646d7ff1 |
chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day minimum-release-age supply-chain guard; nothing here needs it). The bump is a no-op on the existing config. Enable 3 error rules (backlog autofixed to zero in this commit) and 4 warn rules (surface signal without gating CI): error (autofixed, behavior-preserving): - unicorn/prefer-node-protocol (~1531 sites: bare builtin -> node:) - typescript/no-import-type-side-effects (~36: all-inline-type -> import type) - unicorn/no-array-reverse (19: copy-then-reverse -> toReversed) warn (real signal, current fires are test-only/correct): - unicorn/no-array-fill-with-reference-type (aliasing footgun guard) - typescript/no-unsafe-function-type (bans bare Function type) - unicorn/prefer-array-flat-map (map().flat() -> flatMap()) - unicorn/prefer-regexp-test (.match() in bool ctx -> .test()) mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix ran from root and covered mobile/ too. Verification (all green): oxlint 0 errors (root+mobile+aux configs), oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed, builds (electron-vite + web + cli) succeed. node: rewrites confirmed to skip embedded SSH/CLI string payloads (AST-only); all toReversed sites verified to operate on fresh copies or write-once locals. * chore(lint): bump mobile oxlint to 1.71 so inherited rules parse mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile && oxlint' failed to parse the new rule. Bump mobile to match root (1.71). Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit pass, vitest 978 passed / 0 failed. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
5c3ba7be91 |
Improve inactive workspace cleanup UX (#3600)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
8228155e4d |
Improve preserved branch cleanup after squash merges (#6014)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
972078f2c4 |
Fix paste ownership, input bounds, and IPC validation
Supersedes #5745, #5746, and #5747. |
||
|
|
afde3a3741 | Honor configured SSH for remote-base worktrees (#5739) | ||
|
|
0ec3882cb8 |
Add project Windows runtime selection (#5519)
* Add project Windows runtime selection * Fix project Windows runtime selection Co-authored-by: Orca <help@stably.ai> * fix: preserve WSL shell variables --------- Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com> Co-authored-by: Orca <help@stably.ai> Co-authored-by: Neil <neil@stably.ai> |
||
|
|
3ec1a36ba9 |
feat: add safe fork upstream sync setting (#5408)
* add safe fork upstream sync setting * fix fork sync review feedback * Review safe fork sync setting * Fix local preflight env typing * Fix onboarding flow SSR test tooltip provider --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com> |
||
|
|
1d85515a3e |
fix: bound gh cli detail calls (#5413)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
414ae73838 |
Prevent main-process crash on huge git status output (#5371)
* Prevent main-process crash on huge git status output git status on a repo with an enormous un-ignored folder could emit a listing large enough that buffering it into one string exceeded V8's max string length, throwing an uncatchable RangeError inside Node's execFile exit handler and crashing the main process (and blocking mobile). The runner also forwarded an undefined maxBuffer straight to execFile, which silently disabled the cap entirely. - runner: apply a non-bypassable default maxBuffer so no git call can buffer without a bound. - status: stream porcelain-v2 output through an incremental parser and kill git the moment the changed-entry count crosses a limit (default 10,000); skip numstat/upstream probe when limited. Apply the same limit to the relay/SSH status path. - UX: surface a 'too many changes' state, pause auto status polling while a repo is over the limit, and offer to .gitignore a detected huge folder. Co-authored-by: Orca <help@stably.ai> * Address review: validate inputs, fix stream decoding, localize copy - huge-folder-ignore: restrict folderName to the known-folder allowlist before writing .gitignore (reject path-sep/newline injection). - gitStreamStdout: decode stdout/stderr with StringDecoder so multibyte UTF-8 split across chunk boundaries isn't corrupted; flush on cleanup. - gitStreamStdout: wrap the onStdout callback in try/catch so a throwing parser rejects the promise instead of crashing the main process. - status/relay: validate the status limit as a non-negative integer. - SourceControl: localize the 'too many changes' banner and the .gitignore warning toast via translate() with placeholder params. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
72ed268669 |
Run the file watcher off the main process to fix the serve deadlock (#5308) (#5310)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
f66e42a2bb | fix: time out git runner execFile calls (#3836) | ||
|
|
7112c1c767 | fix: clean up command runner capture listeners (#3748) | ||
|
|
a140313d4a |
Add local diagnostics error tracking (#2351)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
e0104372da |
Squashed commits (#2485)
- Fix workspace space cache and git status cleanup checks - Treat browser tabs as workspace delete blockers - Move deletion readiness into shared presentation logic so tests cover it - Preserve explicit empty git status entries for clean worktrees - Add package manager cache cleanup to space manager - Detect npm, pnpm, Yarn, and Bun caches from lockfiles during scans - Add explicit cleanup IPC for safe and aggressive cache actions - Support local, SSH, and Windows command execution paths safely - Tighten workspace deletion decisions with git, editor, agent, and terminal state |
||
|
|
5b1d84232c |
Avoid optional Git locks during status checks (#2330)
* Squashed commits - WIP: uncommitted changes before rebase - ci - Show inline PR check details in task drawer - Add a Checks tab that opens from the PR checks cell and expands runs inline - Fetch check output, annotations, and workflow job steps through IPC/RPC - Improve markdown/comment wrapping so long PR content stays within the drawer * Use app-styled confirmations for PR actions (#2324) Co-authored-by: Orca <help@stably.ai> * fix: pr-bug-scan validated finding from #2274 (#2296) Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai> * fix: avoid optional git locks during status checks --------- Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Co-authored-by: Orca <help@stably.ai> Co-authored-by: buf0-bot[bot] <252831055+buf0-bot[bot]@users.noreply.github.com> Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai> |
||
|
|
e59afeacc4 | Fix WSL tool detection on Windows (#2218) | ||
|
|
31ab1560a7 | Fix WSL gh fallback for task lists (#1879) | ||
|
|
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> |
||
|
|
9bc8166ad8 |
fix: pr-bug-scan findings from #1465 (#1558)
Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai> |
||
|
|
dd1c940fef |
fix: address pr-bug-scan findings from #1424 (#1465)
Gate gh retries on idempotency (auto-detected from argv/-X/mutation), key parent-field probe by (owner,ownerType), accept 'to an' in not_found classifier, and replace bulk label PUT with parallel sing Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai> |
||
|
|
6f2e31afad |
feat(telemetry): PR 4 — wire 7 core events to call sites (#1433)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
70ffa0a73d |
[feat] Add a full Github project view under "Tasks" (#1424)
* WIP: auto-review-fix iteration 1 (project-view.ts fixes applied) Co-authored-by: Orca <help@stably.ai> * refactor(github-project): split project-view and slug-dialog into modules Co-authored-by: Orca <help@stably.ai> * fix(lint): resolve oxlint errors in project-view modules Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
f6ec69c969 |
feat: add WSL support for repos on WSL filesystems (#375)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |