Commit Graph

6444 Commits

Author SHA1 Message Date
Jinjing ac8879c789
feat(markdown): support HTML superscript links (#8307)
* feat(markdown): support HTML superscript links

* Add HTML superscript citation links to the rich markdown editor

- Introduce marked-based tokenizer support for `<sup><a>` citation
  links, with a shared editor context so key/link handlers can resolve
  selection status and open an action bubble for citation atoms
  (which markdown setLink/unsetLink can't edit).
- Extract clipboard-write logic shared by cut and cut-visual-line into
  rich-markdown-clipboard-write.ts, and surface a cut-limit error when
  clipboard readback fails.
- Fix MarkdownPreview same-file anchor scrolling to run before the
  unknown-ownership guard so ambiguous folder-workspace ownership
  still scrolls within the open document.
- Keep search's replace-disabled state derived from live matches
  instead of a stale snapshot.

* Update lockfile to dedupe stale package versions after dependency resolu

- Removes duplicate/superseded resolutions (older @babel/* versions, fs-extra 11.3.4/11.3.5, plist 3.1.0, semver 7.7.4) left over from a prior install
- Aligns transitive deps to the single resolved versions already in use elsewhere in the tree
2026-07-11 14:51:52 -07:00
Jinjing 6be8687c34
feat(status-bar): notify upgraded users usage meters show % used (#8319)
* feat(status-bar): notify upgraded users usage meters show % used

Show a one-time status-bar callout when upgraded profiles still use the
new percent-used default. Brand-new profiles and users who already chose
remaining stay quiet; dismissing or changing the setting is permanent.

* Add settings deep-link to expand Appearance's Window accordion for one-s

- Replaces the searchQuery-based redirect (fragile, flashed filter UI) with a
  dedicated appearanceAccordionDeepLink store field that force-opens the
  correct accordion and scrolls to the target row
- Rebuilds the status-bar change notice as a plain elevated card instead of
  a Popover, since PopoverContent's glass/backdrop-filter defaults fought
  the opaque callout styling and needed heavy overrides
- Simplifies the light/dark card CSS tokens accordingly

* Reposition status-bar usage-change notice via fixed-position portal

Portal the one-shot callout to document.body with fixed positioning
anchored via getBoundingClientRect, since the status-bar's overflow-hidden
flex ancestors clipped or mispositioned the previous in-tree absolute
layout.

* Refine status-bar usage notice styling and test coverage

- Replace hand-tuned light/dark card colors with existing design
  tokens (--popover, --border) and the documented floating elevation,
  so the callout stays in sync with the design system instead of
  duplicating its own palette
- Add tests covering dismiss via X button, "Got it", and Escape
- Scope the foreground-process confirm assertion to the pane's ptyId
  so an unrelated pane's delayed confirm can't cause a false failure
2026-07-11 14:49:49 -07:00
Neil 5092ba9fb8
feat(resource-manager): show browser resources (#8267) 2026-07-11 14:41:32 -07:00
Jinjing 2802f0419d
Fix browser annotation sends to active Windows agents (#8309)
* fix: authorize guarded sends to active ConPTY agents

* Fix stale-handle rejection using controller-less status checks and contr

- Distinguish `terminal_handle_stale` (PTY rebind mid-check) from `terminal_exited`
  so callers get an accurate reason instead of a generic `terminal_not_writable`.
- Move the PTY binding assertion to always run after the fresh foreground read,
  even when no controller is present, closing a gap where a rebind during a
  controller-less check went undetected.
- Call `confirmForegroundProcess` through its owning controller instance so the
  method keeps its `this` receiver instead of being invoked unbound.
- Update reliability gates and design doc to reflect the new test coverage and
  corrected error semantics.

* rm design doc
2026-07-11 14:32:55 -07:00
Neil 800967278e
feat: promote APFS shared paths (#8318) 2026-07-11 14:24:39 -07:00
Trevin Chow b18ec39e1f
fix(naming): lead workspace and tab names with the work-item identifier (#8238)
* fix(naming): lead workspace and tab names with the work-item identifier

Auto-generated workspace names, branch-rename display names, and tab
titles now lead with the referenced PR/MR/issue/ticket — e.g.
`PR 1033 - Review` instead of a paraphrase like "Review community pr
1094" that buried or dropped the number. Identifiers are the highest-
signal, most searchable token, so leading with them makes the sidebar
and tabs scannable and disambiguates same-verb work items.

- New shared `work-item-reference.ts` extracts the identifier from the
  raw prompt: URLs are validated by path structure (owner/repo/pull/N,
  GitLab's `/-/` marker) so GitHub Enterprise / self-hosted GitLab still
  resolve while stray `/pull/<n>` paths (CDN, docs) do not; a ticket-
  prefix denylist keeps `SHA-256` / `UTF-8` / `ISO-8601` from being read
  as Jira/Linear keys.
- Reconciles the existing create-from-work-item naming (was action-first
  `Review PR 1033`) with the first-work auto-rename onto one identifier-
  first format via a shared `formatIdentifierFirst`, so the two paths
  can't drift.
- Fixes a pre-existing tab-title bug where markdown punctuation was
  stripped before URLs, splitting a GitLab `merge_requests` URL at its
  underscore and leaking "requests" into the title.

* fix(naming): keep emphasis-wrapped URLs intact in generated names

The URL/markdown strip reorder left the tab-title URL strip anchored on
\b, which fails when a URL is wrapped in markdown emphasis (_...pull/5_)
and leaked URL fragments into the title. Drop the \b anchor and trim
trailing markdown emphasis (*_~) in the URL identifier parser, keeping
interior underscores (merge_requests) intact. Adds regression tests.

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

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-11 14:14:12 -07:00
Neil 3804f75f6a
fix native chat cleanup registration leak (#7663) 2026-07-11 14:03:49 -07:00
Neil d8a9da7351
Fix PR comment selection persistence leak (#7688)
Bound the PR/MR queued-comment selection cache to 1024 LRU contexts and make cache recency commit-safe so long renderer sessions cannot retain unbounded unsent selections.
2026-07-11 14:03:14 -07:00
Neil 19b63c4cb4
Prune detected worktree scan generation markers (#7679)
* Prune detected worktree scan generations

* Invalidate pending scans in test reset hook

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-11 13:59:28 -07:00
Neil a92fd26c96
perf(renderer): drive the agent-completion feedback observer off the agent-status epoch (#7621)
The always-mounted observer that watches for successful agent completions
subscribed to the whole agentStatusByPaneKey map, which is re-spread to a new
object on every agent status ping (including high-frequency still-working
pings). That re-rendered the observer and re-ran the app-wide done-transition
scan on every ping. Subscribe to agentStatusEpoch instead — it bumps on exactly
the state transitions the observer detects — and read the map imperatively via
getState(), mirroring useActivityUnreadCount. Behavior is preserved; a Profiler
render-count test guards that non-epoch churn no longer re-renders.

Co-authored-by: Orca <help@stably.ai>
2026-07-11 13:46:11 -07:00
Marius 6d3ab9f971
feat(status-bar): choose used or remaining usage (#7574)
Add a persisted Appearance setting that switches provider usage labels between percent used and percent remaining while keeping meter fill consumption-based.

Cover desktop and web persistence, current providers, settings search, localized copy, and regression tests.

Co-authored-by: gatsby74 <166927047+gatsby74@users.noreply.github.com>
2026-07-11 13:45:52 -07:00
Neil 19102355d7
perf(renderer): keep worktree activity summaries ref-stable across unrelated churn (#7626)
selectWorktreeAgentActivitySummary's shared cache keys on agentStatusEpoch, so
any epoch bump — an UNRELATED worktree's agent transition, or a freshness tick —
invalidated it and rebuilt every worktree's summary with fresh objects/Sets. Each
sidebar card subscribes to its own summary via useShallow, and the new nested
agentStatusPaneIdsByTabId ref defeated the shallow compare, re-rendering every
card with agents on every transition anywhere. Reuse the prior summary object
when structurally equal (booleans + Set-membership), mirroring reuseArrayIfEqual,
so only the transitioning card re-renders.

Co-authored-by: Orca <help@stably.ai>
2026-07-11 13:45:50 -07:00
Neil c3ccbdc306
Fix worktree scan generation cache leak (#7675) 2026-07-11 13:44:10 -07:00
Neil 11e537616c
Surface a friendly error when Windows blocks the user PATH write (#6412) (#6588)
* Surface a friendly error when Windows blocks the user PATH write

When HKCU\Environment is locked (Group Policy / restricted ACL / EDR-managed
environment), the PowerShell SetEnvironmentVariable write rejects with a raw
'Command failed: powershell ...' error (often mojibake-localized) that the CLI
Settings toast displayed verbatim. Detect the permission failure via the Latin
PowerShell error-envelope tokens and rethrow an actionable message naming the
exact folder to add to PATH manually, chaining the original error on cause.

Fixes #6412

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

* Tighten Windows PATH permission detection

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-11 13:43:31 -07:00
Neil b5cdab3a26
Fix tracked upstream generation cache leak (#7674) 2026-07-11 13:43:17 -07:00
Neil 884781a552
Contain smart-sort persistence failures on remote disconnect (#6994) 2026-07-11 13:34:41 -07:00
Neil e538a93129
Cap Kimi session index cache (#7673) 2026-07-11 13:31:32 -07:00
github-actions[bot] 9202f92220 release: v1.4.136-rc.1 2026-07-11 19:57:58 +00:00
Jinjing 9b3ed3997e
fix(daemon): resolve Unix shell fallback before node-pty spawn (#8306)
* fix: resolve daemon shell before spawning

* fix(daemon): reconcile shell-ready barrier with the resolved fallback shell

The adapter computes shellReadySupported from the preferred shell before
spawn. When the daemon falls back (e.g. to /bin/sh), the session would
queue startup commands for the full 15s ready-marker timeout and wrap
multiline prompts in bracketed-paste markers the fallback shell cannot
parse. Expose the spawned shell on SubprocessHandle and downgrade the
barrier and paste wrapping in TerminalHost when the actual shell cannot
emit the marker.

Also apply the Unix shell fallback after the relay env scrub so a
scrubbed SHELL cannot drop the corrected value, and cover the resolve-
before-launch-config ordering, the no-shell throw, and candidate dedup
with tests.

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

---------

Co-authored-by: Vitus Apollo <zhzvitus@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-11 10:45:55 -07:00
github-actions[bot] ff8192a331 Update README downloads badge 2026-07-11 12:36:47 +00:00
Neil a4583eb765
fix(rate-limits): auto-refresh stuck on "Refresh failed" after update relaunch (#5355) (#6560)
* fix(rate-limits): debounce auto-refresh off last successful fetch

A failed post-update/relaunch fetch stamped the single debounce
timestamp the same as a success, so refreshIfWindowActive() no-oped
every focus/show/restore and the deferred-startup retry for the next
5 minutes — leaving the status bar stuck on "Refresh failed" until the
15-minute background poll (which on Windows also requires the relaunched
window to be focused).

Key the debounce off the last SUCCESSFUL read instead: only stamp
lastSuccessfulFetchAt when a provider returned fresh 'ok' data, so a
failed fetch no longer suppresses auto-recovery on the next window
activation. Removes the now-unused lastFetchAt field.

Fixes #5355

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

* fix(rate-limits): narrow active refresh retries

* fix(rate-limits): refresh after live Claude credential handoff

* fix(rate-limits): cover antigravity provider in active refresh plan

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

* refactor(rate-limits): compile-enforce active-refresh provider coverage

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

* fix(rate-limits): keep durable non-Claude/Codex error retries on the 5-minute full-fetch cadence

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-11 03:59:58 -07:00
Neil c51d955f0c
fix: hide completed Pi agent row after closing its terminal tab (#6584)
* fix: sweep completed Pi agent row when its terminal tab is closed

A 'done' Pi agent entry lingers in agentStatusByPaneKey after its
terminal tab is closed: its paneKey's tabId no longer matches any open
tab, so dropAgentStatusByTabPrefix never sweeps it. The sidebar selector
getLiveEntriesByWorktree used an unconditional fallback
(tabIdToWorktreeId.get(parsed.tabId) ?? entry.worktreeId), added in
#4371 to surface early child-agent rows before their tab reaches the
renderer. That fallback re-attributed the orphaned 'done' entry to the
worktree, so buildWorktreeAgentRows rendered it as a stale live 'Done'
row forever (Codex/Claude tear down cleanly because their pane/tab
keying matches the closed tab).

Restrict the worktree-attribution fallback to non-'done' entries so
completed rows whose tab is gone are dropped, while still surfacing
active child rows whose tab has not yet reached the renderer.

Supersedes #5914 (adopted and re-verified).

Fixes #5913

Co-authored-by: Alberto Cuervo <Br1NKOL@users.noreply.github.com>

* fix: drop completed Pi orphan during tab close

* fix: skip retention suppressor for completed-orphan keys during tab close

A completed-orphan key's tab is already gone, so buildRetainedAgentsSyncSnapshot
never snapshots it and no live->gone transition ever fires to consume a planted
retention suppressor. Planting one leaked a permanent retentionSuppressedPaneKeys
entry per swept orphan. Plant suppressors only for prefix-matched keys.

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

---------

Co-authored-by: Alberto Cuervo <Br1NKOL@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-11 03:46:04 -07:00
Jinwoo Hong 25ecf2eea2
fix: reconcile SSH repo rows after host re-add (#8201)
Co-authored-by: Orca <help@stably.ai>
2026-07-11 03:20:55 -07:00
Jinwoo Hong 6e3ebf534c
fix(terminal): arbitrate active desktop viewport ownership (#8252)
* fix(terminal): let remote desktop viewers own the shared PTY width

A remote (relay/shared-control) desktop viewer resizes the host source PTY to
its own width, but was never registered as a width owner. So the host's own fit
cascade (window resize, split drag, tab reveal, "+"-new-tab re-render) freely
resized the viewed PTY back to the host-local width with no signal to the
viewer. The viewer kept its narrower grid while the host streamed wider
alt-screen frames -> cell-layout garble ("porridge") until a manual resize.

The mobile "presence lock" already solves this shape for phones by suppressing
the host's pty:resize while the phone drives. This does the same for remote
desktop viewers WITHOUT joining the mobile driver state machine (a viewer needs
only resize suppression, not input lock / phone-fit / driver banners), and it
routes every PTY geometry change through the existing enqueueLayout/applyLayout
serialization path rather than resizing the PTY ad hoc.

Design:
- Registry `remoteDesktopViewers: Map<ptyId, Map<subscriptionKey, viewport>>`,
  keyed per SUBSCRIPTION so duplicate streams of one client cannot release each
  other. isPtyResizeDrivenRemotely() = mobile driver OR any viewer present;
  pty:resize (host fit cascade) bails on it. INPUT is never locked (shared
  control: host and viewers can both type), unlike mobile.
- New internal layout target { kind: 'remote-desktop' } in applyLayout: clears
  terminalFitOverrides like 'desktop', resizes only when dims changed, emits no
  fit-override notifications, and does not call onExternalPtyResize (so a
  viewer's width never pollutes desktop restore state). enqueueLayout remains
  the sole serialized writer of PTY dimensions.
- Smallest client wins: applyRemoteDesktopLayout() sizes the PTY to the SMALLEST
  attached viewer, so viewers with different screen sizes never overflow the
  narrowest grid.
- No snapshot/replay race: a viewport that arrives while the initial scrollback
  snapshot is being serialized is buffered and applied as ONE serialized resize
  before serialization, so a mid-repaint alt screen is never baked into the
  snapshot.
- Reclaim on detach: when the last viewer leaves, applyRemoteDesktopLayout
  resizes the PTY back to the host's own width via enqueueLayout({kind:'desktop'}),
  so the host reflows to full width without a manual window jiggle. The host
  width is captured at the pty:resize suppression point (the host's own resize
  attempts) — a source a remote viewport never pollutes.
- Mobile coexistence: a phone outranks a viewer; when the phone leaves, the
  mobile-release paths call applyRemoteDesktopLayout so a surviving viewer keeps
  the PTY, else the host reclaims.

Verified live (two local desktop instances): correct render on connect, no
garble on viewer-window resize (synchronous), and host reclaims full width on
disconnect. Unit tests cover the registry lifecycle, smallest-client-wins,
reclaim-via-layout, and mobile coexistence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>

* fix(terminal): address remote-desktop PTY width review findings

Resolves four CodeRabbit findings on the remote-desktop viewer width
ownership change, plus a round-trip race surfaced while fixing the leak:

- Leak: the one-shot terminal.updateViewport RPC has no disconnect hook,
  so it must never create a width floor (nothing releases it, pinning the
  host at a stale width). Add refreshRemoteDesktopViewer, which only
  refreshes floors the client already owns via its stream subscription
  (matched by clientId), mirroring the mobile updateMobileViewport
  no-op-without-subscription invariant. The one-shot handler now refreshes
  instead of registering.
- Round-trip replay: with the one-shot fallback now refresh-only, a resize
  landing during the subscribe round-trip (connected, stream not yet
  current) was dropped. The transport now replays the latest viewport over
  the stream once it becomes current.
- Reclaim: keep the host reclaim target unless the reclaim resize actually
  landed (result.ok), so a failed reclaim can retry against true host
  geometry instead of a stale remote width.
- Snapshot drain: drain pendingRemoteDesktopViewport in the
  sendRequestedSnapshot finally block; a viewer resize parked during a
  SnapshotRequest buffering window was otherwise dropped until the next
  resize.
- Key scope: scope the multiplex width-floor key by connectionId so two
  connections reusing the same client-local streamId can't overwrite or
  release each other's floor.

Tests: refresh-never-creates-floor, reclaim-target-retained-on-failed-resize,
SnapshotRequest parked-resize drain, connection-scoped key assertions, and a
round-trip replay race test (verified to fail without the flush).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(terminal): arbitrate active desktop viewport ownership

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

* test(terminal): expect viewport claim capability

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

* fix(terminal): preserve input across ownership teardown

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

* test(terminal): keep subscribe buffer coverage within lint limit

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

---------

Co-authored-by: shady <shady2k@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-11 03:02:29 -07:00
Brandon Bennett dcfa91919f
fix(automations): deliver Hermes prompts via native query (#7862)
* fix(automations): deliver prompt to Hermes TUI via process-ready signal

Hermes's prompt_toolkit TUI never emits the DECSET 2004 bracketed-paste
handshake that the default draft-paste readiness waiter gates on, so the
automation prompt was silently dropped and the agent sat idle (terminal
opens, nothing entered). Add a 'process-ready' DraftPasteReadySignal that
arms the quiet-window on first PTY output and pastes once the TUI settles,
and assign it to the hermes agent config.

Adds a Hermes unit test covering the no-handshake path.

Design for the follow-up PR/issue review loop lives in
docs/design/pr-issue-review-loop.md (not committed; gitignored).

* fix(automations): skip broken process-name fallback for process-ready

CodeRabbit: the process-ready fallback consulted waitForAgentReady, which
compares the foreground process basename via isExpectedAgentProcess. Wrapped
interpreter launches surface as 'python3 .../hermes', so the check can never
confirm readiness and only drops the paste. process-ready readiness is the
PTY-quiet window (handled by waitForAgentDraftInputReady); the process-name
fallback is dead for this signal. Skip it and return false on timeout instead.

* test(automations): assert single paste for Hermes quiet-window path

Guard against a duplicate paste in the no-handshake Hermes path by
asserting sendRuntimePtyInputVerified is called exactly once. Addresses
the CodeRabbit nitpick on PR #7862.

* fix(automations): skip broken process-name fallback on pty-bound paste path

pasteDraftToAgentPtyWhenReady (quick-create/work-item route) still ran the
python3-vs-hermes process-name fallback that can never match for
process-ready agents, burning ~1s and dropping the paste. Mirror the
process-ready guard from pasteDraftWhenAgentReady and surface onTimeout.

Adds regression tests for both the quiet-window happy path and the
fallback-skip on the pty-bound path.

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

* fix(automations): defer submit Enter until the Hermes TUI is interactive

Live-testing against Hermes v0.18.2 showed the fixed 50ms post-paste Enter
is swallowed: the node ui-tui takes 15s+ to boot, the paste fires ~1.5s in
(process-ready quiet window), and the cooked-mode line discipline turns the
early \r into \n, which the editor treats as newline-insert. The prompt
parked in the input box and the automation never executed.

For process-ready agents, defer the Enter until the TUI signals
interactivity (DECSET 2004 enable) or echoes the pasted content marker-free
(legacy prompt_toolkit), with a 120s best-effort cap. PTY input is FIFO, so
the deferred Enter always lands after the buffered paste text. The paste
echo of the content itself (raw or caret-notation markers adjacent) is
rejected so a cooked-mode echo can't release the Enter early.

Verified end-to-end in the dev app: automation prompt pasted, deferred
Enter released on tui-ready, Hermes submitted and ran the turn.

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

* fix(automations): use Hermes native startup query

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

* fix(automations): preserve quoted Hermes queries on Windows

* fix(agents): preserve invalid argument error message

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

---------

Co-authored-by: Brandon Bennett <brandonbennett@macbookair.myfiosgateway.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-11 02:35:01 -07:00
Rod Boev f4a9d33ce0
fix(files): keep SSH deletes on the remote path (#8218)
* fix(files): keep SSH deletes on the remote path (#8135)

* fix(files): preserve explorer operation ownership

* fix(files): preserve runtime owner caller scope

* test(terminal): de-flake stale daemon launch identity ladder assertion

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

* fix(files): fail closed on unresolved operation owner in delete flow

- Treat non-local operation owners (ssh, runtime, unresolved) as remote
  for confirm/error copy, then fail closed when the route is null so an
  unresolved owner never falls through to local filesystem authorization
- Fix test setup to preserve existing window properties when stubbing
  global window, preventing unrelated globals from being clobbered

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-11 02:27:55 -07:00
Neil 674ab49567 Bound simulator prelaunch handoff cache 2026-07-11 02:23:44 -07:00
Neil fb2f25e8f6
Update mobile 0.0.27 Android download links (#8257) 2026-07-11 02:21:28 -07:00
Neil cb6a5e4cb8
perf(renderer): dedupe concurrent Markdown document scans (#8115)
* perf(renderer): dedupe concurrent Markdown document scans

* fix(renderer): preserve Markdown refresh freshness

* fix(renderer): bound shared Markdown scan joins

* fix(renderer): evict abandoned Markdown scan entries

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-11 02:20:08 -07:00
Neil fd6805a299
Fix mobile terminal query reply authority (#8227)
* Fix mobile terminal query reply authority

* fix(terminal): harden mobile query reply handoffs

* fix(terminal): exclude passive mobile query responders

* fix(terminal): gate mobile query replies on host capability

Older hosts strip terminal.send's inputKind (zod drops unknown keys), so a
forwarded xterm reply would land as ordinary floor-taking shell input. Hosts
now advertise terminal.query-reply-input.v1 via status.get and mobile drops
replies unless the host advertises it (pre-fix behavior). Also documents the
bounded desktop-to-mobile handoff double-reply residual.

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

* fix(terminal): advance snapshot seq across recovery snapshots

The pending-overflow recovery loop trims buffered output against
recovery.seq while query replay and boundary strips kept using the
initial snapshot seq. Unreachable under today's control flow (no await
separates the initial-overflow consume from the loop), but the stale
seq would silently drop covered query replies if that ordering ever
changes. Track the seq that actually covered the buffered chunks.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-11 02:13:15 -07:00
Neil 7708f8e7fe
perf: avoid blocking base-ref resolution (#8182)
* perf: avoid blocking base-ref resolution

* fix(git): bound async default-base probes

* fix(git): bound default-base probes during creation

* test(git): cover bounded Windows and WSL probes
2026-07-11 02:05:58 -07:00
OrcaWin c16ea9bae1
fix(crash-reporting): make Windows capture and submission reliable (#8242)
* fix(crash-reporting): make Windows capture and submission reliable

* fix(crash-reporting): harden recovery fallbacks

* test(crash-reporting): cover returned copy failures

* fix(crash-reporting): keep Windows recovery responsive

* fix(crash-reporting): retry transient identity lookup
2026-07-11 02:03:14 -07:00
Neil 20ebe858af
fix(mobile): bump Android versionCode to 7 for 0.0.27 (#8249)
* fix(mobile): bump Android versionCode to 7 for 0.0.27

Android 0.0.26 shipped with versionCode 6. Align Android on marketing
version 0.0.27 with a higher versionCode so side-loaded upgrades install.

* test(mobile): expect direct cmd syntax for live Windows resume

Resume commands are typed into the host terminal; when that shell is
already cmd, wrap with cmd /d /s /c is wrong. Align the mobile unit
test with shared buildAiVaultResumeShellCommand behavior.
2026-07-11 01:39:41 -07:00
Neil 6c2c7e15f6
Fix worktree warning dedupe retention (#7694) 2026-07-11 01:31:13 -07:00
Neil adcc0e9884
Fix Linear setup reminder state retention (#7690) 2026-07-11 01:30:44 -07:00
Neil acb35ee649
Fix git submodule path cache retention (#7687) 2026-07-11 01:30:19 -07:00
Neil d912482752
Fix Source Control huge repo warning dismissal leak (#7686) 2026-07-11 01:29:42 -07:00
Neil fcdcab7cd4
Release simulator launch pending guard on tab creation failure (#7682) 2026-07-11 01:28:22 -07:00
Neil 5da02b0105
Bound GitHub project picker browse cache (#7681) 2026-07-11 01:27:59 -07:00
Neil 5952ad0623
Bound custom pet blob cache (#7671) 2026-07-11 01:27:32 -07:00
Neil 2ddb976f8a
Fix local preflight context cache leak (#7669) 2026-07-11 01:26:53 -07:00
Neil a5486b1351
Fix Codex title index cache leak (#7667) 2026-07-11 01:26:26 -07:00
Andre Cristo f6f497f50c
fix(win): resume quoted cmd.exe startup commands via stdin, not /K (#7978)
* fix(win): resume quoted cmd.exe startup commands via stdin, not /K

Resuming an AI Vault session into a cmd.exe tab on Windows failed with
"'...' is not recognized as an internal or external command" and never
ran the resume. The queued command for a cmd live shell is the
self-contained `cmd /d /s /c "cd /d ""cwd"" && claude ""--resume"" ""id"""`
form, which is correct when typed into cmd's interactive parser (its ""
doubling is cmd's convention). But the local PTY provider embedded it in
the `/K` launch argument, where node-pty's C-runtime argv escaping emits
backslash-escaped quotes (\") that cmd.exe cannot parse — the command
arrived as `\"cd /d \"\"cwd\"\" && ...` and was rejected wholesale.

Unlike PowerShell's -EncodedCommand, cmd.exe has no robust argv-quoting
path, so any startup command containing a double quote now falls back to
stdin delivery, where cmd's interactive parser handles the "" doubling
correctly (verified end-to-end against a real ConPTY via node-pty).
Quote-free commands keep the `/K` fast path.

* fix(win): preserve cmd resume command contracts

* fix(win): match copied resume commands to shell

---------

Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-11 00:59:17 -07:00
Neil 9f078567e5
Update mobile 0.0.26 Android download links (#8246) 2026-07-11 00:48:01 -07:00
Neil 61f2e79f8b
Bump mobile app.json to 0.0.27 (#8245) 2026-07-11 00:45:05 -07:00
Brennan Benson 4572b0a446
perf(worktrees): remove redundant creation probes (#7161)
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
2026-07-11 00:41:28 -07:00
OrcaWin fa691a0dc8
fix(win): bound renderer launch-failed recovery (#8234) 2026-07-11 00:15:44 -07:00
Neil 76c0365110
Cancel stale mode 2031 retries across resubscribe (#8214) 2026-07-11 00:06:32 -07:00
Neil 15213c15e6
Send hidden terminal query replies without batching (#8213) 2026-07-11 00:05:54 -07:00
Neil cf04845f5b
fix(mobile): keep TypeScript 6 for Expo Metro bundling (#8243) 2026-07-11 00:04:03 -07:00