Cline SDK ClineCore 运行时:用内置工具、会话持久化与多进程 Hub 构建有状态编码智能体
本文围绕 Cline SDK 中 @cline/core 包的核心运行时 ClineCore 展开:它如何把 Agent 循环、内置工具、.cline/ 配置发现、SQLite 会话持久化与可选的 Hub 多进程支持整合为一个完整的有状态运行时。读完后,你将能够独立完成 ClineCore 实例的创建与配置、启动和续接会话、订阅事件流、管理会话生命周期(列表/恢复/删除/用量统计),并理解每种后端模式(auto / local / hub / remote)的适用场景与源码实现依据。
何时选择 ClineCore 而非裸 Agent
Cline SDK 提供两层能力:Agent(无状态、最小依赖的 Agent 循环)与 ClineCore(完整运行时)。ClineCore 封装了 Agent 循环,并补齐了生产级应用所需的会话持久化、内置工具、配置发现、插件加载和可选的 Hub 多进程支持(见 ClineCore 运行时参考)。选择建议如下:
| 需要 ClineCore 的场景 | 用 Agent 即可的场景 |
|---|---|
| 需要内置工具(bash、editor 等) | 只需要自定义工具 |
| 需要会话持久化到磁盘 | 无状态运行即可 |
需要从 .cline/ 目录发现配置 |
自己管理配置 |
| 需要定时/自动化 Agent | 不需要调度能力 |
| 需要多客户端共享同一会话 | 单进程运行即可 |
| 在构建完整应用 | 希望最小依赖 |
从源码结构看,ClineCore 类本身是一个“门面”:它持有 RuntimeHost(本地/Hub/远程三种后端)以及 settings、automation、pendingPrompts、featureFlags 等只读服务句柄,绝大多数方法都是对 host 对应能力的直接转发。核心实现位于 ClineCore.ts,包级说明见 @cline/core README。
快速上手
安装 @cline/core 后,最简路径是三步:创建实例 → 启动会话 → 释放资源:
import { ClineCore } from "@cline/sdk"
const cline = await ClineCore.create({ clientName: "my-app" })
const session = await cline.start({
prompt: "Set up CI with GitHub Actions",
config: {
providerId: "anthropic",
modelId: "claude-sonnet-4-6",
apiKey: process.env.ANTHROPIC_API_KEY,
cwd: "/path/to/project",
enableTools: true,
},
})
console.log(session.result?.text)
await cline.dispose()
start() 返回 StartSessionResult,包含 sessionId、manifest、manifestPath、messagesPath,以及会话跑完后的 result?: AgentResult(定义见 ClineCore API 参考)。README 特别提示:当 cwd 与 workspaceRoot 都省略时,运行宿主会把会话放入共享聊天工作区 ~/.cline/data/workspaces/chat,并预置一个 AGENTS.md 规则文件告诉 Agent 以对话模式对待会话、只有用户明确要求时才创建命名项目目录;此时应以 result.manifest.cwd 和 result.manifest.workspace_root 为准读取解析后的路径(见 README 说明)。
实例创建:ClineCoreOptions 全参数
ClineCore.create(options) 是整个 SDK 的主工厂方法。它在内部依次完成:解析 distinctId、归一化 capabilities、按 backendMode 创建 RuntimeHost、初始化特性开关与自动化服务(CronService),详见 create 方法实现。完整选项定义在 cline-core/types.ts:
interface ClineCoreOptions {
clientName?: string // 应用标识,用于遥测与日志
distinctId?: string // 机器/用户标识,默认取系统机器 ID,
// 否则生成 cl-<nanoid> 并持久化到 ~/.cline/data/machine-id
backendMode?: "auto" | "local" | "hub" | "remote"
hub?: HubOptions // hub.endpoint / authToken / strategy 等
remote?: RemoteOptions // remote.endpoint(必填)/ authToken 等
capabilities?: RuntimeCapabilities // 客户端拥有的交互能力回调
telemetry?: ITelemetryService // 省略时遥测为 no-op
featureFlags?: FeatureFlagsService // 省略时使用默认 no-op provider
logger?: BasicLogger // 运行时时选择/回退等诊断日志
toolPolicies?: Record<string, ToolPolicy>
messagesArtifactUploader?: ... // messages.json 落盘后的镜像上传钩子
automation?: boolean | ClineCoreAutomationOptions
fetch?: typeof fetch // 注入自定义 HTTP 行为(代理/重试/测试替身)
prepare?: (input) => StartSessionBootstrap | ...
}
几个值得展开的细节:
distinctId:默认取系统机器 ID,缺失时生成cl-<nanoid>并持久化到~/.cline/data/machine-id,用于遥测归属(types.ts 注释)。fetch:会被透传给本地会话所用 AI 网关各 provider 的ProviderConfig.fetch,用于注入代理、重试、追踪或测试替身。注意作用范围:仅对本进程内执行的会话(local 及 auto 回退 local)生效;Hub/remote 运行时的 HTTP 调用发生在拥有网关的那个进程内,需在@cline/hub的startHubServer({ fetch })处配置(fetch 字段注释)。prepare:每次会话启动前的准备钩子,可用于装配工作区级运行时状态(watcher/扩展/遥测),再通过返回的StartSessionBootstrap.applyToStartSessionInput()改写启动输入。注意它运行在宿主解析省略的工作区之前,因此“无路径启动”时cwd/workspaceRoot对该钩子均不可见(README Session Bootstrap)。automation:传true或ClineCoreAutomationOptions启用文件/事件驱动的自动化;autoStart不为false时,create()内部会自动调用automation.start()(ClineCore.create)。
HubOptions 与 RemoteOptions
interface HubOptions {
endpoint?: string
authToken?: string
strategy?: "prefer-hub" | "require-hub"
clientType?: string
displayName?: string
workspaceRoot?: string
cwd?: string
}
interface RemoteOptions {
endpoint: string // remote 模式下必填
authToken?: string
clientType?: string
displayName?: string
workspaceRoot?: string
cwd?: string
}
两者定义见 types.ts。hub 在 backendMode 为 "hub" 或 "auto"(偏好共享本地 Hub)时生效;remote 仅在 backendMode: "remote" 时相关。
后端模式:auto / local / hub / remote
| 模式 | 行为 |
|---|---|
"auto"(默认) |
优先尝试连接本地 Hub;不可用时回退到进程内执行 |
"local" |
进程内执行 + 本地 SQLite 存储,不接触 Hub |
"hub" |
要求存在可用的本地 WebSocket Hub,否则失败 |
"remote" |
连接显式指定的远程 Hub 端点 |
模式选择在 createRuntimeHost(options) 中完成(ClineCore.create 调用点),底层宿主类型包括 LocalRuntimeHost、HubRuntimeHost、RemoteRuntimeHost。实践建议与参考文档一致:简单脚本和 CLI 工具使用 "local" 可避免 Hub 发现开销;Hub 模式则解锁多客户端会话共享——例如一个仪表板进程订阅另一个进程里正在运行的会话事件(auto 模式默认优先本地 Hub,从 hub-runtime-host 测试 可看到其工作区解析行为)。
启动会话:ClineCoreStartInput 与 CoreSessionConfig
cline.start(input) 接受 ClineCoreStartInput,其结构为:
interface ClineCoreStartInput {
prompt: string
config: CoreSessionConfig
source?: string // 会话来源标记
interactive?: boolean
sessionMetadata?: Record<string, unknown>
initialMessages?: AgentMessage[]
toolPolicies?: Record<string, ToolPolicy>
capabilities?: RuntimeCapabilities
localRuntime?: LocalRuntimeStartOptions // 本地运行时的启动选项
}
config: CoreSessionConfig 是核心配置面(完整定义见 API 参考):
interface CoreSessionConfig {
cwd?: string // 工作目录
providerId: string // LLM 提供商(必填)
modelId: string // 模型标识(必填)
apiKey?: string // 提供商 API Key
systemPrompt?: string // 自定义系统提示词
tools?: readonly AgentTool[] // 追加的自定义工具
enableTools?: boolean // 是否启用内置工具
hooks?: Partial<AgentRuntimeHooks> // 运行时钩子
extensions?: AgentPlugin[] // 内联加载的插件对象
pluginPaths?: string[] // 插件包目录路径
extensionLoading?: "isolated" | "direct"
extensionContext?: {
workspace?: { rootPath: string; cwd: string } // 传给插件 setup() 的上下文
}
checkpointConfig?: CoreCheckpointConfig
compactionConfig?: CoreCompactionConfig
telemetry?: ITelemetryService
logger?: BasicLogger
enableSpawnAgent?: boolean // 允许生成子 Agent
enableAgentTeams?: boolean // 启用团队协同
teamName?: string
}
start() 的实际执行路径是:归一化输入 → 调用 prepare 钩子(若有)→ 交给 host.startSession(),并在成功后发出 session-started 遥测;任何一步失败都会先清理 bootstrap 再抛出(start 方法)。两个容易踩坑的点:
extensions与pluginPaths是两条插件注入路径:前者直接传插件对象,后者指向package.json中含cline.plugins字段的目录。- 必须设置
extensionContext.workspace,否则插件setup()中的ctx.workspaceInfo为undefined(API 参考说明)。
内置工具与配置发现
当 enableTools: true 时,ClineCore 自动提供以下内置工具:
| 工具 | 说明 |
|---|---|
bash |
执行 shell 命令 |
editor |
编辑文件 |
read_files |
读取文件内容 |
apply_patch |
应用 unified diff |
search |
搜索文件内容与结构 |
fetch_web |
HTTP 请求与网页内容获取 |
从源码结构看,这些工具由 createBuiltinTools(...) 统一装配进运行时构建器,见 runtime-builder.ts;@cline/core 同时导出 createDefaultTools、createDefaultExecutors 供宿主自行组合(README Default Tools 一节)。
除代码内配置外,ClineCore 还会监听 .cline/ 目录,发现以下六类资源:
- Rules(系统提示词附加内容)
- Skills(领域知识)
- Workflows(多步骤流程)
- Hooks(生命周期逻辑)
- Plugins(工具 + 钩子捆绑包)
- MCP servers(外部工具提供方)
这使得“把仓库里的 .cline/ 目录配好,任何 ClineCore 应用自动获得这些能力”成为可能,也是它与裸 Agent 的关键差异之一。
关键 API 一览
以下 API 均来自 ClineCore 公开接口(实现见 ClineCore.ts):
| API | 说明 | 源码映射 |
|---|---|---|
ClineCore.create(options) |
创建并初始化实例 | static create |
cline.start(input) |
启动新会话 | host.startSession |
cline.send({ sessionId, prompt }) |
发送后续消息 | host.runTurn |
cline.subscribe(listener, options?) |
订阅会话事件,返回 unsubscribe | host.subscribe |
cline.list(limit = 200, options?) |
列出历史会话 | listSessionHistory |
cline.get(sessionId) |
获取会话元数据 | host.getSession |
cline.readMessages(sessionId) |
读取持久化消息(模型/回放视角) | host.readSessionMessages |
cline.getAccumulatedUsage(sessionId) |
累计 token/成本 | host 服务扩展 |
cline.abort(sessionId) |
中止当前工具执行,会话继续存活 | host.abort |
cline.stop(sessionId) |
优雅终止会话(不可再续) | host.stopSession |
cline.update(sessionId, updates) |
更新会话元数据(如 title) | host.updateSession |
cline.delete(sessionId) |
删除会话及全部关联数据 | host.deleteSession |
cline.restore(input) |
从 checkpoint 恢复会话 | host.restoreSession |
cline.dispose(reason?) |
释放全部资源,之后实例不可复用 | host.dispose |
几点语义澄清,避免误用:
abort与stop的区别:abort(sessionId)中断的是“正在执行的工具操作”(如文件读取、shell 命令),会话仍存活并继续处理;stop(sessionId)则彻底结束会话且无法恢复(abort 文档注释、stop 文档注释)。readMessagesvsreadLiveMessages:持久化转录只在 assistant 消息/轮次边界追上磁盘,进行中的轮次可能缺失;需要“当前对话”时(如 plan/act 模式切换时为新会话播种消息)应使用readLiveMessages,它优先读取宿主内存中的实时对话(readLiveMessages 注释)。此外readDisplayMessages提供面向 UI 展示的消息投影,把观测类模型工具活动投影为普通工具块。getAccumulatedUsage返回两个口径:usage只统计根/主 Agent,aggregateUsage额外包含 teammates 与子 Agent。list(limit)默认 200(list 方法)。
从 checkpoint 恢复:restore
skill 文档中的简写是 cline.restore({ sessionId, checkpointId }),而当前仓库源码中 RestoreInput 的实际字段为 checkpointRunCount(数字,表示修剪到第几个 run),且可选附带 start(在新会话中继续)与 restore 选项(RestoreInput/RestoreOptions 定义):
interface RestoreInput {
sessionId: string
checkpointRunCount: number
start?: ClineCoreStartInput // 恢复后立即开始新会话
cwd?: string
restore?: {
messages?: boolean // 默认 true:fork 出修剪到 checkpoint 的消息历史
workspace?: boolean // 默认 true:从 checkpoint 的 git 快照恢复工作区文件
omitCheckpointMessageFromSession?: boolean
}
}
配套的 cline.compareCheckpoint({ sessionId, checkpointRunCount, cwd }) 可比较 checkpoint 与工作区当前状态的差异(compareCheckpoint)。
事件流:CoreSessionEvent 与 AgentResult
cline.subscribe(listener, { sessionId? }) 发出的是 ClineCore 层面的 CoreSessionEvent 类型,它与独立 Agent 类发出的 AgentRuntimeEvent 是不同的两套事件体系(完整对比见 events/REFERENCE.md):
type CoreSessionEvent =
| { type: "chunk"; payload: SessionChunkEvent }
| { type: "agent_event"; payload: { sessionId: string, event: AgentEvent } }
| { type: "ended"; payload: SessionEndedEvent }
| { type: "team_progress"; payload: SessionTeamProgressEvent }
| { type: "status"; payload: { sessionId: string, status: string } }
| { type: "hook"; payload: SessionToolEvent }
流式输出场景的标准写法:
cline.subscribe((event) => {
switch (event.type) {
case "chunk":
if (event.payload.type === "text") {
process.stdout.write(event.payload.text)
}
break
case "ended":
console.log(`Session ended: ${event.payload.finishReason}`)
break
}
})
注意结果对象上的字段差异:ClineCore 的结果使用 AgentResult.text,而独立 Agent 的 AgentRunResult 使用 .outputText——混用两套 API 时这是最常见的字段取不到值的原因。AgentResult 完整字段包括 text、usage、messages、toolCalls、iterations、finishReason(completed | max_iterations | aborted | mistake_limit | error)、model、startedAt/endedAt/durationMs(见 API 参考 AgentResult)。
会话持久化布局
所有会话统一存储在 ~/.cline/data/sessions/ 下:
~/.cline/data/sessions/
sessions.db # SQLite 数据库(会话索引)
[session-id]/ # 每会话一个目录
[session-id].json # 消息历史/manifest
源码依据:SQLite 库文件由 SqliteSessionStore 在会话数据目录中创建为 sessions.db(sqlite-session-store.ts);历史列举路径则直接扫描该目录、读取 [session-id]/[session-id].json manifest(history.ts)。这个布局支撑了跨实例能力——任意同机 ClineCore 实例都能 list / readMessages / restore 之前创建的会话。
实战模式(源自 patterns 文档)
以下模式整理自 ClineCore Patterns,均可直接用于生产代码。
多轮会话
const session = await cline.start({
prompt: "Create a new Express server",
config: {
providerId: "anthropic",
modelId: "claude-sonnet-4-6",
cwd: "/path/to/project",
enableTools: true,
},
})
const result = await cline.send({
sessionId: session.sessionId,
prompt: "Now add a health check endpoint",
})
console.log(result?.text)
分层权限模型(ToolPolicy)
读取类工具自动放行,写类工具走审批回调:
const cline = await ClineCore.create({
clientName: "my-app",
toolPolicies: {
read_files: { autoApprove: true },
search: { autoApprove: true },
fetch_web: { autoApprove: true },
bash: { autoApprove: false },
editor: { autoApprove: false },
apply_patch: { autoApprove: false },
},
capabilities: {
requestToolApproval: async (request) => {
const approved = await promptUser(
`Allow ${request.toolName}?\n${JSON.stringify(request.input, null, 2)}`
)
return { approved }
},
},
})
ToolPolicy 仅两个字段:enabled: false 表示工具对模型完全隐藏;autoApprove: false 表示执行前必须经过 requestToolApproval 回调(ToolPolicy 定义)。toolPolicies 既可以在 create() 级别设置,也可以在 start() 输入中按会话覆盖。
自定义工具与内置工具并存
import { ClineCore, createTool } from "@cline/sdk"
import { z } from "zod"
const deployTool = createTool({
name: "deploy",
description: "Deploy the application to the specified environment.",
inputSchema: z.object({
environment: z.enum(["staging", "production"]),
}),
execute: async (input) => {
const result = await runDeployment(input.environment)
return { url: result.url, status: "deployed" }
},
})
await cline.start({
prompt: "Deploy the app to staging",
config: {
providerId: "anthropic",
modelId: "claude-sonnet-4-6",
cwd: process.cwd(),
enableTools: true,
tools: [deployTool],
},
})
无状态 Worker 模式(API/队列负载)
一个长驻 ClineCore 实例 + backendMode: "local",每个请求开新会话,返回文本、用量与会话 ID,会话本身留盘可追溯:
const cline = await ClineCore.create({
clientName: "worker",
backendMode: "local",
})
async function handleRequest(prompt: string, workspace: string) {
const session = await cline.start({
prompt,
config: {
providerId: "anthropic",
modelId: "claude-sonnet-4-6",
cwd: workspace,
enableTools: true,
},
})
return {
text: session.result?.text,
usage: session.result?.usage,
sessionId: session.sessionId,
}
}
Hub 多客户端共享
// 进程 1:启动会话
const cline = await ClineCore.create({
clientName: "backend",
backendMode: "hub",
})
const session = await cline.start({
prompt: "Long running refactor task",
config: { /* ... */ },
})
// 进程 2:附着同一会话并按 sessionId 过滤订阅
const viewer = await ClineCore.create({
clientName: "dashboard",
backendMode: "hub",
})
viewer.subscribe((event) => {
dashboard.render(event)
}, { sessionId: session.sessionId })
会话列举与回放、优雅退出
// 列出最近 10 个会话
const sessions = await cline.list(10)
for (const session of sessions) {
console.log(`${session.id}: ${session.title}`)
}
// 回放消息 + 用量统计
const messages = await cline.readMessages(sessions[0].id)
const usage = await cline.getAccumulatedUsage(sessions[0].id)
console.log(`Total tokens: ${usage.aggregateUsage.totalInputTokens + usage.aggregateUsage.totalOutputTokens}`)
// SIGTERM 时优雅释放
process.on("SIGTERM", async () => {
await cline.dispose("SIGTERM received")
process.exit(0)
})
自动化 API(Scheduled / Event-Driven Agents)
在 create() 中启用 automation: true(或传入 ClineCoreAutomationOptions,如 cronSpecsDir、cronScope、pollIntervalMs、globalMaxConcurrency 等,见 ClineCoreAutomationOptions)后,实例即获得 cline.automation 控制器:
const cline = await ClineCore.create({
clientName: "my-app",
automation: true,
})
cline.automation.start()
cline.automation.stop()
cline.automation.reconcileNow()
cline.automation.ingestEvent(event) // 事件驱动入口
cline.automation.listEvents(options?)
cline.automation.listSpecs(options?) // one_off / schedule / event 三类触发器
cline.automation.listRuns(options?) // 状态: queued | running | done | failed | cancelled
底层由 CronService 承担(SQLite 存储 + 轮询 + 事件摄取),未启用 automation 时调用任何 cline.automation.* 会抛出明确错误提示(构造函数中的守护逻辑)。
小结与延伸阅读
ClineCore 的定位可以用一句话概括:@cline/core 是 Cline SDK 的“有状态编排层”,把 Agent 运行时、provider 配置、存储、默认工具与会话生命周期组装为宿主就绪的运行时(README 首段)。选型时的判断顺序是:先问是否需要内置工具/持久化/配置发现/调度/多客户端(是则 ClineCore),再看部署形态决定 backendMode(单机脚本 local,多进程共享 hub,跨机 remote,探索期 auto)。
配套资料(均在当前仓库内):
- ClineCore 运行时参考 REFERENCE.md — 本文的原始参考文档
- ClineCore API 参考 api.md — 完整接口细节
- 常见模式 patterns.md — 模式代码集
- 常见坑与调试 gotchas.md
- 内置实现入口 ClineCore.ts、选项类型 cline-core/types.ts
- 周边主题:tools/REFERENCE.md(自定义工具)、plugins/REFERENCE.md(插件系统)、scheduling/REFERENCE.md(定时 Agent)
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 StartedRust0622
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