首页
/ Cline CLI 本地开发指南:Bun 工作区构建、OpenTUI 终端 UI 架构与调试实战

Cline CLI 本地开发指南:Bun 工作区构建、OpenTUI 终端 UI 架构与调试实战

2026-09-06 13:03:56作者:韦蓉瑛

本文以 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 依次执行 cleaninstallbuild: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.jsondev 脚本的定义就是文档中给出的最终形态:

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.jsonexports 字段解析 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.jsonworkspaces 字段声明了 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(含 sharedllmsagentscoreuisdk 子包)。

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.3react 19.2.4@opentui/core/@opentui/react 均固定 0.4.3@opentui-ui/dialog ^0.1.2opentui-spinnerpino ^10.3.1;devDependencies 中还有 TUI 自动化测试用的 @microsoft/tui-testtuistory ^0.10.1。根 package.jsonpatchedDependencies 表明仓库对 @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.tsxchat-entry.tsxinput-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 的完整实现,可以补充三个文档未展开的工程细节:

  1. 主题先行绘制:渲染首帧前会先探测终端调色板(renderer.getPalette({ timeout: 150 })),并用所选主题的 appBackground 设置渲染器背景,避免启动瞬间闪现终端自带背景色;
  2. stdio 捕获与恢复installTuiStdioCapture() 在渲染期间接管 stdio,失败路径上会 restoreStdio()renderer.destroy() 后重新抛出;
  3. 优雅销毁destroy()root.unmount(),再在微任务里(等 OpenTUI 解析完当前 stdin 批次)重置终端标题、销毁渲染器;waitUntilExit() 返回的 Promise 在 renderer.on("destroy") 时 resolve。

文档强调的运行时契约与此一致:渲染器返回 destroy()waitUntilExit(),运行时退出时调用 destroy() 并 await waitUntilExit() 完成清理。

5.2 运行时桥:run-interactive.ts

该文件是 SDK 与 TUI 之间的唯一桥梁,职责有四:

  1. 通过 createCliCore() 创建 SessionManager
  2. 建立事件订阅(agent 事件、pending prompts、team 事件);
  3. 以 props 形式向 TUI 传递回调(onSubmitonAbortonModelChange 等);
  4. 管理会话生命周期(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.tsxevent-bridge-context.tsx 两个 Provider 实现;views/ 目录下则有 home-view.tsxchat-view.tsxconfig-view.tsxhistory-view.tsxonboarding/ 子目录。

5.4 Context Provider:各自掌管一块状态

  • SessionContext — 核心聊天状态:entries: ChatEntry[](会话全部消息)、isRunning/abortRequested(agent 执行态)、mode(plan/act)、autoApproveAllhasSubmittedlastTotalTokenslastTotalCostturnStartTime 等。
  • EventBridgeContext — SDK 事件订阅:在 useEffect 中通过 subscribeToEvents prop 订阅一次,借助稳定 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.tsuse-autocomplete.tsuse-slash-commands.tsuse-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 接收 resolvedismiss 回调,用 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 惯例:flexDirectionflexGrowflexShrinkgappaddingmargin 等。

六、测试与代码质量

测试命令(仓库根目录或 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:unitvitest run --config vitest.config.ts,三个 E2E 变体分别使用 vitest.e2e.config.tsvitest.interactive.e2e.config.tsvitest.tuistory.e2e.config.tstest: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 组件

  1. src/tui/components/ 下创建 .tsx 文件;
  2. 文件顶部加 JSX pragma:// @jsxImportSource @opentui/react
  3. 用 OpenTUI 元素(<box><text> 等)搭建布局;
  4. 在父视图或 root 中 import 并使用。

7.5 新增 Dialog

  1. 编写接收 ChoiceContext<T> props 的内容组件;
  2. useDialogKeyboard 处理键盘;
  3. resolve(value) 返回结果,dismiss() 取消;
  4. 从 hook 或视图打开:const result = await dialog.choice<T>({ content: ... })
  5. 任何异步数据在调用 dialog.choice() 之前取好,不要放在 dialog 内部(呼应 5.7 节的布局坑点)。

7.6 新增斜杠命令

  1. root.tsx 的斜杠命令处理区定义命令 handler;
  2. components/dialogs/help-dialog.tsx 的帮助对话框中登记该命令;
  3. 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:http server 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 附加稳定的运行时日志绑定(如 clientIdclientTypeclientApp)。

登录之后,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.tsapps/cli/script/guard-direct-publish.ts),防止绕过发布流水线直接 bun publish 出错包。

参考入口

登录后查看全文
热门项目推荐
相关项目推荐