The sidebar now groups conversations by project, so the embedded project picker in the search box duplicated the main navigation model and hid state inside a compact icon. Remove that picker and its store state, leaving search as plain text filtering and keeping the project header menu focused on organization and sorting.
The archive-all entry was also hidden because a broad destructive action does not belong in the lightweight project menu.
Constraint: Project grouping is now the primary project navigation surface.
Rejected: Keep the embedded project picker hidden in place | it would leave dead filtering state and a stale recovery path.
Rejected: Keep archive-all in the header menu | broad destructive actions are too risky for this surface.
Confidence: high
Scope-risk: moderate
Directive: Do not reintroduce broad session deletion or hidden project filters into the sidebar header without a dedicated reviewed management flow.
Tested: cd desktop && bun run test src/components/layout/Sidebar.test.tsx src/stores/sessionStore.test.ts src/components/layout/TabBar.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
The previous tab strip height made session titles and toolbar affordances feel cramped. Increase the shared titlebar height token for tabs, overflow controls, and the native drag gutter so the top chrome reads as a deliberate desktop titlebar while preserving the existing drag, close, and toolbar interactions.
Constraint: Keep the change scoped to the desktop tab strip and avoid changing session state, ordering, or window-control behavior
Rejected: Increase only the outer bar height | tab hit targets and overflow controls would remain visually misaligned
Confidence: high
Scope-risk: narrow
Directive: Keep tab, overflow button, and drag-gutter heights aligned when changing this titlebar again
Tested: cd desktop && bunx vitest run src/components/layout/TabBar.test.tsx
Tested: bun run check:desktop
Tested: Browser smoke on Vite with tab bar measured at about 44px and toolbar controls centered
Not-tested: Native packaged Tauri window rendering on Windows titlebar controls
Desktop sessions need a fast local escape hatch that opens the same materialized cwd the agent is editing, without showing unavailable IDE choices or persisting detection state. This adds a local open-targets API with silent in-memory detection for common IDEs and platform file managers, then wires a compact Codex-style toolbar menu into the desktop TabBar for active session workdirs.
Constraint: The first version is local IDE/editor and Finder/Explorer/file-manager only, no terminal targets or IDE plugin integration.
Constraint: The opened path must come from the active session workDir so isolated worktrees open the actual agent editing surface.
Rejected: Persisting detected applications | detection is cheap and temporary state avoids stale app inventory.
Rejected: Rendering unavailable IDEs as disabled menu rows | the user asked to show only detected targets and fall back to Finder/Explorer when no IDE is available.
Confidence: high
Scope-risk: moderate
Directive: Keep this path session-workdir based; do not switch it to repository root without proving isolated worktree behavior.
Tested: bun test src/server/__tests__/open-target-service.test.ts src/server/__tests__/open-target-api.test.ts
Tested: cd desktop && bun run test -- src/stores/openTargetStore.test.ts src/components/layout/OpenProjectMenu.test.tsx src/components/layout/TabBar.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Tested: bun test src/server/__tests__/h5-access-auth.test.ts -t 'allows local desktop H5 access settings under explicit server auth with a valid bearer'
Not-tested: bun run check:server full suite had one unrelated H5 auth integration timeout in the full concurrent run; the timed-out test passed when rerun alone.
When the tab strip overflows, newly opened sessions were active but could remain outside the visible horizontal viewport. The tab bar already owns element refs for drag and close behavior, so the focused fix scrolls the active tab into view after activation and refreshes overflow controls on the next frame.
Constraint: Preserve existing tab ordering, drag behavior, and close-button affordances.
Rejected: Reorder new sessions to the left | changes established tab order and makes history harder to scan.
Confidence: high
Scope-risk: narrow
Directive: Keep active-tab visibility behavior in TabBar so all activation paths share it.
Tested: cd desktop && bun run test -- TabBar
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: agent-browser overflow smoke with six tabs confirmed active Untitled Session fullyVisible=true
Not-tested: Full bun run verify gate.
Contributors and coding agents need one local command that both reports and enforces the quality contract. This change turns the PR gate into the shared verification entrypoint, adds path-selected local lanes, tightens coverage accounting around changed lines, and documents the repair loop in contributor and agent-facing guidance.
Constraint: Ordinary PR verification must stay non-live and runnable without provider credentials
Constraint: Coverage policy updates in this commit require maintainer approval before push/merge
Rejected: Keep quality guidance only in docs | agents need executable scripts and AGENTS.md instructions to follow the loop consistently
Confidence: high
Scope-risk: broad
Directive: Do not bypass `bun run verify` for production changes; fix failed lanes and coverage reports instead of lowering thresholds
Tested: bun run check:policy
Tested: ALLOW_CLI_CORE_CHANGE=1 ALLOW_COVERAGE_BASELINE_CHANGE=1 bun run verify
Not-tested: live provider baseline; no provider credentials were required for this non-live PR gate
Desktop terminal access should behave like an IDE: active project sessions open a bottom panel in the session working directory while keeping a full terminal tab available for dedicated use. The panel has constrained resizing and cleanup so session tab state remains isolated, and terminal guidance points users to the bundled claude-haha command for extension setup.
Constraint: Desktop bundles the user-facing CLI as claude-haha while claude-sidecar remains internal
Rejected: Always opening a standalone terminal tab | loses the current project context and diverges from common IDE behavior
Rejected: Exposing claude-sidecar in terminal guidance | it is an internal launcher, not the supportable user command
Confidence: high
Scope-risk: moderate
Directive: Keep bottom terminals keyed by session id and pass session workDir/projectPath into spawned terminals
Tested: bun run check:desktop
Tested: git diff --check
Tested: Computer Use E2E against built macOS app during implementation
Not-tested: bun run quality:pr is blocked by existing branch policy requiring allow-cli-core-change approval
The desktop start screen can already collect a project directory before the first chat turn, but workspace management is intentionally session-scoped. Creating a draft session immediately after project selection keeps the file manager, changed-file view, runtime selection, and terminal toolbar on the same path users see after sending the first message.
Constraint: Workspace file management state is keyed by session id.
Rejected: Add a separate non-session workspace mode | it would duplicate panel state and create a second lifecycle to maintain.
Confidence: high
Scope-risk: narrow
Directive: Keep workspace management session-scoped; create or reuse a session before exposing the workspace panel.
Tested: cd desktop && bun run test -- TabBar.test.tsx EmptySession.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Native Tauri folder dialog manual smoke test.
Expose a workspace inspector for desktop sessions so users can browse the active project, preview files, inspect session-derived changes, and review diffs even when the work directory is not a git repository.
Constraint: The workspace view must work for temporary and non-git project directories.
Rejected: Rely only on git status | non-git sessions would lose the changed-files surface.
Confidence: medium
Scope-risk: moderate
Directive: Keep undo semantics separate from workspace browsing; checkpoint-backed rewind should remain the source of truth for rollback.
Tested: bun test src/server/__tests__/sessions.test.ts src/server/__tests__/workspace-service.test.ts
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx src/stores/workspacePanelStore.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check
Not-tested: Full desktop packaged app build after this commit
The desktop terminal already supported independent PTY sessions, but it only lived inside settings. This change promotes it to a first-class tab workflow so users can open multiple host terminals without leaving the chat-oriented desktop layout.
Constraint: Tauri terminal sessions are process-backed and must stay mounted while switching tabs.
Rejected: Reuse the settings terminal as a navigated page only | it cannot support multiple independent terminal tabs.
Rejected: Hide inactive xterm panes with display none | xterm lost visible output after tab switches during E2E.
Confidence: high
Scope-risk: moderate
Directive: Keep inactive terminal panes mounted and avoid display none unless xterm repaint behavior is reverified.
Tested: bun run test src/components/layout/ContentRouter.test.tsx src/components/layout/Sidebar.test.tsx src/components/layout/TabBar.test.tsx src/pages/TerminalSettings.test.tsx
Tested: bun run lint
Tested: bun run build
Tested: ./scripts/build-macos-arm64.sh
Tested: Computer Use E2E against build-artifacts/macos-arm64 app for multiple terminals, command output retention, tab switching, and terminal cleanup
Not-tested: Intel macOS package
The pointer-drag rewrite left the tab close control without its hover trigger,
so tabs could still be closed logically but no longer exposed the affordance.
This restores the hover group, trims the close icon to a lighter visual weight,
and adds a regression test to keep close-click behavior from colliding with drag.
Constraint: Tab close must remain compatible with the custom pointer-drag reorder flow
Rejected: Reintroduce a larger hoverable close button | made the tab chrome look visually heavy
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the close control visually subordinate to the tab label and verify drag-click interactions before changing tab hit areas
Tested: cd desktop && bun run test -- TabBar; cd desktop && bun run lint
Not-tested: Full desktop app manual visual QA in Tauri runtime
The tab strip was relying on browser drag-and-drop, which worked in the web UI
but did not reliably start inside the macOS overlay title bar in the packaged
Tauri desktop app. This switches tab reordering to a pointer-driven interaction
that computes insertion positions directly, keeps the drag indicator behavior,
and preserves the separate window-drag fallback for non-tab title-bar space.
Constraint: Must work inside the macOS overlay title bar where native window hit-testing interferes with browser drag events
Rejected: Keep tuning draggable/drop handling | web behavior stayed fine while desktop never consistently entered the drag sequence
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep tab reordering on explicit pointer handling unless the title-bar architecture changes away from overlay hit-testing
Tested: bun run test -- src/components/layout/TabBar.test.tsx; bun run lint; bun run build
Not-tested: Manual packaged desktop app verification after this commit
The recent macOS title-bar drag fix marked the entire session tab strip as a
native drag region. That restored window movement in the overlay title area,
but it also intercepted the tab component's own HTML drag events and regressed
manual tab reordering. This narrows the native drag surface to a small gutter
beside the tabs while keeping the explicit empty-space startDragging fallback,
and adds a focused regression test for drag-to-reorder.
Constraint: Must preserve window dragging from non-tab title-bar space on macOS overlay windows
Rejected: Keep the whole tab bar as a drag region | conflicts with tab-level drag-and-drop reordering
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not reapply data-tauri-drag-region to the full tab strip unless tab reordering is redesigned around a different drag mechanism
Tested: bun run test -- src/components/layout/TabBar.test.tsx; bun run lint; bun run build
Not-tested: Manual desktop runtime verification after this commit
The macOS desktop build could lose its draggable gutter on the right side of
the tab bar once multiple session tabs consumed the native overlay title area.
This adds a Tauri window-drag fallback for clicks on the tab strip's empty
space while preserving tab and control interactions, and locks that behavior
with focused regression tests.
Constraint: Must preserve tab clicks, close buttons, and overflow controls while restoring drag behavior
Rejected: Rework the title bar layout around a dedicated spacer | larger UI diff for a narrow hit-testing bug
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep drag fallback limited to true empty gutter hits; do not trigger it from interactive tab descendants
Tested: bun run test src/components/layout/TabBar.test.tsx; bun run lint; bun run build; manual macOS app verification
Not-tested: Windows runtime drag behavior was not manually exercised after this change
Related: #92