Cline CLI 本地开发指南:Bun 工作区构建、OpenTUI 终端 UI 架构与调试实战
本文以 apps/cli/DEVELOPMENT.md 为蓝本,系统讲解如何从零搭建 Cline CLI(@cline/cli)的本地开发环境:从 Bun + Zig + Node.js 三件套的准备、工作区安装与构建,到 bun link 全局链接的模块解析陷阱,再到基于 OpenTUI + React 19 的 TUI 架构(Provider 树、事件流、ChatEntry 数据模型、Dialog 系统)与 tuistory 无头终端调试方案。读完你可以独立完成 CLI 的日常开发、修改 SDK 包后的重建、新增 TUI 组件/Dialog/斜杠命令,以及类型检查、单测、E2E 测试的完整验证链路。
一、环境准备:Bun、Zig 与 Node.js 三件套
开发 Cline CLI 需要在克隆仓库后先装齐三样工具,缺少任何一项都会导致后续步骤失败:
| 依赖 | 版本要求 | 角色 |
|---|---|---|
| Bun | ≥ 1.0.0 | 包管理器、运行时、打包器 |
| Zig | 任意近期稳定版 | OpenTUI 原生核心的编译工具链 |
| Node.js | ≥ 22 | 部分构建工具与测试基础设施 |
其中 Zig 是最容易忽略的一环:@opentui/core 包内附带了一个用 Zig 编写的原生二进制,在 bun install 安装阶段会从源码现场构建。没有 Zig 时,OpenTUI 相关包的安装会直接失败。仓库根 package.json 也印证了这一点:engines 声明 "bun": "1.3.13"、"node": ">=22",并通过 overrides 将 @opentui/core、@opentui/react 锁定在 0.4.3,在 trustedDependencies 中放行了原生依赖的构建。
验证环境:
bun --version # 应 >= 1.0.0
zig version # 任意近期稳定版
node --version # 应 >= 22
二、首次搭建:安装、构建与 dev 模式运行
在仓库根目录执行:
# 安装全部 workspace 依赖(含 OpenTUI 原生构建)
bun install
# 构建 SDK 各包与 CLI
bun run build
# 以 dev 模式(交互式)运行 CLI
bun run cli
对照 根 package.json 的 scripts 可以看到真实调用链:
build依次执行clean→install→build:sdk→ 进入@cline/cli子工作区构建(bun -F @cline/cli build,实际跑 apps/cli/bun.mts);build:sdk通过bun --production -F './sdk/packages/*' build批量构建sdk/packages/下的所有 SDK 包;- 根级的
cli脚本是bun --conditions=development --cwd apps/cli dev,即进入apps/cli工作区执行其dev脚本。
apps/cli/package.json 中 dev 脚本的定义就是文档中给出的最终形态:
CLINE_BUILD_ENV=development bun --conditions=development ./src/index.ts
这里有两个关键细节:CLINE_BUILD_ENV=development 让运行时知道自己处于开发态;--conditions=development 使 Bun 直接从源码解析 @cline/llms、@cline/core 等 workspace 包,而不是走 package.json exports 指向的 dist/。这就是为什么 dev 模式下改动 SDK 源码后无需重新构建(见下文第五节)。
2.1 全局链接:bun link 与 dist 依赖陷阱
想让 cline 命令在任意目录可用,需要先构建 SDK 再链接:
# 仓库根目录 -- 构建全部 workspace 包
bun run build:sdk
# 然后链接 CLI 二进制
cd apps/cli
bun link
build:sdk 这一步不可省略,原因在于 bun link 不带 --conditions=development,Bun 会按 package.json 的 exports 字段解析 workspace 包,而 SDK 各包(如 @cline/core)的 main/exports 都指向 dist/。没有先跑构建,dist/ 不存在,运行时会报 "Cannot find module"。链接后即可在任意目录使用:
cline # 交互模式
cline "prompt" # 单条提示模式
cline auth # 认证某个 provider
若不想走构建,直接在 apps/cli/ 下 bun run dev 即可——dev 模式的 --conditions=development 会把包解析到源码。
2.2 SDK 变更后的重建策略
如果你修改了 sdk/packages/ 下任何包(shared、llms、agents、core 等),需要重建 SDK:
bun run build:sdk
两条路径的取舍:
- 使用
bun run dev:包直接从源码解析,SDK 改动即时生效,无需重建; - 使用链接后的
cline二进制:走dist/产物,必须bun run build:sdk后改动才生效。
三、Monorepo 结构与 CLI 源码布局
仓库是一个 Bun workspace 单仓(根 package.json 的 workspaces 字段声明了 sdk/packages/*、apps/*、apps/examples/* 等)。开发文档给出的结构概览:
packages/ # SDK 包(发布到 npm),实际位于 sdk/packages/
shared/ # 契约、schema、路径助手、运行时工具
llms/ # Provider 配置、模型目录、AI SDK handler
agents/ # 无状态 agent 循环、工具编排、hooks
scheduler/ # 定时执行、并发控制
core/ # 有状态编排、会话、hub、存储、配置
enterprise/ # 内部企业集成(不对外发布)
apps/
cli/ # 本包 -- CLI 宿主与 TUI
code/ # Tauri + Next.js 桌面应用
vscode/ # VS Code 扩展
desktop/ # 桌面应用
examples/ # 示例集成
biome.json # Linter 与格式化工具配置(Biome)
需要说明的是,文档中的 cline-sdk/ 是逻辑视图;在当前仓库中 SDK 包实际位于 sdk/packages(含 shared、llms、agents、core、ui、sdk 子包)。
CLI 侧的源码布局(apps/cli/src/):
apps/cli/src/
index.ts # 入口(shebang、信号处理)
main.ts # CLI 命令定义、参数解析
runtime/
run-interactive.ts # 交互模式运行时(会话生命周期、事件接线)
run-agent.ts # 单条提示运行时
session-events.ts # 事件桥接类型与 pub/sub
active-runtime.ts # Abort 注册表
tool-policies.ts # 自动批准切换逻辑
prompt.ts # 系统提示词与用户输入组装
defaults.ts # 默认配置值
tui/ # 终端 UI(OpenTUI + React)
index.tsx # 渲染器入口
root.tsx # Provider 树、视图路由、全局键盘
types.ts # ChatEntry 联合类型、TuiProps、共享常量
interactive-config.ts # 配置数据加载
interactive-welcome.ts # 欢迎行、斜杠命令解析
components/ # 可复用 UI 组件
contexts/ # React Context Provider
hooks/ # 自定义 React hooks
views/ # 全屏视图组件
utils/ # TUI 专用工具
session/ # 会话状态管理
commands/ # CLI 子命令(auth、config、history 等)
connectors/ # 聊天适配器桥(Telegram、Slack 等)
utils/ # 共享工具
wizards/ # 交互式配置向导
logging/ # Pino 日志适配器
从 apps/cli/src/index.ts 的实现可以验证入口文档描述得相当精确:文件顶部是 #!/usr/bin/env bun shebang;启动时先调用 initVcr(process.env.CLINE_VCR)(设置 CLINE_VCR=record|playback 可录制/回放 HTTP,便于测试);随后做信号接线——SIGINT/SIGTERM 都转发给 abortActiveRuntime(),uncaughtException/unhandledRejection 走统一的 handleFatalProcessError(其中对 abort 过程中的预期 rejection 做了特殊吞没,避免 OpenTUI 错误浮层误报);最后动态 import("./main") 执行 runCli(),并在退出前 disposeAll()、尽力应用启动时记录的延迟自动更新。
四、技术栈选型:为什么是 OpenTUI
| 层 | 技术 | 用途 |
|---|---|---|
| 运行时 | Bun | 包管理、脚本执行、打包 |
| 语言 | TypeScript (strict) | 全部源码 |
| CLI 框架 | Commander.js | 参数解析、子命令 |
| TUI 渲染器 | OpenTUI(@opentui/core) |
原生终端渲染引擎(Zig + C ABI) |
| TUI 组件 | OpenTUI React(@opentui/react) |
面向终端 UI 的 React 19 reconciler |
| TUI 对话框 | @opentui-ui/dialog |
模态对话框系统(模型选择器、工具审批等) |
| Linter/Formatter | Biome | 代码质量与格式化 |
| 测试 | Vitest | 单元与 E2E 测试 |
| 日志 | Pino | 运行时文件日志 |
apps/cli/package.json 的依赖清单与上表一一对应:commander ^14.0.3、react 19.2.4、@opentui/core/@opentui/react 均固定 0.4.3、@opentui-ui/dialog ^0.1.2、opentui-spinner、pino ^10.3.1;devDependencies 中还有 TUI 自动化测试用的 @microsoft/tui-test 与 tuistory ^0.10.1。根 package.json 的 patchedDependencies 表明仓库对 @opentui-ui/dialog@0.1.2 打了本地补丁(patches/@opentui-ui%2Fdialog@0.1.2.patch)。
OpenTUI 是 Zig 编写、暴露 C ABI、再由 TypeScript 绑定的原生终端 UI 核心。相比 Cline 此前的终端渲染方案,它带来:
- 原生 diff 渲染与语法高亮
- 流式 Markdown 渲染
- 可滚动内容区域
- 鼠标交互(点击、悬停、拖选、滚动)
- 内建剪贴板支持(OSC52)
- 原生渲染带来的更高性能
CLI 实际用到的 OpenTUI 生态包:
@opentui/core— 原生渲染器与内建元素@opentui/react— React reconciler(createRoot、hooks)@opentui-ui/dialog— 对话框/模态系统opentui-spinner— Spinner 组件
五、TUI 架构深入
TUI 位于 apps/cli/src/tui/,采用 React + OpenTUI reconciler 实现。每个 .tsx 文件顶部都带 per-file JSX pragma:
// @jsxImportSource @opentui/react
apps/cli/tsconfig.json 中已全局设置 "jsx": "react-jsx" 与 "jsxImportSource": "@opentui/react",per-file pragma 的作用是让意图更显式,并避免与非 TUI React 代码产生冲突。当前 src/tui/ 下约有十余个带该 pragma 的文件(root.tsx、chat-entry.tsx、input-bar.tsx、各 dialog 与 model-selector 组件等)。
5.1 入口:index.tsx 与 renderOpenTui
TUI 通过 renderOpenTui() 启动。文档给出的核心片段:
const renderer = await createCliRenderer({
exitOnCtrlC: false, // Ctrl+C 由我们自己处理
autoFocus: false, // 避免任意位置点击抢走焦点
enableMouseMovement: true,
});
const root = createRoot(renderer);
root.render(<Root {...props} />);
对照 apps/cli/src/tui/index.tsx 的完整实现,可以补充三个文档未展开的工程细节:
- 主题先行绘制:渲染首帧前会先探测终端调色板(
renderer.getPalette({ timeout: 150 })),并用所选主题的appBackground设置渲染器背景,避免启动瞬间闪现终端自带背景色; - stdio 捕获与恢复:
installTuiStdioCapture()在渲染期间接管 stdio,失败路径上会restoreStdio()并renderer.destroy()后重新抛出; - 优雅销毁:
destroy()先root.unmount(),再在微任务里(等 OpenTUI 解析完当前 stdin 批次)重置终端标题、销毁渲染器;waitUntilExit()返回的 Promise 在renderer.on("destroy")时 resolve。
文档强调的运行时契约与此一致:渲染器返回 destroy() 与 waitUntilExit(),运行时退出时调用 destroy() 并 await waitUntilExit() 完成清理。
5.2 运行时桥:run-interactive.ts
该文件是 SDK 与 TUI 之间的唯一桥梁,职责有四:
- 通过
createCliCore()创建SessionManager; - 建立事件订阅(agent 事件、pending prompts、team 事件);
- 以 props 形式向 TUI 传递回调(
onSubmit、onAbort、onModelChange等); - 管理会话生命周期(start、stop、restart、resume、compact)。
这条“TUI 不直接碰 SDK”的约束在源码结构中可以得到印证:apps/cli/src/runtime/ 下实际存在 interactive/session-runtime.ts(承载 createCliCore/SessionManager 相关逻辑)、session-events.ts(事件桥接类型与 pub/sub)、active-runtime.ts(abort 注册表)、tool-policies.ts 等,而 src/tui/ 内部没有任何直接 import SDK 会话管理的代码——TUI 只消费 TuiProps(定义于 apps/cli/src/tui/types.ts)中的回调与数据。
5.3 组件树
Root (root.tsx)
DialogProvider # 模态对话框系统
SessionProvider # 聊天条目、运行状态、模式
EventBridgeProvider # 订阅 SDK 事件
View Router
HomeView # 欢迎屏(首次提交前)
ChatView # 消息列表 + 输入栏 + 状态栏
OnboardingView # 首次运行的 provider 配置
ConfigView (dialog) # 设置浏览器
HistoryView (dialog) # 会话历史
contexts/ 目录下对应着 session-context.tsx 与 event-bridge-context.tsx 两个 Provider 实现;views/ 目录下则有 home-view.tsx、chat-view.tsx、config-view.tsx、history-view.tsx 与 onboarding/ 子目录。
5.4 Context Provider:各自掌管一块状态
- SessionContext — 核心聊天状态:
entries: ChatEntry[](会话全部消息)、isRunning/abortRequested(agent 执行态)、mode(plan/act)、autoApproveAll、hasSubmitted、lastTotalTokens、lastTotalCost、turnStartTime等。 - EventBridgeContext — SDK 事件订阅:在
useEffect中通过subscribeToEventsprop 订阅一次,借助稳定 ref 把 agent 事件转发给 SessionContext 的处理器,并处理 pending prompts 与 team 事件。
组件只订阅自己需要的切片,避免无关重渲染。
5.5 事件流
SDK (AgentLoop)
--> AgentEvent emitted
--> subscribeToAgentEvents() fires
--> UIEventEmitter.emit("agent", event)
--> EventBridgeProvider receives event
--> useAgentEventHandlers processes event
--> SessionContext.entries updated
--> React re-renders affected components
与 tui/hooks/ 下实际存在的 use-agent-events.ts、use-autocomplete.ts、use-slash-commands.ts、use-queued-prompts.ts 等 hooks 相吻合:agent 事件处理被拆到独立 hook 中,保持 EventBridgeProvider 精简。
5.6 ChatEntry 类型:会话消息的判别联合
文档给出的骨架版本:
type ChatEntry =
| { kind: "user"; text: string }
| { kind: "assistant_text"; text: string; streaming: boolean }
| { kind: "reasoning"; text: string; streaming: boolean }
| { kind: "tool_call"; toolName: string; inputSummary: string; ... }
| { kind: "error"; text: string }
| { kind: "status"; text: string }
| { kind: "team"; text: string }
| { kind: "user_submitted"; text: string; delivery?: "queue" | "steer" }
| { kind: "done"; tokens: number; cost: number; elapsed: string; iterations: number }
对照当前源码 apps/cli/src/tui/types.ts,实际联合类型已经比文档更丰富,还包含:
assistant_media(image/audio/video/file 模态的生成媒体);compaction(自动/手动压缩的开始、完成、跳过、失败、取消状态,附带压缩前后 token 与消息数);- 所有条目上额外打一个可选的
mode?: AgentMode戳,保证恢复会话时每条消息按产生时的 plan/act 模式着色,而不是全部染成当前模式。
这个细节对理解 TUI 的数据契约很有参考价值:新增消息种类时,应在该判别联合中扩展 kind,再由渲染层按 kind 分派。
5.7 Dialog 系统
Dialog 基于 @opentui-ui/dialog:
import { useDialog } from "@opentui-ui/dialog/react";
const dialog = useDialog();
const result = await dialog.choice<string>({
style: { maxHeight: termHeight - 2 },
content: (ctx) => <MyDialogContent {...ctx} />,
});
内容组件通过 context 接收 resolve 与 dismiss 回调,用 useDialogKeyboard 做 dialog 作用域内的键盘处理。
重要坑点:在 dialog 内部用 useEffect/useState 做异步数据加载,会在 OpenTUI 中造成 flex 子元素之间的布局空隙。正确做法是先取好数据再打开 dialog,把数据作为 props 传入。
5.8 关键组件速览
components/input-bar.tsx— 文本输入与提交:非受控<textarea>配合key={inputKey}实现重置;通过ref回调接线node.onSubmit(React reconciler 模式);支持换行(Shift+Enter)与自动补全集成。components/chat-entry.tsx— 按kind渲染单条 ChatEntry:assistant 文本走<markdown>渲染、文件编辑走<diff>、文件读取走<code>高亮、流式状态配 Spinner。components/status-bar.tsx— 底部状态栏:模型名、上下文条、token/成本、Plan/Act 模式指示、workspace/分支/自动批准状态。components/tool-output.tsx— 工具结果的富渲染:带语法高亮的 unified diff、可展开/折叠输出段、带行号的文件读取。views/home-view.tsx— 欢迎屏(动画机器人与居中输入框;components/robot-animation.tsx与帧数据文件即为动画来源)。views/chat-view.tsx— 主会话视图(scrollbox + 输入 + 状态栏)。views/onboarding-view.tsx— 首次运行的 provider/模型配置向导。
5.9 OpenTUI 内建元素与样式
OpenTUI 提供一组类 HTML 标签的内建元素:
<box>— Flexbox 容器(类<div>)<text>— 文本显示(类<span>)<span>— 内联文本修饰(给嵌套文本上色)<scrollbox>— 可滚动容器<textarea>— 多行输入<input>— 单行输入<select>— 列表选择<code>— 语法高亮代码块<diff>— unified/split diff 查看器<markdown>— 流式 Markdown 渲染器
样式使用终端命名色作为 props:
<text fg="cyan">colored text</text>
<box backgroundColor="gray" paddingX={1}>padded box</box>
布局遵循 flexbox 惯例:flexDirection、flexGrow、flexShrink、gap、padding、margin 等。
六、测试与代码质量
测试命令(仓库根目录或 apps/cli 下,视脚本而定):
# 单元测试
bun run test:unit
# E2E 测试
bun run test:e2e
bun run test:e2e:interactive
# TUI 专用 E2E(基于 @microsoft/tui-test)
bun run test:e2e:cli:tui
# 通过 tuistory 驱动的 TUI E2E(PTY + Ghostty 终端模拟器)
bun run test:e2e:tuistory
# 类型检查
bun run typecheck
# Lint 与格式化(仓库根自动修复)
cd ../.. && bun run fix
这些脚本在 apps/cli/package.json 中一一对应:test:unit 跑 vitest run --config vitest.config.ts,三个 E2E 变体分别使用 vitest.e2e.config.ts、vitest.interactive.e2e.config.ts、vitest.tuistory.e2e.config.ts;test:e2e:cli:tui 则进入 src/tests 目录直接跑 tui-test(该目录含 tui-test.config.ts 与 fixture)。根目录的 test:unit 则是并行拉起 agents/llms/core/cli/hub/vscode 六个包各自的测试进程。fix 脚本即根 package.json 中的 Biome 检查命令:bun biome check --write --unsafe --diagnostic-level=error ...,覆盖 sdk/、apps/cli/、apps/cline-hub/、apps/examples/。
七、常用开发任务实操
7.1 交互模式运行
bun run dev
7.2 测试 onboarding 流程
用临时配置目录模拟全新安装:
bun run dev -- --interactive --config /tmp/cline-test
或设置 CLINE_FORCE_ONBOARDING=1,无视已有配置强制进入 onboarding 视图。
7.3 无头环境手工驱动 TUI(tuistory)
tuistory(以 devDependency 形式安装)把 TUI 包进一个命名的后台 PTY 会话,可在纯 shell 中脚本化操作——无需真实终端或显示器。这是 AI agent(或任何无头环境)"戳"交互式 TUI 的首选方式:
cd apps/cli
# 在后台会话中启动 TUI
bunx tuistory -s cline --cols 120 --rows 36 -- bun src/index.ts --provider anthropic -m claude-sonnet-4-6 -k test-key
# 反应式等待聊天视图出现(无需 sleep 盲等)
bunx tuistory -s cline wait "What can I do for you?" --timeout 30000
# 交互与检查
bunx tuistory -s cline type "/settings"
bunx tuistory -s cline press enter
bunx tuistory -s cline snapshot --trim # 当前屏幕文本
bunx tuistory -s cline screenshot # 当前屏幕样式化 PNG
# 人类可在另一终端 attach 同一会话观看/接管
tuistory attach -s cline
# 拆毁
bunx tuistory -s cline close
同一引擎也驱动 test:e2e:tuistory 这套 vitest 套件(对应 src/cli.tuistory.e2e.test.ts,仓库中实际文件为 apps/cli/src/cli.tuistory.e2e.test.ts),其中使用编程式 launchTerminal() API 对仿真屏幕做断言。
7.4 新增 TUI 组件
- 在
src/tui/components/下创建.tsx文件; - 文件顶部加 JSX pragma:
// @jsxImportSource @opentui/react; - 用 OpenTUI 元素(
<box>、<text>等)搭建布局; - 在父视图或 root 中 import 并使用。
7.5 新增 Dialog
- 编写接收
ChoiceContext<T>props 的内容组件; - 用
useDialogKeyboard处理键盘; resolve(value)返回结果,dismiss()取消;- 从 hook 或视图打开:
const result = await dialog.choice<T>({ content: ... }); - 任何异步数据在调用
dialog.choice()之前取好,不要放在 dialog 内部(呼应 5.7 节的布局坑点)。
7.6 新增斜杠命令
- 在
root.tsx的斜杠命令处理区定义命令 handler; - 在
components/dialogs/help-dialog.tsx的帮助对话框中登记该命令; - 在
hooks/use-autocomplete.ts中添加自动补全条目。
7.7 调试 TUI:React DevTools
# 带 React DevTools 运行(需要 react-devtools-core@7)
DEV=true bun run dev
# 另开终端
npx react-devtools@7
7.8 调试 CLI 进程:--inspect-brk
cd apps/cli
CLINE_BUILD_ENV=development bun --conditions=development --inspect-brk=6499 ./src/index.ts
然后让 VS Code 或 Chrome DevTools attach 到 ws://127.0.0.1:6499。
八、运行时职责边界、日志与配置迁移
8.1 运行时所有权
文档用一组边界条款划清了 CLI 与 Core 的分工:
- CLI 负责渲染运行时事件、处理终端 UX;
- Core 负责 agent 创建、运行时组合、会话消息持久化;
- CLI 不为聊天/任务执行直接实例化
Agent; - CLI 在 run/interactive 路径中不做直接的 file/db 消息持久化;
- CLI 拥有 user-instruction watcher(rules/workflows/skills),因为提示词组装要在会话开始前就用规则上下文;watcher 在所有退出路径上都会被 dispose;
- RPC 运行时复用同一套 prompt resolver,接受运行时配置中的可选
rules(或调用方完全预构建时直接传systemPrompt)。
commands/ 下的 rpc-runtime/ 子目录与 connectors/ 目录印证了这一划分:CLI 只承担宿主、桥接与渲染职责。
8.2 Connector 运行时行为
面向 Telegram、Slack、Google Chat、WhatsApp 等聊天渠道(对应 apps/cli/src/connectors/ 及 @chat-adapter/* 依赖):
- Telegram 的最终 assistant 回复走 Telegram entity 富文本负载(纯文本兜底);Google Chat 与 WhatsApp 走共享 connector 运行时格式化路径;
- assistant 文本流式增量进入使用共享流式路径的聊天界面;Telegram 在回合完成后才发送最终回复;
- 工具活动被概括为紧凑的 start/error 消息,附短参数预览;
- 需要批准的工具会回贴到聊天线程,接受
Y/N回复; - Google Chat 的 webhook 挂在
/api/webhooks/gchat,Google Chat App URL 配置为<base-url>/api/webhooks/gchat; - webhook 类 connector 通过共享的 CLI
node:httpserver helper 托管,而非Bun.serve; - WhatsApp 的 webhook 挂在
/api/webhooks/whatsapp,Meta callback URL 配置为<base-url>/api/webhooks/whatsapp。
8.3 日志适配器(Pino)
cline 使用 pino 后端适配器实现 core 的 BasicLogger 契约:
- CLI 运行时把
logger直接传入本地@cline/core会话; - Hub 托管的会话把序列化后的 logger payload 放进
ChatStartSessionRequest.logger,运行时重建同一套 pino 配置并注入 core; - 宿主可通过
RuntimeLoggerConfig.bindings附加稳定的运行时日志绑定(如clientId、clientType、clientApp)。
登录之后,OAuth 凭据会持久化 auth.expiresAt,@cline/core 会在会话回合中自动刷新 token。provider 认证与模型设置应通过 cline auth、交互式配置 UI 或 core 的 provider-settings API 变更,不要直接编辑 provider 设置文件。
8.4 启动时的旧配置迁移与自定义 provider 注册
启动时 cline 还会尝试一次 legacy 配置导入:
- 源文件:
<CLINE_DATA_DIR>/globalState.json与<CLINE_DATA_DIR>/secrets.json - 目标文件:
<CLINE_DATA_DIR>/settings/providers.json(或CLINE_PROVIDER_SETTINGS_PATH指定路径) providers.json中已有 provider 从不被覆盖- legacy 文件中发现的缺失 provider 会被合并进
providers.json - 迁移而来的 provider 条目标注
tokenSource: "migration"
自定义 provider 注册的相关约定:
- provider 运行时设置仍持久化在
<CLINE_DATA_DIR>/settings/providers.json; providers.json中的 provider 可通过"protocol": "openai-responses"选择 OpenAI Responses API——运行时改走 OpenAI client,同时保留用户自定义的 provider ID、base URL 与模型目录;- 用户添加的 OpenAI 兼容 provider 模型目录持久化在
<CLINE_DATA_DIR>/settings/models.json(或与CLINE_PROVIDER_SETTINGS_PATH同目录); models.json按 provider ID 存储模型列表,由运行时 provider actions 加载;- 只含
models的条目扩展已有 provider;带provider元数据的条目则注册或覆盖自定义 provider。
九、发布流程
CLI 以 cline 包装包形式发布到 npm,各平台二进制位于 @cline/cli-* 之下。发布流程在仓库根的 publish-cli skill(.cline/skills/publish-cli/SKILL.md)中定义。在 apps/cli 工作区内:
# 干跑:检查包体积与构建产物
bun publish --dry-run
# 发布到 npm(需先做版本号提升)
bun run release
打包细节参见 apps/cli/DISTRIBUTION.md。从 apps/cli/package.json 可以看到配套防护:prepack/prepublishOnly 都会执行 bun script/guard-direct-publish.ts(apps/cli/script/guard-direct-publish.ts),防止绕过发布流水线直接 bun publish 出错包。
参考入口
- 开发文档本体:apps/cli/DEVELOPMENT.md
- CLI 使用与命令参考:apps/cli/README.md
- 入口与信号处理:apps/cli/src/index.ts、apps/cli/src/main.ts
- TUI 渲染入口与类型契约:apps/cli/src/tui/index.tsx、apps/cli/src/tui/types.ts
- 运行时桥与会话:apps/cli/src/runtime/run-interactive.ts、apps/cli/src/runtime/interactive/session-runtime.ts
- 工作区脚本与版本锁定:package.json、apps/cli/package.json
- 发布打包说明:apps/cli/DISTRIBUTION.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00