Feat: sub-agent chat view and others#10
Open
SunZhiC wants to merge 36 commits into
Open
Conversation
SunZhiC
commented
Feb 1, 2026
- Added sub-agent chat view
- One-click copy everything as Markdown
- Delete a session
- Check how many messages are in a session
Remove session entries from ~/.claude/history.jsonl via a DELETE API endpoint and a trash icon that replaces the timestamp on hover in the sidebar. Conversation data files are kept intact for reversibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add backend API and UI for searching conversation content:
Backend (api/storage.ts):
- Add SearchResult and SearchMatch interfaces
- Implement extractTextFromContent() to recursively extract text from ContentBlock arrays
- Implement extractMessageText() to get searchable text from messages
- Implement createSnippet() to generate context snippets with highlighted matches
- Implement searchConversations() to search all session files in parallel
Backend (api/server.ts):
- Add POST /api/search endpoint accepting { query: string }
- Returns array of SearchResult with matching sessions and snippets
Frontend (web/components/session-list.tsx):
- Add search mode toggle (Title / Content)
- Implement debounced search (300ms) for content mode
- Display search results with match count and highlighted snippets
- Update placeholder text based on search mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add button to export conversation as Markdown with preview modal: Frontend (web/components/markdown-export.tsx): - New component to generate Markdown from conversation messages - Extracts text from message content blocks (text, thinking) - Handles code blocks and escapes special Markdown characters - Shows preview modal with copy-to-clipboard functionality - Displays truncated preview (first 30 lines) with full copy option Frontend (web/components/session-view.tsx): - Integrate MarkdownExportButton in header next to summary - Pass session info and messages to export component Dependencies: - Add @notionhq/client ^5.9.0 (for future Notion integration) - Add zod ^4.3.6 for validation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When hovering over a session item, the delete button appears and replaces the timestamp. The button's padding caused the row height to change slightly. Changes: - Use 'invisible' instead of 'hidden' for timestamp to preserve layout - Add fixed h-4 height to timestamp container - Remove p-0.5 from delete button, use fixed h-4 w-4 instead This ensures the item height remains constant during hover. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add message count to session items for better context about conversation size: Backend (api/storage.ts): - Add messageCount field to Session interface - Add countSessionMessages() to count user/assistant messages - Update getSessions() to include message count for each session Frontend (web/components/session-list.tsx): - Display message count next to timestamp (e.g., "2m · 12 msgs") - Shows on both hover and non-hover states - Consistent h-4 height for stable layout Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Parse progress messages from parent session JSONL to map Task tool_use blocks to their sub-agent conversation files, then lazy-load and render nested conversations inline with colored borders by agent type. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add token usage aggregation (base input, 5m/1h cache writes, cache reads, output) with Opus 4.6 pricing and display in session view header. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add inline session rename with edit/save/cancel in header - Display model provider badges (Claude, Kimi, GLM, etc.) in session list and message blocks - Add getProviderInfo utility for model-to-provider mapping Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show session start time as "YYYY-MM-DD HH:mm" instead of relative format like "2h", "3d". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add sessionMetaCache to avoid re-reading session files on every getSessions() call. Parallelize countSessionMessages with Promise.all instead of sequential awaits. Cache is invalidated per-session when the file watcher detects changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add provider adapter pattern to support browsing conversation history from Claude Code, Codex CLI/Desktop, and Gemini CLI in a unified UI. Backend: - ProviderAdapter interface and ProviderManager with auto-detection - CodexAdapter: reads ~/.codex/ JSONL sessions, maps originator to surface (cli/tui/app/exec), extracts model from turn_context - GeminiAdapter: reads ~/.gemini/ JSON sessions, prefers displayContent over content for user messages, message-index-based streaming - Provider guards: delete/rename return 400 for non-Claude sessions - Watcher: addWatchTarget() for non-Claude file watching with emitSessionChange/emitHistoryChange helpers - Lazy rescan: new sessions picked up on next getSessions() call Frontend: - Provider filter dropdown (shown when >1 provider detected) - CLI provider badges (Codex/Gemini) in session list - Model name shown in session metadata (e.g. gpt-5.3-codex) - Token display: Claude=costs, Gemini=counts only, Codex=hidden - Resume: claude→claude --resume, codex→codex resume, gemini→hidden - Delete button Claude-only, rename Claude-only - Codex/Gemini tool icons (exec_command, read_file, replace, write_file) - Provider-aware markdown export assistant labels Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix double-counting bug where OpenAI's input_tokens (which includes cached tokens) was charged at full price AND cached tokens were charged again at cacheRead price. Now subtracts cached from input to align with Claude's additive token semantics. Update all OpenAI/Codex model prices from official pricing page — fix incorrect cacheRead values (o3, o3-mini, gpt-4.1 series), correct codex-mini and gpt-5.3-codex prices, add cacheRead to all models that support it, and add missing models (gpt-5.4-nano, gpt-4o, o1, etc). Hide token pricing bar for sessions with unknown models (e.g. Kimi) where findPricing returns undefined. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…fallback - findPricing: use longest prefix match so "gpt-5.1-codex-mini-20260301" correctly resolves to Codex Mini instead of GPT-5.1 (up to 12x price error) - Codex adapter: reasoning_output_tokens is a subset of output_tokens, not additive — remove the double-counting - Claude storage: when cache_creation TTL breakdown is missing, default to 5m (older API predates 1h TTL) instead of assuming 1h Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all pricing logic to backend adapters so each provider computes costs during getSessionMeta(). SessionMeta now includes a `costs` field with pre-calculated dollar amounts per token category. Key changes: - Add calculateSessionCosts() for per-turn cost calculation with long-context pricing detection (>200K input tokens per turn) - Claude and Gemini adapters collect per-turn TurnUsage[] and detect long-context pricing; Codex uses aggregate calculation (per-turn data unavailable) - Frontend TokenUsageBar/GenericTokenUsageBar simplified to pure display — no more findPricing() import or client-side cost math - Effective $/MTok rate derived from cost/count for display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Scale cache read/write prices by longContextInput/input ratio when a turn exceeds 200K tokens, so >200K sessions are no longer under-billed - Change has_long_context from boolean to boolean|null — Codex returns null (unknown) instead of a misleading false - Add vitest with 12 regression tests covering findPricing longest prefix match, long-context cache pricing, mixed turn billing, and Codex aggregate cost semantics Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Anthropic confirms Opus 4.6 and Sonnet 4.6 include the full 1M context window at standard pricing — no >200K surcharge. The longContextInput and longContextOutput fields were incorrectly copied from Sonnet 4.5. Long-context pricing remains correctly configured for Sonnet 4.5 and Sonnet 4.0 which do have the >200K surcharge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d provider fetch retry - Add provider field to SearchResult and tag results in ProviderManager - Show provider badge in content search results - Fall back to CLI provider badge for Claude sessions without model info - Allow deleting sessions whose conversation file no longer exists on disk - Retry /api/providers fetch on failure to handle dev server startup race Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sessions on disk but not in history.jsonl (e.g. subagent sessions) were invisible to search and could not be loaded when clicked. Add a resolve endpoint and fallback lookups so orphan sessions can be found by session ID in both Title and Content search, and render correctly when selected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sessions on disk but not in history.jsonl (e.g. sysmon project) were invisible in the session list. Now getSessions() scans fileIndex for orphan sessions and includes them with display text from the first message. Also updates getProjects() to include projects that only have orphan sessions, and extracts shared decodeProjectDir() helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the plain <select> dropdown with a custom ProjectPicker component that sorts projects by session count (descending) and includes a search input for quick filtering. Counts update based on the selected provider. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.