feat: add persistent workspace state, first-class terminals, and setup streaming#197
Open
feat: add persistent workspace state, first-class terminals, and setup streaming#197
Conversation
- Remove orphaned PID lock code from bootstrap (moved to supervisor) - Fix worktree archive adapter to look up workspace by directory - Replace registerWorktreeWorkspaceRecord with inline SQLite implementation - Remove unused imports (stat, createPersistedWorkspaceRecord, PersistedProjectRecord)
Services defined in paseo.json get reverse-proxied through the daemon
via hostname-based routing on *.localhost. Each service receives $PORT,
$HOST, and $PASEO_SERVICE_URL env vars, and is accessible at
{service}.localhost:6767 (main) or {branch}.{service}.localhost:6767
(worktrees).
Built-in service proxy with branch-based URLs, service health monitoring, workspace hover card with service status, and "Forget about ports" homepage section.
# 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
# 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
- Align portless code with storage branch's numeric workspace IDs and new field names - Update workspace kind comparisons (local_checkout → checkout/worktree) - Add missing services, supportsTerminalMode, terminal fields to test fixtures - Fix archive timestamp assertions to match dynamic archiveSnapshot flow - Fix dictation, voice runtime, and service health monitor test timing - Add xterm-addon-ligatures type declaration for terminal emulator
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
# Conflicts: # nix/package.nix
# Conflicts: # nix/package.nix
Reuse existing project when a matching git remote is found instead of creating duplicates. Detect git worktrees via --git-common-dir and set workspace kind accordingly.
…low and stabilize worktree PASEO_HOME
# 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
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.
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
| return await initPromise; | ||
| } finally { | ||
| const current = pendingAgentBootstrapLoads.get(options.agentId); | ||
| if (current === initPromise) { |
| const hasLog = commandLog.trim().length > 0; | ||
|
|
||
| // All non-running commands are expandable (completed/failed) | ||
| const isExpandable = command.status !== "running" || hasLog || !!hasError; |
| ); | ||
| } | ||
|
|
||
| const isArchivingCurrentAgent = Boolean(agentId && isArchivingAgent({ serverId, agentId })); |
Brings in 8 main commits (0.1.48 release, provider overhaul, keyboard shortcuts, desktop login shell env, question form Enter key) with proper git history. Resolves conflicts by keeping dev branch architecture where it subsumes main's changes, and main's provider snapshot COMPAT comments.
…ouping - DbProjectRegistry/DbWorkspaceRegistry: use ON CONFLICT(directory) instead of ON CONFLICT(id) so inserts and upserts handle duplicate directories gracefully instead of crashing - Bootstrap: wrap legacy imports in try/catch (non-fatal), move reconciliation start after imports so first pass cleans up stale data - Legacy project/workspace import: deduplicate by rootPath (prefer git over non_git), derive gitRemote from legacy projectId field - Legacy agent snapshot import: detect git metadata and group agents by remote/toplevel instead of creating one project per cwd, clamp running/initializing statuses to closed - Timeline hydration: set historyPrimed based on whether durable store has rows (not just whether it exists), remove hard gate so imported agents get their timelines populated lazily from provider history - Durable timeline append: use bulkInsert with pre-assigned seq instead of appendCommitted which recalculates seq, fixing UNIQUE constraint failures during concurrent hydration writes
The reconciliation service was skipping worktree workspaces when updating displayName from the current git branch, causing the sidebar to show the initial random animal name instead of the actual branch.
- Replace workspace setup dialog with full-screen new workspace route - Restyle Combobox SearchInput to match CombinedModelSelector Level 2 design: borderless sticky search bar above scroll area instead of inline bordered box - CombinedModelSelector now uses shared SearchInput, removing duplicate ProviderSearchInput - Fix TooltipTrigger children type to accept render functions (remove PropsWithChildren wrapper) - Fix empty rightControls View causing gap between dictation and send buttons - Add branch picker with searchable Combobox and GitBranch icons - Muted icon buttons (attachment, dictation, voice mode) that brighten on hover
- 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)
- Change workspace id/projectId from z.number() to z.union([z.string(), z.number()]).transform(String) for backward compat - Add "non_git" to projectKind, "local_checkout" to workspaceKind enums - Session converts numeric IDs to strings at the descriptor boundary - Update tests and daemon-client event types to match
Add onComplete callback to warmCheckoutShortstatInBackground so session can push a workspace_update once diff stats resolve.
getCurrentPathname used window.location.pathname instead of Expo Router's pathname, which returns a file path on Electron — blocking navigation from the index route. Also gate the bootstrap progress UI to desktop-only since web has no local server to start/connect.
Numeric string IDs like "164" are valid base64 that decodes to garbage (Hebrew character ""), causing silent workspace lookup failures. Skip base64 encoding/decoding for numeric IDs and only use it for legacy path-based workspace identifiers.
No-op clearDraft so the prompt stays while worktree + agent are being created. Screen navigates away on success; text remains for retry on error.
Extend the existing gh pr view call with statusCheckRollup and reviewDecision fields so check data arrives in a single request. The workspace row now shows an aggregate check icon (green checkmark, red X, or amber dot) next to the PR badge, and the hover card lists each individual check with its status and a link to details.
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.
…nd agent form state improvements - Add service-route-branch-handler for routing requests to branch-specific services - Add service-hostname utility for generating hostnames from branch names - Redesign workspace hover card with CI check status display - Update combined model selector and sidebar workspace list - Improve agent form state and input draft hooks - Update checkout-git with enhanced branch handling - Add workspace git watch and bootstrap improvements
…based workspace IDs, and add backward-compatible schema fields
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR overhauls how Paseo models workspaces, terminals, and persisted agent state.
From
main, it introduces SQLite-backed persistence for agents, timelines, projects, and workspaces; replaces terminal-agent flows with first-class terminals; adds a streaming workspace setup flow; and makes workspace status more informative with service health/routing and CI visibility in the sidebar and hover card.It also includes the app and daemon changes needed to make those systems work together cleanly, plus parity fixes so the newer composer, provider, and workspace UX continue to behave correctly on top of the new architecture.
User-facing changes
Technical implementation
Notes for reviewers
db,session/workspace,terminal,service proxy, then app workspace UX) will be easier than reading strictly commit-by-commit.