Commit Graph
3030 Commits
Author SHA1 Message Date
Mohamed Boudra ad4d910aef fix(markdown): retry transient image decode failures 2026-10-15 16:55:15 +02:00
Mohamed Boudra b88b018d5f fix(markdown): preserve literal image fallback labels 2026-10-15 16:54:07 +02:00
Mohamed Boudra f90e160ac6 fix(markdown): normalize HTML following code elements 2026-10-15 16:53:16 +02:00
Mohamed Boudra 65f16f6322 fix(markdown): preserve spacing between HTML elements 2026-10-15 16:52:02 +02:00
Mohamed Boudra e7589cbc86 fix(markdown): classify web links explicitly and complete renderer types 2026-10-15 16:42:14 +02:00
Mohamed Boudra e014113792 fix(markdown): preserve complete assistant messages on native 2026-10-15 16:40:41 +02:00
Mohamed Boudra f829ce6ef3 fix(markdown): keep the first image reference definition 2026-10-15 16:25:58 +02:00
Mohamed Boudra e851a71ded fix(markdown): normalize only parsed HTML nodes 2026-10-15 16:24:52 +02:00
Mohamed Boudra 9e275bf361 fix(markdown): size inline images to the line and collapse failed loads 2026-10-15 16:22:37 +02:00
Mohamed Boudra 58f2fed621 fix(markdown): keep the renderer tree stable while images resolve 2026-10-15 16:17:52 +02:00
Mohamed Boudra fca12a89d6 fix(markdown): normalize inline HTML before rendering 2026-10-15 16:08:55 +02:00
Mohamed Boudra 648f290687 fix(markdown): restore file link hover tooltips on web 2026-10-15 16:05:50 +02:00
Mohamed Boudra 8057a65f41 fix(markdown): restore selection highlight on web 2026-10-15 16:00:26 +02:00
Mohamed Boudra 134b796859 fix(markdown): derive table and task list colours from the theme 2026-10-15 15:57:03 +02:00
Mohamed Boudra f5fb20cc55 fix(markdown): preserve encoded image paths after rebase
Keep the shared renderer image normalization and file-read regression coverage that originally lived in the main integration merge.
2026-10-15 15:33:33 +02:00
Mohamed Boudra 307f0dee0d test(markdown): exercise find across whole-message history 2026-10-15 15:32:20 +02:00
Mohamed Boudra d2169a061c fix(markdown): preserve authored empty link titles 2026-10-15 15:32:20 +02:00
Mohamed Boudra ee4a5bca7a fix(markdown): avoid empty web history measurements 2026-10-15 15:32:19 +02:00
Mohamed Boudra b782963970 fix(markdown): retain diagram identity and reference scope 2026-10-15 15:32:19 +02:00
Mohamed Boudra 3d06f652b2 fix(markdown): restore diagrams and preserve link origin 2026-10-15 15:32:19 +02:00
Mohamed Boudra 554530a667 fix(markdown): preserve file links and image revisions 2026-10-15 15:32:19 +02:00
Mohamed Boudra 35302f7251 test: verify library image controls and isolate website config 2026-10-15 15:32:19 +02:00
Mohamed Boudra 096508240f feat(markdown): use enriched renderer across all platforms 2026-10-15 15:32:19 +02:00
Mohamed Boudra 3639084530 revert(app): remove shared prose-run renderer changes
Reverts ab4737bb2 and ac47e1063 before replacing the Markdown engine across all platforms.
2026-10-15 15:32:02 +02:00
Mohamed Boudra 2db3488dbd fix(app): preserve Markdown containers before grouping prose 2026-10-15 15:32:02 +02:00
Mohamed Boudra bf100e1752 fix(app): share selectable native prose across Markdown surfaces 2026-10-15 15:32:02 +02:00
Mohamed Boudra ab234d5f12 fix(app): skip prose classification for blocks over the render cap 2026-10-15 15:32:02 +02:00
Mohamed Boudra 633950bb6a fix(app): preserve bracketed IPv6 links in native prose 2026-10-15 15:32:02 +02:00
Mohamed Boudra 1fbdac728f fix(app): keep growing markdown on the streaming block renderer 2026-10-15 15:32:02 +02:00
Mohamed Boudra 9b7a6ba782 fix(app): preserve parser-owned links and streaming tilde tails 2026-10-15 15:32:02 +02:00
Mohamed Boudra aeaee471a6 fix(app): preserve home paths and normalized prose links 2026-10-15 15:32:02 +02:00
Mohamed Boudra 9bbfe29c0e fix(app): bound prose append work and preserve markdown edge cases 2026-10-15 15:32:02 +02:00
Mohamed Boudra d42e0ca00c fix(app): preserve provisional syntax at cached reveal boundaries 2026-10-15 15:32:02 +02:00
Mohamed Boudra eedf916023 fix(app): preserve native prose entities and links while bounding preparation cost 2026-10-15 15:32:02 +02:00
Mohamed Boudra 7023d20a5b fix(app): preserve markdown source and file actions in native prose
Prepare original source blocks with source-position edits from the assistant parser. Keep reference scope and live/history projection consistent, and retain link text when dispatching workspace file actions.
2026-10-15 15:32:02 +02:00
Mohamed Boudra 5bf0e4b588 fix(app): preserve inline image formatting and reference scope 2026-10-15 15:32:02 +02:00
Mohamed Boudra 9ef289e7f4 fix(app): allow additive task lists and admonitions in native prose 2026-10-15 15:32:02 +02:00
Mohamed Boudra 83061e0312 fix(app): preserve markdown semantics and render limits in prose runs 2026-10-15 15:32:02 +02:00
Mohamed Boudra 75907b360b fix(app): render selectable native prose with enriched markdown 2026-10-15 15:32:01 +02:00
Mohamed Boudra d8f79925d1 fix(app): group native assistant prose into selectable runs 2026-10-15 15:32:01 +02:00
Mohamed Boudra 74282dac12 fix(app): return to chat after fullscreen submission (#6987) 2026-10-15 14:55:19 +07:00
Mohamed BoudraandClaude e5124b039a Put sheets on one stack and show an agent's facts in its sheet (#6958)
* Put sheet tabs on the one sheet stack

Sheets are one primitive with one stack. A sheet opened from any sheet
stacks on top of it, and closing it uncovers the sheet underneath. The
compact workspace's file and subagent sheets were an in-tree Gorhom
BottomSheet with their own stacking, so a subagent chosen from the
subagents list sheet replaced the list instead of covering it.

- SheetHostScope: a subtree hosts the sheets presented inside it, so the
  sheet tabs draw inside the compact column and read the workspace
  providers while still joining the app-wide stack. Needs Gorhom's
  BottomSheetModalInternalProvider, which the patch exports.
- IsolatedBottomSheetModal takes enableDismissOnClose; false keeps the
  content mounted through a close so the unsaved-changes guard can veto
  it. Its backdrop then closes the sheet rather than dismissing the top
  modal. The Gorhom patch also keeps a dismissing modal's status through
  its final onChange(-1), without which such a modal unmounting while
  presented never left the portal.
- SheetTabs (was WorkspaceSheetHost) renders one IsolatedBottomSheetModal
  per store entry. The store never reorders sheets; a reveal of a covered
  sheet drops the unmodified sheets above it.
- Subagent rows that open a sheet keep the list open (closeOnSelect
  false); rows that open a tab still close it.
- A menu closes when its retained panel goes inactive, instead of hiding
  and reappearing with the panel on the next tab switch.

Co-Authored-By: Claude <noreply@anthropic.com>

* Show an agent's model and thinking in its sheet, and fit Open as tab in the header rail

A Paseo agent shown in a sheet has no composer, so the facts the composer's
model and thinking controls would show now sit in one line under the sheet
header, the same row provider subagents already get from the daemon. The line
resolves exactly as the controls do (resolveAgentModelSelection), from the
session agent and the providers snapshot, and shows wherever the pane host is
a sheet.

Open as tab becomes the full-screen glyph beside Close, drawn by the shared
SheetHeaderIconButton, so the title keeps its width. The tab switcher sheet is
titled "Workspace tabs" so it reads as what it lists.

Co-Authored-By: Claude <noreply@anthropic.com>

* Show mode and context usage in the sheet facts line

The line under a sheet's header now carries everything the composer's
controls and context meter show: model, thinking, mode, and used/max context
tokens with the share, each resolved as its control resolves it.

Co-Authored-By: Claude <noreply@anthropic.com>

* Re-render subagent rows when the workspace's tabs change

A row decides at render time whether choosing it opens a sheet or reveals
a tab, and keeps the list open only for a sheet. The hook behind it only
subscribed to the layout mode, so a row rendered while its agent was a
full tab kept closing the list after that tab was gone: on iOS, promoting
a managed child, closing its tab, and reopening it from the list dropped
the list under the sheet. Subscribe to the workspace's layout too.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-15 12:16:45 +07:00
Mohamed Boudra 6db47b3c37 fix(app): keep the keyboard closed after mobile sidebar dismissal (#6945)
Separate composer keyboard eligibility from pane focus restoration. A sidebar dismisses the keyboard without hiding the pane, so its close must not restore editing focus.
2026-10-15 08:59:49 +07:00
paseo-bot[bot] 73221ce5bd fix(app): render local Markdown images with encoded paths (#6877)
Decode assistant Markdown image destinations before resolving a filesystem read. Keep plain filesystem paths and direct image URIs unchanged so Markdown Preview and literal percent filenames are decoded only once.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-15 03:14:42 +02:00
Mohamed Boudra 6ad124758c Stack workspace sheets and tighten sidebar density (#6885)
* Stack workspace sheets and tighten sidebar density

- Workspace sheets stack: opening a target from a sheet covers it, Back and
  drag close only the top sheet, and the header is the sheet's drag handle.
- The workspace sheet reuses the shared sheet handle, background and header.
- Fix the shared sheet handle indicator rendering black.
- Sidebar text returns to semantic sizes; Pinned and Workspaces share one
  section header.

* Pause covered workspace sheets and mock the shared sheet handle in tests

* Export BottomSheetHandle from the browser test Gorhom stub

* Let a stacked sheet's backdrop catch taps on iOS

* Bring a revealed sheet to the top instead of duplicating it as a tab
2026-10-15 06:30:17 +07:00
Mohamed Boudra f3ddf99fe3 fix(app): restore fullscreen composer keyboard motion and clearing (#6902)
* fix(app): keep fullscreen composer in the keyboard dock

* fix(app): preserve composer caret and scope keyboard actions
2026-10-15 06:30:13 +07:00
paseo-bot[bot] e1a5664d9b fix(app): keep malformed font settings from breaking the UI (#6695)
Unfinished CSS strings in font preferences consumed the shared theme stylesheet. Reject incomplete syntax at the settings boundary, recover persisted malformed values through the existing default path, and restore rejected edits in the font field.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-14 19:17:06 +02:00
paseo-bot[bot] b58af43a06 fix(app): render mixed HTML headings without literal tags (#6650)
Keep a matched heading together before splitting its image and text contents. Splitting first stranded the opening heading tag in a text slice without its closing tag.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-14 18:14:08 +02:00
56448842f0 Download files over the connected host (#6595)
* Let readFile callers disable the request timeout

readFile resolves only when FileEnd arrives, so the default 60 s request
timeout bounds the whole transfer. A large file over a slow relay fails
before it finishes even though every chunk is arriving. Thread an optional
timeout through requestFileExplorer; 0 disables the timer, as the
workspace.create request already does, and a dead connection still rejects
on disconnect.

The relay e2e case reads a 1 MiB file through a real daemon and a local
relay with timeout 0 and compares SHA-256 digests with the source.

* Reject a binary file transfer whose byte count differs from FileBegin.size

concatByteChunks allocated FileBegin.size bytes and copied the chunks in:
a short transfer resolved as a zero-padded file, and a long one threw a
RangeError inside the transport callback and left the request pending.
Count the received bytes at FileEnd and reject the read when they differ
from the announced size.

* Download files over the session socket when no direct connection is active

The download store only knew the HTTP token route and picked the first
directTcp connection in the host profile, whatever connection the host
runtime was using. A relay-only host has none, so every download ended in
"Download host is unavailable." (#543). SSH, socket and pipe hosts failed
the same way, and a stale directTcp entry won over a working relay (#3753).

Choose the transport from the active connection: directTcp keeps the HTTP
token download unchanged; anything else reads the file over the session
socket with the binary frames previews already use, then hands the bytes
to the browser's download manager on web and Electron or writes them to
the cache directory and offers the share sheet on native. Files over
64 MiB are refused before any byte moves, using the existing fileTooLarge
string, and a daemon response without content fails instead of saving an
empty file.

* fix(app): enforce the session download size limit during the read

The token size is sampled before the file is read. Pass the download byte budget through the actual read so a changed file cannot bypass the in-memory limit.

Co-authored-by: Michael Vandesompel <mv@droggol.be>
Co-authored-by: YASICJUNWOO <joonoo3@naver.com>
Co-authored-by: JrDw0 <JrDw0@users.noreply.github.com>

* test: verify TCP downloads and own relay fixture cleanup

---------

Co-authored-by: Michael Vandesompel <mv@droggol.be>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: YASICJUNWOO <joonoo3@naver.com>
Co-authored-by: JrDw0 <JrDw0@users.noreply.github.com>
2026-10-14 17:25:31 +02:00
paseo-bot[bot]andRaisal P Wardana cafa04d3fb fix(app): traverse workspaces beyond nine (#6586)
Relative navigation shared the list capped for digit shortcuts, so it wrapped at the ninth workspace. Keep all sidebar targets and cap only numbered badges. Carry forward #4128 with keyboard-routing and browser regressions.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: Raisal P Wardana <IEatCodeDaily@users.noreply.github.com>
2026-10-14 13:14:08 +02:00