- 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>
Remove .claude/ and docs/superpowers/ from git tracking as they are
local-only config and planning files. Also remove stale screenshots
and update docs/channel content.
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>
Both components now look up state via activeTabId from useTabStore,
reading from sessions[activeTabId] in chatStore. Action calls
(sendMessage, stopGeneration) pass the sessionId as first argument.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add useTabStore.openTab call after session creation so new sessions are
registered as tabs, and update sendMessage to pass sessionId as first arg.
Co-Authored-By: Claude Sonnet 4.6 <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>
The desktop chat view flattened Agent tool activity, which made sub-agent work
hard to follow and separated key evidence from the main conversation. This
change threads parent tool linkage through the server bridge and desktop store,
renders dispatched sub-agents as grouped cards with nested tool activity, and
moves long final outputs into a markdown preview dialog so the main transcript
stays readable on narrow layouts.
Constraint: Existing sessions and live websocket events both needed to preserve parent-child relationships
Rejected: Add brand-new subagent websocket event types | unnecessary protocol expansion when parent linkage already existed upstream
Rejected: Inline full sub-agent markdown in the card body | too cramped for narrow desktop chat layouts
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep Agent card summaries compact; route long-form sub-agent output through the preview dialog unless the main chat layout is widened substantially
Tested: cd desktop && bun run test -- MessageList.test.tsx chatStore.test.ts
Tested: cd desktop && bun run lint
Tested: bun test src/server/__tests__/sessions.test.ts -t should\ reconstruct\ parent\ agent\ tool\ linkage\ from\ parentUuid\ chains
Not-tested: Full end-to-end visual verification against live CLI sessions with sub-agent text/thinking nested inline
The session view exposed copy affordances in a way that implied the
whole conversation would be copied, while user prompts had no copy
path at all. This changes copy to a per-message footer action so the
scope is explicit for both prompts and assistant replies, and reuses
the shared clipboard helper instead of maintaining a second copy path.
Constraint: The worktree contains unrelated in-progress changes that must stay uncommitted
Rejected: Keep a floating action above each message | it interrupted reading order and still looked session-scoped
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep copy affordances attached to individual message blocks so the copied scope stays obvious
Tested: bun run test src/components/chat/MessageList.test.tsx; bun run lint
Not-tested: Manual desktop visual QA across dense multi-message sessions
Previously, creating a new session without selecting a project directory
defaulted to process.cwd(), which in the desktop app resolves to the app
installation path. Now it defaults to os.homedir().
Co-Authored-By: Claude Opus 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>
Use rejection sampling to ensure uniform distribution across the
safe alphabet. Values >= 232 are rejected and resampled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After the first assistant response, derive a quick placeholder title from
the user message, then asynchronously call the provider's Haiku model to
generate a polished 3-7 word title. Titles update again at message 3 with
fuller conversation context. Updates push to frontend in real-time via
WebSocket `session_title_updated` event.
- extractTitle now reads `ai-title` JSONL entries (priority: custom > ai > first message)
- New titleService with deriveTitle + generateTitle using active provider config
- Handler tracks per-session message count and triggers generation on result
- Frontend sessionStore receives live title updates for sidebar + header
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implement IM adapters allowing users to chat with Claude Code from Telegram
and Feishu/Lark. Includes persistent session management (chatId→sessionId
mapping), project selection via /projects command, and a web UI settings page
for configuring bot tokens, allowed users, and default project directory.
Key changes:
- adapters/: Telegram and Feishu adapter scripts with shared common modules
(WsBridge, MessageBuffer, SessionStore, HttpClient, config, formatting)
- Backend: adapterService + REST API (GET/PUT /api/adapters) with secret masking
- Frontend: AdapterSettings page in Settings tab with i18n support
- DirectoryPicker: use React Portal for dropdown to fix overflow clipping
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 7 frequency modes (every N min/hours, daily, weekdays, specific days, monthly, custom cron) with progressive disclosure UI
- Add "Run Now" button with confirmation popover and fire-and-forget API
- Add execution logs panel (TaskRunsPanel) with auto-polling and accordion behavior
- Add task edit mode with cron reverse-parsing (parseCron) to populate form
- Add server-side extractAssistantText to store meaningful AI responses instead of raw NDJSON
- Fix session linking: pass --session-id to CLI subprocess so "View conversation" navigates to actual content
- Fix MACRO undefined error by adding --preload to Bun.spawn
- Add confirmation popovers for all destructive actions (run/disable/delete)
- Add DayOfWeekPicker component for specific-days scheduling
- Add cronDescribe utility with i18n support and unit tests
- Display task creation time and last run time
- Add ~50 i18n keys (en/zh) for all new UI elements
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace Google Fonts CDN links with locally hosted woff2 files to avoid
FOUT/FOIT on slow networks and ensure the app works in regions where
Google is blocked. Material Symbols uses font-display: block to prevent
raw icon text from flashing on load.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix FileSearchMenu and slash command popups appearing incorrectly in
EmptySession by adding relative positioning to container and absolute
positioning to slash menu. Prevent IME composition Enter from triggering
message send in both ChatInput and EmptySession.
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.
Refactor PermissionModeSelector and ModelSelector to support controlled
(prop-driven) mode alongside the existing store-driven mode, enabling
reuse in the new task creation dialog. Rewrite NewTaskModal with embedded
prompt editor that combines textarea + permission/model/folder controls,
matching Claude's original design. Add desktop-online warning banner on
the scheduled tasks list page and default folder to current session workDir.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace prism-react-renderer with shiki/react-shiki in CodeViewer for
dramatically better tokenization (50+ TextMate scopes vs ~15 Prism tokens).
Custom warm-code theme with improved comment contrast (#5C6B7A, ~5:1 ratio)
and warm off-white background (#FDFCF9). Update DiffViewer to use matching
warm color palette with CSS variables instead of hardcoded GitHub colors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Input @ in composer to open file search popup showing project root
- Filter files/directories by typing, navigate with keyboard or mouse
- Click directory to enter subdirectory, type / to navigate deeper
- Enter selects item and inserts path text at cursor, popup closes
- Parse filter path (e.g. @src/components/) to auto-navigate and search
- Desktop: filesystem browse/search API supports includeFiles and search
- Web: directory tree browser with real-time search filtering
When all tasks were completed and the user continued chatting, the inline
task summary was shown correctly. But on page refresh, loadHistory and
fetchSessionTasks would re-populate the task store, making the sticky bar
reappear.
- Add completedAndDismissed flag to cliTaskStore
- Detect user messages after last task tool call in history (V1 + V2)
- SessionTaskBar skips render when allCompleted && completedAndDismissed
- refreshTasks/setTasksFromTodos reset the flag for new task activity
- Fix InlineTaskSummary width to match parent container
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CLI subprocess runs in --print (non-interactive) mode, which disabled
V2 task tools (TaskCreate/TaskUpdate). Only TodoWrite was available, but
the frontend only tracked V2 tool names for task refresh — so the Tasks
bar never appeared for new WebApp sessions.
Changes:
- Set CLAUDE_CODE_ENABLE_TASKS=1 in CLI subprocess env to enable V2 tasks
- Add TodoWrite to TASK_TOOL_NAMES for backward compat with V1 sessions
- Parse TodoWrite input.todos directly into TaskBar state (no disk read)
- Extract last TodoWrite from history on session load for V1 sessions
- Inline completed task summary into message flow when user continues chat
(sticky TaskBar converts to scrollable inline summary)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
DirectoryPicker now detects runtime environment:
- Tauri desktop: opens native OS folder picker via @tauri-apps/plugin-dialog
- Web browser: falls back to backend API directory tree browser
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>
- Official provider shown as fixed card in provider list (click to activate)
- Add Provider modal conditionally rendered — state resets on close (fixes API key leak)
- Remove official from preset chips (not applicable to Add flow)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Official preset shows Name, Notes, and full settings.json editor
- Non-official presets show Base URL, API Key, Model Mapping, Test, plus settings.json
- Settings JSON re-loads when switching presets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>