Commit Graph

3667 Commits

Author SHA1 Message Date
Mohamed Boudra
357c31d16e Clarify mobile release completion checks 2026-06-01 10:30:39 +07:00
Geoffrey Marc
a3b0af9ac0 fix(app): render inline links via UITextView span on iOS (#1257)
AssistantMarkdownLink's native branch wrapped its children in a plain RN
<Text>. On iOS that <Text> sits inside the paragraph's native UITextView
and is not hoisted into a UITextViewChild, so link text (markdown links,
bare URLs, and inline-code path links) was silently dropped — the same
root cause as the bold/italic/strikethrough fix in this PR.

Route the native link through MarkdownTextSpan so it composes as a
UITextViewChild and stays visible + selectable. MarkdownTextSpan now
forwards onPress/accessibilityRole across platforms: tappable on
Android/web; on iOS react-native-uitextview nulls onPress on the root
native view, so reliable tap-to-open is still tracked by #21 — but
visible, selectable, copyable link text strictly beats an invisible one.

Refs #1253

Co-authored-by: Geoffrey <geoffrey.marc@consulting-for.edenred.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 11:29:59 +08:00
Daniel Salmerón Amselem
632c48fde3 Add timezone-aware cron schedules (#1232)
* feat: add timezone-aware cron schedules

* chore: normalize schedule timezone property

* fix: reject blank schedule timezone in mcp

* Stabilize terminal resize browser repro

* Fix terminal resize repro row assertions

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-06-01 00:32:45 +08:00
Mohamed Boudra
922a93af2f Serialize browser app tests 2026-05-31 22:42:25 +07:00
Mohamed Boudra
2227540fad Show context usage beside compact mode selector 2026-05-31 22:38:46 +07:00
Mohamed Boudra
360110accc Stabilize terminal resize browser repro 2026-05-31 22:27:07 +07:00
Mohamed Boudra
6260224514 Update changelog for 0.1.88 2026-05-31 22:05:25 +07:00
Mohamed Boudra
1821f2853a Fix release prep checks 2026-05-31 22:05:18 +07:00
paseo-ai[bot]
c60bc9f5ae fix: update lockfile signatures and Nix hash [skip ci] 2026-05-31 14:45:49 +00:00
Mohamed Boudra
9f88b4e69c Refine appearance settings and syntax highlighting
Keep parsed chat and tool detail content in sync with appearance token changes. Hide font-family controls on native, use One as the default syntax theme, add Swift highlighting, and give Nord a distinct light palette.
2026-05-31 21:40:38 +07:00
Mohamed Boudra
4cc72a84e8 Fix terminal snapshots reflowing after resize
Terminal snapshots now carry soft-wrap row metadata only to clients that advertise support, so restored output can resize like live output without breaking older clients.
2026-05-31 19:40:15 +07:00
Mohamed Boudra
794cbcef63 Fix scripts menu resizing after service launch
Reanimated entering animations can leave the measured menu surface with an inline height. Release that fixed height after opening and when measured content changes so service rows can grow in place.
2026-05-31 19:40:15 +07:00
Mohamed Boudra
a1c8e1a1f9 Add appearance settings for theme, fonts, and syntax highlighting (#1236)
* Add appearance settings for theme, fonts, and syntax highlighting

New Appearance section in Settings to configure the app theme, UI and
mono font family + size, and a syntax-highlighting theme chosen
independently of light/dark. Font family fields default to empty and
show the active system stack as the placeholder; a live split-diff
preview reflects the choices as they change. The theme picker moves
here from General.

Preferences are client-only (AsyncStorage) and applied at runtime by
patching every registered Unistyles theme via
UnistylesRuntime.updateTheme, so existing StyleSheet consumers repaint
with no per-component preference reads and no useUnistyles. No
daemon/protocol change.

* Expand syntax themes and move the preview under the chooser

Replace the small fixed syntax-theme set with eight popular themes — GitHub,
Catppuccin, Dracula, Tokyo Night, One, Nord, Gruvbox, Solarized — built from a
compact per-theme role palette. The app theme and syntax theme stay separate;
the only coupling is the light/dark axis: a theme with both variants uses its
light palette on a light app and its dark palette on a dark app, while the code
frame (gutter, line numbers, background) keeps following the app theme. Default
is now GitHub (GitHub keeps its existing hand-tuned maps for an exact match).

Move the live preview directly under the syntax-theme chooser, drop the
"preview.ts" filename header, and use a clearer code snippet for it.

* Update settings e2e for the moved theme picker and Appearance section

The theme picker moved from General to the new Appearance section, so the
General-content assertion no longer finds "Theme" — point it at "Default send"
(which stays in General) and add Appearance to the e2e section map plus an
expectAppearanceContent check, and exercise the Appearance section in the
sidebar-navigation test.

* Render the appearance preview as a unified diff

Switch the live preview from side-by-side columns to a single unified diff:
unchanged context lines plus "-"/"+" rows for the change, matching how diffs
read elsewhere in the app. Same snippet, mono font, syntax colors, and live
code-font draft behavior.

* Fix code font size change shrinking all UI text

applyAppearance scaled the live (already-patched) theme ramp instead of the
authored FONT_SIZE ramp, so it was not idempotent: every appearance change
re-scaled the current sizes, compounding the whole-UI font scale. With any
non-default UI size, changing the code size — or any setting — shrank (or grew)
all app text, and it persisted into the theme. Build the ramp from the canonical
FONT_SIZE ramp each apply (code size still set absolutely), so applies are
idempotent and a code-size change never touches the UI ramp.

* Apply the interface font across the app on web

react-native-web stamps a default font onto every text element, so the interface
font only reached the few components that set a font explicitly. Inject one rule
that points all text at a CSS variable (updated live as the setting changes),
with high specificity (1,2,0) so it deterministically beats RN-web's base font
and Unistyles' generated classes — no stylesheet-order fragility. Code, diff, and
monospace surfaces carry a `data-pmono` marker (and their subtrees are excluded),
so they keep their code font.

Web-only: React Native has no global font cascade, so native still applies the UI
font only where components opt in. Inline `code` within chat prose is a known
minor gap (its render paths aren't tagged yet).

* Keep preview code in the code font

* Apply code font settings to terminals

* Fix settings host picker import after rebase

* Format terminal webview bundle
2026-05-31 16:09:01 +08:00
Mohamed Boudra
f26a81798b Make workspace tab switching faster (#1251)
* Avoid workspace shell renders when toggling sidebar

* Avoid rerendering inactive workspace screens

* Avoid rerendering unchanged sidebar rows

* Keep sidebar selection state in the list

* Speed up workspace tab switching
2026-05-31 15:46:17 +08:00
Mohamed Boudra
67133e3ebc Fix terminal resize after splitting panes (#1249) 2026-05-31 15:42:39 +08:00
Mohamed Boudra
d1f37b5d72 Route real provider tests through OpenRouter 2026-05-31 13:57:17 +07:00
Mohamed Boudra
8cf80c2486 Mark oversized generated diffs as too large
Gate tracked diff sections by content size before parsing and highlighting while preserving the existing batched git diff path.
2026-05-31 13:57:17 +07:00
Mohamed Boudra
3d96ea6354 Fix chat history paging around tool updates (#1247)
* Fix projected timeline paging

* Avoid full timeline fetches for plain pages
2026-05-31 05:38:29 +00:00
Mohamed Boudra
0e3eb9cf75 Flatten settings sidebar with a host picker (#1241)
* Flatten settings sidebar with a host picker

Settings had two implicit tiers: app-level sections as flat sidebar rows,
and per-host settings hidden behind a drill-in to one monolithic host page.
This flattens both into a single sidebar with an "App" group and a "Host"
group, where the host's settings are top-level rows scoped by a host picker.

- Split the monolithic HostPage into four section pages: Connections,
  Orchestration (was the unnamed inject-tools + system-prompt block),
  Providers, and Daemon (status, updates, restart, remove).
- Host picker reuses the canonical <Combobox> sidebar host switcher; defaults
  to the local host so a single-local-host user never thinks about "the daemon".
- Host sections become real sub-routes (/settings/hosts/[id]/[section]); the
  old /settings/hosts/[id] redirects to the connections section, so existing
  deep links (pairing, workspace, open-project) keep working.
- "Open providers" from the project screen now lands on the Providers section.

* Fix e2e host-settings navigation for the flat sidebar

The flat-settings refactor moved host settings onto separate section pages,
but three e2e helpers still expected the old monolithic host page:

- openDesktopSettings: the daemon-lifecycle card now lives on the Daemon
  section — navigate there before asserting it.
- acp catalog: "Add provider" now lives on the Providers section — open that
  section before opening the add-provider modal.
- openAddHostFlow: "Add host" is now an item inside the host picker (Combobox),
  not a standalone button — open the picker first.

Test-only; no product changes. Fixes the 8 playwright failures on this branch.
2026-05-31 12:55:08 +08:00
Mohamed Boudra
c8ca503cc3 Show agent terminals created in workspace subdirectories (#1245)
Terminals were bucketed and looked up by exact cwd, so a terminal an
agent opened in a subdirectory of the workspace never appeared in the
workspace panel and its live updates were dropped — the panel only ever
queried and subscribed the exact root.

getTerminals(root) now aggregates every bucket at or below the root, and
the session controller delivers a subdirectory change to each subscribed
root above it, keyed by that root and carrying the full aggregated list.
Keying by the root with the complete set is what keeps the client's
cache replacement from dropping the terminals that live at the root.
2026-05-31 12:29:05 +08:00
Mohamed Boudra
41cb1af036 Add handle pan-down fallback to bottom-sheet reopen e2e
The "model selector can open, close, reopen, and close again" test still flaked
on loaded CI runners even after re-tapping the backdrop: the model-selector
sheet re-renders as its model list settles, and Gorhom drops backdrop presses
during that churn, so the tap never dismisses within the retry window.

Fall back to dragging the sheet handle down, which drives Gorhom's pan-to-close
directly and is unaffected by the backdrop churn (mirrors the resilient close in
e2e/helpers/app.ts). The backdrop tap remains the primary path, and the
post-close "stays hidden" guard that protects the dismiss-then-re-present
regression is unchanged. Verified locally by forcing the fallback (backdrop tap
disabled): the handle drag closes the sheet on its own.
2026-05-31 08:38:46 +07:00
Mohamed Boudra
17aa957d3e Stabilize bottom-sheet reopen e2e by retrying the backdrop tap (#1238)
The "model selector can open, close, reopen, and close again" test fails on
loaded CI runners: a single backdrop tap that lands while the sheet is still
present-animating is dropped (Gorhom ignores backdrop presses until the sheet
settles at its snap point), so the sheet never dismisses and the backdrop stays
visible. The reopen behaviour itself is correct — the visibility tracker is
unit-tested and the spec passes locally (3x), so this is test-interaction
fragility, not a product regression.

Re-tap the backdrop until the sheet dismisses, mirroring the resilient close
loop already used in e2e/helpers/app.ts. It stays a pure backdrop dismissal (no
Escape/pan fallback) so the real close path is still exercised, and the
post-close "stays hidden" guard that protects the dismiss-then-re-present
regression is unchanged.
2026-05-30 22:59:02 +08:00
paseo-ai[bot]
2c756e9a8a fix: update lockfile signatures and Nix hash [skip ci] 2026-05-30 02:53:33 +00:00
Mohamed Boudra
bb6a4db6e0 chore(release): cut 0.1.87 v0.1.87 2026-05-30 09:49:45 +07:00
Mohamed Boudra
2a13a082b7 Changelog for 0.1.87 2026-05-30 09:48:43 +07:00
Mohamed Boudra
eea5932a21 Fix mobile bottom sheets reopening after dismiss 2026-05-30 09:43:49 +07:00
paseo-ai[bot]
e04bb942e2 fix: update lockfile signatures and Nix hash [skip ci] 2026-05-29 16:05:39 +00:00
Mohamed Boudra
3c3574d670 Fix intermittent Android crash by upgrading Reanimated to 4.3.1
Reanimated 4.1.x crashes on Android with a NullPointerException in
ViewGroup.dispatchDraw (ReactViewGroup.dispatchDraw) — a child view is
null mid-draw because Reanimated commits a ShadowTree change during the
Android draw pass, mutating the view hierarchy while it's being painted.
Fixed upstream in 4.3.0 (software-mansion/react-native-reanimated#9072).

4.3.x requires react-native-worklets 0.8.x, so worklets moves 0.5.1 ->
0.8.3 in lockstep. react-native is pinned to exact 0.81.5 so the
re-resolve can't pull 0.81.6 (which needs react ^19.1.4, conflicting with
the react 19.1.0 override), and reanimated/worklets are added to root
overrides to force a single version across the tree — two copies of the
worklets runtime throw a version-mismatch at startup.
2026-05-29 23:01:07 +07:00
Mohamed Boudra
44863ec1dd Forward subagent permission requests 2026-05-29 22:02:18 +07:00
Mohamed Boudra
47414abc5e website tweaks 2026-05-29 19:33:57 +07:00
paseo-ai[bot]
9860dd36ef fix: update lockfile signatures and Nix hash [skip ci] 2026-05-29 11:50:20 +00:00
Mohamed Boudra
9e0c9d0662 chore(release): cut 0.1.86 v0.1.86 2026-05-29 18:46:22 +07:00
Mohamed Boudra
654ebadaf5 Add 0.1.86 changelog entry 2026-05-29 18:27:57 +07:00
Mohamed Boudra
c2b4f3aa18 Add projectIconToDataUri to the projects-screen test mock 2026-05-29 18:27:48 +07:00
Mohamed Boudra
64e3a7152d Publish Electron migration post 2026-05-29 18:27:35 +07:00
Mohamed Boudra
daae71d1a8 Add Grok to the website and supported-providers docs
Adds the /grok SEO landing page (and its auto-generated route/sitemap
entries), the /agents directory card, and the Grok line in the ACP
catalog docs, following the Grok Build provider added to the in-app
catalog.
2026-05-29 18:10:51 +07:00
Mohamed Boudra
c1453b25a7 Add Claude fast mode toggle 2026-05-29 18:01:56 +07:00
Mohamed Boudra
c47f3190d8 Add Grok Build to the ACP provider catalog
Verified the ACP entrypoint against a real install (grok 0.2.11): the
command is `grok agent stdio`, and an initialize handshake returns a
valid ACP response (protocolVersion 1, model grok-build). Running
prompts requires a SuperGrok or X Premium+ login.
2026-05-29 17:59:03 +07:00
Mohamed Boudra
0803d5ff41 Show model selector provider errors 2026-05-29 17:16:35 +07:00
Mohamed Boudra
7ed0ce97df Fix local speech worker audio transport
Worker IPC now carries plain byte payloads instead of Node Buffer objects, so provider code receives process-local Buffers instead of transport-shaped views.
2026-05-29 17:09:01 +07:00
Mohamed Boudra
fcd93a23ac Add metadata generation page to public docs 2026-05-29 15:57:58 +07:00
Mohamed Boudra
ef3b8a42fd Merge branch 'main' of github.com:getpaseo/paseo 2026-05-29 14:16:19 +07:00
Mohamed Boudra
8b1bb90ce3 Show colored icons for projects without an icon
The letter-on-grey placeholder is replaced by a fill whose color is a
deterministic hash of the project key, so each project keeps a stable
color across the sidebar, projects list, and settings header. Mid-
saturation tones keep the white letter legible in both themes.
2026-05-29 14:06:47 +07:00
Mohamed Boudra
524aef5d75 Add Parakeet v3 local STT model for multilingual dictation
v2 is English-only; v3 covers 25 European languages with automatic
language detection. The archive shares v2's filenames, architecture,
sample rate, and feature dim, so no runtime loader changes are needed.

Document that the `language` config field and PASEO_*_LANGUAGE vars
only steer the OpenAI STT provider — the local Parakeet models ignore
them, so multilingual local dictation means selecting the v3 model.
2026-05-29 14:06:18 +07:00
Mohamed Boudra
69d36c76fe Show connected host daemon versions on the About page (#1220)
* Show connected host daemon versions on the About page

* Update About E2E assertion for the App version label
2026-05-29 14:51:53 +08:00
Mohamed Boudra
38f0560f9b Syntax-highlight Edit, Write, and Read tool calls (#1218)
Highlighting reuses the existing code-block tokenizer and LRU cache, runs
lazily on expand, and falls back to plain text above a size cap so a large
Read can't stall the main thread. The diff highlighter reconstructs the old
and new file text by position rather than from @@ line ranges, so diffs that
arrive without real hunk headers still highlight.

Read content is normalized server-side: the cat -n line-number gutter some
providers emit is stripped so content is uniformly raw source, with the first
line number surfaced as offset for the client to rebuild the gutter.
2026-05-29 14:51:14 +08:00
Matt Cowger
25d6fc8515 Prefer configured provider fallbacks for metadata generation (#1219)
* Prefer configured provider fallbacks for metadata generation

* Update client config test for metadata defaults
2026-05-29 06:38:22 +00:00
Mohamed Boudra
d1eb976653 Fix duplicate /clear in the slash command menu
A client command and a provider command can share a name (e.g. clear).
Both produced the same option id, which became a duplicate React key —
React then left stale rows and scrambled ordering, so /clear showed
twice and ranking broke as the query narrowed. Drop the colliding
provider command and keep the client one, which has extra affordances.
2026-05-29 13:23:29 +07:00
Mohamed Boudra
14d176a4e2 Add manual refresh button to git diff controls (#1216)
* feat(git): add manual refresh button to diff controls

Adds a checkout_refresh RPC that forces a hard re-read of the git and
GitHub snapshot plus the diff, bypassing polling. The diff controls now
show a refresh button (feature-gated) that triggers it and surfaces
errors via a toast — an escape hatch when the polled state goes stale.

* refactor(git): address review — dotted RPC name + withUnistyles

- Rename checkout_refresh RPC to the dotted convention
  (checkout.refresh.request/response) per docs/rpc-namespacing.md.
- Replace the banned useUnistyles() call in DiffRefreshButton with
  withUnistyles wrappers for the icon/spinner color, per docs/unistyles.md.

* refactor(git): move refresh into the checkout actions store

Per the feature audit: the manual refresh was the one checkout action
whose UI logic lived inline in the component instead of alongside its
siblings (commit/pull/push) in useCheckoutGitActionsStore. Move it into
the store so there's one home for "UI triggers a checkout RPC" — it now
reuses runCheckoutAction's pending/success status and query invalidation.
The component just reads status and shows an error toast.

* fix(git): size refresh loader to the icon to stop layout shift

ActivityIndicator size="small" renders ~20px regardless of platform,
wider than the 14px refresh icon, so swapping to it grew the button and
shifted the controls row. Use SyncedLoader at the same iconSize — it
renders into a size×size box, so both states share one footprint.

* fix(git): match file-explorer refresh control (RotateCw + LoadingSpinner)

Mirror the file-explorer pane's refresh button exactly: RotateCw icon,
LoadingSpinner while refreshing, both centered in a fixed icon-sized box
so the spinner can't grow the control or shift the row. Replaces the
ad-hoc RefreshCw + SyncedLoader pairing.
2026-05-29 14:23:16 +08:00
Mohamed Boudra
04fb0f9b82 Keep local voice memory out of the daemon (#1217)
* Move local speech work out of daemon

Run local speech models in a lazily spawned worker so native model memory and blocking synthesis/transcription work stay out of the daemon process. The worker exits after idle time so local speech RSS can be reclaimed.

* Update supervisor stop test for process title
2026-05-29 13:27:28 +08:00