原本只是想测试一下大模型在 UI 复刻方面的能力,结果意外将 Claude 桌面版软件完整地复刻了下来。
既然界面(UI)已经完成,顺势也就把对话(Chat)功能一并实现了。
对话功能上线后,写代码的能力自然也必须跟上——于是 Code 功能也被成功开发出来。
目前的情况是,相当于打造了一个界面版的 Claude Code,而这个界面本身就是官方版的模样,形成了完整的闭环。
不仅要复刻它,还要超越它。毕竟这个克隆版拥有官方始终不具备的功能:纯粹的全中文界面,以及支持接入任意第三方模型,无论是国内还是国外的大模型都能使用。
中文界面效果如下:
第三方模型配置界面如下:
将 Anthropic 的 API 配置到这里,这就相当于官方纯正版本了。理论上,甚至可以把 OpenAI 的 GPT-5.5 接入到这个 Claude 桌面版中——这个功能后续必须实现。
下面来详细汇报一下具体修改了哪些内容。主要分为两个部分:界面层面的调整,以及背后的技术实现方案。
界面调整
本次调整的核心,是为了与 Claude Desktop 新版布局保持一致。从首次复刻该项目至今,界面的细节已经发生了不少变化。
最显著的变化就是三个 Tab 的切换功能:
在左侧区域中,对聊天 Chat、协作 Cowork、代码 Code 进行了明确区分。官方的设计思路很清晰,桌面版覆盖了三大核心功能,对应三种重要使用场景。左侧面板也进行了调整,菜单、搜索、展开等图标被移到了最顶部。
为了与时俱进,我们也同步添加了这些功能。
还有一个细节:Code 模式在右下角新增了一个开关图标,可以快速切换字体和主题。我们也加入了这一功能,目前已经可以实现主题的快速切换。字体功能暂时尚未添加,目前还没有把重点放在字体优化上。
也就是说,现在这个“复刻版”Claude 也拥有了三大核心功能。
第一个是聊天 Chat 功能。
该功能的特点是纯粹的对话体验,直接与 AI 进行交流。缺点是无法控制电脑和读写文件,优点是节省 tokens、响应速度快,是知识问答场景的最佳选择。
第二个是办公协作 Cowork。
由于平时较少使用这个功能,目前仅完成了界面设计,尚未真正实现其功能。后续会以打工人视角切入,再来更新这个功能,将其打造为“办公效率神器”。官方版本的这个功能支持任务分配、定时任务执行,以及手机远程操控电脑等。
第三个是编程 Code。
写代码是高频使用场景,也是目前大模型真正能够落地应用的能力,因此优先完善了这个功能。今天重点介绍的就是这部分。
实际上,Code 功能并不仅限于编程,任何类型的工作都可以使用。目前复刻版主要实现了 token 预览、模型选择、项目选择以及权限控制等界面功能。
其中的 tokens 消耗统计目前还是占位数据,并非真实数值。这个功能已经在 JCode 中实现过了,实现起来并不复杂。
文件夹选择是必备功能,已经完成了 UI 制作并实现了相关功能。模型选择同样是必备功能,也已经完成了 UI 制作和功能实现。最近更新的 Opus 4.7 fast mode 也已收录——虽然对第三方模型来说意义不大,但界面嘛,先加上再说。
授权选择也是必备功能,同样完成了 UI 制作和功能实现。这些 UI 的内容、描述以及布局的还原度都相当高。很多时候甚至会产生错觉:到底是在使用 Claude,还是在用复刻版?
还好,具体的对话界面与官方版还是存在一些差异。官方版的输出显得有些“扁平化”,文字内容和工具调用混在一起,没有做好区分,整体上给人一种密密麻麻的感觉。相比之下,Codex 的 UI 在这方面会好一些。
Claude 本身的 UI 非常有特色,但这几个月频繁更新,有些设计变得有些潦草。例如用户输入框的那个蓝色框和内容,与整体软件风格完全不协调,不知道设计团队当时是怎么考虑的。
在实现这部分功能时,希望能够比较清晰地观察整个执行过程。目前还在持续优化中,当前效果大致如下:
这样可以清晰地查看每一个环节的具体情况。比如写入工具到底写了什么文件、写了什么内容;授权工具到底授予了什么权限、执行了什么操作。这些工具调用全部支持展开和收起,默认收起状态不占用空间,有需要时可以手动展开查看细节。每一次问答和授权都有明确的交互界面。
目前这种风格感觉分块还是有点多,还有很大的优化空间。
界面方面大致就是这些内容。虽然看起来简单,但要实现成这样、没有奇怪的样式问题,也并不是那么容易。将一个界面做到简洁又好用,是非常困难的——仅仅是看起来不让人反感,就已经很不容易了。
技术方案
在刚开始动手之前,其实并没有太多信心。因为实践往往比想象中要复杂很多倍。为了少走弯路,也做了一些前期功课。
方案对比
大致有以下几种可选方案:
第一种,直接 spawn 本地的 Claude Code。优点是 Claude Code 的全套能力可以零成本获得,UI 功能基本可以一对一实现。缺点是用户的电脑上需要安装 Claude Code,并且无法获取 agent loop 的内部内容,只能通过 JSON 事件进行观察。不过这些缺点可以接受——如果没安装的话提示用户安装即可,或者直接使用 sidecar 打包。agent loop 的内部内容本来也不是关注重点,能够通过 JSON 进行交互就足够了。
第二种,嵌入 Claude Agent SDK。这也是 Claude 官方产品,专门为专业开发者提供的智能体开发套件。优点是可控性更强:tool 定义、system prompt、hooks、上下文压缩都可以自行控制。缺点是担心搞不定——据分析,这个方案“相当于把 Claude Code 重新写一遍”。不是不能写,实力上允许,但 tokens 不允许。
第三种,接入类似 Pi Agent 这样的第三方智能体。Pi 是 OpenClaw 的智能体实现部分。咨询了所有 AI 后,都没有把这个作为首选方案,这里就不展开了。确实,有条件上 Claude Code 的话,没有理由去用 Pi——谁会拿 Pi 来写代码呢。
所以最终毫不犹豫地选择了第一种方案。而第一种方案的关键,就在于下面这一行命令:
claude --print --input-format stream-json --output-format stream-json --verbose --permission-prompt-tool stdio --permission-mode acceptEdits --model GLM-5.1
为了探索出这一行命令,花费了不少时间,查阅了大量资料,并进行了多轮实践验证。
开发目标
大的方案确定之后,还需要明确自己的核心目标:
- 全方位复用 Claude Code
- 与官方模型解绑,支持接入任意第三方模型提供商
- 界面操作体验要与 Claude 桌面版对齐,包括模型选择、权限控制等
- 支持管理 session 和对话
代码结构
这是经过分析总结后的调用结构:
┌─ Tauri front-end (vanilla JS)
│Code workspace UI
│ • cwd 选择 / model / mode / send
│ • 三种特化权限卡:AskUserQuestion / ExitPlanMode / 通用工具
│ • 折叠工具块、思考中胶囊、markdown 渲染、Recents 持久化
│ ▼
│ invoke('claude_code_session_*')
└──────┬──────────────────────────────────────────────────────────────┐
│ Tauri IPC
┌──────▼──────────────────────────────────────────────────────────────┐
│Rust commands (desktop/src-tauri/src/lib.rs)
│claude_code_check 探测 CLI 是否可用
│claude_code_config_dir 暴露隔离的 CLAUDE_CONFIG_DIR
│claude_code_session_start spawn CLI、起 stdin writer + init
│claude_code_session_send 写一条 user message 到 stdin
│claude_code_session_respond 写 control_response 到 stdin
│claude_code_session_set_mode 中途切 plan/acceptEdits/...
│claude_code_session_end kill 子进程
│
│ emit "claude-code-event" ◄── stdout JSON lines
└──────┬──────────────────────────────────────────────────────────────┐
│ stdio
┌──────▼──────────────────────────────────────────────────────────────┐
│claude --print --input-format stream-json
│ --output-format stream-json --verbose
│ --permission-prompt-tool stdio ← 关键 flag
│env: ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY /
│ ANTHROPIC_MODEL / CLAUDE_CONFIG_DIR / CI=1
└─────────────────────────────────────────────────────────────────────┘
因为涉及到一些内部代码,可能有些难懂,但可以看个大概。
业务流程
- 启动检测,确认是否安装了 Claude Code
- 选择目录,所有开发必须先选择工作目录
- 发送第一条消息,需要跳过官方权限检测,同时隔离官方 Claude Code 配置
- 后续轮询,同一个 session 不重启进程
核心协议
整个调用过程中比较困难、或者说比较花时间摸索的,是 JSON 格式,也可以称为“核心协议”。需要摸清 Claude Code 返回的信息格式是什么样,工具调用、授权、Ask 这些交互都是如何返回和如何发送的。
比如一开始就遇到了 Ask 模式里无法回答 Ask 的问题;Plan 模式无法选择选项、无法退出 Plan 的问题;还有各种授权被挂起来的问题。细节非常多,关键是 --permission-prompt-tool stdio 和 can_use_tool。
跑通这个协议的步骤大致如下:
1、传上面的关键参数:--permission-prompt-tool stdio
2、初次握手(host → CLI):{"type":"control_request","request_id":"init-
3、接收返回(CLI → host):{"type":"control_request","request_id":"...","request":{"subtype":"can_use_tool","tool_name":"
然后根据具体的信息,处理 AskUserQuestion、ExitPlanMode、Bash、Write、Edit、Read、WebFetch、WebSearch、Glob、Grep、Task 这些类型,弹出对应的确认卡片供用户选择。
4、下发反馈(host → CLI):{"type": "control_response", "response": { "subtype": "success", "request_id": "<原 control_request 的 id>", "response": {"beha vior": "allow"|"deny","updatedInput": {...}|null,"message": "..."|null }}}
注意 control_response 有两层 response 嵌套。
5、中途切换权限模式:{"type":"control_request","request_id":"set-mode-...","request":{"subtype":"set_permission_mode","mode":"plan|acceptEdits|default|bypassPermissions"}}
主要的操作都在这里了。
作为一篇公众号文章,好像讲得有点多了,需要收一收。技术细节就不展开了。
这次开发主要遇到了以下几个问题:
问题 1:UI 卡死,发送按钮无法点击取消
问题 2:响应只到第一条,无法继续
问题 3:"Not logged in · Please run /login"
问题 4:Overview 卡片在会话开始后还占位
问题 5:cwd 默认指到了 `src-tauri`
问题 6:Ask permissions 模式下工具被静默拒绝
问题 7:AskUserQuestion 提交答复后 CLI 没反应,超时报 "stream closed"
最后补充下遗留问题和后续改进方向:
1、Worktree 复选框尚未联动
2、未对接 `--add-dir`:cwd 之外的额外参考目录还没 UI
3、MCP server 配置
4、`--resume
5、真实 token 计费
6、权限协议字段兼容性,这是个持续性的事情
7、AskUserQuestion 题数限制,现在默认官方遵守规则,就不做校验了
8、Always allow 颗粒度的问题
这里面的 resume 是比较关键的,其他部分不是很紧迫。
有人可能觉得调用一下 Claude Code 很简单——但实际操作下来,一堆问题,一个头两个大。写代码就是个无底洞。
万幸,核心功能已经搞定了。简单测试,非常丝滑。
万事开头难,最难的部分已经过去了。
说点题外话
上次发布第一个版本之后,很多人给了鼓励和支持,也有很多人默默获取了软件。还是挺开心的。
但也有一些人表达了一些比较负面的评论。比如“套壳有什么用”、“重复造轮子毫无意义”、“搞个界面有什么,有种把 Claude Code 也给加上”。
这些问题,其实也早就问过自己。但是当别人怼脸批评的时候,还是要回应一下。
有没有用,关你什么事?我觉得有意义就行了。又不是给你打工的,又不收你的钱,爱用不用。Claude Code 已经加上了,别哔哔了。
有人觉得没啥用——那就自己用吧,不更新了。
开玩笑的。既然写出来了,气早就放完了。
暂时不更新的主要原因是:Claude Code 周配额已经耗尽。实测下来,Claude 的周配额确实很少。同时也不想让其他模型插手这个软件,要坚持用 Claude 克隆 Claude。
目前有些软件细节还没改完,没法打包。所以先把界面、进展、关键技术记录一下,稍后更新。
日子很长,不差这几天。
最近没啥牛逼的闭源更新,都跑去玩开源了。有什么好玩的开源项目没?或者——开源自己的项目?
```