Commit Graph
4096 Commits
Author SHA1 Message Date
Mohamed Boudra ff83ca4bdc fix(workspaces): restore clean runtime test paths 2026-08-14 14:11:12 +02:00
Mohamed Boudra e2ac23da70 chore(merge): integrate main into workspace runtimes 2026-08-14 13:28:32 +02:00
Mohamed Boudra 7c32fcda98 refactor(workspaces): finalize runtime package boundaries
Keep the daemon dependent only on the public runtime contract and helper, while optional runtime implementations remain external command registrations. Workspace setup continues asynchronously through the bound runtime without coupling production packages to an implementation.
2026-08-14 12:48:35 +02:00
Mohamed BoudraandJimmy Lee 30195d3bd1 fix(app): make composer input IME-safe and paste-aware (#3343)
* fix(app): preserve native composer input semantics

Native text was round-tripped through application state on every keystroke, which could overwrite an input method's in-flight edits. Keep native text ownership inside the input and reserve application-driven replacement for explicit draft mutations.\n\nRoute native clipboard images through the existing persisted attachment pipeline so keyboard and system paste actions behave like other image sources.

* fix(nix): refresh dependency hash

The native composer dependency changes the fixed npm dependency closure used by desktop builds.

* fix(app): keep composer locked across image pastes

Count concurrent native image persistence operations so submit remains disabled until every pasted image is attached.

* fix(app): replace composer text through the DOM on web

Web TextInput refs are DOM elements, so application-driven draft replacement must update their value and selection without native setNativeProps.

* fix(app): preserve web IME composition

Carry the Chinese IME fix from #2990 into the web composer input boundary.

Co-authored-by: Jimmy Lee <jimersylee+github@gmail.com>

---------

Co-authored-by: Jimmy Lee <jimersylee+github@gmail.com>
2026-08-14 11:52:24 +02:00
770b87a15c fix(desktop): keep element selectors available on loaded pages (#3187)
* fix(desktop): keep element selectors available on loaded pages

Annotate element and Screenshot element returned early when a cached load signal said the guest was not ready, even if the current document was complete and executable. Let executeJavaScript own the readiness boundary and keep selector cleanup available in the same stale-signal state.

Extend the real Electron browser regression to reproduce the complete-document/stale-signal mismatch through both toolbar actions.

* test(desktop): await browser selector injection

Poll the guest selector state through the browser bridge instead of assuming injection completes within 250 ms. This keeps the Electron regression deterministic on slower CI hosts.

* Harden browser selector session lifecycle

* Keep selector E2E fixtures independent

* fix(desktop): harden selector and annotation lifecycle

* fix(desktop): keep selector PR focused

* refactor(desktop): own element selector lifecycle

---------

Co-authored-by: Daniel G. Kang <180234654+dgk-dev@users.noreply.github.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-08-14 15:51:42 +08:00
Mohamed Boudra b03dc804eb feat(app): make pinned workspaces sortable (#3341)
Reuse the existing workspace drag interaction for pinned rows and persist their local order across grouping modes. Keep pressed and dragged row scrims aligned with the active backdrop, and preserve memoized row rendering on web.
2026-08-13 23:48:01 +02:00
Mohamed Boudra 373a98c64d Restore host directories instantly before reconnect (#3259)
* feat(sync): restore host directories before reconnect

Persist complete project, workspace, and active-agent replicas so every registered host can paint immediately, including offline hosts. Reconcile those replicas through monotonic per-entity cursors on the existing directory RPCs without retaining an event journal.

* fix(sync): preserve active turn identity during catch-up

Own Agent-to-wire projection beside the existing snapshot normalizer so replica persistence does not reach through directory-sync internals. This also keeps identified active turns intact when unchanged agents are folded into an incremental directory response.

* test(e2e): inspect the real IndexedDB replica

Keep cache setup, reload, and hydration coverage on the production browser storage backend after the replica moved off localStorage. Measure writes at the actual IndexedDB put boundary as well.

* fix warm reconnect cache paths

* feat(sync): persist project icons and deepen directory sync

* fix(sync): preserve project update order

* fix(cache): preserve validated replica persistence

* fix(sync): retain cached agents during catch-up
2026-08-13 23:10:44 +02:00
Mohamed Boudra 599846650c Stabilize live relay status coverage (#3337)
* test(cli): stabilize live relay status coverage

The regression fixture deleted the supervisor's active PID lock to model a reachable daemon without local process state. Under CI load, worker readiness could race that deletion and make the supervisor tear down the daemon while status and pairing were probing it.\n\nLaunch the real worker directly so the no-PID state exists naturally, then wait on the CLI-visible live relay state before asserting behavior.

* test(cli): wait for complete relay probe state

Status readiness alone does not guarantee the next pairing RPC or the foreign-home identity probe will finish inside the CLI's per-call timeout under CI contention. Retry each exact observable outcome within the fixture deadline and resolve the real worker entry through the server package.

* test(cli): name retry mechanics once

Keep the relay scenarios expressed as CLI probes and exact outcomes while one file-local helper owns the shared deadline, worker-liveness check, and retry cadence.
2026-08-13 23:10:28 +02:00
Mohamed Boudra 36d8464068 refactor(workspaces): make Docker a generic runtime
The server build, typecheck, and dry-run package pass with the Docker implementation deleted from the tree. paseo-workspace-helper remains a mandatory generic runtime contract requirement.
2026-08-13 21:59:13 +02:00
Mohamed Boudra b44bb63cf4 chore(release): cut 0.4.0 2026-08-13 21:31:47 +02:00
Mohamed Boudra a732cc5756 fix(app): open sole provider model picker directly
Running chats expose one provider, so an intermediate provider screen and back action are redundant. Restore the direct model-list entry behavior while preserving the multi-provider picker.
2026-08-13 20:34:21 +02:00
Desmond 2b9501a810 fix(app): support copying Hermes resume commands (#3300) 2026-08-13 17:54:38 +00:00
Mohamed Boudra 52e4060d76 fix(server): prefer portable project icons
Project icon discovery could select an ICO that native clients cannot decode even when a renderable SVG or PNG was available. Keep ICO as the final fallback and recognize common sized icon names.
2026-08-13 19:34:37 +02:00
Mohamed Boudra a4b92768d9 fix(providers): allow two minutes for catalog refreshes
Provider catalog discovery can exceed one minute during cold startup. Increase the default deadline while preserving explicit config and environment overrides.
2026-08-13 18:52:16 +02:00
Mohamed Boudra 0f27230746 feat(app): unify task list status styling
Use one task-row presentation across message and composer lists so running, pending, and completed states keep the same hierarchy and status language.
2026-08-13 18:52:15 +02:00
Mohamed Boudra 9c195feb9b Keep agent profile settings valid across providers (#3331)
* fix(app): keep profile modes scoped to providers

Applying a profile through sequential field setters allowed a provider change
to race mode persistence, poisoning modeless provider preferences with another
provider's mode. Apply profiles as one form transition and heal invalid
provider-scoped mode preferences when profiles are used.

* test(app): cover profile features across providers
2026-08-13 18:48:02 +02:00
Mohamed Boudra 90f3d95415 Add guided Hub setup (#3318)
* feat(cli): add Hub init wizard

Reuse the existing login, daemon enrollment, project listing, and deploy paths so onboarding stays compatible with current Hub servers. Generated triggers require an explicit sender allowlist and existing bundles are never modified.

* fix(cli): stop Hub init until daemon is ready

A durable Hub relationship can be reconnecting without being ready to execute workflows. Keep enrollment skipped, but stop the wizard until daemon status reports connected.

* fix(cli): wait for Hub daemon readiness

Both fresh enrollment and reconnect paths can expose a durable relationship before the execution socket is connected. Poll the existing status RPC with a bounded wait before resolving projects or deploying.

* fix(cli): make hub init detect resolvable resources
2026-08-13 16:24:38 +02:00
Mohamed Boudra 1a6054138d Stop idle workspace Git refreshes from starving daemon requests (#3323)
* fix(server): trust healthy workspace git watchers

Quiet observed workspaces were periodically scheduling full Git refreshes, saturating the daemon-wide process pool as workspace count grew. Keep only cheap observation re-ensure work, refresh ignore paths from watcher events, and detect silent metadata watchers with a one-shot canary before accepting the subscription.

* fix(server): refresh watcher ignores from git metadata

Repository exclude and Git configuration changes also affect the standard ignore set. Route those metadata events back to linked working-tree observations so their excluded directory lists stay current without periodic Git polling.

* test(server): drive ignore updates through watcher events

The integration contract now exercises the production event-driven ignore refresh instead of waiting for the removed periodic audit.

* fix(server): normalize git metadata paths on windows

File observation returns platform-native relative separators. Normalize those paths before matching Git metadata names so repository exclusion changes refresh working-tree ignores on Windows too.

* fix(server): trail concurrent ignore refreshes

Remember ignore-source events that arrive during an in-flight Git query and recompute once more before considering the working-tree observer current.
2026-08-13 22:08:23 +08:00
Mohamed Boudra 20bccd31a3 Make provider catalog refresh deadlines configurable (#3322)
* fix(providers): make catalog refresh deadlines configurable

Provider startup can legitimately exceed a fixed short timeout when catalog discovery has substantial initialization work. Give each provider refresh one configurable deadline covering availability and the complete catalog probe, and cancel named child operations before allowing retries so timed-out work cannot accumulate in the background.

* fix(opencode): abort catalog server acquisition

A provider refresh could expire while the helper server was still starting because acquisition only tracked the activity without observing its abort signal. Reject acquisition before transferring a server reference, while leaving the manager-owned startup reusable by the next caller.

* test(file-observer): allow native burst recovery
2026-08-13 15:08:46 +02:00
Mohamed Boudra d0d60a4052 Disconnect daemons locally when Hub is unreachable (#3321)
* fix(hub): make daemon disconnect unilateral

Local relationship removal must not depend on reaching the Hub. Fence execution authority, make one bounded courtesy revocation attempt, then clear local state so status and reconnect eligibility agree immediately.

* fix(hub): preserve disconnect intent across crashes

Persist the terminal disconnect marker only while the bounded Hub notification is in flight. Startup removes that marker, so a crash cannot restore the old relationship or create a revocation retry loop.
2026-08-13 14:00:37 +02:00
Mohamed Boudra 9ca6f24315 Let Claude apply its native MCP timeouts (#3315)
* fix(claude): preserve native MCP timeouts

Paseo forced Claude MCP startup and tool waits to ten minutes, turning unavailable servers into long silent first turns. Let Claude apply its own defaults while preserving explicit user environment overrides.

* test(claude): isolate MCP timeout regression

Exercise timeout precedence through the existing provider runtime environment input without mutating process-wide test state.

* test(workspace-git): await refresh boundaries

Synchronize fetch observation tests with initial snapshot and fetch completion before advancing fake timers.
2026-08-13 13:40:31 +02:00
Mohamed Boudra 36312352db fix(app): validate persisted client state (#3289)
* fix(app): validate persisted client state

Persisted replica data could satisfy TypeScript through an assertion while missing fields required by renderers. Treat every AsyncStorage value as untrusted input, clear values that fail strict schemas, and version the replica DTO so incompatible caches cannot hydrate.

* fix(app): preserve validated legacy state

* fix(app): preserve validated preferences

Preserve supported legacy location fields and every shipped theme while keeping unknown persisted fields rejected. Align browser test seeds with the current preference shape so strict validation exercises the intended provider.

* fix(app): migrate legacy agent preferences

Released clients stored host/location fields and per-provider thinkingOptionId together. Migrate those exact strict bytes into current preferences without admitting unknown fields.

* fix(app): preserve drafts with legacy reviews

Accept the exact strict shape released for workspace review attachments so migration can discard that obsolete attachment without clearing every persisted draft.
2026-08-13 12:02:39 +02:00
Mohamed Boudra c190fed27c Keep new worktrees clean when setup changes are uncommitted (#3311)
* fix(worktrees): preserve selected base config

New worktrees were overwriting the selected ref's paseo.json with source-checkout bytes, which could create an accidental revert in an otherwise fresh workspace. Keep committed base config authoritative and warn when locally saved setup changes still need to be committed.

* fix(worktrees): seed config exclusively

* fix(projects): refresh config status on focus
2026-08-13 12:02:15 +02:00
Mohamed Boudra cbb8295ceb fix(workspaces): unblock desktop runtime lifecycle
Electron-hosted Local helpers bypassed the sanitized self-Node launch policy, so they lacked ELECTRON_RUN_AS_NODE and provider probes hung.

Command-runtime adapters lacked exact detached POSIX process-group ownership, so forced lifecycle cleanup could leave adapter descendants alive.
2026-08-13 00:46:16 +02:00
Mohamed Boudra 9a7301d9a0 test(app): remove unintended replica cache case 2026-08-13 00:15:32 +02:00
Mohamed Boudra 44b9980a70 chore(release): cut 0.4.0-beta.2 2026-08-12 23:18:28 +02:00
Mohamed Boudra 1b887e534b fix(app): invalidate incompatible replica cache
Todo timeline entries gained required activity metadata in beta.1 while the persisted cache format remained unchanged. Reject version 3 snapshots so upgrades hydrate authoritative state instead of rendering legacy rows.
2026-08-12 23:07:14 +02:00
Mohamed Boudra 4426a6b11f Preserve opened subagents when parents are archived (#3279)
* fix(subagents): preserve opened children on parent archive

Opening a managed child represents user ownership only while that client's tab remains open. Track that intent per client, detach surviving children during parent archive, and keep single and bulk tab-close behavior consistent.

* fix(subagents): mark generic tab openings

Centralize managed child tab ownership in agent navigation so list, command-center, deep-link, notification, and subagent-track openings all mark ownership before creating the tab. Use stable localized errors for lifecycle failures.

* fix(subagents): classify cold tab openings

Fetch uncached agents before deciding whether tab ownership must be recorded, so notification, desktop, and cold-route openings cannot bypass parent archive protection.

* fix(app): translate navigation fallback errors

* fix(navigation): allow offline workspace intents

* refactor(app): derive subagent ownership from open tabs

* fix(server): serialize subagent lifecycle ownership
2026-08-12 21:18:55 +02:00
Mohamed Boudra 33afa7283b feat(workspaces): define project runtime source authority
Route probe and user materialization through one projectRuntimeSource seam, where persisted Git source overrides the host-only convenience root and must belong to Git project data.

Lock default revision, explicit revision, and subdirectory semantics with real Docker acceptance. Enforce provider-probe internals structurally and document that the current Docker POC needs a locally built image because its default reference is unpublished.
2026-08-12 20:53:05 +02:00
Mohamed Boudra 0c6dbefa40 chore(release): cut 0.4.0-beta.1 2026-08-12 20:39:35 +02:00
Mohamed Boudra 635a8be437 Restore model-default variant selection (#3281)
* fix(providers): restore implicit model variant selection

Provider catalogs list only explicit overrides, so treating the first override as the default made base model behavior unreachable. Represent the base choice in the catalog and translate it back to an omitted variant at the provider boundary.

* test(providers): exercise variant catalog boundary

The regression concerns the model catalog callers receive, so verify normalization through fetchCatalog instead of coupling the test to its internal builder.
2026-08-12 19:54:06 +02:00
Mohamed Boudra 527b252497 feat(workspaces): reconcile provider probe lifecycle
Keep lifecycle policy in provider-probe while WorkspaceRuntimeService remains the sole lifecycle executor. Idle probes pause without discarding runtime state; source and runtime fingerprints recreate probes and rotate provider bindings, while restart and project removal converge persisted records.

Close provider snapshot and helper bindings before lifecycle transitions to avoid leaks. Keep scriptTerminal in the exact bound-runtime surface because reusable local script terminals were intentionally introduced in the preceding accepted runtime slice.
2026-08-12 19:35:26 +02:00
Mohamed Boudra d03e4298ab feat(workspaces): accept Docker runtime journeys
Exercise probe, creation, terminals, file observation, Git, scripts, and agent edits through the Desktop Docker runtime while proving host decoys remain untouched.

Selected-runtime creation has a longer request budget because materialization and setup can legitimately exceed the legacy RPC ceiling; legacy creation keeps its existing timeout. Materializing records remain durable but private until final placement is published.

Scope Docker resources to the daemon owner and validate both container and volume before every lifecycle operation and creation race. Explicit Local and Worktree selection remains behaviorally unchanged, including reusable Local script terminals and the shared common-Git watcher.

Real-provider manual QA uses ignored checkout-local configuration and is intentionally not committed.
2026-08-12 18:28:06 +02:00
Mohamed Boudra 8e916fd2dc fix(app): align agent profile controls
Keep trailing edit controls from changing section heading rhythm, and center each profile's icon with its own text block so one-line and noted rows share the same visual alignment.
2026-08-12 17:27:08 +02:00
Mohamed Boudra 474b4e70b4 fix(app): restore file tree layout
Restore the established tree rails while retaining file actions. Keep Escape local to generic editable fields so cancelling a file draft cannot interrupt an agent.
2026-08-12 15:54:11 +02:00
Mohamed Boudra 124e512b58 fix(app): align track header hover states
The subagent track used a custom hover path that left its label and chevron muted. Reuse the ghost button interaction so track headers promote their content consistently.
2026-08-12 15:53:00 +02:00
Mohamed Boudra 0ba7251280 Revert "Make large diffs open quickly and scroll as one surface (#3212)"
This reverts commit b599d38a77.
2026-08-12 15:29:21 +02:00
James Strain b58ccf9269 fix: stop completed Codex subagents appearing active (#3188) 2026-08-12 14:05:45 +02:00
Mohamed Boudra 359d5443a9 feat(workspaces): probe providers in selected runtimes
Pre-creation provider truth now comes from an invisible real runtime workspace and reuses the normal provider snapshot pipeline. Probe records are owned separately, keeping them structurally absent from ordinary workspace projections.

Setup eligibility follows fresh content materialization rather than lifecycle resource ownership. Adopted Local directories never execute repository setup, while fresh Worktree, Docker, and external content may; provider probes never execute repository setup.
2026-08-12 13:02:21 +02:00
Mohamed Boudra 2f6b585a3a fix(desktop): shut down cleanly with workspace terminals (#3268)
Workspace terminal shutdown only signaled an npm wrapper, leaving Electron alive with broken output pipes. Make the signal-handling runner the terminal-owned process and route external Electron termination through the existing quit lifecycle.
2026-08-12 13:00:55 +02:00
2c5c629db8 fix(usage): read Cursor token from modern state.vscdb key via node:sqlite (#2704)
* fix(usage): read Cursor token from modern state.vscdb key via node:sqlite

Settings → Usage showed Cursor as unavailable for a normal Cursor desktop
login. The quota fetcher read the access token from the legacy `cursorAuthStatus`
key, but current Cursor builds store a plain JWT under `cursorAuth/accessToken`
with no such legacy row, so the lookup returned null.

Read the token with built-in node:sqlite instead of shelling out to a `sqlite3`
CLI (absent by default on Windows) — a second, independent cause of the same
"token not found → unavailable" failure. Prefer the modern key, fall back to the
legacy `cursorAuthStatus` blob for older builds, and log read failures at debug
so an unavailable card stays diagnosable.

Fixes #2586

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(usage): cover Cursor sqlite text and blob auth

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-08-12 12:25:04 +02:00
Mohamed Boudra 3a36c76733 feat(workspaces): choose runtime when creating workspaces
Expose the runtime catalog and carry an explicit runtime ID through workspace creation while preserving omitted-field compatibility for older clients.

The runtime POC made useGitActions require WorkspaceGitBoundary, but Command Center mounted that consumer without the boundary and crashed. Bind the active workspace at that consumer.

Keep provisional Worktree reservations unpublished until final placement so observers never bind the source checkout as the new workspace. Gate legacy cwd Git compatibility by hostVisiblePath instead of runtime kind because Local and Worktree remain host-visible runtimes.
2026-08-12 11:22:55 +02:00
Mohamed Boudra 74f2158c45 Preserve daemon sessions when workers stall (#3263)
Stop treating heartbeat silence as proof that a live daemon worker should be destroyed. Crash recovery, explicit lifecycle requests, and supervisor-loss cleanup remain unchanged.
2026-08-12 10:58:58 +02:00
Mohamed Boudra d012b6f071 Help agents diagnose Paseo provider problems (#3243)
* feat(skills): add Paseo help and provider diagnostics

Give support agents a topology-aware troubleshooting entry point backed by the deployed documentation index, and expose the daemon provider diagnostic through the CLI so agents can inspect the affected host directly. Agent-launching skills now use configured profiles instead of the removed orchestration preferences.

* test(cli): keep provider diagnostics on real boundaries

Remove the internal client mock and preserve its normalization and host-targeting assertions through the existing isolated-daemon coverage.
2026-08-12 00:57:33 +02:00
Mohamed Boudra 5f5c585e68 fix(app): avoid unsupported Android array sorting (#3241)
Hermes in the production Android app does not provide Array.prototype.toSorted. Multi-host project selection and provider cache eviction could therefore crash when they reached deterministic sorting paths.
2026-08-12 00:23:22 +02:00
Mohamed Boudra 23d7a8eaf9 Improve Markdown file preview readability (#3240)
* feat(app): improve markdown file previews

Keep rendered documents on the chat reading rail, surface YAML front matter as readable metadata, and make shared Markdown links retain the chat accent and hover treatment.

* fix(app): preserve unsafe frontmatter source

* test(app): cover markdown link behavior
2026-08-12 00:18:30 +02:00
Mohamed Boudra 6ca27a9b12 feat(workspaces): publish external runtime contract
Publish the rootless workspace runtime protocol, enforce module and host-execution boundaries, and prove an independently authored command runtime across lifecycle, PTY, files, Git, providers, and CI.
2026-08-11 22:14:47 +02:00
Mohamed Boudra 7b167784d7 fix(app): bound Android provider snapshot storage (#3234)
Android AsyncStorage's 6 MiB SQLite ceiling was exhausted by per-workspace provider snapshots with no eviction. Raise the native cap to 10 MiB and bound snapshots to 4 MiB with indexed eviction, clearing legacy unindexed data without scanning payloads on every save.
2026-08-11 22:00:21 +02:00
Mohamed Boudra 40bdb9a043 fix(server): keep daemon workers alive across host sleep (#3235)
The worker watchdog treated wall-clock time spent in host sleep as evidence that the worker was unresponsive. Count consecutive observed heartbeat misses instead so sleep does not destroy live terminal sessions while genuinely stalled workers still restart after the same active observation window.
2026-08-11 21:48:06 +02:00
Mohamed Boudra 2f54c0e309 Use saved Project Settings for new worktree setup (#3233)
* fix(worktrees): honor saved setup configuration

Project Settings writes paseo.json in the source checkout, but existing committed copies in new worktrees previously won silently. Copy the saved project config before lifecycle setup so the command shown to users is the command that runs.

* fix(worktrees): replace config symlinks safely

A selected ref can place a symlink at paseo.json, so copying over that path may overwrite a file outside the worktree. Materialize the saved source config with atomic rename semantics to replace the path entry without following it.
2026-08-11 21:20:30 +02:00