Skip to content

v1.8.6

@coln2018 coln2018 tagged this 07 Oct 05:16
## 背景与决定

用户反馈:用 LLM 开发时 VOBS_C210 非常频繁。讨论后确定三条通道,按可靠性排序:

  诊断文本(最高,顺着 agent 一定会看的构建输出)
  AGENTS.md(中,常驻上下文)
  SKILL.md(中低,支持面窄)

1.8.5 做了第一条(C210/C211 的 fix 改为先教结构)。本次做第二条。

用户的判断我采纳:**不应针对某个特定 LLM** —— 内容工具中立,工具差异只在"从哪个
文件名读"。所以只做两个通道(AGENTS.md + CLAUDE.md 指针),SKILL 后置。

## 关键设计:由框架产出,不由用户手抄

契约随框架演进(1.8.0 Show/ClientOnly、1.8.3 on()/C106、1.8.4 C107、1.8.5 fix 文案)。
手写的话每个项目一份副本**必然漂移**。所以契约正文放在 @vobs/cli 里,
`vobs agent-doc` 生成到项目 —— **与框架版本绑定**:升级 → 重新生成 → 永远同步。

## 三个开关

  vobs agent-doc              → stdout(先看)
  vobs agent-doc --write      → 写入 AGENTS.md + CLAUDE.md
  vobs agent-doc --check      → 与当前框架版本不一致时 exit 1(可进 CI)

--check 是把它从"靠人记得"变成"机器拦"的那一步。

## 不覆盖用户内容(关键)

- 生成内容包在 `<!-- vobs:begin -->` / `<!-- vobs:end -->` 之间,块外是项目自有约定
- **手写的 AGENTS.md(无标记块)不被覆盖** —— 生成块追加在后。
  丢掉别人的规则比不生成更糟。
- CLAUDE.md 只写一行 `@AGENTS.md` —— 内容只有一份,不复制。

## 契约正文(一屏内,工具中立)

八节硬约束 + 一句话速记表,每条带诊断码:run-once / 条件渲染(RouterView vs Show vs
JSX 子节点)/ effect 自订阅(on())/ async / 客户端守卫 / 列表换引用 / 数字输入 /
SVG / 提交前自测。全部来自本会话真实踩坑与已落地的诊断。

## 实现中修掉的一个真问题

第一版用 `new URL('../../src/templates/agent-contract.md', import.meta.url)` 读模板,
**全量测试时 8 条全红、单独跑 8 条全过** —— vitest 全量跑会转换模块,
`import.meta.url` 指向虚拟路径,相对路径解析到不存在的文件。

改成把正文内联为 TS 模块 `templates/agent-contract.ts`(脚本从 .md 生成,转义反引号
与 ${),**免疫打包与转换**,也省掉发布时拷模板。全量 1390 测试通过。

## 验证

- agent-doc.test.ts(8 例):生成内容含全部关键约束 · **手写 AGENTS.md 不被覆盖** ·
  再次 --write 只替换块且块外新内容保留 · --check 未生成 exit 1 / 生成后 0 ·
  块被手改报不一致 · CLAUDE.md 被改成副本也报 · --body 不带标记块 ·
  不加开关不写文件
- **真实 CLI 端到端**:①②③ 三个开关实跑,原有内容确认保留、CLAUDE.md 为 `@AGENTS.md`

全量门禁 1390 测试全绿 · typecheck 0 · check:source 0。

## 未做(等用户定)

SKILL.md 手册(建议先写「新增页面」与「发版」两本)·
其它工具的薄指针(.cursor/rules、.clinerules、copilot-instructions——取决于用户用哪些)。
Assets 2
Loading