Cline 定时自动化实战:用 type-check-strict.cron.md 构建每日 TypeScript 严格类型检查
在大型 TypeScript 项目中,类型问题往往在开发高峰期的缝隙里悄然积累:隐式 any、缺失的注解、null/undefined 边界遗漏,最终都变成重构时的技术债。Cline 的自动化体系提供了一份现成的解法模板——type-check-strict.cron.md:一个每天凌晨 6 点自动执行 tsc --noEmit 严格类型检查、分类统计错误并输出改进建议的定时自动化任务。读完本篇,你将掌握 Cline cron spec(.cron.md)的完整字段语义、这份模板的检查流程与报告结构,以及如何在本地将其落地为自己的定时质检任务。
一、type-check-strict 规范文件全解
先看这份规范文件的完整内容(sdk/examples/cron/type-check-strict.cron.md):
---
id: type-check-strict
title: Strict TypeScript Type Checking
workspaceRoot: /absolute/path/to/repo
schedule: "0 6 * * *"
tools: run_commands,read_files
mode: plan
enabled: false
modelSelection:
providerId: cline
modelId: anthropic/claude-opus-4.7
timeoutSeconds: 1800
maxIterations: 20
tags:
- automation
- quality
- typescript
metadata:
owner: development
strictLevel: strict
---
Run TypeScript type checking with strict compiler options:
1. Run `tsc --noEmit` with strict mode settings
2. Collect all type errors and warnings
3. Categorize errors:
- Missing type annotations
- Implicit any types
- Null/undefined safety issues
- Generic type issues
- Import/export mismatches
Generate a detailed report showing:
- Total type errors
- Errors by category with counts
- Top 10 files with most type errors
- Specific recommendations for each category
Suggest improvements:
- Files that would benefit from JSDoc
- Places where explicit types would improve clarity
- Breaking changes if we made types more strict
Use plan mode to suggest fixes without applying them automatically.
这是一份典型的「YAML frontmatter + Markdown 正文」结构:frontmatter 声明调度与执行约束,正文则是交给 Agent 的提示词。逐字段解读如下:
| 字段 | 示例取值 | 含义与源码依据 |
|---|---|---|
id |
type-check-strict |
规范唯一标识,解析器会将其作为 externalId 持久化,见 cron-spec-parser.ts |
title |
Strict TypeScript Type Checking |
人类可读标题,缺失时回退为文件主干名 |
workspaceRoot |
/absolute/path/to/repo |
目标项目绝对路径,必填项——解析器对缺失该字段的 spec 直接报 workspaceRoot is required |
schedule |
"0 6 * * *" |
5 段 cron 表达式(分/时/日/月/周),每天 06:00 触发;.cron.md 文件必填 |
tools |
run_commands,read_files |
工具白名单,只允许执行命令与读文件,禁止 apply_patch/editor 等写操作 |
mode |
plan |
规划模式:只建议、不落盘修改 |
enabled |
false |
模板默认关闭,复制到 ~/.cline/cron/ 后需自行置为 true |
modelSelection |
cline / anthropic/claude-opus-4.7 |
为该任务单独指定 provider 与模型,覆盖默认模型 |
timeoutSeconds |
1800 |
运行超时 30 分钟,超时则中止会话并记录失败 |
maxIterations |
20 |
Agent 迭代次数上限 |
tags / metadata |
automation、quality、typescript;owner: development |
分组标签与自定义元数据,metadata 可携带任意键值(如这里的 strictLevel: strict) |
从源码结构看,解析逻辑位于 sdk/packages/core/src/cron/specs/cron-spec-parser.ts。它有几个值得注意的校验行为:
- 触发类型由文件命名推断:
*.cron.md推断为schedule(定时)、events/*.event.md推断为event(事件驱动)、其余.md视为一次性任务。因此schedule、timezone只允许出现在.cron.md中,出现其他位置会被拒收。 - mode 白名单校验:
normalizeMode只接受act/plan/yolo三者之一,非法值直接使 spec 解析失败并持久化错误状态,而不是静默丢弃。 - tools 白名单校验:
normalizeToolList会对照内置默认工具集合校验每个工具名,出现未知工具会报unknown tool(s)错误。 - 解析永不抛异常:单个坏文件只产生带
error信息的解析结果,由协调器持久化parse_status='invalid',保证整体状态机不丢状态。
二、Cron 表达式与时区:每天 6 点是怎么算出来的
schedule: "0 6 * * *" 的校验与触发时刻计算在 scheduler.ts 中实现,核心是 parseCron 与 getNextCronTime 两个函数:
parseCron要求恰好 5 个字段(分钟 0-59、小时 0-23、日 1-31、月 1-12、周 0-6),支持*、区间-、步长/、逗号枚举以及月份名(jan~dec)与星期名(sun~sat)——所以 daily-code-review.cron.md 里的0 9 * * MON-FRI(工作日 9 点)这类写法也能被正确解析。getNextCronTime负责计算下一次触发时间:未指定timezone时走系统本地时区的快速跳转算法;指定 IANA 时区(如America/New_York)时改用基于Intl.DateTimeFormat的按分钟扫描,并在 4 年窗口内找不到匹配时刻时报错。spec 解析阶段就会调用validateCronSchedule做一次预检,写错表达式在落盘前就能被发现。
常用表达式速查(引自 scheduled-agents.mdx):
| 表达式 | 调度 |
|---|---|
0 9 * * MON-FRI |
周一到周五上午 9 点 |
0 */6 * * * |
每 6 小时 |
0 8 * * MON |
每周一早上 8 点 |
30 17 * * * |
每天下午 5:30 |
0 0 1 * * |
每月 1 号午夜 |
*/30 * * * * |
每 30 分钟 |
三、为什么选 plan 模式 + run_commands/read_files 工具组合
这份模板的安全设计体现在两处字段的配合上:mode: plan 加上 tools: run_commands,read_files。
运行器在 cron-runner.ts 的 buildToolPolicies 中把这两个声明翻译成了具体的工具策略:
// 伪代码示意,摘自 buildToolPolicies 的实现逻辑
const policies = spec.tools === undefined
? { "*": { autoApprove: true } } // 无白名单:全放开
: { "*": { enabled: false, autoApprove: true } }; // 有白名单:默认全禁
for (const tool of spec.tools ?? []) {
p[tool] = { enabled: true, autoApprove: true }; // 仅白名单内启用
}
由此得到三个关键结论:
- 只读性质由白名单保证:
run_commands允许执行tsc --noEmit、git log这类命令,read_files允许回读报错文件做归类分析;而apply_patch、editor等写工具被显式禁用,即使模型「想修」也修不了。 - 无头运行的兜底:定时任务没有人可以询问,所以
ask_question工具在策略中被强制禁用;只有mode: yolo才会启用submit_and_exit。plan模式的语义则是「产出修复建议,等待人工确认」。 - 超时与并发保护:
timeoutSeconds: 1800在executeClaim中被换算为执行截止时刻,超过即中止会话并把报告标记为failed(错误上下文会注明是在哪个阶段超时的,见 cron-runner.ts 的 catch 分支);maxIterations: 20则限制单轮对话的迭代深度,防止无限打转。
四、任务正文:类型检查的分类法与报告结构
正文(frontmatter 之后)就是交给 Agent 的提示词,定义了 type-check-strict 的核心工作流程:
第一步:执行严格检查
npx tsc --noEmit
在仓库根目录(workspaceRoot)下以严格编译选项运行 TypeScript 编译器,只报告、不产出。
第二步:错误五分类
| 类别 | 典型场景 |
|---|---|
| Missing type annotations | 函数参数/返回值缺注解,开启 noImplicitAny 后报错 |
| Implicit any types | 回调参数、泛型默认推断为 any |
| Null/undefined safety issues | strictNullChecks 下未做窄化的可能为空的值 |
| Generic type issues | 泛型约束不满足、条件类型推导失败 |
| Import/export mismatches | 模块导出名不一致、循环引用导致的类型缺失 |
第三步:生成结构化报告,包含四个必备板块——类型错误总数、按类别统计的数量、错误最密集的 Top 10 文件、每类的具体修复建议。
第四步:改进建议,额外覆盖三个维度:哪些文件适合补 JSDoc、哪些位置显式类型能提升可读性、以及「如果把类型收得更严格」会引入哪些破坏性变更。这一点很务实——严格化的代价评估(breaking changes)往往比错误列表本身更能支撑排期决策。
plan 模式收尾的最后一句指令明确约束了行为边界:「Use plan mode to suggest fixes without applying them automatically」,与 frontmatter 的工具白名单形成双保险。
五、本地落地:从模板到自己的定时质检
参考 sdk/examples/cron/README.md 给出的标准流程,把这份模板接入自己的项目只需四步:
1. 放置规范文件
mkdir -p ~/.cline/cron
cp sdk/examples/cron/type-check-strict.cron.md ~/.cline/cron/
2. 定制 spec:把 workspaceRoot 改为你项目的绝对路径;enabled 置为 true;按需调整 modelSelection(如换成成本更低的模型跑日常巡检)与 timeoutSeconds(monorepo 可放宽)。
3. 启用自动化,三种入口任选其一:
- Hub:
new HubWebSocketServer({ cronOptions: { workspaceRoot: "/absolute/workspace" } }) - SDK:
ClineCore.create({ automation: true })后调用cline.automation.start() - CLI:
cline --enable-automation
规范在启动时会被协调(reconcile),下一次运行时刻自动入队。也可以用 CLI 的 schedule 命令 交互式管理:cline schedule list 查看、cline schedule trigger <id> 立即触发一次验证、cline schedule executions <id> 查看历史。
4. 查看运行报告:每次完成或失败的运行都会写入 .cline/cron/reports/<run-id>.md,包含 YAML frontmatter(run ID、状态、耗时、token 用量)、工作总结、工具调用明细。对于 type-check-strict,这份报告就是当天类型健康的快照:对比连续几天的 Top 10 文件与分类计数,就能看到类型债的增减趋势。
六、组合进更大的自动化体系
type-check-strict 只是 Cline 定时模板矩阵中的一环。examples/cron 目录 中同类 plan 模式的只读审计任务还有 dead-code-finder(周日 4 点找死代码)、documentation-check(周四 5 点查文档覆盖率),act 模式的任务则包括 code-style-audit、test-coverage-report、dependency-check 等。官方推荐的「全量开发自动化套件」把 type-check-strict 排在每天 6 点,与 2 点的性能基线、22 点的测试覆盖率报告形成错峰巡检,配合 PR 事件驱动任务(如 pr-test-coverage.event.md)即可覆盖「持续 + 事件」两个维度,无需开发者记住手动跑检查。
七、小结
type-check-strict.cron.md 的价值不在于它检查了什么,而在于它示范了 Cline 自动化规范的完整写法:文件命名决定触发类型(.cron.md = 定时)、frontmatter 声明调度与护栏(cron 表达式、工具白名单、plan 模式、超时与迭代上限)、正文即提示词(检查步骤、分类法、报告结构、行为边界)。源码侧的解析器(cron-spec-parser.ts)、调度器(scheduler.ts)与运行器(cron-runner.ts)保证了这份声明式文件的每一步都被严格校验与持久化追踪。把 workspaceRoot 指向你的仓库、enabled 置为 true,第二天早上就能收到第一份按类别统计的类型检查报告。
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 StartedRust0627
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