Quitting the desktop app now shuts down the daemon it started, so
"restart the app" is a complete reset users can act on without first
learning what a daemon is. The old default kept it alive; the toggle
under Settings > Host still opts back in.
Existing installs already persisted `keepRunningAfterQuit: true` from
the old default, so a new default alone would only reach fresh installs.
A one-time migration resets it, and an explicit toggle afterwards
persists the migration flag and is never overridden again.
Only a desktop-managed daemon is stopped — one started with
`paseo daemon start` is left alone.
* fix(claude): select the correct Opus 5 context window
Bare Opus 5 IDs resolve to 200K behind third-party gateways. Expose explicit context variants and require a Claude Code version that recognizes the model.
* fix(claude): add Fable and Sonnet context variants
* test(cli): expect Claude context variants
* test(cli): compose Claude catalog expectations
* fix(claude): preserve catalog on version probe failure
* fix(claude): preserve parsed context variants
* chore(release): cut 0.2.2
* 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
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.
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(desktop): keep browser tabs connected across workspaces
Electron can replace a guest WebContents when a retained browser tab is reparented. Re-register each attachment and keep background actionability checks running so agent browser tools retain the tab through workspace eviction.\n\nCover the full app, daemon, Electron, and MCP path in the existing desktop CI job.
* fix(desktop): launch Electron E2E reliably on Linux
CI Electron must receive --no-sandbox before the app starts because the hosted runner cannot use Electron's bundled SUID sandbox helper. Forward explicit dev-runner arguments and fail readiness waits as soon as a child exits.
* fix(desktop): preserve active browser on repeated registration
* fix(desktop): keep browser keyboard attachment idempotent
* fix(desktop): wait for E2E bridge readiness
* fix(desktop): close E2E logs after output drains
* Reapply "Always revalidate desktop updates before install"
This reverts commit 623c05aa4d.
* fix(desktop): make update revalidation safe on quit
Updater-triggered quits now bypass normal quit handling, and manifest revalidation gives up after five seconds without allowing a late install.
* fix(desktop): preserve fail-closed update installs
Keep cached updates deferred when quit-time validation is offline, and report validation timeouts separately from superseded releases.
* fix(desktop): preserve updater quit behavior
Automatic installs remain silent without relaunching, updater handoff is bounded, and background preparation failures remain visible without pinning manifest checks.
* fix(desktop): keep AppImage updates manual
Preserve the AppImage safety exemption by skipping ordinary quit-time installation while retaining the explicit Update now path.
* fix(desktop): serialize update preparation
* fix(desktop): recognize macOS updater quit handoff
* fix(desktop): keep browser input out of the composer
Unhandled webview keys could be redispatched into the active host window, allowing agent Enter to submit a draft prompt. Give pages first refusal for ordinary shortcuts and contain automation at the guest boundary.
* fix(desktop): tighten browser shortcut validation
* fix(desktop): respect browser shortcut ownership
* fix(desktop): retain browser keys across windows
* fix(desktop): scope browser webviews by host
* Reshape browser shortcut ownership
Use the browser webview registry as the single guest identity authority, scope browser operations to their host window, publish chord continuations only while pending, and restore focus to the originating browser after command center dismissal.
* Fix host-scoped browser shortcut follow-ups
* Fix browser keyboard review follow-ups
* Fix browser keyboard lifecycle regressions
* Fix browser shortcut review regressions
* Fix desktop browser review regressions
* Fix browser shortcut frame regressions
* Fix rebase integration regressions
* Preserve browser-native shortcut ownership
* Isolate browser shortcuts and automation by context
* fix(workspace): keep focus mode scoped and easy to exit
Route focus mode through the active workspace so persisted state cannot hide chrome on settings or other screens. Add a visible exit control and keep desktop window chrome aligned and visually quiet.
* fix(app): clarify muted chrome semantics
* fix(desktop): keep sign-in popups connected
Turning every window-open request into a workspace tab severed the opener relationship required by popup authentication flows. Keep script-created and POST-backed opens as secured child windows while ordinary links continue to use workspace tabs.
* fix(desktop): keep Shift-click links in workspace tabs
Electron reports both popup windows and Shift-clicked links as new-window. Use popup features or a named target to preserve script popups without bypassing Paseo tab state for ordinary links.
* fix(desktop): tighten popup profile handling
* fix(desktop): preserve popup feature intent
* fix(desktop): match browser popup heuristics
* feat(desktop): open files in more installed editors
Detect bundled app commands as well as PATH launchers and preserve file positions through editor-specific launches.
* fix(desktop): preserve editor target compatibility
Keep existing file-manager preference ids, retain project context for file launches, and recognize Windows 64-bit IDE commands.
* test(desktop): exercise packaged app startup
The previous smoke exited before IPC, window creation, and preload execution, so a broken packaged preload could still pass. Launch the normal app and observe its renderer bridge and managed daemon through CDP instead.
* test(desktop): preserve Linux sandbox in smoke
Configure the unpacked artifact's chrome-sandbox helper with the permissions Electron requires, while keeping sandboxing enabled so preload failures remain observable. Bound startup probes and include process logs in daemon timeout failures.
* ci(desktop): keep packaged smoke on releases
Remove the temporary pull-request artifact build after it validated the Linux launch path. Keep the real packaged smoke in the native desktop release matrix.
* ci(desktop): gate packaged smoke by changes
Run the Linux real-artifact smoke in pull-request CI when packages/desktop changes, while leaving the regular desktop unit-test matrix unconditional.
* fix(desktop): stop sandboxed preload from requiring a local module
The preload imported PASEO_BROWSER_PROFILE_PARTITION from the local module
./features/browser-profile.js. The preload runs in Electron's sandbox and is
tsc-compiled (not bundled), so that import emits require("./features/
browser-profile.js") at the top of preload.js. A sandboxed preload cannot
require a local module, so the require throws before
contextBridge.exposeInMainWorld runs. window.paseoDesktop is then undefined,
the app no longer detects itself as the desktop host, and it never starts the
built-in daemon (users had to run `paseo start` by hand).
The import was added in 0.1.108; 0.1.107 is clean, which matches the reports
that downgrading fixes it. See #2103.
Inline the one value the preload needs (the partition string) so it no longer
loads any local module, and keep browser-profile.ts as the source of truth for
the main process. Add preload-sandbox.test.ts, which parses preload.ts with the
TypeScript compiler API and asserts the only runtime module load is "electron"
(covering value imports, side-effect imports, re-exports, require, dynamic
import, and import-equals; type-only imports are ignored), plus a drift check
that the inlined literal matches the canonical constant.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test(desktop): clearer preload drift-check failure message
Assert the inlined PASEO_BROWSER_PROFILE_PARTITION is present before comparing its value, so a missing/renamed constant reports "not found" instead of a misleading value-drift mismatch (Greptile feedback on #2111).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(desktop): share persistent browser data across tabs
Keep browser sign-ins and site storage across tabs and app restarts, with a Settings action to clear the shared profile.
* fix(settings): prevent duplicate browser data clears
* fix(desktop): complete browser data cleanup
Clear legacy per-tab profiles after upgrades and localize the browser data settings in every supported language.
* fix(desktop): close browser profile cleanup races
* fix(app): preserve desktop layout in half-screen windows
Treat native window controls as physical corner obstructions instead of deriving clearance from compact layout state. Keep 751px windows in desktop mode while preserving usable content when persisted sidebars are wide.
* fix(app): retain sidebar width across window resizes
* fix(app): yield app sidebar to narrow settings
* test(app): wait for mobile sidebar motion to settle
* fix(app): yield navigation to narrow workspace explorer
* fix(app): mark sidebar sizing helpers as worklets
* fix(app): hide app navigation when space is constrained
* Fix shortcut capture ignoring - = ; ' keys
KEY_MAP was missing Minus/Equal/Semicolon/Quote, so
keyboardEventToComboString returned null for those physical keys and
the capture UI silently dropped them. Add the four entries with their
shifted variants.
Also suppress the Electron View > Zoom accelerators (Cmd+-/=/0) while
capturing, so those combos reach the renderer instead of zooming the
window. Driven by the existing capturingShortcut flag via a new
paseo:menu:set-capturing-shortcut IPC.
* fix: address review feedback from PR #2047
Trim the capturing useEffect so it only fires when capture is active
(removes the redundant on-mount false and the double-fire on true->false),
and reset the main-process capturingShortcut flag on renderer reload via
browser-window-created + did-finish-load so a Cmd+R mid-capture can't
leave the zoom accelerators disabled.
---------
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
* fix(diagnostics): include desktop app logs
Settings diagnostics now collect the Electron main-process log separately from daemon.log so desktop startup and environment-probe failures are included in app reports.
* refactor(desktop): share log tail reader
* fix(diagnostics): surface desktop app log read errors
* refactor(diagnostics): tighten desktop report API
* fix(desktop): retry login shell env resolution
Finder-launched desktop sessions can inherit launchd's minimal PATH if the login shell probe times out or never prints its marker. Retry once with a non-interactive login shell so profile PATH still has a chance to apply.
* fix(desktop): cap login shell probe retry budget
* fix(desktop): repair csh login env retry
* test(desktop): pin login shell env retry platform
* refactor(desktop): use object params in shell env helpers
Delete the renderer capture prep handshake and keep screenshots on the serialized invalidate/retry path. The capture harness now defaults to the production P1 attach-off parking check.