Continuous Android stream updates kept bottom-anchor verification pending, so genuine finger drags were mistaken for programmatic corrections. Preserve explicit drag ownership so user scrolling can detach immediately.
OmpRpcSlashCommandSchema had a strict source enum
['extension', 'prompt', 'skill', 'builtin'] that rejected omp
commands with source 'custom' or 'file'. When omp reported any such
command, the entire get_available_commands response failed Zod
validation and listCommands returned an empty array — so the Paseo
autocomplete only showed /exit and /clear instead of all omp commands.
Relax source to z.string().optional(), matching the already-permissive
OmpAvailableCommandSchema used for the available_commands_update event.
* fix(app): open notifications on the right host
Agent notifications previously omitted workspace ownership, so a cold target host was treated as missing and fell back to its empty home route. Carry the authoritative workspace and keep older notifications on a target-host resolver until lookup is conclusive.
* fix(app): separate notification and agent URL routing
Notifications use their authoritative workspace target directly. Stable agent URLs remain server-and-agent targets whose workspace is resolved by the agent route.
* fix(protocol): preserve notification workspace targets
Both attention message variants retain workspaceId through outbound validation so notification clicks receive the authoritative route target.
* test(app): use workspace-scoped notification target
* test(server): give notification agents workspace targets
* test(app): target notification workspace in navigation e2e
A usage bar in Settings -> Usage stayed green all the way to 100%, so
the one moment the meter matters was the moment it said nothing.
The client already computes this. `window-bar.tsx` reads
`window.tone ?? deriveTone(usedPct)`, and `deriveTone` escalates past
70% and 90%. But `usage.ts` only assigns `window.tone` when a provider
sends one, so any provider that sends a tone opts out of the thresholds
entirely. Claude and Kimi hardcoded `tone: "ok"`, and Codex escalated to
`warning` past 70% but could never reach `danger`.
Providers now derive tone from the percentage they already have, through
one shared `toneFromUsedPct` whose thresholds match the client's.
Claude, Codex and Kimi windows all escalate correctly.
Balances had the same gap by a different route: `balance-bar.tsx` has no
`deriveTone` fallback, and `balanceToneFromRemaining` only escalates
once a balance is completely spent, so a credits bar at 99% was green.
Cursor and Grok know their limit, so they now tone by used percentage.
Codex credits report only a remaining balance with no limit, so they
keep the remaining-based tone, documented as the no-limit case.
MiniMax is unchanged: it maps a status its own API supplies rather than
hardcoding a tone.
Verified against the live Anthropic API with a session window at 83%,
which now reports `warning` where it previously reported `ok`.
Closes#2320
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Accept OMP session state without thinkingLevel
Models whose reasoning effort is encoded in the model ID (e.g.
cursor-grok-4.5-high-fast) are marked reasoning: false by OMP, which
omits thinkingLevel from get_state. The required schema field made
session creation throw a ZodError. Make it optional and resolve the
thinking option to null when absent.
* Render OMP advisor messages as blocks
Open the complete working comparison in a desktop workspace tab while preserving inline sidebar diffs when the tab is closed.
Working and commit comparisons share one diff panel, and workspace layout is the sole owner of live tab persistence and identity.
Refs #1520
* feat(desktop): open existing agents from links
Register a stable agent deep link and route it through the existing Desktop window. Add a matching CLI command that resolves the local server and activates the requested agent without creating or messaging it.
* fix(desktop): recover agent link delivery
* Fix pending checkout diff subscriptions
* Reduce checkout status Git spawns
* fix(checkout): own pending diff cancellation
Checkout sessions could invalidate a subscription before its shared watch had finished opening. Register targets synchronously and let the diff manager honor cancellation so pending and concurrent subscriptions share one teardown path.
---------
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
* fix(app): restore archived agents from History
History navigation lost the explicit archived-agent intent during tab reconciliation, and workspace recovery stopped after restoring the workspace. Preserve the selected tab and recover its provider session as one action while serializing provider resume with timeline hydration.
* fix(app): preserve archived agent recovery invariants
* fix(server): preserve timeline hydration call shape
* fix(app): retain agent tabs through lookup
* fix(server): upgrade in-flight timeline broadcast
The outer batch shell expanded the hook variable and control operators before terminal send-keys received them. Encode the probe for PowerShell so expansion happens inside the packaged terminal.
Keep layout-only styles on stable React Native style IDs when they share Reanimated hosts with keyboard transforms. This prevents style regeneration from disturbing the animated native views while preserving keyboard and safe-area behavior.
Custom line-break rules dropped the resolved full-width break style, allowing adjacent native text spans to collapse onto one line. Preserve the break styles in both chat and shared Markdown renderers.
Large project, status, and pinned groups now render 20 rows until expanded. Newly discovered workspaces are prepended without disturbing the saved order.
* feat(app): show recent commit history in explorer
* fix(app): keep recent commit history accurate
* fix(app): include merged commits in recent history
* perf(app): bound recent commit classification
* fix(app): refresh recent commits on Git updates
* fix(app): open chat file links at referenced lines
Pass chat file locations through the editable CodeMirror path so opening a reference selects and scrolls to its requested line. Cover the real assistant-link flow with a browser regression.
* fix(app): repeat chat file navigation
Track file navigation separately from stable tab identity so reopening the same path and line recenters both editable and read-only panes. Extend the browser regression to cover moving away and clicking the same link again.
* test(app): stabilize repeated file link navigation
The inverted list's native position maintenance fought the sticky-bottom controller as the live message grew. Let the controller exclusively own the Android sticky-bottom anchor while preserving position maintenance when reading history.
Timeline catch-up treated the first unmatched optimistic prompt as an insertion boundary, which could move later acknowledged prompts behind assistant output. Apply canonical entries directly and preserve submission slots during replacement.
Live canonical user rows consumed the oldest optimistic prompt even when a client message ID identified a later submission. Match identified rows exactly while retaining FIFO reconciliation for legacy rows.
The desktop daemon resolved the CLI through a packaged module entrypoint that is not an executable outside the archive. Publish the existing bundled shim as the daemon's authoritative CLI path so terminal hooks use a callable command.
The web UI font rule only targeted the app root, so portaled content fell back to the default font. Extend the rule to the shared overlay root and cover it with a browser regression test.
Visibility catch-up could select the blocking overlay after optimistic continuity cleared, even though history was already hydrated. Keep hydrated content non-blocking and cover the creation handoff with a browser regression test.