* feat(protocol): define streamed diff revisions and resolve tag bases
* feat(server): stream shared diff revisions with paced file bodies
* feat(client): observe streamed diffs with atomic revision updates
* feat(app): show the Changes tree while diff bodies stream
* fix(server): retain the legacy structured diff payload budget
* fix(diff): preserve revision ordering and readable files
* fix(diff): select renamed patches and read dangling symlinks
* fix(diff): preserve nested checkouts and ambiguous patch paths
Only regular files and symlinks are readable untracked entries. Prefer patch metadata to ambiguous unquoted headers so paths containing a prefix delimiter keep their hunks.
* fix(diff): preserve BOM text and complete file replacements
Decode each string without consuming its leading BOM. File-type replacements emit multiple patch sections for one listed path, so retain all matching hunks. Assert the optional rename metadata in the existing commit-file journey.
* fix(diff): highlight symlinks from their stored target text
Working tree source context must match the symlink blob emitted by Git rather than the contents reached by following the link. Otherwise highlight runs do not cover the patch line and encoding fails the revision.
* fix(diff): tolerate disappearing highlight sources
Source context is optional after Git has produced the patch. Missing worktree link metadata must preserve the existing hunk-based highlighting fallback instead of failing the revision.
* fix(diff): batch cold reads and refresh logical comparison inputs
Acquire bounded pages of tracked patches lazily after Begin while retaining per-file highlighting and awaited frame delivery. Keep legacy preferred-base selection live across revisions and include submodule Git state in worktree cache identity.
* fix(diff): distinguish gitlink directories from replacements
A raw old gitlink mode also occurs when a submodule becomes a regular file. Query nested Git state only for a current directory, preserving normal file identity for replacements.
* fix(diff): invalidate timestamp-preserving file replacements
Size and modification time do not identify live file contents after a preserving copy. Include filesystem change time and file identity for tracked and untracked reuse, and verify live revisions agree with fresh reads.
* fix(diff): align highlight tokens with normalized patch lines
Git can normalize CRLF worktrees while highlighting reads their original line endings. Match tokens to the emitted patch text and trim only a normalization CR before encoding runs; mismatched source tokens are not attached.
* fix(diff): refresh equivalent worktree paths across platforms
Explicit refreshes must match filesystem-equivalent roots, including Windows path aliases. Use the existing realpath-aware matcher, budget real Git completion waits consistently, and assert optional status metadata in the filesystem commit-file journey.
* fix(diff): validate Git inputs and resolve refresh roots
Reuse now accounts for effective attributes, configuration, and canonical worktree blobs as well as filesystem state. Explicit refresh resolves repository identity like subscription creation, and callers await that resolution before acknowledging the command.
* fix(diff): keep non-Git workspace refresh successful
Diff invalidation has no target repository for an ordinary folder. Treat that expected absence as a no-op while preserving other root-resolution errors.
* fix(diff): observe scoped Git interpretation settings
Classify each metadata root with its worktree and common scopes, retaining both when the directories coincide. Shared attributes affect all checkouts, while config.worktree belongs to the owning checkout. Real subscriptions verify automatic binary and hunk-context refreshes in main and linked worktrees.
* fix(diff): observe interpretation inputs for pinned comparisons
Immutable commit objects still depend on mutable Git configuration and attributes. Declare those metadata inputs independently of ref, index, and worktree mutability, while keeping unrelated endpoint events out of pinned comparisons.
* fix(diff): observe interpretation independently of comparison endpoints
Commit comparisons still read worktree attributes. Watch those inputs independently, checking effective Git interpretation before invalidating fixed contents. Retain paths hidden by whitespace filtering so attribute changes can expose them. Forward binary frames through the branch-loading test interceptor.
* fix(app): hold the loading screen until first-run setup is decided
A new user saw the empty home, the sidebar and a logo jump before setup
popped in. Startup now keeps the splash while setup may still open over
the empty home, for at most 3 s and only while the setup host is
reachable. Remembered-workspace restore does not wait. Web dialogs now
fade in as they already fade out.
(cherry picked from commit a0a7620b62)
(cherry picked from commit 72d7c0bf26)
* fix(app): fade the dialog card in and land the dim at once
(cherry picked from commit 6ef05705a0)
(cherry picked from commit 71c28b431c)
* fix(app): keep the loading screen up while startup redirects
(cherry picked from commit 0b28d4cbff)
(cherry picked from commit 13cc485e6f)
* test(app): cover a setup host that drops while startup waits
(cherry picked from commit 2a906ef83e)
(cherry picked from commit 7b6e21207a)
* fix(app): type the web-only dialog enter animation style
The CSS animation props are not part of ViewStyle. CI typechecks without the
generated expo-env.d.ts, which declares them, so the cast is required there.
(cherry picked from commit b887d979d2)
* fix(app): keep the setup window mounted when the theme changes
The shell's appearance boundary remounts its dialog hosts whenever a theme
color changes, so picking a theme in setup, or a system light/dark switch,
replaced the open setup window and replayed its fade. Setup draws colors
through CSS variables and themed props, which update in place, and changes
no font size, so it now sits outside that remount.
The dialog enter fade is skipped with reduced motion, and its style is typed
for CI, which typechecks without the generated expo-env.d.ts.
(cherry picked from commit b24c6eacf8)
(cherry picked from commit cb0e9907f5)
* docs(changelog): prepare 0.15.2
(cherry picked from commit 5af1a8ff66)
* chore(release): cut 0.15.2
(cherry picked from commit e896c05b09)
Bring in what v0.15.0 shipped: the 0.15.0 entry in CHANGELOG.md and
CHANGELOG.zh-CN.md exactly as tagged (replacing the 0.15.0-beta.1 series
entry), version 0.15.0 across package.json/package-lock.json, the F-Droid
changelogs 150001-150004.txt, and the matching Nix npm deps hash.
Bring in what v0.14.0 shipped: the 0.14.0 entry in CHANGELOG.md and
CHANGELOG.zh-CN.md exactly as tagged (replacing the 0.14.0-beta.2 series
entry), the 0.14.0 version in every package.json and package-lock.json, and
the generated F-Droid changelogs. The unreleased notes on main stay above the
entry and now say they are not in 0.14.0.
Release commit: 8c6de842a3 (tag v0.14.0)
* docs(changelog): fold 0.14.0-beta.2 UI fixes into the 0.14.0 entry
(cherry picked from commit 28bb7e29be)
* chore(release): cut 0.14.0-beta.2
(cherry picked from commit 1a05491be5)
* docs(changelog): keep unreleased main changes out of the 0.14.0-beta.2 entry
The beta.2 tag was cut from a selective hotfix branch, so #8100, #8117 and #8081 are on main but not in beta.2. Every changelog parser (app, website, release-notes sync) skips the preamble, so listing them there keeps them out of the beta.2 release body and What's new until the next release entry absorbs them.
* fix(app): keep the sidebar alive when a workspace entry has not hydrated (#7896)
ProjectBlock asserted that every placement in a project has an entry in
workspaceEntriesByKey. A retained sidebar that is inactive (compact layout
with the sidebar closed) or still waiting for sessions keeps an empty map,
and Show background stops the project list from being pruned to hydrated
entries. From the eighth workspace on, selectSidebarGroupVisibility asked
for the status of a missing entry and the app crashed on start.
Count a missing entry as Done. It renders no row, so it should not claim a
slot past the limit.
Closes#7869
Co-authored-by: brucey0x <11062155+brucey0x@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 6bc4b73c42)
* docs(release): add 0.13.1 hotfix notes
* chore(release): cut 0.13.1
---------
Co-authored-by: Budi <11062155+budivoogt@users.noreply.github.com>
Co-authored-by: brucey0x <11062155+brucey0x@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(hosts): connect to saved hosts through a daemon
* fix(hosts): validate safe targets and verify encrypted relay routes
* test(hosts): include relay coverage in existing CI contracts
* fix(cli): preserve validated addresses in daemon command hints
* fix(hosts): share daemon links across isolated routed sessions
Multiplex logical sessions over the monitored daemon connection and wrap original binary bytes in routing headers. Admit channels under their authenticated parent and current grants; preserve scoped delivery and physical send completion.
* fix(hosts): bound encrypted overload and initial acquisition
Check encrypted wire capacity before the async channel converts a resource limit into a physical connection error. Bound initial routed acquisition with the existing client timeout, then enable reconnect after admission.
* fix(hosts): keep compact row actions clear of host labels
Give compact connected-host rows separate text and action widths so long names and producer labels cannot compete with primary controls.
* refactor(hosts): remove management settings UI from phase one
Keep connected-host management in the CLI and shared SDK while preserving app saved connections and plugin access.
* test(hosts): control physical write backpressure across platforms
Hold real TCP writes until assertions finish instead of assuming a paused receiver exhausts every platform receive buffer. Preserve physical send settlement, byte identity, capacity and sibling checks.
* refactor(hosts): use the ordinary client contract over channel transports
Keep queuing, permission codes and reconnection independent of transport selection. Track submitted request outcomes generically while retaining connection error codes and structured causes.
* test(e2e): keep transient developer toasts from stalling checks
Concurrent locator handlers can wait for a dismiss button another handler removed. Dismiss existing toast DOM at document lifetime, including its open shadow root, without intercepting app actions.
* Create, prompt, and monitor agents across connected hosts (#7507)
* feat(hosts): delegate agents across connected hosts
Resolve MCP host operations through in-process commands for self and the existing routed client transport for other destinations. Keep ordinary parent labels, app sessions and idle finish notifications.
* test(app): normalize subagent fixtures through snapshots
* docs(protocol): clarify same-host parent labels
* fix(hosts): resolve subagents through destination sessions
A child address identifies its destination regardless of the connection used. Reuse the existing host candidate selection for discovered routes and direct connections, and keep navigation and row actions independent of the parent transport.
* fix(hosts): keep routed destinations distinct during discovery
A routed candidate names only the origin daemon. Match it within the named destination profile so two destinations discovered through the same origin retain separate identities and connections, including existing saved routes.
* feat(hosts): prompt and query agents on selected hosts
Extend the existing MCP host operation boundary with prompt, status, activity and list operations. Local calls retain their handlers and notification owner; selected destinations use ordinary client RPCs and the existing idle finish wait.
* test(e2e): preserve toast coverage with CSS hiding
* docs(hosts): translate connected host references
The relay exports map sent the import and default conditions to src/*.ts,
which the published package does not include, so any bundler resolving
@getpaseo/client failed with 'Could not resolve "@getpaseo/relay/e2ee"'.
Every condition now resolves to dist, like @getpaseo/protocol and
@getpaseo/client. The client build now builds relay first, and the Metro
workaround for compiling relay source is removed.
Fixes#4730
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
* feat(claude): add Fable 5.1 model
Expose the new 1M-context model through the curated Claude catalog and normalize its dated and context-suffixed runtime IDs back to one canonical entry.
* fix(claude): group Fable models in catalog
* chore(release): cut 0.7.1
* fix(nix): refresh 0.7.1 dependency hash
* test(cli): follow package version in plugin scaffold
* test(cli): keep Claude catalog checks extensible