[upstream #12812] fix(skills): match official skill files despite local sidecars - #136
Open
innocarpe wants to merge 1058 commits into
Open
[upstream #12812] fix(skills): match official skill files despite local sidecars#136innocarpe wants to merge 1058 commits into
innocarpe wants to merge 1058 commits into
Conversation
…stablyai#12166) * fix(browser): import __Host- cookies host-only so Chromium keeps them The cookie file/JSON import path passed a Domain attribute for every cookie. Chromium rejects any __Host--prefixed cookie that carries a Domain (the prefix requires host-only, path=/, Secure), so file import silently dropped session cookies like GitHub's __Host-user_session_same_site and users stayed logged out after importing. Mirror the browser-native import path, which already shapes __Host- cookies host-only: omit domain and force path=/ when the name is __Host--prefixed. Add a regression test covering both a __Host- cookie and a normal domain cookie in one import. * test(browser): cover __Host- cookie payload constraints * test(browser): preserve ordinary cookie paths
…nes (stablyai#12146) * fix(codex): execute accepted account-switch restarts for unmounted panes Accepting the Codex account-switch restart prompt queued every awaiting pane but only mounted TerminalPane instances executed the queue, so background-tab and parked panes stayed input-blocked on the old account with no prompt. - Add a detached store-level driver (codex-detached-pane-restart) that kill-and-respawns any queued pane no mounted transport claims, rebinding tab/layout state so a later mount reattaches to the replacement PTY. - Re-offer the prompt when a detached execution fails, and clear the notice when the pane is gone, so input is never silently blocked. - Sweep restored PTY ids at startup so stale panes in never-mounted tabs are re-offered after an app restart. - Carry launchAgent codex on the restart respawn so it waits for managed-auth readiness and records the pane's launch account. * fix(codex): fence detached restart ownership races * fix(codex): unblock detached restart handoffs * fix(codex): contain detached restart cleanup * fix(codex): detach restart progress from cleanup * fix(codex): avoid detached restart size wait * fix(terminal): scope Codex restart prompt to pane * fix(codex): contain detached restart sweep failures
* fix(codex): make quota probes credential-safe Codex OAuth uses rotating refresh tokens, and Orca's quota probes spawned real codex app-server processes inside live credential homes, hard-killed them at a 10s deadline (cold starts run 10-25s), re-probed every inactive account on each switch, and deselected accounts on torn auth.json reads. - arm the RPC read deadline only after initialize responds (30s/40s boot budget), and terminate probes via stdin EOF + SIGTERM with a bounded drain before any hard kill; resolve only once the child exits - serialize Orca-spawned codex processes per credential home (probe vs probe, probe vs commit-message/PR-fields/branch-name/model-discovery) - keep the inactive-probe debounce across account switches and stagger inactive probes; the active account still refreshes immediately - grade credential reads (present/missing/unreadable/no-credential) and require absence to outlive a grace window before deselecting * fix(codex): close remaining credential races * fix(codex): keep failed probes under home lock * fix(codex): observe probe pipe failures * fix(codex): await Windows generation tree kills * fix(codex): preserve incomplete shared credentials
…emoval (stablyai#12153) Destructive worktree removal proves every PTY is dead before touching the filesystem. When a stop RPC failed, it re-listed the provider to check whether the PTY had already exited — but on the same deadline the sweeps had just spent, so it timed out without ever asking and read "could not verify" as "still live". The sweep spends that budget every run, making the refusal deterministic; --force never reached the gate, so the workspace was unremovable forever. - Verification gets its own budget instead of an exhausted remainder. - Verdicts split into exited / live / unverifiable; the error names the blocking PTY ids and why. - A reachable escape hatch: allowUnverifiedPtyStop, set only by genuine Force Delete affordances and the CLI's --force — never by the force the ordinary delete confirmation already sets — with an 'unstopped-pty' classifier reason so the desktop actually offers the button. - Force also survives a sweep that cannot complete; the non-force path still fails fast. Fixes stablyai#11960
…view cap (stablyai#12159) * fix(native-chat): stop clipping assistant text blocks at the tool-preview cap Long assistant messages read over a paired connection (headless orca serve viewed from desktop or mobile) were cut at 4,000 chars with a '… (truncated)' marker and no way to read the rest. The mobile payload diet in nativeChat RPC applied the tool-preview char cap to text blocks, which are the fully rendered message body. Give text blocks their own 64k safety ceiling so real replies pass through whole while pathological multi-hundred-KB blocks still can't freeze the phone. Fixes STA-3230 * test(native-chat): cover long text stream frames
Groups 5/6 filled; point community join flow at group 6 + group 7.
Older groups are full; community join path is group 7 only.
…missal (stablyai#12167) * Keep your New Linear and Jira creation drafts after an accidental dismissal * Avoid draft store writes while typing * Update draft retention refs after commit
…tablyai#12172) * Open SSH host add/edit form in modal dialog Form moves from inline to a viewport-stable modal (STA-3067) so fields stay accessible with long host lists. Includes sticky header/footer, dirty-state protection against outside click, and session-aware Advanced state reset on cancel/reopen. * fix: add missing SshTargetForm localization keys Sync en.json catalog for modal title/description strings so verify:localization-catalog passes in static analysis. * fix: translate SshTargetForm modal strings in es/ja/ko/zh Add non-English catalog entries for the new modal title and description keys so localized UIs match English. * Prevent SSH form double-submit and fix dismissal detection Adds a saving state to prevent concurrent saves when a user double-clicks the submit button. Fixes outside-click dismissal by correctly tracking form state across re-renders using refs. Extracts session termination logic to a reusable module. * fix: stop mutating formRef during render in SshTargetForm React Doctor fails the static-analysis gate when refs are written during render. Sync form into formRef in an effect so render stays pure.
…tablyai#12183) * fix(updater): recover Linux .deb/.rpm installs that fail escalation A `.deb` install fails with `No authentication agent found` when the session has no polkit agent. Orca reported "Quit and reopen Orca, then try again" — wrong advice — and its only action was Retry Download, discarding a verified 160 MB package that was still in the updater cache. Keep the one-click install path, but make a failed root-package install recoverable without downloading again: - Retain the downloaded package and its expected SHA-512 from the `update-downloaded` event, mirroring electron-updater's cache-name rule. - Capture the child stderr that BaseUpdater logs but drops from the `error` event, redact it (ANSI, control bytes, `<home>`, `<package>`, `<user>`, 1 KiB cap), and classify the failure. Classification reads the original text — redaction can rewrite a matched phrase. - Send a structured `linux-package-install` recovery status and render a dedicated card: Copy Install Command / Try Automatic Install Again / Show Package. - Revalidate on every action: cache containment, lstat, streamed SHA-512, timingSafeEqual. Concurrent requests coalesce into one hash pass. - Build the command from fixed tokens plus one POSIX-single-quoted absolute path, resolving sudo and the package manager only from /usr/bin, /bin, /usr/sbin, /sbin. Orca never runs it. - Disable `autoInstallOnAppQuit` for .deb/.rpm so an ordinary quit cannot trigger the same failing escalation after the UI is gone. Extracts the error-card presentation into UpdateErrorCardContent so UpdateCard does not absorb another stateful surface. Lifecycle breadcrumbs carry package type, reason, exit code and version — never a path, command, username or raw child output. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Improve Linux package install recovery diagnostics - Distinguish invalid-package-path errors from missing package manager - Expand ANSI escape sequence stripping to handle OSC hyperlinks and DCS - Prevent generic error logs from overwriting specific diagnostic verdicts - Add error handling for shell.openUrl in update UI - Fix test isolation with proper afterEach hooks --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tablyai#12191) The parent-drift repair path (destroyPersistentWebview with preserveViewport: true, introduced in stablyai#12137) tears down and rebuilds the webview under the same browserTabId, but unconditionally forgot the tab's explicit user zoom. BrowserPane then re-seeds from the Settings default on the next mount, silently resetting per-tab zoom. Only forget explicit zoom on a real close; a preserveViewport rebuild keeps the same logical tab, so its zoom must survive.
…ver a bare renderer PTY (stablyai#12197) A mobile New Tab -> Codex create resolves the launch command and hands it to the renderer, but when the renderer's startup queue is lost (the stablyai#7587 stall class) the pane spawns a plain shell and the create still settles ready via PTY adoption - silently binding the phone to a bare terminal forever, since the ready status also disables the stablyai#7837 activation-time materialize recovery. Record the resolved launch command on the pending create and, at every renderer-backed settle point, deliver it to the adopted PTY when no spawn command was recorded for it. Spawn commands are noted per PTY by both spawn IPC handlers, so a missing record on the locally registered live PTY proves the launch never ran; delivery types the command exactly like the create would have, and the note prevents double delivery. Fixes STA-3214
…r breadcrumbs (stablyai#12198) * feat(crash-reports): add byte attribution to renderer memory highwater breadcrumbs Entry counts stay flat when a slice grows by value weight (97b9e86d leaked ~700MB while its biggest slice grew by 4 entries), so highwater breadcrumbs now carry sampled per-slice KB estimates for the store plus a live pane census (managers, panes, estimated scrollback KB) — the dominant heap cost the store census cannot see. * fix(crash-reports): bound renderer OOM profiling * fix(crash-reports): total raw store estimate bytes
…tablyai#12194) * fix(browser): bound retained webview guests across worktree switches * fix(browser): merge duplicate imports flagged by import/no-duplicates * fix(browser): evict guests without unmounting the worktree surface Unmounting the surface disposed every parked terminal byte watcher for the evicted worktree (bell/title/agent-completion facts dropped for good after the 15s handoff TTL) and skipped the force-park scrollback capture remote panes rely on. Destroy the guests only: hidden slots mount no BrowserPane, so nothing resurrects a destroyed guest before the next visit, and no slot ever unmount-detaches a live guest (STA-3228). Terminal-state vetoes and the eviction re-render bump are no longer needed; the only veto left is a guest an automation/mobile controller is actively driving. * fix(browser): veto eviction for downloading pages; keep zoom; add kill switch Main cancels a page's active downloads when its guest unregisters (tab-close semantics), so eviction now vetoes worktrees with a page still writing a download, tracked app-wide because download state was pane-local and hidden panes are unmounted. Eviction is not a user close: re-remember explicit zoom past the destroy-path forget so a revisit reasserts the user's zoom instead of resetting same-host siblings through Chromium's partition-wide HostZoomMap. browserGuestWorktreeRetentionBudget mirrors the terminal budget kill switch.
…yai#12233) * fix(terminal): route remote-runtime link clicks to the system browser Terminal link clicks classified ownership from the global activeRuntimeEnvironmentId, which is null when runtimes are bound per workspace, so a link clicked in a remote-hosted pane opened a local-only Orca browser tab and never reached the host. Thread each pane's resolved runtimeEnvironmentId into openHttpLink as sourceOwner across the OSC 8, WebLinksAddon, and click-fallback paths. Co-authored-by: Orca <help@stably.ai> * fix(terminal): route link clicks based on pane ownership, not global sta Clicking links on remote-hosted panes was routing based on global runtime state, causing unexpected reconnections. Now link routing decisions (where to open: Orca vs system browser) are based on the actual pane's owner — local, SSH connection, remote runtime, or unknown — regardless of whether any runtime is globally active. This ensures a local pane can route to Orca while another pane's remote runtime is active, and a remote pane always routes to the system browser. --------- Co-authored-by: Orca <help@stably.ai>
…tablyai#12103) (stablyai#12204) * fix(onboarding): run skill setup in the configured Windows runtime (stablyai#12103) Onboarding was the one skill-setup surface that did not route its install command through the resolved runtime. Settings, the feature-wall panels and the Linear prompt all wrap theirs as `wsl.exe -d <distro> -- sh -c ...` and pass a matching shell override; onboarding spawned a bare terminal and handed it the raw `npx skills add ...`. With Node inside WSL, npx is not on the Windows PATH, so the install failed. The runtime resolver had a second gap behind that: it only consulted per-project settings, and onboarding runs before any project exists. With no project it returned undefined and fell through to the Windows host, ignoring a global WSL default entirely. `getLocalAgentPreflightContext` already had a no-project fallback for PATH detection; the skill-install path had none. - extract that fallback as `getGlobalWindowsExecutionRuntimeContext` and rewire the existing agent-preflight branch through it so the two cannot drift - adopt it in `useActiveProjectSkillRuntime` when no project is active. WSL only: a windows-host default already matches the old no-project behavior, and resolving it would hand skill discovery a target where it had none, re-triggering scans for every host-default user - build the onboarding terminal's command for the runtime and pass its shell override - register the CLI in WSL rather than on the host, so `orca` lands on the PATH the install actually runs on, and wrap the copied command to match * fix(onboarding): keep skill setup runtime consistent * test(onboarding): satisfy runtime settings contract --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…rktrees (STA-3123) (stablyai#12235) * fix(mobile): surface worktree catalog failures instead of showing 0 worktrees (STA-3123) A connected host whose worktree.ps request fails now shows an explicit catalog-failure state (with the RPC error code) on the host page, and 'Worktree list unavailable' on the home host card, instead of silently rendering as a healthy host with zero workspaces. * fix(mobile): mark cached worktree catalogs unavailable
stablyai#12209) Co-authored-by: Orca <help@stably.ai>
…#11987) * fix(terminal): expand variables in Windows PATH * fix(terminal): preserve expanded Windows PATH at spawn --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Adapted from stablyai#11273 commits c690ee6, 5065240, and cc69fa7.
Adapted from stablyai#11616 commit 9f449d7 and stablyai#12120 commit 290f42a. Co-authored-by: holdn2 <club.makersfarm@gmail.com>
… Enter-keyup newline On Windows, the Enter-keyup synthesis path inferred the modified-Enter chord from release-time modifier state. A plain committing Enter (Process/229, no modifiers) followed by a rolled-over Shift for the next doubled consonant made the keyup report shiftKey=true and synthesized a Shift+Enter the user never chorded; a directly-sent Shift+Enter could likewise send a second newline from its keyup once the next composition started. Record observed Enter keydowns (code -> timeStamp) and let the keyup synthesis run only for presses whose keydown the IME swallowed entirely; a balancing keyup that copies the keydown timeStamp keeps the evidence for the later physical release. Refs stablyai#11878 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A single slot per code let a rapid second Enter press go unguarded: the first release found a mismatched timeStamp, dropped the only entry, and the second release then synthesized the Shift+Enter this guard exists to prevent. Track one entry per press and drain exactly one per physical release, so every press stays guarded until its own release. Auto-repeat keydowns do not stack an entry, since the whole run ends in one release, and the list is bounded so a press whose release never arrives cannot grow it without end. Refs stablyai#11878 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adapted from the physical Windows event trace contributed on stablyai#11878.
* fix(native-chat): select Codex models directly * fix(native-chat): confirm agent exits before switching views * fix(runtime): handle unavailable foreground probes
…stablyai#12759) Reorganize the host and project filters to share a unified single-row design (label left, value right) with detailed selection moved to nested panels. Group both filters under a "Show" section label to keep the parent menu flat. Extract project-filter search logic into SidebarProjectFilterPanel with explicit focus and keyboard-handling tests.
* Refactor GitHub work-item mutations onto a shared optimistic coordinator - Extract PR/issue status, assignee, reviewer, and merge/auto-merge mutations out of TaskPage cell components into a registry-backed begin/confirm/rollback pipeline (task-page-github-work-item-mutation-*), so soft-hide, sticky filter-membership, and quiet revalidation behave consistently across all mutation types instead of each cell re-implementing optimistic update/rollback/toast logic. - Add quiet revalidation (no filter skeleton, no page blanking) and soft-hide handling so a row that exits the active filter (e.g. closing an issue under `is:open`) stays hidden without a jarring list reflow. - Restyle the GitHub task table: opaque sticky ID/Title cells, distinct header fill, accent hover, and tighter row/toolbar chrome to fix background bleed and muddy contrast in the scrolled table. * Fix quiet-revalidate cancellation and sticky-hide scoping in TaskPage - Replace per-render `cancelled` flag with a ref that only flips on true unmount, so a nonce-triggered re-render no longer strands the shared quietState's trailing/backoff bookkeeping mid-flight. - Fix backoff index to use max lag attempts instead of lagging-key count, matching processTaskPageQuietRevalidateSettle so several single-lag items can't jump the delay tier. - Scope sticky-hide retention in materializeTaskPageItemList to the originating query key, preventing non-membership confirms (e.g. auto-merge) from lingering as stale rows across refetches. * Fix is:draft filter to soft-hide non-draft PRs Previously state was forced to 'open' for is:draft queries, so a PR that stopped being a draft still passed the state check and stayed visible. Add an explicit draft check to soft-hide it. * Improve GitHub work-item mutations with scoped quiet revalidation Prevent race conditions and stale data by tracking quiet run ownership, validating scope changes with generations, and blocking overlapping mutations with pre-flight checks. Extract quiet state management into a dedicated module with improved authority clearing and network retry logic.
…tton (stablyai#12483) * feat(browser): add hard reload option and shortcut hints to reload button Add a tooltip to the browser reload button showing the reload shortcut. Add a right-click context menu with Reload and Hard Reload options. Add localized labels for Hard Reload across EN, ZH, JA, KO, ES. * fix(browser): add aria-labels to reload buttons * feat(browser): make reload button contextual and extract action logic - Button label now reflects actual action: Stop when loading, Retry on failure, Reload when idle - Extract reload intent resolution into reusable browser-reload-action module with tests - Add keyboard support (Enter/Space) for the reload button - Simplify remote page reload to tooltip-only (no ignore-cache RPC for remote pages) - Add "Stop" translations for all supported languages * fix(browser): exhaust reload intent switch for type-aware lint Replace the default branch with an explicit reload case so oxlint switch-exhaustiveness-check accepts BrowserReloadIntent. --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* fix(browser): align cookie import safeguards * fix(browser): preserve sessions on failed cookie imports * fix(browser): bound single-label cookie replacement * fix(browser): preserve host-only parent cookies * fix(build): bundle cookie scope parser
…tablyai#12614) PR 9501 shipped real-home routing for the host system default, and the env override that could turn it back off was never a shipped control. The managed-account half of the shared runtime mirror has been unreachable since: every host account routes to its own self-contained CODEX_HOME before that code runs. Delete the flag module and its env plumbing plus the managed branch of syncForCurrentSelection and the six helpers only it called. The three lanes that still use the shared mirror -- Windows, a custom CODEX_HOME, and a hook-lane gate that reports unusable -- are untouched, as are every legacy migration and the WSL read-back helpers.
* fix(mobile): stop native-chat send button flicker * fix(mobile): keep composer lock rendering pure
* fix(mobile): preserve multi-image chat attachments * fix(mobile): use preferred array syntax * fix(mobile): harden multi-image attachment flow * fix(mobile): retain first-send image previews
…stablyai#11782) * fix(windows): make managed grok-hook.cmd safe when GROK_HOME is unset Fixes stablyai#9358 and stablyai#9941. cmd.exe expands %VAR:~n,m% at parse time. When GROK_HOME is unset (default outside Orca terminals), the generated length/trailing-backslash guards became a syntax error and every Grok hook event failed with exit 255. - Skip substring work when GROK_HOME is undefined (if defined + goto) - Replace if "%x:~-1%"=="\" (itself a quote-parser bug) with findstr - Extract Windows script builder; add template + spawn tests * fix(windows): harden grok-hook GROK_HOME guards and tests Address review on stablyai#11782: - Inject grokHome via buildWindowsAgentHookPostCommand extra form lines (no fragile string replace of the shared payload line) - Spawn tests delete GROK_HOME and keep PORT/TOKEN/PANE_KEY set so the GROK_HOME path actually runs before curl * fix(windows): cover Grok hook home boundaries --------- Co-authored-by: OrcaWin <alpha-eng@stably.ai>
* fix(mobile): open host editor from root navigation * test(mobile): update task navigation router contract
* Add branch line total chip to source control header Display the total lines added and removed across a branch from its fork point, measured via `git diff <mergeBase>`. Only computed when the chip is visible (request gate on merge base OID), with 500ms soft deadline to protect status latency and 15s hard timeout. Deduplicated across concurrent pollers and cached alongside line stats. Omitted on failure — always shows exact or nothing, never a partial estimate. Updates throughout the stack: native git status, relay, renderer store/API, and UI components. * Pin branch line total to app locale Format line counts using the app's configured locale instead of the system locale, ensuring consistent cross-platform display and test reliability. * test: wait for coalescer joins instead of fixed sleep Hold the diff until the second status pass actually takes the branch-total coalescer lease instead of using a fixed 400ms sleep. Fixes timing-dependent flakiness on slow machines.
- Replace 'Send answer' with 'Submit' for clarity and consistency - Update all locale translations (en, es, ja, ko, zh) - Remove fixed button width and add whitespace-nowrap for flexible sizing - Update component and test references
* Reorder source control to show staged changes first by default Stages are closest to the commit action and most relevant to the commit workflow. Merges untracked files into Changes visually while preserving their Git area. Removes the untracked-first preset and includes migration logic for existing user settings. * Drop source control group order user preference Remove the sourceControlGroupOrder setting and related UI, migrations, and persistence logic. The source control view now always displays sections in the order: staged changes, unstaged changes, untracked files. * Reorder source control to show changes before staged Aligns with the edit-stage-commit workflow by showing unstaged changes (active edits) before staged changes (queued for commit).
…12646) * Display SSH worktrees immediately using persisted metadata Users can now see known worktrees for SSH hosts without waiting for the provider connection to establish. Worktrees are fetched from local metadata and displayed as non-authoritative, then merged without replacing richer live data once the provider becomes available. * Show SSH folder workspaces immediately via persisted metadata Add safeguards for metadata fallback: track authoritatively removed worktrees per host to prevent resurrection, position new rows within the host block to avoid jumping on authoritative scan arrival, and preserve co-owner detection status during merge. Coalesce concurrent metadata fetches to dedupe overlapping queries.
Add a new census module that tracks pending and retained OSC sequences across all active PTY output processors. Each processor registers a gauge at creation and unregisters it on dispose, detach, or destroy — this prevents retained gauges from inflating later heap high-water profiles and allows the memory profiler to detect stalled processors as a sign of leaks.
…isting surface (stablyai#11576) * fix(file-explorer): sort numbered file names naturally The File Explorer compared names with bare localeCompare, so numbered files listed 100, 200 before 99. Hoist the numeric collator Source Control file rows already use (stablyai#10850) into src/shared and apply it to the local and runtime directory listings, the name-filtered view, and Source Control directory nodes, which were inconsistent with the file rows one line below (stablyai#11426). * fix(file-explorer): natural sort on SSH funnels, relay, and pickers Adversarial-review round 1 rework: - Both readDir funnels short-circuited to the SSH filesystem provider before the patched sort, so SSH workspaces kept lexicographic order; re-sort locally after the provider returns (the remote relay may be an older build), and fix the relay's own comparator for relay-native consumers. - sortDirEntries (shared, unit-tested) owns the directories-first + natural-order listing contract used by every funnel. - compareFileNames breaks numeric-collation ties ('2' vs '02') by code units so sibling order stays total instead of readdir order, and pins the collator locale to 'en' so every host produces one order. - The SSH folder browser and runtime server dir picker now match the Explorer they browse into. - Ordering pinned by tests at the relay, source-control tree, and shared helper. * fix(mobile): natural sort in the mobile file explorer Mobile re-sorted host readDir results with bare localeCompare, undoing the host funnel's natural order (round-2 review). Reuse the shared comparator and pin the order in the mobile suite. * fix(file-explorer): natural sort at the renderer choke point and remaining ties Round-3 review: the remote-runtime RPC and paired-web routes return the host's order verbatim, so re-sort in readFileExplorerDirectory where every desktop route converges; pin the SSH funnel with a handler-level test; and route Source Control path compares through compareFileNames so numeric-collation ties share one total order with the Explorer. * docs(file-name-sort): state the real perf baseline in the hoist comment * refactor(source-control): drop the dead collator export; pin the test oracle locale * fix(file-listings): cover remaining natural-sort surfaces
…ve (stablyai#12791) `orca serve` publishes a ready graph under HEADLESS_RUNTIME_WINDOW_ID with no BrowserWindow behind it. `shouldCreateInBackground` only degraded when the create was renderer-backed, so any focus-requested create fell through to getAuthoritativeWindow() and threw "No renderer window available" — leaving `terminal create --focus` with no workaround on a remote server (stablyai#10333). With a worktree selector and no renderer window, a background spawn is the only usable path, so collapse the renderer-backed window check into a plain "no window" check. That is the existing rendererBacked clause plus exactly the missing focus case, and it drops the confusing `rendererWindow === null` indirection (rendererWindow is already gated on rendererBacked). Focus is not lost by the degrade: the spawned pane is still published to the session-tab model and revealed with `activate: true`, which is how a paired client learns about it. Mirrors the in-tree precedent in runCreateMobileSessionTerminal. Headed hosts are unaffected — the clause only fires when no window exists. Co-authored-by: Jinwoo-H <Jinwoo-H@users.noreply.github.com>
…ablyai#12495) * fix(mobile): keep the cached transcript visible while reconnecting A manual retry closes the client and opens a fresh one, so the chat session hook saw a new client under an unchanged identity, dropped its settled read, and handed out an empty list — the transcript collapsed to a full-screen spinner until the swapped client's snapshot landed. Hold the last settled list per identity (captured post-commit) and keep rendering it while the re-read is in flight. `transcriptLoading` still gates consumers that decide from an empty transcript, so the launch-draft seed is unaffected. The held list is keyed by a new `sourceIdentity` (host/workspace) in addition to agent/session/transcript, so it can never serve another source's messages. Refs STA-3333. * test(mobile): assert the whole reconnect window, not just its first frame The re-subscribe lands a commit after the first render of the swap, so a regression that cleared the held list there left frame 0 green and still blanked the transcript. Verified: clearing the cache in the subscribe cleanup now fails this test, where before only the view-toggle test caught it. * fix(mobile): don't derive a tappable ask card from the held transcript The cache this PR adds keeps the previous list rendered while a swapped client re-reads. useMobileNativeChatPrompts was the one consumer reading `messages` without honouring `transcriptLoading`, so an ask answered on the terminal resurrected as a live, tappable card during that window. Gating on `transcriptLoading` is exactly base behaviour: `setRead` only ever stores 'ready'/'error', so status==='loading' implied an empty list before this PR. The live `askFromStatus` path is untouched. * chore: keep merge formatting scoped
Scope known-snapshot matching to manifest-listed files so agent-written sidecars (e.g. agents/openai.yaml) no longer mark a package unrecognized and block updates when official bytes still match. Preserves fail-closed detection when a listed file's content drifts. Fixes stablyai#12694
Sidecar tolerance stopped at the snapshot match, leaving three disk-vs-official comparisons still judging the whole folder. The lock-comparable hash covered every observed file, so a clean update beside agents/openai.yaml reported as failed and read 'may be modified'. It is now carried both whole and scoped to the current bundle's paths, and either may satisfy the lock: the sidecar case only ever matches scoped, while an upstream revision that ADDS a file only ever matches whole, so publishing one alone would trade this bug for stablyai#11220. Convergence re-derived the disk revision from that same whole-folder digest, which no revision matches once a sidecar lands, retiring the stuck-lock gate and arming an update the command provably cannot perform; it now honours the revision observation already resolved. Subset matching also let an older revision launder drift on a file the current bundle lists, since that revision does not list it and so read it as a neighbour. Identity now keys tolerance on what the current bundle owns.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upstream
fileslist stablyai/orca#12694Summary
Description Treat a skill placement as matching a known snapshot when every manifest-listed file matches, even if local sidecars exist (e.g.
agents/openai.yaml). This unblocks skill updates that were permanently skipped as "modified" despite byte-identicalSKILL.md.Note
innocarpe/orcamainuntil the upstream PR is merged.