Agent 出 DSL,runtime 出版式。一份短标签 HTML,渲染成可投递的结构化文档。
talon-doc-runtime(下文简称 TDR)是一个面向 Agent 的结构化文档运行时。Agent 输出一组短小、语义明确的 HTML 标签 — <d> / <src> / <branch> / <evidence> / <myth> 等 — 浏览器加载 runtime 后,DOM 被原地增强为带主题、折叠、代码高亮、引用跳转和受控事件的可交付文档。
它的设计目标只有一个:让 Agent 用尽可能少的 token,输出结构稳定、视觉成熟、可复用的文档制品。
- 30+ 语义组件:决策卡(
<d>)、误解澄清(<myth>)、类比(<analogy>)、分支可能性(<branch>)、评估轨道(<tracks>)、风险登记(<risk>)、时间线、流程图、引用证据……每个组件对应一种"读者在第几秒该看到什么"的判断。 - Archetype 视觉系统:同一份 DSL,切换
data-archetype即可在"商务文档"和"长文杂志"之间无损切换。新增 archetype 只需要写一份 CSS,不动 DSL。 - 受控动作协议:Agent 写
<btn a="open" to="src1">,runtime 处理事件分发;宿主通过registerAction()接入业务系统。Agent 永远不写 JS。 - 代码即证据:
<src p="file:line-line" l="ts">渲染出折叠的源码块,配可点击的行号、复制按钮、内联注解、跨段引用跳转。 - 完整暗色模式:OKLCH 调色板,浅色/深色都经过手工调过感知亮度,避免"暗色模式 = 把背景调成黑"这种廉价做法。
- 零依赖、单 IIFE:编译后约 220 KB(含 highlight.js 子集),无 Vue / React / Lit。
- 文件转换路径:
tdr convert input.md -o doc.html把.md/.markdown/.txt/.html/.htm自动转成完整 TDR HTML。Markdown 路径在原有约定(admonition、file:path代码块、task list)之外,新增三条语义提升:无标记块引用 →<call k="note">、保守的两栏表格 →<kv>、紧贴标题上方的---→<divider t="标题">。.txt走启发式段落/列表/代码识别后复用 Markdown 管线;.html抽取正文并做共享 hast 提升。原生 TDR 标签可以混写在 Markdown 里。tdr format现为convert --ext md的向后兼容别名。
→ darkmice.github.io/talon-doc-runtime
- 组件总览 · business-document — 一份支付链路 P0 复盘,覆盖全部 30+ 组件
- 同一份 DSL · editorial-longform — 同样的 DSL,杂志风格
- 最小入门 · demo — 50 行内理解 DSL 写法
pnpm install
pnpm build
python3 -m http.server 4174然后打开 http://localhost:4174/examples/。
<html data-archetype="business-document">
<body>
<main class="tdr-doc">
<h1>支付链路 P0 复盘</h1>
<d s="bad" v="P0" t="幂等键碰撞导致重复扣款">
<because>键由"订单号 + 秒级时间戳"拼成,同一秒内的两次请求会得到相同的键。</because>
<so>改由客户端在请求前生成 UUIDv7,通过 header 透传,重试自然去重。</so>
</d>
<c t="复现链路">
<src id="bug-site" p="src/gateway/idempotency.ts:42-58" l="ts">
<pre><code>switch (record?.status) {
case 'committed': case 'failed': return replay(record)
// BUG: missing 'processing' case
default: return processAsNew(key, req)
}</code></pre>
</src>
</c>
<btn a="open" to="bug-site">展开证据</btn>
</main>
<script src="/dist/talon-doc-runtime.iife.js"></script>
</body>
</html>IIFE 包会自动 mount()。要手动控制:
import { mount, registerAction, setArchetype } from '@talon-ui/doc-runtime'
registerAction('accept', ({ target }) => {
acceptArtifact(target?.id)
})
setArchetype('editorial-longform')
mount(document.querySelector('#artifact'))TDR 以 Anthropic Skills 格式打包,安装后任何 Agent 会话提到"结构化文档 / 复盘 / 决策记录 / 评审报告"时自动触发。
📋 完整的 Agent 安装运行手册见 → docs/install-skill.md:含「先确定你所属 CLI 的 skill 目录」对照表(Claude Code / Cursor / Codex / Gemini / Copilot …,不写死
~/.claude)、各下载方式的完整命令、验证与故障排查。
速查(以 Claude Code 为例,其它 CLI 把 SKILLS_DIR 换成自己的路径):
SKILLS_DIR=~/.claude/skills && mkdir -p "$SKILLS_DIR" && \
gh release download --repo darkmice/talon-doc-runtime --pattern '*.skill' \
--output /tmp/tdr.skill && \
unzip -o /tmp/tdr.skill -d "$SKILLS_DIR/" && rm /tmp/tdr.skill && \
echo "✓ installed: $SKILLS_DIR/talon-doc-runtime/"没有 gh、还没发版、或非 Claude 的 CLI(Codex/Gemini/Copilot 等经 AGENTS.md / GEMINI.md 注入),都见安装手册的对应小节。
rm -rf "$SKILLS_DIR/talon-doc-runtime" # SKILLS_DIR 同你安装时所用<SKILLS_DIR>/talon-doc-runtime/ # Claude Code 下 SKILLS_DIR = ~/.claude/skills
├── SKILL.md 触发条件 + DSL 速查 + 最小骨架
├── references/
│ ├── canvas.md 写作准则(视觉预算、组件选型、状态契约)
│ └── lineage.md 改完 runtime 后的回流 SOP
├── scripts/
│ ├── critique.mjs 结构 & 风格 lint(节点对齐、Markdown 残留、callout 滥用)
│ └── balance.mjs 视觉预算(重组件 ≤ 1.5 × <h2>)
└── assets/
└── talon-doc-runtime.iife.js runtime 本体(standalone HTML 写法用)
SKILL.md、references/canvas.md、references/lineage.md 在仓库根的同名路径下也能直接阅读 — 它们是仓库与 skill 共享的同一份契约。
如果你 fork 或 clone 了本仓库做本地改造,自己打 skill:
pnpm install
pnpm skill:pack # 验证 + 打包到 dist/skill/talon-doc-runtime.skill然后手动把生成的 .skill 解压到 ~/.claude/skills/。
完整协议见 docs/protocol.md。下面是按"读者在文档里想做什么"组织的命中表:
| 想表达 | 用 |
|---|---|
| 判断 + 前提 + 结论 | <d> + <because> + <so> |
| 重要打断 / 注意事项 | <call k="info|note|warn|bad|ok"> |
| 折叠详情 | <c> |
| 代码证据(折叠 + 行号 + 注解) | <src id p l> 内含 <pre><code> + <note> |
| 简单代码片段 | <cb f> |
| 行内跳转 | <ref to="id"> |
| 行内状态徽标 | <x s> |
| 受控按钮 | <btn a to> |
| 关键指标行 | <ms> + <m v t> |
| 顺序步骤 | <steps p> + <step s t d> |
| 并行分支可能性 | <branch r> + <bi c s out> |
| 多维评估轨道 | <tracks> + <tk t f> |
| 横向柱状图 | <bars> + <bar t v p s> |
| 堆叠条 + 图例 | <sb> + <seg p s> + <lg t s> |
| 流程图(线性) | <flow v> + <n s t meta> + <arr t> |
| 优劣两栏 | <cmp> + <pro> + <con> |
| 同一词两种语境 | <contrast w d> + <l c> + <r c> |
| "A ≈ B" 类比 | <analogy s sd t td why> |
| 误解 → 事实 | <myth> + <wrong> + <right> |
| 结论 + 论据 | <evidence t> + <ei> |
| 单条洞察 | <finding t> + <detail> |
| 时间线 | <timeline> + <ev d t s> |
| 风险登记 | <risk> + <r t sev lik mit> |
| Key-Value | <kv> + <row k v vk> |
| Tabs | <tabs> + <tab t> |
| Checklist | <chk> + <ck k> |
| 卡片网格 | <grid c> + <card t> + <foot> |
| 文件变更清单 | <files> + <fg m> + <f p s why> |
| 行内术语(hover 定义) | <term w d> |
| 题记 | <lead> |
状态属性 s / k 接受语义值:ok、bad、warn、note、info、done、active、accent。常见别名(approved / rejected / success / danger / exploring / pending / p0 / p1 / p2 / blocked / at-risk ...)会被自动规范化。
不想直接写 HTML 标签?写 Markdown / 纯文本 / HTML,让 tdr convert 自动转:
npm install @talon-ui/doc-runtime
npx tdr convert docs/spec.md -o spec.html # 单文件 → stdout 或指定文件
npx tdr convert notes.txt index.html -o out/ # 批量,-o 指定输出目录tdr convert 按扩展名路由:.md / .markdown 走 Markdown 管线;.txt 先做启发式(空行分段、- * • · / N. 列表、4 空格缩进代码、裸 URL 自动链接)再复用 Markdown 管线;.html / .htm 抽取正文(article › main › body)后做共享 hast 提升(blockquote → <call>、两栏表格 → <kv>、details → <c>)。可用 --ext md|txt|html 强制走某条管线。tdr format 是 convert --ext md 的向后兼容别名。
Markdown 支持 GFM + 这些语义增强约定:
| Markdown 写法 | 转成 |
|---|---|
> [!NOTE] / > [!WARNING] / > [!CAUTION] ... |
<call k="…"> |
> NOTE: … / > 注意:… |
<call k="note"> |
> 普通块引用(无 admonition 标记) |
<call k="note"> |
```ts file:src/auth.ts:8-12 |
<src p="src/auth.ts:8-12" l="ts"> |
- [x] done / - [ ] todo |
<chk> + <ck k="true"> / <ck> |
| 保守的两栏表格(≤8 行、键列短且无尾标点、单元格纯文本) | <kv> + <row k v> |
紧贴标题上方的 ---(非 H1) |
<divider t="该标题文本"> |
<details><summary>X</summary>…</details> |
<c t="X">…</c> |
YAML frontmatter archetype: / title: / theme: |
写入 <html> 属性 |
不满足保守判定的两栏表格保持 <table>,独立的 --- 保持 <hr>。.txt / .html 也走同一套提升规则。原生 TDR 标签(<d>、<branch>、<myth> 等)直接写在 Markdown 里也能跑 — 转换器不会动它们。完整规范见 docs/markdown-flavor.md。
代码里调用:
import { convert } from '@talon-ui/doc-runtime/markdown'
// 按扩展名路由 .md/.txt/.html
const { html, frontmatter, warnings } = await convert(fileContent, { ext: 'md' })
// 仍可直接用 Markdown 入口
import { mdToTdr } from '@talon-ui/doc-runtime/markdown'
const out = await mdToTdr(markdownString, {
document: true,
enrich: async (frag, ctx) => /* optional LLM-driven semantic uplift */ frag,
})一份 DSL,多套视觉。在根元素上挂 data-archetype 选择风格:
<html data-archetype="business-document"> <!-- 或 editorial-longform -->| Archetype | 视觉血统 | 适用 |
|---|---|---|
business-document |
Stripe Atlas / Linear changelog / Vercel docs article pages | 工程报告、决策记录、复盘、交付文档 |
editorial-longform |
文学杂志 / 衬线长文 | 深度长文、技术随笔、评论 |
注册自定义 archetype:
import { registerArchetype, setArchetype } from '@talon-ui/doc-runtime'
registerArchetype('my-style', CSS_STRING)
setArchetype('my-style')CSS 契约见 docs/talon-doc-runtime-formats-css-brief.md — 所有可覆盖的 --tdr-* token 都在里面。
Agent 写意图,不写代码:
<btn a="open" to="bug-site">展开证据</btn>
<btn a="jump" to="bug-site">定位</btn>
<btn a="copy">复制</btn>
<btn a="theme" to="dark">深色</btn>
<btn a="archetype" to="editorial-longform">切换长文风</btn>
<btn a="emit" to="my-event">触发自定义事件</btn>内置动作:jump / open / close / toggle / copy / tab / theme / archetype / emit。宿主通过 registerAction(name, handler) 接入业务事件,例如把 accept、handoff、open-in-jira 等接回 Talon Pilot / 自有平台。
talon-doc-runtime/
├── src/
│ ├── index.ts renderer 注册 + mount + action registry
│ └── styles/
│ ├── base.css.ts 跨 archetype 的组件骨架
│ └── archetypes/
│ ├── business-document.css.ts
│ └── editorial-longform.css.ts
├── docs/
│ ├── protocol.md 完整 DSL 协议
│ ├── architecture.md runtime / host / Agent 三方边界
│ └── talon-doc-runtime-formats-css-brief.md CSS 契约速查
├── references/ skill 内嵌的写作 references
│ ├── canvas.md
│ └── lineage.md
├── scripts/
│ ├── build.mjs esbuild 构建
│ ├── critique.mjs 文档 lint
│ └── balance.mjs 视觉预算计算
├── examples/
│ ├── demo.html
│ ├── showcase.tdr.html 完整组件总览
│ └── showcase.editorial.tdr.html
├── tests/ Vitest + jsdom
└── SKILL.md skill 入口
- SKILL.md — Agent 入口,给 LLM 看。
- references/canvas.md — 写作准则(视觉预算、组件选型、状态契约)。
- references/lineage.md — 改完组件后如何回流到契约层。
- docs/protocol.md — 完整 DSL 协议,包括所有标签的属性、子标签、行为细节。
- docs/markdown-flavor.md — TDR-flavored Markdown 规范(
tdr convert/tdr format接受的 Markdown 写法 + L1/L2 转换规则)。 - docs/architecture.md — runtime、host、Agent 三方的责任边界。
- docs/talon-doc-runtime-formats-css-brief.md — CSS class 与 token 契约。
pnpm install
pnpm typecheck # TypeScript
pnpm test # Vitest(runtime + 渲染 + smoke)
pnpm build # esbuild → dist/
# 文档质量检查(可对任意 TDR HTML 文件运行)
node scripts/critique.mjs path/to/doc.html
node scripts/balance.mjs path/to/doc.htmlpnpm skill:pack 会把当前 SKILL.md + references + scripts + dist runtime 打包成可分发的 .skill 文件。
每次 push / PR 都会跑 CI(typecheck + test + build)。npm 发布由推送 git tag触发:
# 1. 修改 package.json 里的 version(必须与即将创建的 tag 一致)
# 例如 0.1.0 → 0.1.1
pnpm version patch # 自动改 package.json + 创建本地 tag v0.1.1
# 2. 推送 tag
git push --follow-tags
# 3. GitHub Actions 自动:
# - 校验 tag 与 package.json version 一致
# - 跑 typecheck / test / build
# - npm publish --provenance --access public
# - 创建 GitHub Release(自动生成 changelog)首次发布前,需要在 GitHub repo Settings → Secrets and variables → Actions 配置一个 NPM_TOKEN secret,token 在 npmjs.com → Access Tokens → Generate New Token → Automation(必须是 automation 类型,否则 provenance 签名会失败)。
预发版本用带连字符的 tag,会自动标记为 prerelease:
pnpm version prerelease --preid=rc # 0.1.1 → 0.1.2-rc.0
git push --follow-tagsTDR 属于 Talon 生态里的底层可复用能力:
- 提供:Agent DSL runtime、受控事件协议、Archetype 视觉系统、组件库。
- 不提供:业务流程、产品壳、文档站、CMS、协作编辑。
上层产品(Talon Pilot、SuperClaw 等)通过 registerAction() 把 accept / handoff / trace / open-artifact 等动作接回自己的业务系统;通过 registerArchetype() 提供品牌化的视觉皮肤。
MIT.