Commit Graph
18 Commits
Author SHA1 Message Date
7418andClaude Opus 4.6 94fdd36d27 feat: assistant workspace V2 — indexing, retrieval, security hardening & workspace switching
Assistant Workspace V2:
- Markdown indexing engine (incremental manifest + chunks JSONL)
- Keyword retrieval with CJK bigram support and hotset boosting
- Directory taxonomy inference and evolution suggestions
- Workspace config management (.assistant/config.json)
- Organize API: capture, classify, move, archive, suggest-evolution

Workspace switching:
- Inspect API (GET /api/workspace/inspect) for pre-switch validation
- Two-phase switching with confirmation dialogs (5 workspace statuses)
- Atomic save: init/reset runs before setSetting(), rollback on failure
- Auto-navigate to new/reused session after switch
- Mismatch banner in ChatView (only for former assistant sessions)
- Debounced path validation with visual indicators

Security hardening:
- Completion fence (onboarding-complete/checkin-complete) only processes
  when session.workingDirectory === assistant_workspace_path (frontend)
  AND session.working_directory === workspacePath (backend double-check)
- assertContained() in workspace-organizer: rejects absolute paths, ~/,
  ../ traversal, and symlink escapes for captureNote/moveFile
- organize API validates all path params at entry (validateRelativePath)
- captureDefault sanitized to relative path on onboarding write
- R_OK + W_OK validation on GET settings, session creation, and PUT

Bug fixes:
- hookTriggeredSessionId now read before auto-trigger; allows retry if
  session has no messages (previous trigger failed silently)
- workspace-switched event listener matches oldPath (not just != newPath)
  so normal project chats never show the mismatch banner
- Daily check-in card hidden when onboarding not complete
- Refresh docs now calls generateRootDocs() + generateDirectoryDocs()
- Banner "Open" button reuses latest session (checkin mode) instead of
  always creating new onboarding session

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:37:02 +08:00
7418andClaude Opus 4.6 19aba25c8f feat: assistant workspace — persistent AI personality & memory via Markdown files (#165)
Add "Assistant Workspace" feature that lets users designate a directory
(e.g. Obsidian vault) containing 4 Markdown files (soul.md, user.md,
memory.md, claude.md) to define AI personality, user profile, long-term
memory, and execution rules. These files are automatically injected into
the system prompt for assistant project sessions.

Core library (src/lib/assistant-workspace.ts):
- Workspace validation, initialization with template files
- File loading with 8000-char truncation, XML prompt assembly (40k limit)
- State management via .assistant/state.json
- Directory docs generation (README.ai.md + PATH.ai.md)
- Case-insensitive file name fallback (soul.md → SOUL.md)

System prompt injection (src/app/api/chat/route.ts):
- Scoped to sessions where working_directory === workspace path
- Workspace prompt prepended before session-level system prompt
- Onboarding/check-in instructions injected as <assistant-project-task>
- autoTrigger flag skips user message save and title update

Chat-based onboarding (10 questions) & daily check-in (3 questions):
- AI conducts conversation, outputs structured completion code blocks
- Frontend detects onboarding-complete/checkin-complete blocks
- Backend calls Claude API to generate file content from answers
- Fallback to raw answers if API call fails

Auto-trigger pipeline:
- Mount trigger (500ms delay) + focus fallback in MessageInput
- assistantTriggerFiredRef prevents duplicate triggers per mount
- hookTriggeredSessionId in state.json prevents cross-reload duplicates
- Daily check-in only triggers in the most recent workspace session
- hookTriggeredSessionId cleared via __clear__ sentinel after completion

API endpoints:
- GET/PUT /api/settings/workspace — path CRUD + file status
- POST /api/workspace/session — create (onboarding) or reuse (check-in)
- POST /api/workspace/onboarding — AI-generate soul.md + user.md
- POST /api/workspace/checkin — AI-update memory.md + user.md
- POST /api/workspace/hook-triggered — set/clear trigger guard
- GET /api/workspace/latest-session — latest session lookup
- POST /api/workspace/docs — refresh directory documentation

UI:
- Settings "Assistant" tab with workspace path, file status, controls
- Violet badge on workspace project group in ChatListPanel
- useAssistantWorkspace hook for state queries

Also includes:
- 102 passing tests (16 new regression tests for workspace logic)
- i18n keys for en.ts and zh.ts
- Handover documentation and execution plan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:31:42 +08:00
7418andClaude Opus 4.6 113e15e2f4 feat: Discord bridge adapter — 完整实现 Discord 作为第三个桥接渠道
新增文件:
- discord-adapter.ts: 基于 discord.js v14 的适配器,支持 DM/频道消息、
  按钮交互、流式预览(edit-based)、@提及过滤(兼容角色 mention)、
  图片附件下载、!→/ 命令归一化、消息去重、typing indicator
- markdown/discord.ts: Discord 2000 字符分段,代码块围栏自动平衡
- API routes: settings CRUD(Token 掩码)+ verify(Discord REST 验证)
- DiscordBridgeSection.tsx: 设置 UI(凭据、授权、服务器策略、配置指南含 ID 获取方法)
- discord-bridge.test.ts: 22 项单元测试(chunking/auth/command/HTML 转换)

修改文件:
- bridge-manager.ts: Discord 分段投递 + channel-aware stream config
  (Discord 默认 1500ms/40chars/1900max vs Telegram 700ms/20/3900)
- BridgeLayout/BridgeSection: Discord 渠道开关和侧栏入口
- bridge/settings/route.ts: 新增 14 个 Discord 设置键
- next.config.ts: serverExternalPackages 添加 discord.js/zlib-sync
- i18n: 中英文完整翻译(30+ keys)
- docs/handover/bridge-system.md: Discord 架构文档

依赖:discord.js ^14.18.0, zlib-sync ^0.1.9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:32:46 +08:00
7418andClaude Opus 4.6 538cc1b7fd docs: 工程质量保障体系执行计划文档
- 新建 completed/engineering-quality-assurance.md:记录 Harness Engineering
  全部 5 个已完成 Phase 和 4 个未实现 Phase 的详细内容
- 更新 exec-plans/README.md 索引

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:08:49 +08:00
7418andClaude Opus 4.6 62dbecd5dc docs: 执行计划体系 + 技术债务追踪 + CLAUDE.md 执行计划规则
docs/exec-plans/(新建目录):
- README.md — 执行计划规范、模板、何时需要写执行计划
- active/context-storage-migration.md — 从 research/ 迁移,标注 Phase 0-3 进度状态
  (Phase 0 部分完成:sdk_cwd 上线;projects 表和 canUpdateSdkCwd 未实现)
- tech-debt-tracker.md — 4 项已知技术债务(ESLint 存量 error、内存态注册表、
  固定 50 条 fallback、Phase 0 剩余项)

CLAUDE.md:
- 新增"执行计划"区块:中大型功能必须先写执行计划再开工
- 文档区块增加 exec-plans/ 索引

ARCHITECTURE.md:
- 关键文档索引增加执行计划和技术债务条目

docs/research/README.md:
- context-storage-migration-plan 条目增加交叉引用指向执行文档

docs/CLAUDE.md:
- 增加 exec-plans/ 目录说明和文档分类规则

目的:确保 AI 后续会话能自动遵循执行计划流程,
读取进度状态而不需要重新口头解释历史。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:44:12 +08:00
7418andClaude Opus 4.6 243724a765 feat: 飞书(Feishu/Lark)Bridge 适配器 + 发布 v0.25.0
新增飞书 IM 通道,通过 @larksuiteoapi/node-sdk WSClient 接收消息、REST Client 发送回复。

适配器核心 (feishu-adapter.ts):
- WSClient 长连接接收 im.message.receive_v1 事件
- 消息去重 (message_id LRU 1000)、授权校验、群聊策略 (open/allowlist/disabled)
- @提及检测 (bot open_id/user_id/union_id 匹配)
- 图片/文件/音频/视频/富文本(post) 下载 → base64 FileAttachment
- Typing 指示器 (Openclaw 方案: emoji reaction)
- /perm 文本命令处理权限审批

渲染策略 (markdown/feishu.ts):
- 代码块/表格 → schema 2.0 interactive card (markdown 元素)
- 纯文本 → post (md tag), 支持粗体/斜体/行内代码/链接
- 权限卡片 → schema 2.0 card + /perm 文本命令 (无按钮, 见下方决策)
- 每层降级: card → post → text

关键决策 — 权限交互无按钮:
- 飞书 card.action.trigger 回调需 HTTP webhook, WSClient 不支持
- schema 2.0 不支持 action 标签 (错误码 200861)
- schema 1.0 按钮可渲染但点击报 200340 (无 webhook 端点)
- Openclaw 用 http.createServer + Lark.adaptDefault 解决, CodePilot 桌面端无公网端点
- 最终方案: 格式化卡片 + /perm 文本命令, 用户复制发送即可审批

其他变更:
- permission-broker.ts: permissionRequestId 去重 (30s TTL)
- telegram-bot.ts: bridge 模式互斥 (globalThis 标志)
- bridge-manager.ts: 飞书渲染分发 (deliverResponse feishu 分支)
- UI: FeishuBridgeSection 设置页 + 侧边栏入口 + 通道开关
- i18n: 中英文飞书配置文案
- 交接文档: bridge-system.md 更新飞书架构、数据流、6 项设计决策

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:03:13 +08:00
7418andClaude Opus 4.6 b1a043a995 feat: Telegram 流式预览(sendMessageDraft)+ 出站渲染解耦 + 投递容错
Bridge 新增"边生成边显示"能力,利用 Telegram Bot API 9.5 的
sendMessageDraft 在私聊中以草稿形式流式展示 Claude 生成进度。
架构上抽象为通道级可选能力,便于后续扩展到其他 IM。

types.ts
- 新增 PreviewCapabilities、StreamingPreviewState 接口

channel-adapter.ts
- BaseChannelAdapter 新增三个可选方法:
  getPreviewCapabilities / sendPreview / endPreview
- sendPreview 返回 'sent'|'skip'|'degrade' 三态,
  区分瞬时失败(跳过)和永久失败(降级)

telegram-utils.ts
- 新增 sendMessageDraft() API 封装(plain text,截断到 4096)

telegram-adapter.ts
- 实现 getPreviewCapabilities: 开关检查 + 私聊/群聊检测 + 降级状态
- 实现 sendPreview: 调 sendMessageDraft,400/404 永久降级,429 仅跳过
- 实现 endPreview: 空操作
- stop() 清空 previewDegraded Set

conversation-engine.ts
- 新增 OnPartialText 回调类型
- processMessage / consumeStream 透传 onPartialText 参数
- 使用独立 previewText 变量(只累积、不因 tool_use 清零),
  避免预览文本在工具调用后回退/抖动

bridge-manager.ts
- 流式预览状态机:generateDraftId / getStreamConfig / flushPreview
  节流闭包(间隔+最小增量+trailing-edge timer),finally 清理
- flushPreview 仅在 'degrade' 时降级,'skip'/网络错误不降级
- 新增 deliverResponse() 按 channelType 分发渲染:
  Telegram → markdownToTelegramChunks + deliverRendered
  其他 IM → deliver() 纯文本(内部自动分块)
  解除 handleMessage 对 Telegram 渲染的硬编码依赖

delivery-layer.ts
- deliverRendered: chunk 失败后继续投递剩余 chunk(不中断),
  追发截断提示通知用户,返回 ok:false 标识不完整投递
- deliver: 保持原有 fail-fast 行为(短消息无需跳过)

route.ts (bridge/settings)
- BRIDGE_SETTING_KEYS 白名单追加 5 个流式配置项

docs/handover/bridge-system.md
- 更新目录结构、数据流、设计决策(#12 流式预览)、设置项表

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:20:47 +08:00
7418andClaude Opus 4.6 38e7c96daa feat: Telegram Bridge 出站消息 Markdown 渲染
新增三层 Markdown → Telegram HTML 渲染管线:

markdown/ir.ts — markdown-it 解析 Markdown 为中间表示 (MarkdownIR)
  - 支持 bold/italic/strikethrough/code/code_block/blockquote/links/lists/headings/tables/hr
  - 表格使用 code-block 模式渲染为 ASCII 表格(<pre> 保留对齐)
  - HTML 内联 <br> 标签转换为换行符

markdown/render.ts — 通用标记渲染器
  - boundary tracking + LIFO stack 处理嵌套样式

markdown/telegram.ts — Telegram 专用渲染器
  - 样式映射到 Telegram HTML 标签 (b/i/s/code/pre+code/blockquote/a)
  - 文件引用保护:README.md/main.go 等不被误识别为 URL
  - render-first 分片:按渲染后 HTML 长度分片,超限时按比例重分割

delivery-layer.ts — 新增 deliverRendered() 接收预渲染 chunks
  - HTML + plain text 双通道,解析失败自动降级纯文本
  - sendWithRetry 支持 plainFallback 参数

bridge-manager.ts — Claude 回复改用 markdownToTelegramChunks + deliverRendered
  - 命令响应和错误消息保持 escapeHtml + deliver

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 14:38:12 +08:00
7418andClaude Opus 4.6 8526b58d59 docs: 更新 bridge 交接文档 — 图片接收能力
- 目录结构增加 telegram-media.ts
- 数据流图补充图片/相册处理路径
- 设计决策 #2 补充连续水位推进机制
- 新增决策 #9(图片接收)和 #10(DB 格式统一)
- 设置项表增加 image_enabled 和 max_image_size

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:06:48 +08:00
7418andClaude Opus 4.6 ead5cfcf8b refactor: 精简 CLAUDE.md + 分层上下文管理
根 CLAUDE.md 从 80 行压缩到 15 行,详细规则拆分到按需加载位置:

- .claude/rules/development.md — 开发规则、测试要求、commit 规范
- .claude/rules/release.md — 发版流程、纪律、Release Notes 格式、构建说明
- docs/CLAUDE.md — docs 目录导航,要求检索前先读子目录 README
- src/lib/bridge/CLAUDE.md — bridge 模块关键约定(runAdapterLoop 时序、
  bridgeModeActive 互斥、offset 安全水位、adapter 扩展方式)

目的:减少每次会话的固定上下文消耗,非相关模块的文档不加载到上下文。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:59:00 +08:00
7418andClaude Opus 4.6 6209c865fd refactor: 整理 docs 目录结构
- docs/handover/ — 交接文档(架构、设计决策)
- docs/research/ — 调研文档(技术方案、可行性分析)
- 各目录添加 README.md 索引,要求 AI 增删文件时更新索引
- CLAUDE.md 更新文档路径引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:41:14 +08:00
7418andClaude Opus 4.6 6ad821d3af feat: 多 IM 远程桥接系统 + Bridge 一级导航 + bug 修复
**Bridge 系统核心(src/lib/bridge/)**
- bridge-manager: 生命周期编排、adapter 事件循环、会话级并发控制
- channel-adapter: 抽象基类 + 注册式 adapter 工厂
- channel-router: IM 地址 → CodePilot session 自动映射
- conversation-engine: 服务端消费 streamClaude() SSE 流
- permission-broker: 权限请求转发到 IM 内联按钮
- delivery-layer: 出站分片、限流、重试退避、HTML 降级
- telegram-adapter: Telegram 长轮询 + offset 安全水位 + 幂等去重
- security/: 路径校验、危险输入检测、滑动窗口限流

**Telegram 通知 Bot(src/lib/telegram-bot.ts)**
- 独立通知模式,与 bridge 模式互斥
- bridgeModeActive 使用 globalThis 存储,避免 HMR 重置导致轮询冲突

**API 路由**
- /api/bridge: GET 状态查询 + POST start/stop/auto-start
- /api/bridge/channels: 活跃通道列表
- /api/bridge/settings: bridge 设置读写
- /api/settings/telegram: 凭据管理(含 allowed_users 白名单)
- /api/settings/telegram/verify: 连接验证 + chat ID 自动检测

**UI 重构:Bridge 提升为一级导航**
- NavRail 新增 Bridge 图标导航项
- /bridge 页面:BridgeLayout hash 路由,Bridge + Telegram 两个子 tab
- BridgeSection: 总开关、状态、启停、通道开关、适配器状态、默认设置
- TelegramBridgeSection: 凭据配置 + 白名单 + Setup Guide(6 步)
- Settings 移除 Telegram 和 Bridge tab,只保留 4 个核心 tab

**Bug 修复**
- bridge-manager: runAdapterLoop 在 state.running=true 之前被调用,
  while 条件同步求值为 false 导致消费者循环不启动。修复为先设 running
  再启动 loop
- telegram-bot: bridgeModeActive 改用 globalThis 防止 HMR 丢失状态
- settings/telegram route: TELEGRAM_KEYS 补充 telegram_bridge_allowed_users

**Electron**
- 窗口关闭时 bridge 活跃则最小化到系统托盘而非退出
- 启动时通过 auto-start API 恢复桥接
- preload 暴露 bridge 相关 IPC

**文档**
- docs/bridge-system.md: 完整架构文档
- docs/chat-sdk-integration-feasibility.md: Chat SDK 集成调研
- CLAUDE.md 添加 bridge 文档链接

chore: bump v0.21.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:18:19 +08:00
7418andClaude Opus 4.6 c4d03c46e6 feat: Skills.sh marketplace integration + navigation restructure
Skills.sh Marketplace:
- Add marketplace browser with search, detail panel, and install/uninstall
- Search API proxying skills.sh with lock file integration for installed state
- Install/remove APIs using `npx skills` CLI with SSE streaming progress
- SKILL.md content fetching via GitHub Git Trees API with in-memory caching
- MarketplaceSkillCard, MarketplaceSkillDetail, MarketplaceBrowser components
- InstallProgressDialog with real-time SSE log output
- SkillsManager gains "My Skills" / "Marketplace" segmented control
- Type definitions: MarketplaceSkill, SkillLockFile, SkillLockEntry

Navigation restructure:
- Split Extensions page into standalone /skills and /mcp top-level pages
- NavRail: replace single Extensions icon with separate Skills (ZapIcon) and MCP (Plug01Icon) entries
- /extensions page now redirects to /skills or /mcp based on ?tab param
- /plugins redirects updated to point to new routes
- Remove redundant source badges from SkillListItem (section headers suffice)

Other:
- Add WeChat user group QR code to README.md and README_CN.md
- i18n: add 19 marketplace-related keys in en.ts and zh.ts
- Bump version to 0.18.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 21:43:46 +08:00
7418andClaude Opus 4.6 0c379e5607 fix: address tool_result dedup, SDK task ID collision, and doc accuracy
P1: tool_result dedup changed from "first wins" to "last wins"
- claude-client.ts: remove emittedToolResultIds Set, both PostToolUse and
  user message handler emit freely. PostToolUse provides immediate UI feedback;
  user handler's potentially more complete result arrives second.
- route.ts: collectStreamResponse replaces existing contentBlock entry when
  duplicate tool_use_id arrives (last wins for DB persistence).
- ChatView.tsx: onToolResult replaces existing state entry by tool_use_id
  instead of skipping, ensuring most complete result is displayed.

P2: SDK task ID collision risk eliminated
- db.ts: syncSdkTasks now uses full sessionId in task ID
  (`sdk-{fullSessionId}-{index}`) instead of truncated 8-char prefix,
  eliminating cross-session primary key collisions.

P2: Todo ordering stabilized
- db.ts: add sort_order column migration, syncSdkTasks writes array index
  as sort_order. getTasksBySession sorts by sort_order ASC, created_at ASC
  so tasks with identical timestamps maintain insertion order.

P3: Documentation field mapping corrected
- agent-tooling-todo-bridge.md: fix field mapping table — actual implementation
  maps activeForm (not priority) to description column. Updated dedup strategy
  docs from "three-layer skip" to "two-layer last-wins replace".

Lint: fix prefer-const for finalPrompt in claude-client.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:22:10 +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
7418andClaude Opus 4.6 d2a926b353 docs: add CodePilot icon to README titles
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:35:51 +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