* fix: update E2E tests for API changes and selector robustness
- Improve source control file locator specificity to avoid flakiness
- Fix board test to use correct worktree ID attribute
- Update removeWorktree calls to pass host ID parameter
- Simplify git status polling with timeout expectation
* fix: increase packaged-watchdog launch timeout and await git-status rows
Extract hardcoded 15s launch timeout to a 30s constant for better reliability under load. E2E test now waits for all git-status rows to render before asserting absence of status messages, preventing flaky passes when the list is still loading.
* Fix Create PR preparation with unavailable lookup
* test(source-control): align dirty+unavailable intent expectation
Create PR preparation is allowed when review lookup is unavailable; only final create stays fail-closed. Update the local-blocker snapshot test to match.
* Keep Create PR intent running when hosted review lookup fails
A failed or timed-out hosted-review eligibility lookup no longer aborts
Create PR intent mid-run. Local prep (stage/commit/push) continues, the
branch-ahead refresh is deferred until after eligibility resolves, and the
final create preflight still fails closed to prevent duplicate reviews.
Also gate generated PR title/body on eligibility and thread the provider
through the intent run token so an unavailable lookup falls back to the
inferred remote host.
* fix(source-control): align dirty+unavailable intent expectation
Local preparation (stage/commit changes) is safe without review-lookup authority; remote actions stay blocked. Prevents dirty trees from dead-ending at sync-first when lookup is unavailable.
* fix(source-control): distinguish loading state from unavailable lookup
Require head branch presence in shouldAttemptCreateHostedReviewForIntent to
separate real unavailable-lookup results from loading placeholders, which
share the same outcome/reason pair but lack a branch name.
* test(activity): drive portal readiness latch release with explicit rAF
Wall-clock setTimeout waits for requestAnimationFrame were flaky under
CI load (shard 15/16), leaving status stuck at loading instead of ready.
* Distinguish expected absence from git errors in remote removal
Why: swallowing all errors silently masks genuine git failures.
Check presence explicitly instead, so setup/teardown can still
skip when origin is absent while letting real errors surface.
* 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>
Connect the ChecksPanel PR draft generation to the global generation
slice, aligning its behavior with SourceControl. This allows detail
generation to continue in the background when navigating away or
switching worktrees, and guarantees that generated fields, terminal seeds,
and branch-preparation push requirements are restored on remount.
* Make Create PR intent resilient to worktree switching
Co-authored-by: Orca <help@stably.ai>
* Restrict PR creation sidebar actions to foreground worktrees
- Prevent switching tabs and opening the PR URL when a background
worktree's PR creation finishes.
- Extract commit eligibility checking into a dedicated module and
disable the commit message textarea during operations or when
ineligible.
- Fix flakiness in the remote runtime request connection test.
* Abort Create PR if branch changes during details generation
If the branch changes within the active worktree while review details
are being generated, the Create PR flow now aborts and shows a muted
notice prompting the user to retry.
- Allows worktree navigation during PR details generation without
treating it as an intent conflict.
- Adds localized strings for the new retry notice.
- Uses platform-independent paths in tests for cross-platform support.
---------
Co-authored-by: Orca <help@stably.ai>
* Persist commit message generation state across worktree switches
Introduce a new global store slice for commit message generation to prevent
in-flight requests from being orphaned or lost when the Source Control
sidebar is unmounted or when switching between worktrees.
- Key commit generation records by worktree ID/path in the Zustand store
- Hydrate completed messages back into the draft input when returning to
the originating worktree without overwriting active user edits
- Ensure the agent-selection dialog state remains bound to the target
worktree that initiated the generation
- Wait for the PR composer eligibility check before hydrating completed
PR field generations on sidebar remounts
* Route cancellations to starting runtime and prune stale worktree records
Ensure commit message and pull request generation cancellation requests
are always routed to the runtime environment that was selected when
the generation started, even if active settings change before
cancellation.
Additionally, prune commit message and pull request generation records
when worktrees are removed to prevent stale records from lingering in
the store.