在 tldraw 仓库中编写技术博客文章:write-tbp 技能完整实战指南 在 tldraw 仓库中编写技术博客文章write-tbp 技能完整实战指南【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw导读本文基于 tldraw 仓库中 skills/write-tbp/SKILL.md 技能文档完整讲解在 tldraw 代码库中编写技术博客文章technical blog post的六步流程建立工作区、研究主题、提炼角度、撰写草稿、自我评估与交付。文章同时结合仓库内的 blog 风格指南、语音与风格指南并以「scribbles涂鸦笔迹」为示例主题演示如何把源码、类型定义、示例和测试转化为一篇有深度、可发表的技术文章。读完本文你将掌握 tldraw 技术博客的选题标准、行文结构、证据搜集方法以及一套可复用的写作检查清单。write-tbp 技能是什么write-tbp是 tldraw 仓库中用于编写关于 tldraw 特性与实现细节的技术博客文章的技能。它的定位与普通文档写作不同SDK 文档由 skills/write-docs/SKILL.md 覆盖面向「如何用」而技术博客文章回答的是「tldraw 是怎么解决这个有趣问题的」。技能文档把整个写作过程拆成六个阶段下面逐段展开。1. 创建工作区为每个主题建立独立目录第一步是在技能目录下为当前主题创建一个assets文件夹按 kebab-case 短命名约定组织assets/topic/ ├── research.md # Gathered context and notes └── draft.md # The blog post draft主题名要短例如scribbles、arrow-routing、dash-patterns。research.md存放搜集到的上下文与笔记draft.md存放博文草稿。把调研产物与草稿分开是为了让后续的 Explore 子代理与人类编辑各取所需调研文档会被另一个代理阅读不必为人类可读性过度优化。2. 研究主题用 Explore 子代理做证据搜集技能要求使用一个thoroughness: very thorough的 Explore 子代理在 tldraw 代码库中查找与主题相关的全部线索。搜索范围是仓库中与主题相关的核心区域packages/editor与packages/tldraw中的实现文件packages/tlschema中的类型定义apps/examples中的相关示例apps/docs/content中已有的文档能揭示行为的测试解释「为什么这样工作」的注释对每个相关文件记录它做什么、关键函数/类、有趣的实现细节、任何「为什么」注释或非显而易见的决策。以本文示例主题scribbles为例实际调研可以命中这些仓库文件线索类型仓库路径调研要点核心实现ScribbleManager.tsScribbleItem、ScribbleSessionOptions、Session内部结构、五态生命周期类型定义packages/tlschema中的TLScribble记录scribble 的state五个取值starting、active、complete、stopping、paused渲染实现ScribbleOverlayUtil.tsCanvas 2D 渲染、getStroke自由手绘轮廓算法、Path2D 缓存策略相关文档scribble.mdx生命周期表格、直接 API 与 session API、属性表测试packages/tldraw/src/test/overlays/ScribbleOverlayUtil.test.ts渲染路径与缓存失效行为这一阶段的产出物是一份综合摘要主题是如何工作的。它会被另一个代理读取因此要尽量密集而不是追求修辞。3. 提炼有趣的角度先回答四个问题在动笔前必须基于调研结果回答四个问题这决定了主题是否值得写成一篇技术博客它解决什么问题不是「它做了什么」而是「没有它会出什么错」。例如没有 scribble 系统擦除和激光笔就没有指针移动的视觉反馈操作看起来像「瞬移」。有什么令人意外或不直观的地方显而易见的方案行不通的地方或隐藏的复杂度。例如 scribble 的Starting状态要收集超过 8 个点才开始显示用来防止极短笔画的闪烁Paused状态在 schema 中有定义但管理器从不使用。关键洞见是什么让解决方案成立的「啊哈」时刻。例如自消耗self-consuming机制笔迹一边画一边从起点吃掉自己保持恒定长度从而实现橡皮擦那种「跟手」的效果。我们一开始尝试了什么代码或注释中能看到的迭代历程。例如ScribbleOverlayUtil里那段关于缓存的注释解释了为什么用Map而非WeakMaptldraw 的 store 每次更新都会替换记录对象用WeakMap以TLScribble实例为键会导致每帧都缓存失效。技能文档的结论很直接如果找不到有趣的角度这个主题可能不适合写技术博客文章。这个过滤步骤是防止产出「功能公告」或「SDK 教程」的关键——那两类内容应该分别交给发布说明和文档体系。4. 撰写草稿遵循「问题—洞见—实现—收尾」结构草稿遵循 blog-guide.md 定义的结构这正是 VOICE.md 中 nugget 类文章的标准弧线陈述问题— 系统做什么没有它会出什么错展示洞见— 让它成立的关键想法走一遍实现— 代码与解释逐步构建复杂度收尾— 代码在哪儿、权衡取舍、文件链接技能要求草稿目标长度 800–1500 词。注意草稿是给人类编辑的原材料不是成品。语气要保持朴素、直接让内容自己说话编辑器后续再去补充个性与轶事。朴素草稿的具体规则技能文档对草稿文风有非常具体的约束这些约束同样来自 blog-guide.md 与 VOICE.md开头直说系统做什么、文章覆盖什么不要用场景、轶事或虚构用户开头「你的火车钻进隧道……」那会被编辑当成 AI 填充删掉。从机制展开故事按依赖顺序讲每个片段解决什么问题。张力来自设计本身「扫描看不见删除清理器以前会留下空洞」不来自修辞。平铺直叙地交代历程与 bug。「清理器早期版本没有推进水位线导致过期客户端收到不含删除操作的 diff」就足够了不要写「我们艰难地学到了这一课」这类旁白。不要警句、不要对偶、不要收尾金句。如果一句话的存在意义只是好听而不是传达信息就删掉它。每段至多一个破折号通常为零。观点只留在收尾而且要短而具体「为了换取有界的元数据我们接受长时间离线客户端的一次完整重新下载」。属于人类的部分开头、来历、权衡留白即可不要在草稿里虚构色彩但在交接说明里指出这些位置。从调研到代码的示例scribbles 主题的洞见与实现以scribbles为例调研得到的关键机制可以这样组织成文。先看生命周期表源自 scribble.mdx 与TLScribble类型状态说明Starting收集点直到超过 8 个防止极短笔画闪烁Active随指针移动持续累积点Complete绘制结束但尚未开始淡出complete让笔端在抬笔时收尖Stopping通过从尾部逐点移除来淡出全部点清除后管理器删除该 scribblePausedschema 中已定义但管理器不使用关键洞见是自消耗与淡出的分离。自消耗模式默认selfConsume: true下笔迹边画边从起点移除点保持恒定长度——橡皮擦和套索选择都用这个而激光笔使用 session API把selfConsume设为false让一次绘制爆发中的多笔笔迹作为一个整体淡出。直接 API 的最小实现擦除工具的状态节点import { StateNode, TLPointerEventInfo } from tldraw/editor export class Erasing extends StateNode { static override id erasing private scribbleId override onEnter(info: TLPointerEventInfo) { const scribble this.editor.scribbles.addScribble({ color: muted-1, size: 12, }) this.scribbleId scribble.id this.pushPointToScribble() } override onExit() { this.editor.scribbles.stop(this.scribbleId) } override onPointerMove() { this.pushPointToScribble() } private pushPointToScribble() { const { x, y } this.editor.inputs.getCurrentPagePoint() this.editor.scribbles.addPoint(this.scribbleId, x, y) } }这段代码在 ScribbleManager.ts 中有对应的底层行为addPoint会忽略与上一个点距离不足一个页面单位的点stop把 scribble 移入 stopping 状态管理器在所有点清除后自动移除它。渲染侧则由 ScribbleOverlayUtil.ts 负责它用getStroke把点序列转成自由手绘轮廓再填成 Path2D并以「点数量、末点坐标、缩放、size、taper、state」为键做缓存避免每帧重算。session API 的配置项源自ScribbleSessionOptions接口与 scribble.mdx属性默认值说明id自动生成会话标识selfConsumetrue笔迹是否边画边吃掉自己的尾部idleTimeoutMs0无活动多少毫秒后自动停止会话0 表示禁用fadeModeindividualindividual各自淡出grouped整体淡出fadeEasinglinear或ease-in分组淡出的缓动grouped时默认为ease-infadeDurationMslaserFadeoutMs500ms淡出时长5. 自我评估对照检查清单修订草稿完成后逐项核对技能文档给出的检查清单开头— 是否在讲解决方案之前先平实陈述问题且没有设计好的轶事洞见— 是否有关键想法结构是否朝它推进具体性— 是否扎根于 tldraw 的实际实现代码— 示例是增进理解还是只展示语法语气— 平实直接没有悲情、没有警句、没有编辑器一眼能认出的 AI 痕迹链接— 是否指向仓库中真实存在的代码篇幅— 深度是否与主题匹配修订草稿以弥合任何缺口。这里的语气检查可以直接套用 VOICE.md 的禁令清单不要空洞的重要性声明「plays a vital role」、不要尾随动名词「...ensuring a seamless experience」、不要公式化过渡「Moreover」「Furthermore」、不要三点并列的 AI 签名句式、不要破折号泛滥、不要「Its not X, its Y」的否定对仗、不要营销词seamless、robust、cutting-edge。句子间要有节奏短句和长句交替段落长度由内容决定而不是公式。6. 交付交给人类编辑最后一步是把最终草稿呈现给用户审阅并指出人类编辑最可能想添加色彩的位置——通常是开头、任何来历或 bug 故事、以及权衡取舍部分。草稿保留在assets/topic/draft.md直到用户满意再由用户移到合适的位置例如发布到apps/docs之外的博客渠道。这正好体现了 write-tbp 技能对「人机分工」的定位机器负责保证事实正确、结构完整、行文干净人类负责在干净的骨架上添加个性、轶事和点睛之笔。草稿写得朴素编辑加料远比从一篇过度修饰的稿子里删减要容易。参考资源与技能配套的写作规范write-tbp 技能引用了两份核心规范写作时必须同时遵守blog-guide.md— 技术博客的语音、语气与结构。它定义了开头模式先框定问题给出具体而非抽象的张力、结构弧线问题—洞见—实现—收尾、代码呈现方式先给完整可运行的示例再给片段注释要会话化而不是描述显而易见的内容以及「描述我们做了什么而不是告诉读者该做什么」的叙述立场。它还列出了适合博客的主题特征不直观的解决方案、隐藏的复杂度、画布特有的问题、平台/浏览器怪癖、有数据支撑的性能洞见以及不适合的主题功能公告、SDK 教程、与 tldraw 无关的通用编程心得。VOICE.md— tldraw 的通用写作约定面向「专家到开发者」的指导语气自信、直接、务实、诚实温暖但高效。它给出了大量「AI 写作迹象」的清单和改写示范是第 5 步自我评估时逐条对照的依据。技能文档还以「Related articles」的形式指向其他写作类技能可按需交叉参考write-docs/SKILL.mdSDK 文档、write-release-notes发布说明等。总结write-tbp 的核心工作流可以压缩为一条线研究先行、角度为王、朴素成稿、清单自检。先让 Explore 子代理在packages/editor、packages/tldraw、packages/tlschema、apps/examples、apps/docs/content与测试中把证据搜集齐全再回答四个「值得不值得写」的问题找不到有趣的角度就放弃成稿严格遵循问题—洞见—实现—收尾结构并控制 800–1500 词最后对照开头、洞见、具体性、代码、语气、链接、篇幅七项清单修订把成品连同「人类编辑加料点」一起交付。这套方法的价值在于它把一篇技术博客的生产拆成了可检查、可复用、可交给代理执行的步骤同时把「有趣」这种主观标准落到了具体的问题上主题有没有隐藏复杂度有没有令人意外的机制代码里有没有留下「为什么」的痕迹。这也是 tldraw 技术博客内容能保持深度而非沦为功能公告的原因。【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考