Commit Graph
6792 Commits
Author SHA1 Message Date
Brennan Benson d76d955dec fix(codex): snapshot hooks.json bytes+parse in one read to close real-home clobber race
The install/sweep/legacy-cleanup paths parsed hooks.json, then did a separate
later read to capture the previous bytes for the pre-write generation guard.
A concurrent save (second Orca instance or the user editing the file) could
land between the parse and that second read and be silently overwritten.
readHooksJsonWithRaw returns the raw bytes and parse from a single read so the
guard compares against exactly what it parsed. Adds a regression test that
mutates hooks.json mid-RPC and asserts the sweep aborts without clobbering.
2026-07-17 00:36:06 -07:00
Brennan Benson 11f9e911f7 RC: merge latest main 2026-07-16 15:37:34 -07:00
Brennan Benson eb8b9be89f RC: enable system-default real-home routing by default (flag ON)
Flip codexSystemDefaultRealHomeEnabled to default ON for this RC's staged
rollout (a user can still opt out by setting it false, which stays byte-identical
to managed-home behavior). This is the only intended behavior difference between
the RC branch and the individual PRs. Updates the two tests that assumed the
prior OFF default.
2026-07-16 15:37:07 -07:00
Brennan Benson 0f6933cb25 Assemble RC: reconcile app-server transport API across PRs
Unify on the object RPC surface from the index-heal transport (#8921) while
preserving the default-home env strip (#8828) and the narrowed missing-app-server
capability signal (#8847): adapt the user-hook-trust-rebase consumer + tests,
port envToDelete stripping into the shared session, and route stderr
classification through the canonical capability-signal module.
2026-07-16 15:30:18 -07:00
Brennan Benson dd0f4c39c8 fix(pi): stop OMP tab icon flashing to Pi while working (#9077)
OMP runs as a `shell → omp → pi` process tree and Orca recognizes both
`omp` and `pi` as distinct agents, so the foreground-process reader
alternates between reporting the two across command boundaries. In
`resolveTabAgentFromSignals` every identity signal is re-owned onto the
pane's durable owner within its title-identity group (pi and omp share
one) — except the process signal, which was consumed raw. Because it
ranks above launchAgent, each `pi` read repainted an OMP-owned tab's icon
to the Pi glyph and the next read flipped it back.

Re-own the process signal the same way the hook and title signals already
are, so a same-group read collapses onto the owner while a genuine
cross-group process (e.g. Codex) still stands and can reclaim a reused
pane. The tab title text was unaffected — its owner resolution already
excludes the process signal — so this is icon-only.

Adds regression coverage for the oscillation, the mirrored/restored pane
(launchAgent gone, durable hook record), and the cross-group scope guard.
2026-07-16 15:18:58 -07:00
Brennan Benson 1cdecea99e Assemble RC: real-home routing (#8828)
# Conflicts:
#	src/main/codex/codex-app-server-client.ts
#	src/main/codex/codex-app-server-session.ts
2026-07-16 15:13:30 -07:00
Brennan Benson e8e688cb60 Assemble RC: codex session dedup + index heal (#8921) 2026-07-16 15:12:56 -07:00
github-actions[bot] de9e9f8f1b release: v1.4.144-rc.2 v1.4.144-rc.2 2026-07-16 22:01:28 +00:00
Brennan Benson 0702e3dd4c Fix paired-host manual project header ordering (#8919)
* Fix paired-host project header reordering

* fix(sidebar): keep unchanged paired project drops inert
2026-07-16 15:00:09 -07:00
Brennan Benson 09173d02d2 fix(terminal): restore clickable links after returning to a worktree (#9061)
* fix(terminal): restore clickable links after returning to a worktree

Clicking a terminal link (file path, URL, term_* handle, OSC-8) does nothing after switching to another worktree and back, until the terminal is scrolled a little.

xterm's linkifier only re-runs link providers on mousemove when the hovered buffer cell changes vs its cached `_lastBufferCell`. Hiding the terminal surface fires `mouseleave`, which clears the current link but leaves that cache. On reveal the pointer returns to the same cell, so the mousemove handler short-circuits and the link is never re-established; a scroll shifts the buffer position and re-linkifies, which is the "scroll to fix" symptom.

Reset the linkifier hover-cell cache when a terminal surface is revealed (resumeTerminalVisibility) so the next mousemove re-evaluates providers. Covers all link types, including file-path links whose geometry click fallback does not compensate after reveal.

Verified in real Electron via a new e2e that fails without the reset and passes with it, for both a file-path link and a URL.

* test(terminal): prove restored links activate after reveal
2026-07-16 14:48:06 -07:00
Brennan Benson 68fca0b076 Add safe skill freshness detection and update rail (#8637)
* Add safe skill freshness detection

* Accept observed copy-mode rail outcomes

* chore(skills): regenerate snapshot artifacts for the merged guide content

The rebase onto main picked up the reviewed guide fixes (#8624), so the
current manifest hashes and a new appended snapshot generation must
match those bytes; the registry keeps all prior snapshots so existing
installs classify as outdated rather than unrecognized.

* fix(skills): canonicalize snapshot file order and guard released history

Historical snapshots kept git ls-tree byte-order while the working-tree
walk and runtime observation use the sorted depth-first order, so any
future multi-file skill would misclassify older installs as unrecognized
and churn spurious registry revisions; all producers now share one
canonical order (no digest changes for today's single-file packages).
Also rejects executable files from shipped skills (Windows observation
cannot see execute bits, which would misclassify pristine Windows
installs) and adds an explicit append-only invariant for released
snapshots so a generation-logic change cannot rewrite them silently.

* fix(skills): throttle focus rescans and correct self-blocked placement copy

Every window focus re-read and re-hashed all installed packages, and the
nudge and panel each forced their own trailing rescan for one event; a
15s cooldown plus a shared invalidation latch keep one bounded scan per
event while install-change events stay immediate. Bundle artifacts are
now loaded once per run instead of re-parsed on every scan. A read-only
or otherwise unsupported outdated placement now explains that it blocks
itself instead of blaming a phantom sibling placement; the supported
topology set moved to shared so eligibility and copy cannot drift.

* feat(skills): move freshness surfacing to a lingering toast and update modal

The Skills page has been unreachable since its toolbox menu entry was
removed (#4535), so surfacing freshness there buried the feature behind
its own nudge. The nudge now lingers until acted on (ignoring it records
nothing; only the explicit close persists dismissal keys) and opens an
update modal hosting the pre-filled editable terminal, an honest
current/blocked summary, and the per-placement rows in a collapsed
Details section. A compact 'Check for skill updates' row in CLI settings
is the manual re-entry point. Skills page restored to main; design-doc
surfacing section records the venue decision.

* fix(skills): mount update dialog inside the link-routing provider and fold freshness into the setup rails

The dialog hosts a live terminal pane that requires the link-routing
preference context; mounted outside the provider it crashed the renderer
the moment an eligible update existed (caught by live QA — unit tests
mock the terminal). It now mounts inside the provider behind its own
recoverable boundary.

The separate 'Check for skill updates' settings button is gone: the
setup rails' own pill now carries freshness (Update available / Up to
date, falling back to Installed for blocked or unrecognized copies and
for non-local runtimes the local-only scan cannot vouch for), and
Re-check refreshes both installation detection and the freshness
inventory. Wired for the CLI, Orchestration, Computer Use, and
Per-Workspace Environments rails.

* fix(skills): use the sleek scrollbar style in the update dialog

* chore(skills): regenerate manifest for merged main (v1.4.142-rc.1)

Main advanced to 1.4.142-rc.1 with a v1.4.141 release, so the embedded
appVersion and release mapping were stale on the PR's merged tree. Only
appVersion and the new release entry change; no snapshot digests move
(released history preserved).

* fix(skills): bound and batch freshness work

* fix(skills): harden freshness integrity checks

* fix(skills): accept observed copy topology outcomes

* chore(skills): regenerate manifest for current main

* fix(skills): preserve update terminal lifecycle

* chore(skills): regenerate manifest for current main

* fix(skills): fail closed on stale freshness scans

* chore(skills): regenerate manifest for current main

* fix(skills): preserve freshness safety under focus churn

* feat(skills): group the update modal by skill with plain-language status

The Update skills modal now lists only skills that will update or that can't
(with why), grouped by skill with their install locations nested underneath —
no more one row per placement.

- Statuses collapse to "Update available" / "Can't update" at the skill level.
- A location's problem is a chip (Duplicate, Unrecognized, Inaccessible, Read
  only, In a repo, External/Broken link, Plugin cache) with a hover tooltip
  that explains what it means for the user and what to do.
- Up-to-date, unrecognized-only, and unreadable-only skills are hidden; a
  current/unrecognized/etc. location only appears when it explains a shown skill.
- Copy is de-jargoned (drops "copy"/"placement"/"snapshot"/"official copy") and
  names the mechanism as the npx skills update command, not "Orca's update".
- Rename the section to "Update details"; drop the unreachable newer-known state.

Renderer-only: derivation is a pure module (groupSkillFreshness) with unit tests;
no IPC or main-process change. Locales updated for all five languages.

* chore(skills): regenerate manifest for current main (v1.4.143-rc.0)

* feat(skills): don't let a duplicate block the update; clearer skipped copy

- Eligibility: a clean standalone duplicate no longer poisons the whole
  name — the canonical copy still updates and the duplicate is flagged;
  a duplicate-only skill stays unoffered.
- Update modal: "Can't update" -> "Skipped" with a reason-specific
  sentence (edited/read-only/in-a-repo/plugin/link); chips describe only
  the location state; footer "Check now" -> "Re-check".
- Settings sidebar nav pills go amber "Update available" when a skill is
  updatable, matching the setup cards.
- Localized new strings across en/es/ja/ko/zh.

* chore(skills): regenerate manifest for merged main (v1.4.144-rc.1)
2026-07-16 14:47:28 -07:00
Jinwoo HongandOrca f102972cc1 fix(emulator): ignore external serve-sim helpers (#9071)
* fix(emulator): ignore external serve-sim helpers

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

* docs(reliability): align backpressure evidence

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-16 14:44:55 -07:00
Brennan Benson 25ccf9063d test(codex): type child.stdout as PassThrough for oversized-output write 2026-07-16 14:35:49 -07:00
Brennan Benson 6ca71ebeae fix(codex): restore envToDelete on client invocation type after base reconcile 2026-07-16 14:34:03 -07:00
Brennan Benson 50b61c6022 fix(codex): harden trust grant lifecycle 2026-07-16 14:23:47 -07:00
Maxim Syabro fc6570da67 fix(pi): report completion on agent_settled so intermediate agent_end stays silent (#8035) (#8826)
Pi's agent_end fires per low-level run — auto-retry, auto-compaction and
queued follow-ups all emit it while the agent is still working — so Orca
fired premature completion notifications. Pi >= 0.80.4 emits
agent_settled exactly once when nothing is left to run.

The extension now subscribes to both events: the first agent_settled
proves runtime support and mutes agent_end reporting from then on; on
older Pi/OMP runtimes (where unknown event names register silently and
never fire) agent_end keeps reporting done exactly as before. The
settled handler reports the existing agent_end hook event, so the
agent-hooks server contract is unchanged.
2026-07-16 14:16:30 -07:00
Brennan Benson 555cfbdd5f Merge remote-tracking branch 'origin/brennanb2025/codex-trust-rpc-grant' into brennanb2025/codex-real-home-phase1
# Conflicts:
#	src/main/codex/codex-app-server-client.ts
2026-07-16 14:13:17 -07:00
Jinwoo HongandOrca 4e232a030f fix(usage): show CLI-owned session recovery steps (#9069)
Co-authored-by: Orca <help@stably.ai>
2026-07-16 14:12:47 -07:00
Brennan Benson 362b625c5c Merge remote-tracking branch 'origin/main' into brennanb2025/codex-session-dedup-index-heal
# Conflicts:
#	src/main/ai-vault/remote-session-scanner.ts
#	src/main/ai-vault/session-scanner.ts
2026-07-16 14:03:04 -07:00
64181fdd42 feat(native-chat): native chat view across mobile, desktop, and web (#5824)
* feat(native-chat): add native chat view across mobile

* fix(native-chat): address review findings and CodeRabbit threads

Correctness:
- Restore an independent initial readSession seed and surface initial-drain
  errors as snapshot frames so the chat view can never strand on 'loading'
- Pair mobile tool results to calls by ordinal FIFO (parallel calls no longer
  misgraft results); clear a pending ask only when its own call resolves
- Show a new streaming reply immediately (same-turn suppression, not length)
- Delegate mobile noise filtering to the shared harness-injected classifier
- Admit soft-leaving mobile clients in beginMobileInputFloor (parity with
  mobileTookFloor) so grace-window writes aren't dropped
- Self-heal a stale 'working' status once this turn's reply lands
- Catch RPC rejections in mobile file-open helpers; guard sanitizeToolInput
  key collisions; settle web/runtime transports on unrecognized first frames
  and forward snapshot errors

Perf:
- Throttle the mobile streaming bubble (50ms) so per-part status frames stop
  re-parsing the whole accumulated markdown
- Short-circuit markdown path detection on dot-less or oversized runs
  (quadratic backtracking guard)

UX/minor:
- Wire hold-mode dictation through the native chat composer
- Allow scoped-package (@) paths in file-path detection
- Move caret after mid-text autocomplete insertion; index-prefixed ask option
  keys; single scroll-to-end effect; bounded wait + toast when image attach
  races a resubscribe; count-based pending reconciliation; cache-hit search
  cancels stale debounce; chat-tab toggle wins over in-flight preference load
- Share shouldStepNativeChatAskAnswer between desktop and mobile; import
  block guards/source priority from shared instead of local copies
- Defensive non-positive transcript limits; test strengthening (TTL expiry,
  post-unsubscribe stale frame, lease readiness, filtered console.error)

* refactor(native-chat): share desktop/mobile chat logic in src/shared

Extract the parity-mirrored native-chat modules into shared implementations
both surfaces re-export: ask parsing (registry, parseAskFromStatus,
extractPendingAsk, formatAskAnswer), answer stepping offsets/scheduler, diff
detection/parsing, harness-noise filtering, tool fold/pair/split, and tool
summaries. Removes the hand-synced copies and their stale Metro comments.

Divergence reconciliations take the safer side of each: diffs truncate at
120 lines/32KB everywhere (desktop previously unbounded), tool-run summaries
cap at 3 parts with bounded-depth previews, nameless tool calls are skipped,
and basenames split on both separators.

Also: settle and kill every sibling quick-open pass when one reaches
maxResults (main rg/git and relay git; relay rg already did) so a capped
search cannot leave a scan walking a huge tree; fold window-bounding into
the shared merger's applyAppend; localize the web 'Pair a host' snapshot
error.

* fix(native-chat): address CodeRabbit follow-ups on shared modules

- Attachment lease gate re-checks connection/target/tab after the bounded
  wait, so a tab/host switch or disconnect mid-wait can't send into a stale
  terminal; a moved-away target drops silently like the pre-wait guard and
  only an unrecovered lease surfaces the toast. Adds hook tests.
- extractPendingAsk parses transcript tool-calls through the same
  registered-parser + canonical-shape fallback as live status, so a custom
  question tool that rendered live survives reconnect/replay.
- Direct unit tests for the shared ask parser (FIFO ordering, fallback,
  malformed payloads) and tool-summary bounded preview (depth/collection
  caps, circular refs, basename/command branches).

* fix(native-chat): treat initialLimit 0 as a valid empty window

Both engine guards used truthiness, so an explicit zero limit skipped the
bounded tail reader and fell back to an unbounded incremental read. Latent
only (every caller clamps positive), hardened for consistency with the
tail reader's non-positive-limit handling.

* fix(mobile): native-chat composer lock UX + send-failure feedback

- Distinguish input-lock reasons: transport 'disconnected' shows Reconnecting…
  instead of mislabeling a reconnect as locked-by-another-client
- Guard the composer lock behind a 600ms hold so connState blips / lease
  hand-offs don't flicker the placeholder; unlock stays instant
- Surface a rejected send inline above the composer (a bottom toast hides
  behind the keyboard); auto-dismisses after 4s
- waiting-session hint invites the first message instead of implying the
  agent is still starting

* test(mobile): sync answer-send pacing test to the 500ms advance buffer

Missed in merge 8fe3c391c, which carried main's NATIVE_CHAT_ADVANCE_BUFFER_MS
300->500 (#8568) into the shared stepping module that mobile derives from.

* fix(mobile): restore terminal stream after chat cold start

* fix(native-chat): harden retries, optimistic sends, and file scans

* fix(mobile): deliver AskUserQuestion answers by option number (STA-1860)

Port #8840's fix to the mobile native chat: the Ask card now tracks
per-question option INDICES (+ free text) and the answer-send hook drives
Claude's arrow-navigate selector with buildAskAnswerKeys keystroke groups —
option numbers, next-tab arrows, Enter — paced one selector step apart, instead
of pasting label text that the selector ignores (which silently committed the
default option). Non-Claude agents keep the pasted-label path via the
selection-based formatAskAnswer.

Backcompat: keystrokes are built client-side and written through the EXISTING
terminal.send passthrough with enter:false — the same contract the permission
card already uses — so an older desktop runtime (SSH/relay included) replays
them verbatim; no RPC/contract change in either update order. Free text is
newline-sanitized because terminal.send has no paste framing.

Drops the now-unused formatCompleteAskAnswer from the shared module.

* fix native chat send and runtime races

* fix mobile native chat formatting

* fix(native-chat): mobile empty state matches desktop copy

Mobile showed a single generic line ('Send a message to get started') where
desktop shows a titled two-line empty state naming the agent ('Start a chat with
Claude' + 'Ask Claude to inspect code, explain output, or make a change.'). Align
them from one source of truth so they can't drift again:

- Extract the agent-type label map + formatAgentTypeLabel to
  src/shared/agent-type-label.ts (desktop re-exports; mobile imports).
- Add src/shared/native-chat-empty-state.ts with the canonical English copy;
  desktop uses it as its i18n fallbacks (localization unchanged — en/es/ja/ko/zh
  keys still win), mobile substitutes the agent label and renders it directly
  (mobile ships English only).
- Mobile: render title + subtitle for waiting-session AND ready-but-empty (both
  are 'start a chat'), error copy for errors; keep the loading spinner.

Live-verified on the iOS sim against a pn-dev of this branch. typecheck node/web
+ mobile tsc clean; 30 mobile + 428 desktop/shared native-chat tests green.

* style: oxfmt the empty-state parity test (line wrap)

---------

Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-16 13:26:15 -07:00
github-actions[bot] 9716dbd45f release: v1.4.144-rc.1 v1.4.144-rc.1 2026-07-16 20:08:45 +00:00
Jinwoo Hong e8a1674a75 fix(terminal): keep divider resize active after capture loss (#9063) 2026-07-16 13:07:44 -07:00
Jinjing 1536171fdb Add a native macOS menu bar status item with activity indicator (#9042)
* Add native macOS menu bar status item with settings toggle

Extend the Windows-only system tray into a shared status-item module
so macOS gets a template menu bar icon (Open/Settings/Check for
Updates/Quit), a theme-aware attention dot, and a "Show Menu Bar
Icon" appearance setting. Also fixes a startup race where a tray
"Settings…" click could fire before the renderer's ui:openSettings
listener attached, by queuing a one-shot pending-open-settings intent
the renderer consumes on mount.

* Fix Retina blur, race conditions, and menu-label duplication in tray Set

- Rebuild the tray attention icon's @2x representation since toBitmap only
  read 1x pixels, blurring the glyph on Retina displays
- Fix premultiplied-alpha math so light-glyph tinting uses per-pixel alpha
  instead of a flat 0xff, keeping antialiased edges valid
- Always push ui:openSettings and leave a longer-lived pending flag, since
  there was no reliable signal that a renderer's listener was attached
- Preserve tray attention state across macOS menu-bar hide/show toggles
  instead of resetting it on tray destroy
- Route macOS tray creation through syncMacMenuBarIcon so startup and the
  live toggle share one visibility policy
- Reuse app-menu translation keys for tray Settings/Check for Updates and
  drop the now-duplicate tray-scoped locale strings

* Make menu bar icon default on and platform-independent in settings

Previously showMenuBarIcon was hardcoded to darwin-only in both the
default settings and the sanitize/load paths, so a profile written on
macOS lost its opt-out when touched from another OS. Store the raw
boolean everywhere and let darwin-specific consumers decide whether
to act on it, so the value round-trips unchanged across platforms.

* Fix Settings menu click being silently dropped after a slow cold rendere

Replace the 60s pendingOpenSettings TTL with an untimed intent, since a
cold renderer start can outrun any fixed timeout and cause the flag to
expire before the click is consumed. webContents-id scoping plus
consume-on-read still prevent the intent from leaking to an unrelated
renderer. Adds a test covering the queued-before-mount pull path.
2026-07-16 13:06:21 -07:00
Brennan Benson 8630eb286a fix(codex): align hook trust source paths 2026-07-16 12:56:24 -07:00
Jinwoo Hong b8925657a0 fix(terminal): release reattach fit on an unchanged stable grid (#9056) 2026-07-16 12:38:31 -07:00
Brennan Benson e33551d215 fix(codex): disambiguate POSIX trust paths 2026-07-16 12:33:32 -07:00
Brennan Benson 1374d311bd fix(codex): preserve hook symlink trust path 2026-07-16 12:22:11 -07:00
Jinwoo HongandOrca 6be4e29394 fix(remote): isolate shared control request timeouts (#9016)
Co-authored-by: Orca <help@stably.ai>
2026-07-16 12:21:07 -07:00
Brennan Benson b31658b640 fix(codex): retry republished missing session heals 2026-07-16 12:18:40 -07:00
Brennan Benson 57f5dbefe1 fix(codex): keep session migration state recoverable 2026-07-16 12:04:02 -07:00
Brennan Benson f29cb27f91 fix(codex): keep session heal failures retryable 2026-07-16 11:43:29 -07:00
Brennan Benson 93791d5940 fix(codex): stop session backfill after opt-out 2026-07-16 11:26:45 -07:00
Brennan Benson b1a557f3b6 fix(codex): gate session migration on real-home lane 2026-07-16 11:15:07 -07:00
Brennan Benson a3457c8b87 fix(codex): strip inherited Codex homes on mobile real-home resume
The mobile resume surface types a bare real-home codex resume into a
freshly created pane, but never asked for CODEX_HOME/ORCA_CODEX_HOME
deletion at pane spawn, so an agentDefaultEnv-pinned or daemon-inherited
Codex home rerouted the resume away from the user's real ~/.codex while
the same session resumed correctly on desktop. Share the deletion helper
from the AI Vault resume builders and forward it through the mobile
launch and session.tabs.createTerminal call.
2026-07-16 11:12:28 -07:00
Brennan Benson 26e7ef6787 fix(ai-vault): preserve resume env deletion through drag 2026-07-16 11:04:09 -07:00
github-actions[bot] 92fc79ee66 release: v1.4.144-rc.0 v1.4.144-rc.0 2026-07-16 17:49:44 +00:00
github-actions[bot] ef23b6760c Update README downloads badge 2026-07-16 12:50:02 +00:00
7e743c41c2 fix(ssh): reconnect persisted PTYs after shutdown races (#8403)
* fix(ssh): reconnect persisted PTYs after shutdown races

* fix(ssh): harden shutdown reconnect-target derivation

- exclude runtime-owned (ephemeral-VM) targets: a renderer-driven startup
  ssh.connect would dispose the runtime layer's live relay session
- exclude explicitly disconnected / auth-failed targets so startup never
  dials a host the user chose to leave offline (sessions still restore
  on tab focus via the deferred flow)
- avoid re-running buildTerminalSessionData via the default parameter
  when the remote-session map is legitimately empty (null sentinel)
- recompute activeConnectionIdsAtShutdown alongside terminal-field
  patches so a crash between patches cannot strand a stale target
- pin all of the above with tests, including the patch-writer path

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

* fix(ssh): filter runtime-owned targets at startup reconnect consumption

Main's windowless-promotion path can persist runtime-owned ids into
activeConnectionIdsAtShutdown; renderer must never dial those.

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

* test(ssh): pin runtime-owned exclusion independently of the status gate

Give the runtime-owned fixture a transient status so the status gate
alone cannot exclude it; verified by mutation (guard removal fails).

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

* refactor(session): extract reconnect-target derivation to its own module

workspace-session.ts crossed the max-lines budget; the derivation is a
self-contained concern (session ids + live SSH state -> startup targets).
Parameter is now required (null = none) since every caller has the
terminal session data or must opt into the scan explicitly.

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

* fix(ssh): exclude runtime-owned targets from the connected-states path too

A pane-level optimistic write can stamp a runtime-owned connection state;
the live 'connected' filter must apply the same exclusion as the
session-id union (CodeRabbit review finding). Pinned in the test on both
paths.

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

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-16 04:17:21 -07:00
Jinwoo HongandOrca 377082e142 fix(ai-vault): discover Antigravity CLI sessions (#8971)
* fix(ai-vault): discover Antigravity CLI sessions

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

* fix(ai-vault): address remote scanner review

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-16 02:57:43 -07:00
Brennan Benson 0b772fe90d fix(codex): protect symlinked rolling backups 2026-07-16 01:58:11 -07:00
Brennan Benson 18e7414761 fix(codex): stop index heal before delayed spawn 2026-07-16 01:54:11 -07:00
Brennan Benson 69a85f56d2 fix(codex): establish real-home lane before cleanup 2026-07-16 01:45:35 -07:00
Brennan Benson 1f451e5fe2 fix(codex): enforce real-home resume and heal boundaries 2026-07-16 01:44:48 -07:00
Brennan Benson a04fa8259b fix(codex): bound user hook trust rebase retries per host
The rebase lane ran a codex app-server session on every launch prep while a
host was stuck (CLI without app-server support, or keys hooks/list cannot
match). Gate the transaction on the shared capability cache and add the same
5-minute transient cooldown the grant lane uses, so sweep and legacy-cleanup
retries cost plain fs reads instead of a codex session per pane spawn.
2026-07-16 01:34:40 -07:00
Brennan Benson f64fb13961 fix(codex): narrow app-server unsupported detection 2026-07-16 01:20:46 -07:00
Brennan Benson fe278b48a8 fix(ai-vault): preserve execution boundaries and reap children 2026-07-16 01:19:48 -07:00
Brennan Benson f5cf6ea53d fix: harden real-home hook cleanup 2026-07-16 01:16:23 -07:00
Brennan Benson 9ecaee715e fix(codex): fail closed on unsafe backfill install 2026-07-16 00:53:31 -07:00
Brennan Benson 8ce03b4652 fix(codex): harden real-home heal boundaries 2026-07-16 00:47:37 -07:00
Jinjing cf02cc46b1 Add missing WeChat QR image referenced by README
The previous commit updated the README to docs/assets/wechat-qr.jpg and
removed the old dual-QR assets, but never added the new image file, so
GitHub could not load it.
2026-07-16 00:43:11 -07:00