Commit Graph
75 Commits
Author SHA1 Message Date
7418andClaude Opus 4.6 c0e96bd1aa fix: resolve spawn EINVAL on Windows — filter undefined env values and skip .cmd wrappers
Two root causes of spawn EINVAL on Windows:

1. process.env spread can include undefined values. Windows
   child_process.spawn requires all env values to be strings.
   sanitizeEnv now builds a clean object, dropping non-string entries.

2. Claude CLI installed via npm creates .cmd wrappers that cannot be
   spawned without shell:true. Detect .cmd/.bat extensions and fall
   back to SDK's internal resolution instead.

Bump version to 0.10.7.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:48:59 +08:00
7418andClaude Opus 4.6 83a0109af1 fix: sanitize env variables to prevent spawn EINVAL with third-party API providers
Strip null bytes and control characters from environment variable values
before passing them to child_process.spawn via the SDK. Third-party
Anthropic API providers could introduce invalid characters through
api_key, base_url, or extra_env, causing spawn EINVAL errors.

Bump version to 0.10.6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:01:22 +08:00
7418andClaude Opus 4.6 916b8889b7 fix: require valid project directory for session creation
- Backend: POST /api/chat/sessions now validates working_directory
  exists (400 MISSING_DIRECTORY / INVALID_DIRECTORY)
- db.ts: remove process.cwd() fallback in createSession
- ChatListPanel: validate last-working-directory before use,
  open FolderPicker when invalid; add SSR guard for localStorage
- NewChatPage: block sending without a project directory selected

Bump version to 0.10.5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:37:51 +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 5a57098ffd feat: group chat sidebar by project folder with collapsible sections
Restructure the chat list panel to group sessions by working directory
(project folder), similar to Codex App. Each project folder is shown as
a collapsible section with a folder icon and project name. Features:

- Sessions grouped by working_directory, sorted by most recent activity
- Collapsible folder sections with persistent state in localStorage
- Per-folder "+" button to create new chat in that project
- "Open project folder" button in sidebar header with FolderPicker dialog
- NavRail new-chat button creates sessions in most recent project
- Chat header shows "projectName / sessionTitle" breadcrumb
- Search filters both folder names and session titles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:46:50 +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 572bd355f8 fix: require explicit user confirmation before install, cancel on close, tree-kill on Windows
P0: Add "confirm" phase — wizard checks prereqs then shows Install button,
    user must explicitly click before any brew/winget/npm command runs.
P1: Closing the wizard dialog while install is running now auto-calls
    install:cancel to stop the backend process.
P2: On Windows, use taskkill /T /F /PID to kill the entire process tree
    instead of just the shell wrapper, ensuring npm/winget actually stops.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:51:15 +08:00
7418andClaude Opus 4.6 51d4906c77 fix: address Codex review — Node auto-install, first-launch prompt, IPC consistency
P1: When Node.js is missing, auto-install via brew (macOS) or winget (Windows)
    instead of stopping and asking user to install manually.
P1: Auto-open install wizard on first disconnect detection in Electron,
    with localStorage flag to avoid re-prompting after dismissal.
P2: IPC install:start now throws on concurrent calls instead of returning
    silent { error } object. Removed unused return values from handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:33:54 +08:00
7418andClaude Opus 4.6 e4b917172c feat: add one-click Claude Code install wizard
Add an auto-install wizard accessible from the ConnectionStatus dialog
when Claude Code CLI is not detected (Electron only).

- Electron main: install orchestrator with IPC handlers for check/start/cancel
- Preload: expose install API via contextBridge
- InstallWizard: multi-step dialog with real-time log streaming
- ConnectionStatus: add "Install Automatically" button when disconnected

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:29:39 +08:00
7418andClaude Opus 4.6 23d05cabe1 fix: file tree attachment fails on non-home paths in packaged app
- Remove homedir-only restriction from /api/files/raw (desktop app
  doesn't need this sandbox, projects can be anywhere)
- Add console.warn on fetch failure instead of silent swallow
- Fix filename extraction for Windows backslash paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:01:54 +08:00
7418andClaude Opus 4.6 ccd687c8f5 fix: don't cache "not found" binary result, use ref lock for pagination
- platform.ts: only cache positive findClaudeBinary results so a fresh
  CLI install is detected immediately on next check
- ChatView.tsx: use useRef as atomic lock to prevent double-fetch from
  rapid clicks on "Load earlier messages"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:34:36 +08:00
7418andClaude Opus 4.6 9b166be8d6 fix: resolve 25 error-level lint issues (P1-3)
Fix no-require-imports, no-explicit-any, no-html-link-for-pages,
set-state-in-effect, purity, static-components, and refs rules
across 15 files. 0 errors remain (52 warnings unchanged).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:51 +08:00
7418andClaude Opus 4.6 e86f0cfd8f perf: optimize polling with caching and event-driven approach (P1-2)
- CLI binary detection cached with 60s TTL
- Settings poll replaced with visibility/focus events
- Health check uses adaptive backoff (30s → 60s when stable)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:43 +08:00
7418andClaude Opus 4.6 a5805cb380 refactor: extract SSE parsing into shared consumeSSEStream (P1-1)
Deduplicate 150-line inline SSE parsing from ChatView into a reusable
hook. ChatView reduced from 594 to 490 lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:35 +08:00
7418andClaude Opus 4.6 af2830db9b feat: add cursor-based message pagination (P0-3)
Backend returns paginated messages with hasMore flag. Frontend shows
"Load earlier messages" button with scroll anchor preservation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:27 +08:00
7418andClaude Opus 4.6 128ccf951c perf: convert sync file I/O to async in API routes (P0-2)
Replace all readFileSync/existsSync/readdirSync with fs.promises
equivalents to unblock the Node event loop under concurrency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:21 +08:00
7418andClaude Opus 4.6 f3c49a9e49 fix: deduplicate attachment file writes (P0-1)
Upload route now passes persisted filePath to claude-client, which
reuses it instead of writing the file again.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:24:12 +08:00
7418andClaude Opus 4.6 b22788920b fix: file tree folder — separate toggle trigger from row, remove unused select
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 21:49:05 +08:00
7418andClaude Opus 4.6 d5b1d6eb9d feat: redesign settings page with sidebar navigation
Extract settings into General / Providers / Claude CLI sections with
a left sidebar layout. Keep Skills and MCP on the Extensions page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:28:29 +08:00
7418andClaude Opus 4.6 a5cff792e3 fix: read MCP servers from both ~/.claude.json and ~/.claude/settings.json
Claude CLI stores user-scoped MCP servers in ~/.claude.json, while
CodePilot was only reading from ~/.claude/settings.json. Now both
the MCP list API and streamClaude merge configs from both sources.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:28:56 +08:00
7418andClaude Opus 4.6 d3a7fd745e fix: file tree attachment bridge stale closure — use ref for attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:12:40 +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 695daa60e1 fix: allow typing in input while AI is streaming, only block sending
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 01:29:13 +08:00
7418andClaude Opus 4.6 25abfb5404 fix: show "generating response" status when tools completed but AI still streaming
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 01:25:47 +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 8747464c2f fix: doc preview bugs — close on chat switch, copy content, filter binary files
- Close doc preview when switching between chats (pathname change)
- Copy button now copies file content instead of file path
- Skip preview for images, videos, audio, archives, and other binary files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:26:29 +08:00
7418andClaude Opus 4.6 8c6e7bba5b feat: add doc preview panel for HTML and Markdown files
Click files in the file tree to open a dedicated preview panel with
source/rendered toggle for .md/.mdx/.html/.htm files. Preview panel
supports drag-to-resize (320–800px) with localStorage persistence.

Bump version to 0.9.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 13:50:21 +08:00
7418andClaude Opus 4.6 da07f1bd1b feat: draggable panel resize handles and remove extensions divider
Add ResizeHandle component for drag-to-resize side panels.
ChatListPanel (180–400px) and RightPanel (200–480px) widths
are persisted via localStorage. Also remove the border line
below the Extensions page tab selector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:57:37 +08:00
7418andClaude Opus 4.6 7b64948cb4 feat: compact collapsible tool actions UI
Replace full-card tool rendering with a compact, collapsible group.
Each tool action is a single line with category icon, summary, and
status indicator. Collapsed by default for history, auto-expands
during streaming. Uses blockquote-style left border when expanded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:09:20 +08:00
7418andClaude Opus 4.6 74fb784f6d feat: auto update check and dangerously-skip-permissions mode
Add automatic update detection (checks GitHub Releases every 8h with
dialog prompt and blue dot on Settings icon) and a skip-permissions
toggle in Settings that uses the SDK's native bypassPermissions mode
to auto-approve all tool actions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:14:42 +08:00
7418andClaude Opus 4.6 e4bbe8578a fix: persist file attachments so images/documents survive page reload
Previously uploaded files were only held in memory (optimistic message)
and lost when navigating away. Now:
- API route saves all uploaded files to .codepilot-uploads/ on disk
- File metadata (with filePath, not base64) is embedded in message content
- New /api/uploads endpoint serves persisted files
- FileAttachmentDisplay handles both base64 (in-memory) and filePath (DB)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:02:34 +08:00
7418andClaude Opus 4.6 183860587f fix: send images as multimodal vision content instead of file path references
Images were being saved to disk and referenced by text path in the prompt,
causing Claude to hallucinate about image contents since it never actually
saw the image data. Now images are sent as base64 content blocks via the
SDK's multimodal SDKUserMessage, enabling Claude's vision capability.
Non-image files continue to be saved to disk for Read tool access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 20:51:23 +08:00
7418andClaude Opus 4.6 9635585ab6 feat: blue theme migration and chat input UI polish
- Migrate purple/violet theme to blue across entire codebase (globals.css,
  ToolCallBlock, ChatListPanel, SkillEditor, SkillListItem, e2e tests)
- Increase input box border radius (rounded-md → rounded-2xl) and shadow
- Add arrow flip animation on mode/model selector dropdowns
- Change send button to circular with up-arrow icon
- Increase global Hugeicons stroke weight (1.5 → 2)
- Remove theme-colored focus ring on input box

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:48:06 +08:00
7418andClaude Opus 4.6 ee65c62d62 feat: collapse long user messages with expand/collapse toggle (#37)
User messages exceeding 300px are now collapsed by default with a
gradient fade overlay and expand/collapse button. Only applies to
user messages; assistant messages remain fully visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 17:33:49 +08:00
7418andClaude Opus 4.6 f861b3fca1 feat: slash command popover redesign, import dialog scroll fix, and new logo
- Slash command popover: add search box, group commands/skills with section
  headers, assign unique icons per built-in command, remove Built-in badge,
  show source labels for skills, deduplicate API skills with built-in names
- Import CLI Session dialog: fix list overflow and enable scrolling by
  replacing Radix ScrollArea with native overflow-y-auto
- New chat empty state: replace BotIcon with custom CodePilotLogo SVG
  component supporting light/dark theme

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 16:57:49 +08:00
歸藏 487c0a5cb7 fix: prevent path traversal in file APIs (#16)
fix: prevent path traversal in file tree and preview APIs
2026-02-09 16:08:11 +08:00
歸藏 8dcc19d077 fix: add graceful database shutdown (#20)
fix: add graceful database shutdown to prevent WAL file leaks
2026-02-09 16:08:07 +08:00
歸藏 c2c53e9591 feat: import and resume Claude Code CLI sessions (#28)
feat: import and resume Claude Code CLI sessions (closes #10)
2026-02-09 16:08:02 +08:00
歸藏 336897cded fix: 支持读取 ~/.claude/skills/ 目录下的已安装技能 (#36)
fix: 支持读取 ~/.claude/skills/ 目录下的已安装技能
2026-02-09 16:07:58 +08:00
llg-linwei f437024a96 fix: 修复加载大消息会话时卡死的问题 2026-02-09 14:29:58 +08:00
gy212andClaude Opus 4.6 61e3720ded fix: 支持读取 ~/.claude/skills/ 目录下的已安装技能 (#35)
问题:CodePilot 只扫描 ~/.agents/skills/,缺失了 ~/.claude/skills/ 路径,
导致用户通过 CLI 安装到该目录的技能无法在 CodePilot 中显示和使用。

修改内容:

后端:
- 列表接口 (GET /api/skills) 同时扫描 ~/.agents/skills/ 和 ~/.claude/skills/
- 通过 SHA1 内容哈希去重:同名同内容只保留一条,同名不同内容保留两条
- 详情接口 (GET/PUT/DELETE /api/skills/:name) 新增 ?source= 参数精确定位来源
- 详情接口使用 YAML front matter 的 name 字段匹配,修复列表能看到但点开 404 的问题
- 同名不同内容时返回 409,要求前端传 source 消歧

前端:
- SkillItem 类型新增 installedSource 字段
- Badge 显示 installed:claude 或 installed:agents 明确来源
- 保存/删除时携带 ?source= 防止误操作同名技能
- 聊天补全项描述追加来源提示
- 技能展开时精准请求对应来源

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:10:08 +08:00
7418andClaude Opus 4.6 5b69a63c06 fix: show env vars as overridden when a provider is active
When a manually configured provider is active, environment variables
are now shown with "Overridden" badge, strikethrough text, and muted
colors instead of both appearing as active simultaneously.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:32:37 +08:00
7418andClaude Opus 4.6 a42c0e312d fix: resolve session switching stuck on loading spinner
Race condition when quickly switching chat sessions caused the UI to get
stuck on loading. Added cancellation flags and key-based remounting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:19:25 +08:00
7418andClaude Opus 4.6 37cfaacaf0 fix: file upload bugs and UI adjustment
- Include base64 data in file metadata for chat display (fixes broken images)
- Use file-to-disk + Read tool approach instead of SDK multimodal
  messages (fixes slow response caused by invalid prompt format)
- Move attach button before folder picker in input toolbar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:26:42 +08:00
liuxiaopai-ai 187cc23127 feat: import and resume Claude Code CLI sessions (closes #10)
Add ability to browse and import conversation history from Claude Code CLI
into CodePilot, with full resume support via SDK session ID.

Features:
- JSONL parser for Claude Code session files (~/.claude/projects/)
- REST API: GET /api/claude-sessions (list) + POST /api/claude-sessions/import
- Import dialog UI accessible from sidebar 'Import CLI Session' button
- Imported sessions bind sdk_session_id for seamless resume in CodePilot
- Duplicate import protection (409 with redirect to existing session)
- File size guard (50MB max) to prevent memory issues

Files changed:
- src/lib/claude-session-parser.ts — JSONL parser core
- src/app/api/claude-sessions/route.ts — list API
- src/app/api/claude-sessions/import/route.ts — import API with dedup
- src/components/layout/ImportSessionDialog.tsx — browse & import UI
- src/components/layout/ChatListPanel.tsx — sidebar integration
- src/__tests__/unit/claude-session-parser.test.ts — 17 unit tests
2026-02-08 22:04:12 +08:00
liuxiaopai-ai 746cea1eb7 fix: add graceful database shutdown to prevent WAL file leaks
The SQLite database connection was never explicitly closed when the
process exits. In WAL mode, this can leave behind -wal and -shm files
and risk data loss if the WAL hasn't been checkpointed.

Changes:
- Add closeDb() export for explicit database closure
- Register process shutdown handlers (exit, SIGTERM, SIGINT, SIGHUP)
  that call closeDb() before the process terminates
- Idempotent: multiple calls to closeDb() are safe
- After closeDb(), getDb() transparently re-opens the database
- Add 6 unit tests covering close, idempotency, reopen, data
  persistence, and WAL cleanup (all passing)
2026-02-08 21:37:35 +08:00
liuxiaopai-ai 0f05e4fd0f fix: address code review - fallback to homedir, validate baseDir, use afterAll
Address all 3 points from @op7418's review:

1. No baseDir fallback (severe): Both /api/files and /api/files/preview
   now fall back to os.homedir() when no baseDir is provided, preventing
   access to arbitrary system directories/files.

2. baseDir bypass via baseDir=/ (medium): Both APIs now validate that
   baseDir itself is within the user's home directory. Setting baseDir=/
   will be rejected with 403.

3. Test cleanup (minor): Replaced 'it(cleanup...)' with proper after()
   hook. Added 6 new tests for baseDir validation (18 total, all pass).
2026-02-08 21:36:56 +08:00
7418andClaude Opus 4.6 164f730da1 feat: add file upload and preview support (images and documents)
- Support image (JPEG/PNG/GIF/WebP, max 5MB) and document uploads
- Images sent as multimodal content blocks to Claude SDK
- Documents saved to temp dir for Claude's Read tool
- Emerald capsule badges in input for attached files
- Drag-and-drop, paste, and file picker support via PromptInput
- Chat display: image thumbnails with lightbox, file cards
- Lightbox uses Radix Dialog with prev/next navigation
- File metadata embedded in message content as HTML comments
- Compatible with existing slash command badge system

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:35:45 +08:00
liuxiaopai-ai 84de2d1de8 fix: prevent path traversal in file tree and preview APIs
The file tree API (/api/files) and file preview API (/api/files/preview)
had ineffective path safety checks that could allow reading arbitrary
files on the host system.

Issues fixed:
- /api/files: isPathSafe(resolvedDir, resolvedDir) always returns true
  since it compares the directory against itself
- /api/files/preview: isPathSafe(dirname, filePath) always returns true
  since a file is always inside its own parent directory

Changes:
- Add baseDir parameter to both APIs so the frontend can pass the
  session's working directory as a trust boundary
- When baseDir is provided, validate that the requested path is within it
- For /api/files/preview without baseDir, fall back to restricting access
  to the user's home directory (prevents /etc/passwd etc.)
- Add comprehensive unit tests covering path traversal, prefix attacks,
  symlink escapes, and edge cases (13 tests, all passing)

Security: This is a defense-in-depth measure. CodePilot runs locally so
the attack surface is limited, but proper validation prevents accidental
exposure when the dev server is bound to non-localhost interfaces.
2026-02-08 21:35:34 +08:00
7418andClaude Opus 4.6 e956753a38 feat: add version display, cache clearing on upgrade, exclude data dir
- Show app version (v0.4.0) in sidebar bottom
- Clear Electron web cache when version changes to prevent stale JS
- Exclude data/ directory from packaged app

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