Commit Graph
16 Commits
Author SHA1 Message Date
7418andClaude Opus 4.6 e5a48ca6af feat: migrate icon library from Hugeicons to Phosphor + UI polish
Icon library migration:
- Replace @hugeicons/react with @phosphor-icons/react across 60+ components
  (Phosphor supports 6 weight variants: thin/light/regular/bold/fill/duotone)
- Update apps/site (marketing) to use Phosphor icons
- Remove leftover svg.hugeicons CSS rules from globals.css

UI improvements:
- NavRail: selected tab icons use filled weight, unselected use regular
- User chat bubble: dark bg + white text in light mode, light bg + dark text
  in dark mode (new --user-bubble / --user-bubble-foreground CSS variables)
- Fix expand/collapse icons: use CaretRight (triangle) instead of ArrowRight
  in file-tree.tsx and tool-actions-group.tsx

Lint fixes:
- Fix eslint react-hooks/static-components in CodeBlock, ToolCallBlock,
  tool-actions-group — use createElement() instead of PascalCase variable
- Fix react-hooks/rules-of-hooks in MessageItem — move early return after hooks
- Fix react-hooks/set-state-in-effect in GalleryDetail — use ref pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 11:12:12 +08:00
7418andClaude Opus 4.6 789b453e92 fix: onboarding stability, invalid JSON from hooks, file tree race conditions
Issue 1 — Onboarding re-triggering after completion:
- ChatView.tsx: fence regex now tolerates CRLF, trailing whitespace, leading
  whitespace before closing fence; JSON.parse input trimmed
- ChatView.tsx: hookTriggeredSessionId only cleared when backend returns ok
- assistant-workspace.ts: saveState uses atomic write (tmp + rename)

Issue 2 — "CLI output was not valid JSON" during document reads:
- claude-client.ts: remove all SDK hooks (Notification + PostToolUse) to
  eliminate hook_callback control_request transport that corrupts stdout
- claude-client.ts: TodoWrite sync moved to message stream — tool_use records
  pending input, tool_result emits task_update only on success
- claude-client.ts: notifications derived from system/task_notification and
  result/is_error messages; Telegram forwarding preserved via notifyGeneric

Issue 3 — File tree not updating on project switch:
- FileTree.tsx: AbortController cancels in-flight requests on directory change;
  abort fires before empty-directory early return to prevent stale overwrites;
  error state distinguishes empty dir from load failure; loading always reset
- page.tsx: clear workingDirectory immediately on session switch
- SplitColumn.tsx: clear workingDirectory when active column has no directory

Tests: 9 new tests for fence parsing, atomic write, corrupted state fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:27:54 +08:00
7418andClaude Opus 4.6 4da188bfe5 feat: theme family system with 12 color palettes + NavRail redesign
Theme system:
- Two-layer architecture: mode (light/dark/system via next-themes) + theme family (color palette via CSS variables)
- 12 theme families: Default, GitHub, Rosé Pine, Tokyo Night, Everforest, Nord, Kanagawa, Night Owl, Poimandres, Vesper, Horizon, SynthWave '84
- Per-family code block highlighting for Prism, HLJS, and Shiki (no more generic oneLight/oneDark fallback)
- Anti-FOUC: synchronous script in <head> reads localStorage and sets data-theme-family before paint
- Theme JSON files in themes/ directory, auto-discovered by server-side loader
- OKLCH color space for all values; CSS specificity html[data-theme-family] beats :root

UI changes:
- NavRail: moved Settings to bottom (replacing theme toggle), removed light/dark toggle button
- Settings: merged General controls into one card with dividers; Appearance section with live Shiki code preview
- Replaced hardcoded blue-500/blue-600 with primary/primary-foreground across 19 components
- Appearance settings: pill mode selector (light/dark/system), theme family dropdown, live code preview

New files:
- src/lib/theme/{types,loader,render-css,context,code-themes}.ts — core theme infrastructure
- src/components/layout/ThemeFamilyProvider.tsx — client context provider
- src/components/settings/AppearanceSection.tsx — appearance settings UI
- src/hooks/useAppTheme.ts — combined theme hook
- themes/*.json — 12 theme family definitions
- docs/handover/theme-system.md — handover documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:15:01 +08:00
7418andClaude Opus 4.6 7696cbf5c5 refactor: 右侧面板 Tasks/Files 合并为单视图 + 简化 TaskList
- RightPanel: 移除 Files/Tasks 双 Tab 切换,改为单视图布局
  - 顶部标题改为 TASKS,下方直接渲染 TaskList
  - 中间用 mx-4 非贯通分隔线 + border-border/40 降低视觉强度
  - 分隔线下方增加 FILES 小标题,再接 FileTree
- TaskList: 大幅简化
  - 移除筛选 Tab(全部/进行中/已完成)
  - 移除新增任务输入框
  - 移除 TaskCard 组件引用,改为 checkbox + 标题单行展示
  - 点击切换 completed/pending 状态
  - 勾选框使用 foreground 色(黑/白)替代蓝色
  - 空状态显示"暂无任务"
- bump version to 0.20.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:27:30 +08:00
7418andClaude Opus 4.6 c13ff54638 feat: fix tool call chain and Tasks panel integration
Phase 1: RightPanel Files/Tasks tab toggle
- RightPanel.tsx: add Files/Tasks toggle buttons, conditionally render
  FileTree vs TaskList based on panelContent state
- en.ts/zh.ts: add panel.tasks translation

Phase 2: TodoWrite SDK mapping
- types/index.ts: add source field to TaskItem, add task_update SSE event type
- db.ts: add source column migration, syncSdkTasks() replace-all function
  that syncs SDK TodoWrite output to local tasks table (user tasks untouched)
- claude-client.ts: PostToolUse hook detects TodoWrite tool, emits task_update
  SSE with mapped todo items
- route.ts: collectStreamResponse handles task_update, calls syncSdkTasks()
- useSSEStream.ts: add onTaskUpdate callback and task_update case
- ChatView.tsx: onTaskUpdate dispatches tasks-updated CustomEvent
- TaskList.tsx: listens for tasks-updated event to auto-refresh
- tasks/route.ts: add PUT bulk sync endpoint for testing

Phase 3: tool_result three-layer deduplication
- claude-client.ts: emittedToolResultIds Set prevents PostToolUse and user
  message handler from emitting duplicate tool_result for same tool_use_id
- route.ts: seenToolResultIds Set in collectStreamResponse skips duplicate
  DB writes
- ChatView.tsx: onToolResult checks existing tool_use_id before state update

Phase 4: Agent SDK upgrade
- Upgrade @anthropic-ai/claude-agent-sdk from v0.2.33 to v0.2.62
  (29 versions, zero TypeScript errors, all integration points compatible)

Phase 5: Documentation
- docs/agent-tooling-todo-bridge.md: architecture overview, TodoWrite field
  mapping, status mapping, idempotency strategy, three-layer dedup, SSE event
  types, troubleshooting guide
- CLAUDE.md: add Architecture Docs section with reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:12:59 +08:00
7418 00d3fef5a4 feat: refactor image generation to bypass model dependency, fix UI issues
Image Generation Refactor:
- MessageInput: add onImageGenerate callback, remove skill fetch dependency
- ChatView: implement handleImageGenerate that creates image-gen-request
  message for ImageGenConfirmation UI, then user selects params and generates
- New API route POST /api/chat/messages for DB-only message persistence
- image-gen-completed event now only persists notice to DB, no longer triggers model
- Reference images passed via module-level Map (imageGenRefStore) to avoid
  DB bloat from base64 data; user message DB content stores metadata only

Bug Fixes:
- Fix useCallback dependency missing imageGen causing stale closure reads
- Fix React Hooks order violation in MessageItem (early return before hooks)
- Fix localStorage cache collision across sessions (key now includes sessionId)
- Fix empty src attribute in FileAttachmentDisplay for DB-restored messages
- Add JSON parse fallback for malformed image-gen-request blocks

Gallery Reference Images:
- /api/media/generate saves reference images to disk, stores paths in metadata
- /api/media/gallery extracts referenceImages from metadata in mapRow
- GalleryDetail displays reference image thumbnails
- ImageGenCard supports referenceImages prop for chat display

UI Changes:
- ImageGenToggle: replace paint brush icon with text label (en: Image, zh: 生图)
- Model selector button: remove provider name display to save space
- ImageGenConfirmation: support referenceImagesData prop for base64 preview

i18n:
- Add imageGen.toggleLabel key (en: Image, zh: 生图)
2026-02-26 21:07:48 +08:00
7418 c7c3ba5302 feat: v0.13.0 — add i18n support with Chinese/English translations
Implements a zero-dependency i18n framework with TypeScript type safety.
Thanks to @gy212 for the original i18n infrastructure design (PR #89)
and comprehensive translation files (PR #90-96) that inspired this implementation.

## New files (5)

- src/i18n/en.ts: English translations (source of truth, ~270 keys),
  exports TranslationKey type for compile-time key completeness
- src/i18n/zh.ts: Chinese translations, typed as Record<TranslationKey, string>
- src/i18n/index.ts: translate() function with {param} interpolation,
  Locale type, SUPPORTED_LOCALES array
- src/components/layout/I18nProvider.tsx: React Context provider,
  loads/persists locale preference via /api/settings/app
- src/hooks/useTranslation.ts: useTranslation() hook returning
  { locale, setLocale, t }

## Infrastructure wiring

- src/app/layout.tsx: I18nProvider wrapped inside ThemeProvider
- src/app/api/settings/app/route.ts: added "locale" to ALLOWED_KEYS
  for persistence

## Language picker

- src/components/settings/GeneralSection.tsx: added language selection
  dropdown (Select component) in Settings > General, using
  SUPPORTED_LOCALES and setLocale()

## String replacements (33 component files)

All hardcoded user-facing strings replaced with t() calls:

High priority (chat):
- ChatListPanel.tsx: session list, search, empty state, relative time
- NavRail.tsx: nav labels, theme toggle, auto-approve indicator
- MessageInput.tsx: command descriptions, mode labels, attach tooltip
- MessageList.tsx: empty state, load earlier, loading indicator
- StreamingMessage.tsx: thinking, permission actions
- chat/[id]/page.tsx: session title fallback

Settings:
- GeneralSection.tsx: update card, auto-approve section, warning dialog
- SettingsLayout.tsx: title, description, sidebar labels
- CliSettingsSection.tsx: form/json tabs, buttons, dynamic field labels
  (skipDangerousModePermissionPrompt etc.), Enabled/Disabled states
- ProviderForm.tsx: dialog title, form labels, buttons
- ProviderManager.tsx: status badges, delete dialog, section headers

Extensions:
- extensions/page.tsx: title, tab labels
- SkillsManager.tsx: empty state, loading, search
- SkillEditor.tsx: toolbar buttons, placeholder
- SkillListItem.tsx: delete confirmation
- CreateSkillDialog.tsx: form labels, scope, templates, validation

Plugins:
- McpManager.tsx: header, tabs, loading state
- McpServerList.tsx: empty state, badges, field labels
- McpServerEditor.tsx: dialog title, form labels, buttons
- ConfigEditor.tsx: save/format buttons

Layout:
- RightPanel.tsx: panel header, open/close tooltips
- FileTree.tsx: search placeholder, empty states
- FilePreview.tsx: back button, line count, copy path
- DocPreview.tsx: iframe title
- ConnectionStatus.tsx: install prompts, version display
- InstallWizard.tsx: phase descriptions, button labels
- ImportSessionDialog.tsx: search, relative time, import buttons
- FolderPicker.tsx: dialog title, loading, buttons
- TaskList.tsx: filter tabs, input placeholder, empty states
2026-02-24 16:50:57 +08:00
7418 9e7ccfefaa feat: v0.12.0 — fix streaming tool UI persistence, file tree UX improvements, unify icon library
Streaming tool UI fix (ChatView.tsx):
- Add toolUsesRef/toolResultsRef to reliably track tool data across closures
- Serialize tool_use/tool_result into JSON content-blocks array when building
  assistant message after stream ends, matching backend storage format
- MessageItem.parseToolBlocks() now renders tool UI from history messages
- Clean up refs in finally block and timeout auto-retry path

File tree UX (FileTree.tsx, file-tree.tsx):
- Remove folder path header from right panel, merge search + refresh into one row
- Remove file icon spacer (size-5) so file icons align flush with search box
- Change folder icon color from blue to muted-foreground

Chat list panel (ChatListPanel.tsx):
- Folder header: expanded uses FolderOpenIcon, collapsed uses Folder01Icon
- Add tooltip showing full working directory path on folder hover
- Double-click folder header opens in system file manager

Title bar folder name (chat/[id]/page.tsx):
- Add tooltip with full path on project name hover
- Click opens folder in Finder/Explorer via Electron IPC or API fallback

Open folder support:
- electron/main.ts: add shell:open-path IPC handler via shell.openPath
- electron/preload.ts: expose electronAPI.shell.openPath to renderer
- api/files/open/route.ts: fallback API route using open/explorer/xdg-open

Unify icon library — migrate app-level components from Lucide to Hugeicons:
- file-tree.tsx: folder, file, chevron, plus icons
- tool-actions-group.tsx: chevron expand icon
- MessageItem.tsx: copy, check, expand/collapse icons
- MessageInput.tsx: stop button (SquareIcon → StopIcon)
- FileCard.tsx: file icon
- ImageLightbox.tsx: left/right navigation arrows
- InstallWizard.tsx: status icons (check, x, minus, loader, circle, copy, download)
- Keep Lucide in ui/ and ai-elements/ base layers (shadcn standard)
2026-02-24 12:32:03 +08:00
7418 9c13f043d0 feat: v0.11.0 — SDK settingSources, nested session fix, dynamic models, UX improvements
Core fixes:
- Add settingSources to SDK options so CodePilot loads user/project settings
  like the CLI (fixes WebFetch timeouts, tool permission issues)
- Delete CLAUDECODE env var to prevent nested session detection when
  CodePilot runs alongside Claude Code CLI (fixes 'exited with code 1')
- Remove manual MCP config reading (SDK handles it via settingSources)
- Remove hardcoded timeout env vars (SDK loads from user settings)

UX improvements:
- Remember last selected model across sessions (localStorage)
- Same-project new chat skips directory picker
- File tree auto-refreshes on project switch and after each tool completes
- Left sidebar projects default collapsed (only most recent expanded)
- Right-side file tree defaults collapsed
- Fix file tree icon alignment (spacer size-4 → size-5)
- Dynamic model list from /api/providers/models endpoint
- Provider change dispatches event to refresh model selector
- Improved error messages with provider name and troubleshooting hints
- Fix context button file type matching for extension patterns
- Default tool timeout 120s → 300s
2026-02-24 03:08:17 +08:00
7418andClaude Opus 4.6 8f963ed2a9 fix: pass baseDir to file preview API to fix Windows cross-drive 403
FilePreview and DocPreview components were not passing baseDir to
the preview API, causing 403 "File is outside the allowed scope"
on Windows when the project is on a different drive than home.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:13:06 +08:00
7418andClaude Opus 4.6 d446da9717 fix: allow file tree access on Windows cross-drive project paths
FileTree component was not passing baseDir to the file API, causing
it to fall back to restricting access to the home directory. On
Windows, projects on a different drive (e.g., D:\) were blocked
with 403.

Changes:
- FileTree now passes workingDirectory as baseDir parameter
- File API routes no longer require baseDir to be under homeDir
  (allows cross-drive access on Windows)
- Still prevents using filesystem root as baseDir for safety
- Add isRootPath() utility for root path detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:33:06 +08:00
7418andClaude Opus 4.6 ae8a905581 feat: inline title editing, simplify right panel, polish input toolbar
- Add inline title editing in chat header (hover to reveal pencil icon,
  click to edit, Enter/Blur to save, Escape to cancel)
- Simplify right panel: remove Name section, rename header to "Files"
- Align top headers across all three columns (left/center/right)
- Remove folder picker from message input (project already set via sidebar)
- Change attachment icon from paperclip to plus sign
- Remove icon from mode selector, move model selector next to mode selector
- Fix FileTree search icon alignment and left padding consistency
- Add background to chat list delete button to prevent text overlap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:23:36 +08:00
7418andClaude Opus 4.6 d199cbec6c fix: file tree height cut off at half panel — fill remaining space
Remove hardcoded max-h-[400px] on tree content area. Convert the
right panel body and Files section to flex column layout so the
file tree expands to fill all available vertical space.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:33:06 +08:00
7418andClaude Opus 4.6 38ca38e3cb fix: auto-refresh file tree after AI finishes streaming
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 01:31:48 +08:00
7418andClaude Opus 4.6 4fa26032a4 feat: tool timeout auto-retry, file tree attachment, force stop button
- Add configurable tool timeout with auto-retry: when a tool exceeds the
  timeout threshold, abort and send a follow-up message asking Claude to
  try a different approach
- Add "+" button on file tree items to attach files directly to chat
  input via new /api/files/raw endpoint and custom event bridge
- Add force stop button in streaming status bar when tool runs >90s,
  with warning indicators at 60s
- Improve doc preview markdown rendering (padding, list indentation)
- Bump version to 0.10.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:33:21 +08:00
7418andClaude Opus 4.6 ff1fb38735 feat: CodePilot - desktop GUI for Claude Code
Full-featured desktop application built with Next.js + Electron:
- Streaming chat with Claude Code via Agent SDK
- Session management with SQLite persistence
- Project file tree and file preview
- MCP server and custom skills management
- Permission controls with Code/Plan/Ask modes
- Dark/light theme, token tracking
- macOS DMG packaging with electron-builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:04:05 +08:00