This bundles the pending desktop/server team-session fixes with the local adapter recovery changes already in the worktree. The team path now keeps teammate membership stable under concurrent spawns, surfaces real teammate identities in the desktop UI, and allows direct interaction with member transcripts. The adapter changes recover automatically when stale thinking signatures invalidate an existing session.
Constraint: Team config writes can happen concurrently while multiple reviewers spawn in parallel
Constraint: Desktop member views must follow mailbox/transcript semantics rather than hijacking teammate runtime sessions
Rejected: Keep relying on config.json alone for member discovery | in-process teammates can be lost after concurrent writes
Rejected: Open teammate sessionIds as normal desktop sessions | would attach a second CLI instead of the running teammate
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Preserve locked team-file mutation for any future teammate registration path and keep teammate labels sourced from member names before agent types
Tested: bun test src/server/__tests__/teams.test.ts src/server/__tests__/team-watcher.test.ts
Tested: cd desktop && bun run test --run src/stores/chatStore.test.ts src/pages/ActiveSession.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Manual end-to-end validation against a live Agent Teams run in the desktop app
- security: XSS sanitization with DOMPurify in Markdown/Mermaid/PermissionDialog;
path whitelist in filesystem API; fake keys in test/config files
- perf: fine-grained Zustand selectors in Sidebar/StatusBar/ContentRouter;
50ms throttle on streaming deltas; React.memo + useMemo in MessageList;
useRef for frequent keyboard shortcut state; AbortController 30s timeout
- leaks: WS session TTL timers (5-min cleanup on close); batch splice for
sdkMessages/stderrLines; folderPath validation in cronScheduler
- quality: optimistic update rollback in settingsStore; error state in
providerStore/teamStore; i18n for all hardcoded English strings
- docs: desktop architecture and features docs updated; VitePress nav fixed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the default macOS about dialog with a custom menu that emits
a Tauri event, navigating to the Settings > About tab within the React app.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tab drag-and-drop reordering with visual drop indicator
- Add moveTab action to tabStore with localStorage persistence
- Context menu: add "Close Left" and "Close All" options
- Add i18n translations for new menu items (en/zh)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- TabBar: darker background (surface-container), active tab uses top brand
accent + lighter bg, consistent bottom border, draggable empty area
- Settings sidebar width matches TAB_WIDTH (180px) for vertical alignment
- Remove rounded corners and side borders from tabs for cleaner look
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The 38px absolute drag overlay was blocking tab clicks, requiring
padding that created a visible gap. Sidebar already handles its own
drag region, and TabBar uses data-tauri-drag-region directly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move Tauri title bar padding into TabBar instead of main container,
eliminating the double spacing (38px gap + 36px tab bar)
- Remove StatusBar entirely (project/model info already in ChatInput)
- TabBar renders a drag region spacer even when no tabs are open
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Settings and Scheduled Tasks now open as special tabs in the TabBar,
matching IDE conventions (closeable, icon-prefixed, persistent)
- New Session directly creates a session with the current workDir
- ChatInput shows DirectoryPicker before first message, locks after
- Remove connection status from StatusBar (unnecessary noise)
- ContentRouter routes by tab type instead of activeView
- Settings page no longer has a back-button header
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update all components, hooks, and tests to use the new per-session
chatStore API where state is keyed by sessionId under `sessions` and
all action methods require sessionId as the first parameter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add TabBar, useTabStore, useChatStore imports to AppShell
- Restore tabs from localStorage during bootstrap and connect active session
- Render <TabBar /> before <ContentRouter /> in the main content area
- Replace useSessionStore/activeSessionId with useTabStore/activeTabId in ContentRouter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add core🪟allow-start-dragging permission and acceptFirstMouse
config to fix window dragging on macOS with overlay title bar. Also add
JS-based startDragging() fallback in AppShell and Sidebar.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a lightweight custom i18n system supporting English (default)
and Chinese, with a language switcher in Settings > General.
All 35+ UI components internationalized with ~270 translation keys,
including 189 Chinese spinner verbs and server error code mapping.
Shows a warning dialog with the current working directory and a list
of granted capabilities before enabling bypass mode. Dialog is
centered in the content area with a full-screen backdrop.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Tauri sidecar architecture: Rust shell spawns claude-server binary,
dynamic port allocation, health-check wait loop, graceful shutdown
- Fix CORS middleware to accept `tauri://localhost` and `https://tauri.localhost`
origins from Tauri WebView, and add CORS headers to /health endpoint
- Enable native macOS window decorations (traffic lights) with Overlay title bar,
add data-tauri-drag-region on sidebar for window dragging
- Conditionally apply desktop-only padding (44px for traffic lights) vs web (12px)
- Generate brand identity: light-background app icon, horizontal logo, full icon
set (icns/ico/png) for Tauri bundle
- Add brand mark + GitHub link in sidebar, replace mascot SVG with app icon
in EmptySession page
- Update README (zh/en) and docs hero image with new branding
- Add sidecar build scripts and launcher entry points
- Gitignore Rust target/, Tauri gen/, and brand-assets candidates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the separate Tasks sidebar page (wrong concept — was showing
scheduled tasks). Instead, display CLI task progress as a sticky bar
at the bottom of the active session, matching the official desktop app
behavior. Tasks are refreshed in real-time by detecting TaskCreate/
TaskUpdate tool_result messages over WebSocket.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Settings: new Providers tab with full CRUD, activation, and connectivity
test; Model tab shows active provider name; General tab simplified
- Tasks: new CLI Tasks page displaying task lists from ~/.claude/tasks/
with status, owner, and dependency (blocks/blockedBy) visualization
- NewTaskModal: add Advanced options (model, permission mode, working dir)
- Backend: fix TaskService to parse CLI V2 task format; extend /api/tasks
with /lists endpoint for grouped queries
- Fix ModelInfo.context type from number to string
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace project-grouped session list with a flat time-grouped layout
(Today / Yesterday / Last 7 days / Last 30 days / Older) matching
the original Claude Code desktop design. Add ProjectFilter component
with multi-select dropdown for filtering by project. Deduplicate
sessions by ID in the store to fix duplicate-key React errors caused
by the same session appearing across multiple project directories.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The desktop app now keeps the composer stable while turns are active,
reduces low-signal tool noise in the transcript, restores project context
under the composer after session creation, and relies on the CLI's own
permission requests instead of injecting broader desktop-side Bash asks.
This also brings in the supporting desktop app source tree and the server
routes/session metadata needed for git info, filesystem browsing, session
resume, slash commands, and SDK-backed permission bridging so the UI can
operate as a coherent feature instead of a partial patch.
Constraint: Desktop transcript needs to stay usable during long multi-tool sessions without hiding file-change diffs
Constraint: Permission prompts must mirror CLI behavior closely enough that read-only commands do not get desktop-only prompts
Rejected: Keep rendering Read/Bash bodies inline | too noisy and unlike the intended transcript model
Rejected: Commit only the touched desktop files | would leave the newly introduced desktop app incomplete in git history
Confidence: medium
Scope-risk: broad
Reversibility: messy
Directive: Treat non-writing tools as summary-first transcript events; do not re-expand them by default without validating the UX against long sessions
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test -- --run
Tested: bun test src/server/__tests__/conversations.test.ts
Not-tested: Manual visual regression against the exact screenshots in a live desktop session
Not-tested: Full root TypeScript check (repository still has unrelated extracted-native parse failures)