* fix(pairing): keep terminal QR codes scannable
Prompt framing could wrap dense QR codes and alter long pairing links. Print pairing instructions directly, add the standard quiet zone, and suppress codes that cannot fit without auto-wrapping.
* fix(pairing): contain terminal QR background
Route live OMP custom messages through the existing system-notice mapper so background notices render as task notifications while advisor, hidden, and ordinary custom-message behavior stays intact.
Workspace update fanout was constructing one-off reconciliation services, so bursts could launch overlapping all-workspace scans. Keep reconciliation in the daemon service and preserve runtime cleanup for missing workspaces.
* feat(server): expose daemon Git pressure metrics
Separate limiter queue wait from Git execution time and report subscription ownership so accumulating work is visible in the existing runtime log.
* fix(server): collect subscriptions in agent metrics
Reuse the existing agent snapshot during runtime flushes so WebSocket shutdown does not require an additional AgentManager method call.
* test(server): retry transient hub cleanup
* fix(acp): prevent duplicate image prompts
Some ACP agents echo submitted prompts without preserving client message IDs. Attribute live user chunks to the active submitted turn, while coalescing provider-owned chunks outside it.
* fix(acp): flush user messages on failed turns
* fix(acp): flush user messages on session close
* fix(workspaces): stop archived workspace subscriptions
Workspace mutations were persisted globally but projected only through the initiating session, leaving other sessions' Git observers alive after archive. Publish mutations from the shared registry so every session releases its local observer and receives exactly one update.
* fix(workspaces): serialize workspace mutation observers
* fix(workspaces): finish mutation cleanup
Queued workspace mutations now stop at the session cleanup boundary and remove any observer created across an asynchronous cleanup race. Project removal can still enrich an earlier removal delta for legacy clients.
* fix(workspaces): honor global mutation boundaries
Serialize project and workspace lifecycle notifications per session, keep filtered subscriptions from owning unrelated Git observers, and broadcast final project removals to every session that saw the project. Update strict Session harnesses for the registry subscriptions.
* fix(workspaces): preserve initial agent status
Carry initial-agent intent through global workspace mutations and publish the optimistic running status until the agent contribution takes over. This removes the invalid transient Done state exposed by global subscriptions.
* feat(commits): distinguish workspace history from base commits
Keep every workspace commit visible while bounding base history to ten
context commits, and make push and base state readable in the commit rail.
* fix(commits): preserve history when base refs disappear
Fall back to recent HEAD history for stale saved bases, and reject truncated
git output instead of presenting an incomplete commit list.
* fix(commits): classify history against the current base
Use the furthest-ahead local or remote base for classification, and re-infer
base history when saved worktree metadata points to a deleted branch.
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
* 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
* 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
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.
* fix(workspaces): start pasted pull requests from their branch
Recognized pull request links now select their branch directly instead of
waiting for a separate confirmation. Ensure single-branch clones also record
the fetched branch so the new worktree can track it.
* fix(workspaces): keep pasted PR checkout target-safe
* fix(workspaces): make pasted PR resolution deterministic
* fix(workspaces): preserve explicit checkout selection
A recognized pull request selects itself only when its attachment is added. Once the user chooses a branch, later composer edits must not derive checkout state from existing attachments.
* fix(composer): ignore stale pull request lookups
A lookup may finish after the workspace target changes. Only apply its attachment and selection event when the host, working directory, client, and remote still match the target that started it.
* fix(workspaces): make checkout choices authoritative
Arm automatic pull request selection only when a new PR link is detected. An explicit picker choice cancels that pending selection, existing draft attachments never infer checkout state, and target changes suppress carried-over lookups.
* fix(workspaces): stabilize pull request auto-selection
Keep the first PR selected when one edit contains several links, and accept a completed lookup when only the transport client changed for the same host and checkout.
* fix(composer): release removed pull request lookups
Release each auto-attach invocation when its composer state is abandoned, while continuing to discard any stale response.
Expected rev-parse failures were logged like unexpected discovery errors after Git detection became fail-open. Keep ordinary non-Git results silent while retaining diagnostics for genuine process failures.
Keep service route choices independent of daemon transport and persist the selected route per host. Use the shared web overlay stack so menus, tooltips, and toasts layer predictably.
Track proxy route changes from the Git branch rather than the workspace title to avoid transient service health changes.
* fix: emit project.update on rename so empty projects update
The rename handler only re-emitted workspace descriptors, which left
empty projects (no workspaces yet) showing the stale name on the client.
* test(projects): cover renaming empty projects
---------
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
* feat(pi): add 'max' thinking level support
Pi recently introduced a new 'max' thinking level beyond 'xhigh'.
This adds it to the type union, the UI options array, and the
runtime type guard so Paseo users can select it.
Changes:
- rpc-types.ts: add 'max' to PiThinkingLevel union
- agent.ts: add max entry to PI_THINKING_OPTIONS
- agent.ts: add 'max' to isPiThinkingLevel guard
* fix(pi): clarify xhigh description after adding max level
xhigh's 'Maximum reasoning' is now misleading since max is the true
maximum. Changed to 'Very deep reasoning' per review feedback.
* feat(providers): allow turning thinking off
Expose Off only for models that support disabled thinking while preserving Low as the default.
* fix(providers): reset unsupported thinking on model change
Keep the selected thinking option only when the new model advertises it; otherwise use that model's default and persist the runtime change.
* fix(providers): isolate custom model capabilities
Use strict manifest identity when reconciling thinking options so provider-prefixed custom models cannot inherit capabilities they do not advertise.
* fix(providers): clear thinking with default model
* fix(providers): validate disabled thinking support
* fix(providers): validate initial thinking config
* refactor(providers): centralize thinking capability
* fix(server): order config mutation events
* feat(files): edit workspace files on web
Keep source buffers synchronized with host file changes and require an explicit overwrite or reload when revisions diverge.
* feat(panels): surface and protect modified tabs
Expose tooltip and modification state through the generic panel boundary so tabs can show stable metadata and guard every close route consistently.
* fix(tests): use portable fake timeout handle
* fix(files): harden editor conflict handling
Preserve modified panel state across tab eviction, use precise revisions for optimistic writes, coalesce concurrent file watchers, and localize the editor interface.
* fix(files): close editor concurrency gaps
Coalesce clean reloads, preserve subscriber identities and file permissions, suspend pending saves during close confirmation, and carry precise revisions through file reads.
* test(files): expect read revision metadata
* starr
* fix(server): honor service port allocator contracts
* fix(server): pass workspace context to port scripts
* fix(server): cancel released service port plans
* test(server): support Windows port allocator fixtures
* docs(worktrees): clarify shell-less portScript execution
* fix(opencode): surface autonomous parent turns
OpenCode extensions can prompt an idle session without Paseo owning an active turn. Adopt exact-session activity while keeping child permissions unbound.
* refactor(opencode): centralize session ownership guard
Keep autonomous turn ownership in the shared exact-session check so all qualifying events use one source of truth.
* fix(opencode): serialize autonomous handoff
Abort and await provider-side autonomous work before starting a direct Paseo prompt so late output cannot leak into the new turn.
* fix(opencode): reject stale interrupted activity
Keep late output from an interrupted Paseo turn out of autonomous admission until a real user message establishes the next run.
* fix(opencode): fence interrupted turn events
Use provider abort settlement and terminal events as the interrupted-turn boundary so delayed canceled user messages cannot resurrect old work.
* fix(opencode): recover from failed aborts
* fix(opencode): preserve timed-out abort fence
* refactor(opencode): model provider turn lifecycle
* fix(opencode): recover stop fence after stream loss
Canonical provider message IDs and optimistic client IDs occupy different namespaces. Preserve both identities for deterministic reconciliation while retaining a dated content fallback for older daemon timelines.
Cached focused state was leaking into the sidebar before authoritative workspace hydration, while catch-up limits counted raw events instead of projected entries. Keep the focused cache fast, gate directory presentation on hydration, and preserve canonical cursors while paging projected history.
* fix: resume collected agents before pane actions
* fix(server): keep archived agents closed during pane actions
An archive could win while a collected agent was resuming, then lose when the provider runtime registered. Recheck persisted archive state after registration and close the resumed runtime before any mutation runs.
* fix(server): fence archived agents after shared resume
Protected pane actions could join a resume started by an ordinary loader and skip the archive fence. Recheck persisted lifecycle state for every protected caller so archive always wins before mutation.
* fix(server): release resources held by idle agents
Keep unarchived agents resumable while closing their provider runtimes after two minutes. Active agent schedules keep runtimes resident.
* fix(server): preserve resumable agent state
* fix(server): resume agents when listing commands
* fix(server): preserve collected agent interactions
Pi compact is a blocking LLM summarization job that often exceeds the
default 30s control-plane timeout on long sessions, causing a false UI
error while the real compact continues. Wait for the RPC response,
process exit, or session close instead.
Also cover the no-timeout lifecycle: null timeout still rejects on
close, and compact waits past 30s for a late success response.
Closes#1946
* fix(projects): allow non-git folders across mounts
Treat failed Git worktree discovery as non-Git so ordinary directories remain addable. Preserve the underlying diagnostic as a structured warning instead of failing project creation.
* fix(projects): preserve discovery warnings
Propagate checkout context through the remaining worktree discovery calls so fail-open classification retains its structured warning.