Commit Graph
137 Commits
Author SHA1 Message Date
Mohamed Boudra 944978ddb6 Merge branch 'main' into dev 2026-04-10 20:59:14 +07:00
Mohamed Boudra a525b0e22e Merge branch 'main' of github.com:getpaseo/paseo 2026-04-10 20:14:48 +07:00
Mohamed Boudra 497159ada8 Add pull action and restructure git actions policy 2026-04-10 20:13:59 +07:00
Mohamed Boudra 321ffce6a3 Merge remote-tracking branch 'origin/main' into dev 2026-04-10 19:41:19 +07:00
Mohamed BoudraandGitHub ba1ecedca3 feat: middle-click to close tabs on desktop (#232)
Add useMiddleClickClose hook that listens for auxclick (button === 1)
events on web, enabling middle-click-to-close behavior on tab chips.
2026-04-10 19:51:46 +08:00
Mohamed Boudra 78b7e51396 Merge branch 'main' into dev 2026-04-10 17:15:58 +07:00
Mohamed Boudra 49e67363b2 feat(app): add themeable diff stat colors and soften tooltip border
Add diffAddition/diffDeletion semantic tokens with separate light
(muted green-700/red-700) and dark (bright green-400/red-500) sets,
spread into themes so individual variants can override. Update all
diff stat consumers to use the new tokens.

Soften tooltip border to match dropdown menu styling (thinner border,
accent color, medium shadow).
2026-04-10 17:06:41 +07:00
Mohamed Boudra 0deaed3794 Merge branch 'main' into dev 2026-04-10 14:44:57 +07:00
b5a0ee9954 feat: branch switching with stash-and-switch (#231)
* feat: add branch switching and stash management to workspace header

Adds the ability to switch git branches from the workspace header by
clicking the branch name. Includes full stash support: when switching
away from a dirty branch, users are prompted to stash changes; when
switching to a branch with a Paseo stash, they're prompted to restore.
An amber stash indicator in the header provides anytime restore/discard.

New WebSocket messages: checkout_switch_branch, stash_save, stash_pop,
stash_drop, stash_list. Stashes are tracked via git stash messages
with a "paseo-auto-stash:" prefix convention.

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

* fix: await query invalidation after branch switch and stash

The branch switcher became non-clickable after switching because
checkout query invalidation was fire-and-forget. Now we await
invalidation so the UI has fresh checkout status (including the new
branch name) before rendering. Also invalidate after stash-save
so the checkout query sees clean state before the switch.

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

* fix: emit workspace update immediately after branch switch

The sidebar and header were slow to reflect the new branch name because
they relied on the daemon's background git watcher to detect changes.
Now the switch handler calls emitWorkspaceUpdateForCwd immediately after
checkout, pushing the updated workspace descriptor to connected clients.

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

* fix: stash detection and dirty-tree branch switch handling

- Fix stash list parser: git prepends "On <branch>: " to stash
  messages, so use indexOf instead of startsWith to find the
  paseo-auto-stash prefix.
- Remove switchBranchMutation in favor of inline async flow in
  handleBranchSelect. Now tries the switch first; if the server
  returns an uncommitted-changes error, offers the stash dialog
  automatically — no more red error toast on first attempt.
- Move post-switch stash restore prompt into handleBranchSelect
  so the full flow (switch → check stashes → prompt) is sequential.

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

* fix: toast.success → toast.show and await stash invalidation

- Replace toast.success() with toast.show() — the ToastApi only
  exposes show/copied/error, not success.
- Await invalidateStashAndCheckout in stashPop and stashDrop mutation
  onSuccess handlers so the stash indicator disappears immediately
  after restore/discard.

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

* feat: add stash diff preview and multi-stash management

- Add stash_show message pair: server runs `git stash show -p` and
  returns ParsedDiffFile[] through the existing diff parser.
- Stash indicator dropdown now lists ALL Paseo stashes (not just
  current branch) with per-stash Preview, Restore, and Discard actions.
- Preview opens a full diff modal showing file-by-file changes with
  syntax-colored add/remove lines, file stats, and Restore/Discard
  action buttons.
- Clean up: remove unused handleRestoreStash/handleDropStash callbacks,
  add Eye/Trash2 icons, import Modal/ScrollView.

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

* fix: use Fonts.mono instead of theme.fontFamily.mono

The theme object doesn't have a fontFamily property. The codebase uses
the Fonts constant from @/constants/theme for font family values.

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

* fix: filter stashes to current branch and handle restore conflicts

- Stash indicator only shows when the current branch has stashes,
  not all branches. Switching branches hides/shows it correctly.
- When restoring a stash conflicts with uncommitted changes, offers
  to stash current changes first then restore the target stash
  (auto-adjusts stash index after the new save).
- Multiple stashes on the same branch show as "Stash 1", "Stash 2"
  instead of repeating the branch name.

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

* feat: improve branch switcher with recency sort, sticky search, and branch icons

- Sort branches by committer date (most recent first) instead of alphabetical
- Use full refname to fix normalization of branches with slashes
- Filter out bare "origin" symref leaking as a branch name
- Remove server-side search query; fetch all branches once and filter client-side
- Port combobox sticky search design from dev (borderless bar above scroll area)
- Add GitBranch icons to branch switcher items
- Prioritize prefix matches in combobox search results

* fix: move useIsCompactFormFactor hook above early return in ToastViewport

The hook was called after `if (!toast) return null`, violating React's
rules of hooks and causing "Rendered more hooks than during the previous
render" crash.

* fix: include untracked files in stash-and-switch flow

git stash push without --include-untracked left untracked files behind,
causing the clean-tree check to fail on the subsequent checkout.

* refactor: strip stash management UI, keep stash-and-switch flow

Remove the stash indicator icon, dropdown menu, preview modal,
and stash_drop/stash_show RPCs. Keep the auto-stash on branch switch
and the restore prompt on arrival — that's the useful surface.

* refactor: extract filterAndRankComboboxOptions with tests

* refactor: extract BranchSwitcher component and useBranchSwitcher hook

---------

Co-authored-by: heyimsteve <8645831+heyimsteve@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:26:04 +08:00
Mohamed Boudra 1d41a50e1f Background revalidate provider models when model selector opens
On fresh startup the initial provider snapshot request can return
before providers finish loading, leaving the model picker empty.
The server broadcasts updates once providers are ready, but if the
user opens the picker in the interim they see "No models match".

Invalidate the React Query cache (background refetch, no loading
flash) every time the model selector popup opens so stale data is
silently refreshed.
2026-04-10 11:01:01 +07:00
Mohamed Boudra 4176bd8aa1 Merge branch 'main' into merge/main-into-dev
# Conflicts:
#	packages/app/src/components/combined-model-selector.tsx
#	packages/app/src/components/message-input.tsx
#	packages/app/src/components/sidebar-workspace-list.tsx
#	packages/app/src/screens/agent/draft-agent-screen.tsx
#	packages/app/src/screens/settings-screen.tsx
#	packages/desktop/src/main.ts
#	packages/server/src/server/agent/provider-launch-config.ts
#	packages/server/src/server/session.ts
#	packages/server/src/server/session.workspaces.test.ts
#	packages/server/src/shared/messages.ts
#	packages/server/src/utils/checkout-git.ts
2026-04-10 10:15:49 +07:00
Mohamed Boudra c1ebb8c915 Refactor form factor check to reactive useIsCompactFormFactor 2026-04-10 09:53:38 +07:00
Mohamed Boudra b1b85833bb Distinguish services from scripts with type system and runtime tracking 2026-04-09 23:45:00 +07:00
Mohamed Boudra c7399084a4 Add hidden agent tab intent for workspace reconcile 2026-04-09 20:39:27 +07:00
Mohamed Boudra 397d454de0 refactor: rename services to scripts and extract reusable components 2026-04-09 18:54:25 +07:00
Mohamed Boudra 65f8823e4e Merge remote-tracking branch 'origin/main' into merge/main-into-dev
# Conflicts:
#	CLAUDE.md
#	nix/package.nix
#	packages/app/src/components/combined-model-selector.tsx
#	packages/app/src/hooks/use-sidebar-workspaces-list.ts
#	packages/app/src/screens/workspace/workspace-screen.tsx
#	packages/app/src/stores/session-store.test.ts
#	packages/server/src/client/daemon-client.ts
#	packages/server/src/server/agent/agent-manager.ts
#	packages/server/src/server/session.ts
#	packages/server/src/server/session.workspace-git-watch.test.ts
#	packages/server/src/server/session.workspaces.test.ts
#	packages/server/src/shared/messages.ts
2026-04-08 11:38:17 +07:00
Mohamed Boudra 161b2c2378 fix(app): port optimistic workspace tab closing 2026-04-07 14:30:32 +07:00
Mohamed Boudra 1900f43049 fix(app): move reload agent away from close action 2026-04-07 12:20:15 +07:00
Illia PanasenkoandGitHub 5cb424b2e6 feat(app): add open in editor toolbar action (#209)
* feat(app): add open in editor toolbar action

* fix(app): normalize editor icon asset permissions

* chore(website): drop unrelated generated route tree change
2026-04-07 10:25:25 +08:00
Mohamed Boudra 390a3402ab Fix provider snapshot session hydration and agent scoping 2026-04-07 00:11:43 +07:00
Mohamed Boudra c63240b18c feat(app): unified provider snapshot, resilient model selector, and UX polish
- Model selector is no longer disabled while providers load; opens
  immediately and streams available providers as they arrive
- Selecting a non-default provider on mobile now works correctly
- Provider icon added to model trigger in mobile preferences sheet
- Thinking icon (brain) added to thinking trigger in mobile preferences
- Model descriptions for OpenCode/Pi shown inline next to model name
  instead of in a tooltip
- Running agents and draft screen share a single provider/model cache,
  eliminating duplicate network requests
- Provider data is prefetched when entering a workspace so the model
  selector is instant on first open
2026-04-06 23:37:22 +07:00
Mohamed Boudra 7b19dd736f feat: add service start capability with health monitoring 2026-04-06 20:16:32 +07:00
Mohamed Boudra 5d1b3383d7 fix: only confirm archive when agent is running
Skip the confirmation dialog when archiving idle agents — archive
immediately. Show a warning that the agent will be stopped only when
it is running or initializing.
2026-04-06 11:04:05 +07:00
Mohamed Boudra d3e5d6929d fix: optimistic archiving/closing and tab UX improvements
- Archive agents optimistically on close with rollback on error
- Close tabs immediately instead of waiting for RPC response
- Kill terminals in background with cache invalidation on failure
- Bulk close fires RPC in background, closes all tabs upfront
- Move new-tab button out of scroll area, rename to "New agent tab"
- Support invalidateQueries option in applyArchivedAgentCloseResults
- Fix workspace descriptor id/projectId types (string not number)
2026-04-06 08:32:10 +07:00
Mohamed Boudra 4dca672711 Restore features lost during main merge and fix workspace setup flow
Restores all features dropped when merging main into dev:
- Keyboard shortcuts (send, dictation-confirm) with full e2e chain
- Feature toggles (plan/fast mode) in agent status bar
- Sidebar kebab menu (Remove Project) on project rows
- Combined model selector (sticky header, sizing, favorites sort, search)
- Question form Enter key submit with guard
- Input focus restoration (composer + AgentStatusBar onDropdownClose)
- Draft-agent feature toggles and focus restoration
- Provider diagnostics UI (settings section, diagnostic sheet, status badge)
- Provider diagnostics server (snapshot manager, diagnostic utils, RPC)

Fixes dev-branch regressions:
- New workspace button now opens composer in setup dialog via beginWorkspaceSetup
- Setup tab auto-opens when workspace setup is running
2026-04-05 21:10:16 +07:00
Mohamed Boudra 8e482b1613 fix: use numeric workspace ID for worktree setup tracking and improve service list UI 2026-04-05 18:16:31 +07:00
Mohamed Boudra 0d88ce2270 feat(app): provider system overhaul with model selector, diagnostics, and UX polish
- Add CombinedModelSelector with two-level drill-down (providers → models),
  favorites section, search, and single-provider auto-drill mode
- Add provider snapshot system (ProviderSnapshotManager) for cached provider/model state
- Add provider diagnostics with resolved binary paths and versions across all providers
- Add StatusBadge shared component for consistent status visual language
- Add ProviderDiagnosticSheet for detailed provider health inspection
- Add desktop auto-focus on input after any status bar interaction (model, mode,
  thinking, features) using focusWithRetries
- Fix Combobox flicker on height change by switching to bottom-based CSS positioning
  once initial floating-ui position resolves
- Add dynamic dropdown height: Level 1 fits content, Level 2 calculates from model count
- Remove "Other providers" section from model selector (only show available providers)
2026-04-05 15:32:13 +07:00
Mohamed Boudra 2dd597f5f5 Harden SQLite migration and apply post-merge fixes
Migration hardening:
- Back up JSON to $PASEO_HOME/backup/pre-migration/ before import
- Deduplicate projects/workspaces by path before insert
- Log per-batch progress during agent snapshot import
- Clear error messages for corrupt JSON files
- 5 new test cases for backup, dedup, progress, and error clarity

Post-merge fixes:
- Add worktreeRoot to session checkout result (type error fix)
- Port reload agent tab action from main
- Remove deleted useDelayedHistoryRefreshToast hook usage
2026-04-05 13:05:54 +07:00
Mohamed Boudra fcfb9c99da Merge branch 'main' into dev
Surgical merge of 74 commits from main into dev. Key features ported:

- Provider visibility gating (appVersion filtering for Pi/Copilot)
- Pi agent provider + Copilot re-enabled
- Provider-declared features system (Codex fast mode)
- Workspace dedup by worktree root (adapted to integer IDs)
- Bulk close archiving fix for stored agents
- Agent creation timeout increase to 60s
- Audio/voice crash fixes (external buffer copies)
- Multi-host setup fix
- Reload agent tab action

Dev architecture preserved: SQLite storage, service proxy,
workspace setup dialog, hover cards, removed launcher tabs.
2026-04-05 12:59:07 +07:00
Mohamed Boudra a264058a30 Remove noisy agent toasts and debug logging
Remove the "Refreshing" and "Failed to refresh agent" toasts from the
agent panel — they fire frequently but are meaningless since sync
recovers transparently. The "Reconnecting..." toast for host disconnect
is preserved.

Strip debug console.log calls across the app: render tracking in
message/stream views, dependency change tracking in workspace screen,
terminal tab slot logging, and verbose audio engine/voice runtime
bridge stats logging. Legitimate console.error/warn in catch blocks
are kept.
2026-04-05 11:10:49 +07:00
Mohamed Boudra c32bc847bf feat(app): restore reload action for agent tabs 2026-04-05 09:21:45 +07:00
Mohamed Boudra 7e99529bde Add Codex plan mode draft features 2026-04-04 16:35:31 +07:00
Mohamed Boudra 5e1b24b217 refactor(app): remove launcher tabs from workspace flow 2026-04-04 15:37:26 +07:00
Mohamed Boudra 2ca7dd71e2 Tweak new tab button: larger icon, foreground hover, more padding 2026-04-04 15:37:26 +07:00
Mohamed Boudra 23ffec5072 fix(app): prevent tab pruning from closing pinned archived agents
The tab sync effect pruned archived agent tabs without checking if they
were pinned, so clicking an archived agent from the sessions page would
open and immediately close the tab.
2026-04-03 19:02:18 +07:00
Mohamed Boudra 59bc3bd3d1 Merge remote-tracking branch 'origin/main' into dev
# Conflicts:
#	nix/package.nix
#	packages/app/src/components/icons/opencode-icon.tsx
#	packages/app/src/components/provider-icons.ts
#	packages/app/src/panels/agent-panel.tsx
#	packages/cli/src/commands/provider/ls.ts
#	packages/server/src/server/agent/provider-manifest.ts
#	packages/server/src/server/agent/provider-registry.ts
#	packages/server/src/server/agent/providers/claude-agent.test.ts
#	packages/server/src/server/agent/providers/claude-agent.ts
#	packages/server/src/server/persistence-hooks.ts
#	packages/server/src/server/session.ts
2026-04-03 10:10:20 +07:00
Mohamed Boudra 994ee488b9 Increase workspace status emphasis and use amber alert for needs input 2026-04-02 22:53:52 +07:00
Mohamed Boudra 060f3d457c refactor: remove terminal agent concept entirely
Remove the "agent can be a terminal" branching from the entire codebase.
An agent is now always a session-backed chat agent. Standalone terminal
infrastructure (terminal component, ANSI handling, terminal-stream-protocol)
is preserved.

Server: delete ManagedTerminalAgent, AgentKind, TerminalExitDetails,
launchTerminalAgent, registerTerminalAgent, handleTerminalAgentExited,
supportsTerminalMode capability, buildTerminalCreate/ResumeCommand from
all providers, terminal agent persistence/projections.

App: delete terminal-agent-panel.tsx, terminal-agent-reopen-store.ts,
terminal/terminalExit fields on agent state, "Terminal Agents" launcher
section, terminal-agent workspace setup flow, terminal badge in agent list.

CLI: remove terminal column from ls, terminal-agent error from send.

60 files changed, -3592 lines
2026-04-02 10:55:54 +07:00
Mohamed Boudra d75dd33773 Merge branch 'investigate/portless' into dev
# Conflicts:
#	packages/app/e2e/helpers/workspace-setup.ts
#	packages/app/src/components/sidebar-workspace-list.tsx
#	packages/app/src/contexts/session-context.tsx
#	packages/app/src/hooks/use-sidebar-workspaces-list.test.ts
#	packages/app/src/screens/workspace/workspace-tab-menu.ts
#	packages/app/src/stores/workspace-setup-store.ts
#	packages/app/src/stores/workspace-tabs-store.ts
#	packages/app/src/utils/sidebar-project-row-model.test.ts
#	packages/app/src/utils/sidebar-shortcuts.test.ts
#	packages/app/src/utils/workspace-tab-identity.ts
#	packages/server/src/server/bootstrap.ts
#	packages/server/src/server/worktree-session.ts
2026-04-01 22:06:39 +07:00
Mohamed Boudra f1ffecfcd4 Merge branch 'storage-terminal-ui-dev' into dev
# Conflicts:
#	nix/package.nix
#	packages/app/src/app/_layout.tsx
#	packages/app/src/components/sidebar-workspace-list.tsx
#	packages/app/src/hooks/use-command-center.ts
#	packages/app/src/screens/agent/draft-agent-screen.tsx
#	packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx
#	packages/app/src/screens/workspace/workspace-screen.tsx
#	packages/server/src/server/session.ts
#	packages/server/src/server/session.workspaces.test.ts
#	packages/server/src/terminal/terminal.test.ts
#	packages/server/src/terminal/terminal.ts
2026-04-01 21:51:29 +07:00
Mohamed Boudra a7d5ab2497 WIP: workspace execution refactor + notification routing + setup store updates 2026-04-01 21:28:07 +07:00
Mohamed Boudra c13972c835 fix: replace Unix path assumptions with cross-platform isAbsolutePath
Windows daemon paths like C:\Users\... don't start with "/", breaking
the explorer sidebar, checkout status, terminals, and file attachments
when connected to a Windows daemon. Consolidate three private
isAbsolutePath implementations into a shared utility and use it
everywhere, with correct file URI conversion for Windows and UNC paths.
2026-04-01 18:20:02 +07:00
Mohamed Boudra cafff08a30 fix: rewrite titlebar drag to match VS Code's static pattern
Replace the stateful TitlebarDragRegion (hooks, ResizeObserver, IPC,
fullscreen tracking) with a pure static component — matching VS Code's
titlebar-drag-region exactly: position absolute, full size, no z-index,
no pointer-events, no state, no event listeners.

Remove TitlebarNoDragContent entirely — VS Code doesn't wrap content in
no-drag; interactive elements get no-drag from the global CSS backstop
in index.html.

Add drag regions to all header surfaces:
- ScreenHeader (sessions, workspace header)
- Left sidebar (traffic light area + header)
- Split container pane tabs
- Explorer sidebar header (Changes/Files tabs)

Fix workspace header empty space not draggable by changing
headerTitleContainer from flex: 1 to flexShrink: 1.
2026-04-01 17:36:26 +07:00
Mohamed Boudra 2d02db6ae0 fix(app): improve light mode theming
- Make PaseoLogo theme-aware (uses foreground color instead of hardcoded white)
- Add shadow tokens (sm/md/lg) to theme with per-scheme opacity, radius, and offset
- Replace all 16 hardcoded shadow instances with spreadable theme.shadow tokens
- Fix button icon color for default variant (use accentForeground, not foreground)
- Fix dark background flash on startup (root layout used hardcoded darkTheme)
- Add theme.colorScheme to replace fragile hex-string dark mode detection
- Add scrollbarHandle and surfaceWorkspace tokens to eliminate isDark branching
2026-04-01 14:24:17 +07:00
Mohamed Boudra 51411182fe fix(app): support ipad desktop layout safely 2026-04-01 13:37:51 +07:00
Mohamed BoudraandGitHub f53c770a71 [codex] add batch close rpc for workspace tabs (#165)
* style: add subtle teal tint to dark mode surfaces

Replace neutral gray surfaces with a teal-tinted palette across
the app and website, giving Paseo a warmer, more recognizable feel.
App uses a restrained tint (G-R ~3), website is slightly stronger
(G-R ~6) as a brand showcase.

* fix(opencode): handle message.part.delta events for assistant text streaming

OpenCode v2 streams assistant text via `message.part.delta` events (with
field "text" or "reasoning"), but the translator only handled
`message.part.updated`. This caused assistant messages to be silently
dropped during live streaming.

* feat: show agent short ID in tab context menu and tooltip (#161)

Add agent short ID to the "Copy agent id" menu item as trailing hint
text and to the tab tooltip next to the title. Add leading icons to
all workspace tab context menu items.

* add batch close rpc for workspace tabs
2026-04-01 14:31:38 +08:00
Mohamed Boudra d8243bfb72 WIP: snapshot workspace execution refactor baseline 2026-04-01 10:35:06 +07:00
Mohamed Boudra 5b3ec572cb feat: service proxy, health monitor, hover card, and homepage section
Built-in service proxy with branch-based URLs, service health
monitoring, workspace hover card with service status, and
"Forget about ports" homepage section.
2026-04-01 10:31:15 +07:00
Mohamed BoudraandGitHub ee50d3b8d0 WIP: fix archive tab reconciliation (#158)
* WIP: fix archive tab reconciliation

* fix: converge archive into AgentManager for cross-session propagation

CLI archive left agent tabs visible in passive app clients because
Session.archiveAgentState only notified the archiving session's own
subscription. LoopService had the same gap via AgentManager.archiveAgent.

Converge on AgentManager.archiveAgent as the single canonical archive
path: persist updatedAt, call notifyAgentState before closeAgent so all
sessions receive the archived snapshot. Delete Session.archiveAgentState
and make handleArchiveAgentRequest a thin wrapper.
2026-03-31 16:03:36 +07:00
Mohamed Boudra 1f6ffa9e0e Add workspace setup streaming and setup tab 2026-03-31 09:09:38 +07:00