尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Anarlog 产品更新邮件实战指南:基于 changelog 的事实源写作与 Loops 编辑器自动化

Anarlog 产品更新邮件实战指南:基于 changelog 的事实源写作与 Loops 编辑器自动化 Anarlog 产品更新邮件实战指南基于 changelog 的事实源写作与 Loops 编辑器自动化【免费下载链接】anarlogOpen source Granola AI Alternative项目地址: https://gitcode.com/GitHub_Trending/hy/anarlog本文完整解读 Anarlog 仓库中用于「桌面版发布 → 用户更新邮件」的product-update-newsletter技能它以已发布的桌面版 changelog 为唯一事实源规定了一整套从文案风格、活动搭建、正文结构契约到 Lexical 编辑器程序化编辑、配图生成与发送前审计的完整流程。读完本文你将掌握如何为 Anarlog 每个稳定版桌面发布撰写、修订并预检一封面向真实用户的产品更新邮件并能直接复刻仓库中的 Playwright Lexical 自动化编辑方案。一、技能定位与文档体系Anarlog 仓库内维护了一套面向 Agent 的「技能Skill」文档体系其中product-update-newsletter负责在桌面版发布时起草、修订或审计一封基于 changelog 的产品更新邮件并发布到名为 Loops 的营销平台app.loops.so仓库内称 campaign。该技能在仓库中有两个入口兼容入口.claude/skills/product-update-newsletter/SKILL.md —— 这是 Claude 专用技能发现所需的兼容条目正文只有几行明确声明通用权威指令位于下方路径并要求不要在兼容条目里维护第二份检查清单权威入口.agents/skills/product-update-newsletter/SKILL.md —— 全部规范指令的真正所在包括事实源、文案风格契约、活动搭建、正文结构契约、Lexical 编辑器操作、配图、发送前审计与报告规则。技能的使用时机在文档开头就写得很清楚必须在 changelog 合并、版本正式发布之后才执行。它依赖同一目录体系下的另外两个技能按顺序完成前置工作new-changelog 技能生成稳定版或 Nightly 的桌面 changelogrelease-new-version 技能发布版本。也就是说一封产品更新邮件的素材链是new-changelog产出 changelog→release-new-version发布版本→product-update-newsletter撰写邮件。技能强调已发布的 changelog 是邮件的文案来源而不是原始 commit 日志。二、事实源以已发布 changelog 为唯一依据2.1 事实源的定义技能规定邮件的 Source of Truth 是anarlog.so/changelog/version渲染出的已发布 changelog 页面该页面在仓库中由 packages/changelog/content 目录下的版本号.md文件渲染而成。网站 changelog 的解析流水线位于 packages/changelog/src/process.tsparseFrontmatter解析每个 changelog 文件头部的---frontmatter提取date与summary两个字段fixImageUrls把正文中/api/assets/...形式的图片路径重写为对象存储的公开地址。2.2 增量同步原则技能明确提示changelog 在首次发布之后经常被再次编辑。当被告知 changelog 发生变化时正确的做法是重新获取最新版本与当前邮件正文做 diff只应用变化的部分delta绝不重新执行一遍整篇重写。这是为了保持邮件与发布说明严格一致同时避免引入无谓的文案漂移。2.3 结构映射规则来自 changelog 的条目要映射到邮件已有的结构而不是简单追加一段倾倒式罗列changelog 条目类型邮件中的落点功能级Feature-level条目成为或扩展一个 H3 小节次要 UX 改进变为 Small things that add up 下的要点可靠性与隐私类条目追加到要点之后的 fixes 段落同时要求诚实标注未完全上线的功能如果某个执行链路尚未接通邮件里必须如实说明不能把半成品写成已发布功能。2.4 真实 changelog 示例以 1.4.8 版 changelog 为例其 frontmatter 与正文结构如下--- date: 2026-08-10 summary: Anarlog 1.4.8 connects eight meeting assistants for automatic imports, makes cross-device sync near-instant, syncs appearance preferences across devices, and improves recording recovery, window placement, transcription errors, and billing. --- ## Sync - Upload local changes within about a second of settling instead of waiting for the next 30-second interval, and pull promptly when you switch back to the app - Wake your other devices as soon as a sync lands ... - Sync your theme, app icon, and week start choices across devices, end-to-end encrypted like the rest of your notes ## Importing - Connect Granola, Circleback, Fireflies.ai, Krisp, Read AI, Fellow, Tactiq, or Jiminny directly to bring your existing meeting history into Anarlog - Keep new meetings importing automatically while Anarlog is running, with controls to sync now or disconnect and export files available as a fallback这份 changelog 展示了邮件文案的素材形态summary是一句面向用户的概述预览用正文按主题分组Sync / Importing / Recording and transcription / Window and settings每条要点都聚焦用户能感知的变化。邮件写作就是在这一素材上做面向邮件读者的重组与精简。三、稳定版与 Nightly邮件的发布节奏契约3.1 只跟随稳定版发布技能第一条节奏规则产品更新邮件只跟随稳定版stable发布不针对每个 Nightly 发布邮件。这与 new-changelog 技能 中的Channel contract完全一致——网站 changelog 目录packages/changelog/content/只接受major.minor.patch.md格式的文件名Nightly 的更新说明维护在 packages/changelog/nightly.md构建时被嵌入应用并快照到 GitHub prerelease绝不出现在网站 changelog 中也不会为每个 Nightly 发邮件。3.2 Nightly 复活公告Nightly 并非永远不发——技能要求在下一个稳定版邮件中附带一个可选的 Nightly 公告opt-in announcement其文案草稿已经放在 nightly-announcement.md 中Anarlog Nightly is backTry upcoming improvements before they reach stable and help us catch bugs earlier. Nightly installs as a separate app, updates more frequently, and may be less reliable. Your current Anarlog installation stays on stable unless you choose to install Nightly.草案还写明 Nightly 与稳定版的关系Nightly 以独立应用形式安装、更新更频繁、可靠性可能更低Nightly 与稳定版共用本地笔记数据但登录与设置互相独立两个应用不能同时运行反馈时需要附上 Nightly 版本号和操作系统。3.3 发布前必须先验证技能特别强调在把 Nightly 描述为可用之前必须先验证Nightly 的安装包installers已发布更新源update feed可用Nightly 下载页已上线。这一点与 release-new-version 技能 互相印证Nightly 构建由desktop_nightly.yaml每天 15:00 UTC 触发版本号形如共享版本-nightly.n如1.4.24-nightly.1Nightly 与稳定版是各自独立签名的包绝不允许把 Nightly 二进制说成与稳定版逐字节相同。技能还明确Nightly 公告文件本身并不授权发送或排期该 campaign——发送前仍需走完整流程。3.4 邮件来源的版本校验在进入写作之前需要先确认真实版本与 changelog 对应关系可参考 release-new-version 技能 的校验方式VERSIONversion [[ $VERSION ~ ^[0-9]\.[0-9]\.[0-9]$ ]] node scripts/release-version.mjs --check $VERSION test -f packages/changelog/content/$VERSION.md稳定版发布从不推断版本号必须精确匹配release-version.json且对应版本必须存在 changelog 文件。四、文案风格契约Copy Style Contract技能把邮件文案的写作标准固化为一份契约核心观点是写一封产品邮件而不是一篇论文。要求紧凑、具体、易于扫读crisp, concrete, easy to scan。4.1 开头直入主题邮件开头必须开门见山地说明发了什么、什么时候发的。技能给出正反例推荐写法We shipped four releases since last week. Anarlog 1.4.8 is here.避免写法If youve been putting off updating, this is the one to take这类场景铺垫式开头。4.2 升级理由用功能绑定损失如果鼓励用户升级要用具名功能来绑定错失的收益而不是空洞的 hype 或内疚感If you arent updating, youre missing out on Automations that run after every meeting, editable transcripts, meeting imports, and near-instant sync.禁止使用模糊的夸大、内疚或指责语气。4.3 用事实和数据说话用结果与具体数字领起30 assistants、eight connect directly、about a second能用事实表达的地方就删掉形容词使用简短、主动语态的 H3 标题例如Automations do the work now、Transcripts you can fix、Sync you stop thinking about。4.4 段落与句法大多数段落控制在 13 句拆开过长的链条去掉重复的铺垫不要在引言和 fixes 段落里重复同一套框架使用缩略语和直接动词Last week ... This week ...是连接相邻两期更新的有效节奏避免故作可爱的过渡如Now they earn it和含糊短语如Accuracy got quieter improvements。4.5 主题行与预览文本主题行要紧凑、名词主导例如Anarlog 1.4.8: automations, meeting imports, instant sync。预览文本preview text要前置加载具体结果长度保持在约 90140 个字符——这是主流邮件客户端截断预览的典型区间。4.6 自我批评语言的边界自我批评道歉语气只在 Anarlog 或公司确实有过错时使用绝不能为了显得亲切而强行道歉。4.7 终稿朗读检查最终把成稿朗读一遍凡是删掉后不影响事实、指令或观点的内容一律删掉。技能同时允许 changelog 列表式写法——不要为了硬凑散文而强行改写本来就适合列表的内容。五、Loops 活动搭建Campaign Setup在 Loops 平台中技能规定活动的搭建方式是复用而非新建从 Loops Home 页面复制最近一期 Anarlog update (...) campaign这样发件人sender、回复地址reply-to、小节标题、Download 按钮和页脚都会被继承将 campaign 重命名为新日期。技能特别指出一个 Loops 行为细节campaign 的指标页metrics pages只显示发送/打开/点击统计因此内容编辑必须在 compose 视图撰写视图中进行。六、正文结构契约Body Structure Contract6.1 固定的块序列邮件的每个小节必须严格遵循同一套块序列任何编辑都必须保留它H3 heading P (empty spacer) DIV.editor-image P (empty spacer) P (body text)即H3 标题 → 空段占位 → 编辑图片块 → 空段占位 → 正文段落。6.2 结构自动校验在完成编辑后技能给出了一段可在 Playwright 中执行的校验脚本逐块检查每个 H3 之后是否满足SP,IMG,SP模式await page.evaluate(() { const blocks [...document.querySelector(.ContentEditable__root).children]; return blocks .filter((b) b.tagName H3) .map((h) { const i blocks.indexOf(h); return ( h.innerText - blocks .slice(i 1, i 4) .map((x) x.className.includes(editor-image) ? IMG : x.innerText.trim() ? SP : TXT, ) .join(,) ); }); });这段脚本直接读取ContentEditable__root根节点的子块序列对每个 H3 后面的三个块依次判断是图片块editor-image、空段SP还是文本TXT用于在发送前确认结构契约未被破坏。七、Lexical 正文编辑程序化操作与失败模式7.1 编辑模型认知邮件正文是一个div.ContentEditable__root页面上存在多个[contenteditabletrue]元素Sender、From、Reply、Subject、Preview、正文。技能警告必须匹配具有辨识度的既有文本绝不能依赖缓存的索引或 ref任何多块编辑前都要重新扫描完整的块映射并重新解析目标因为用户可能正在并发编辑一个先前正确的索引会漂移并破坏标题、要点或问候语。正文编辑器的语义###创建 H3-创建列表项。7.2 可靠的中段替换Range 选择后输入技能给出的推荐做法是Range 选择 键入async function selectTextInBody(searchStr) { return await page.evaluate((str) { const root document.querySelector(.ContentEditable__root); const walker document.createTreeWalker(root, NodeFilter.SHOW_TEXT); let node; while ((node walker.nextNode())) { const idx node.textContent.indexOf(str); if (idx ! -1) { root.focus(); const range document.createRange(); range.setStart(node, idx); range.setEnd(node, idx str.length); const sel window.getSelection(); sel.removeAllRanges(); sel.addRange(range); node.parentElement.scrollIntoView({ block: center }); return true; } } return false; }, searchStr); }该函数通过TreeWalker遍历正文的所有文本节点找到目标字符串后用Range精确框选并滚动到可视区域。对于版本号这种会出现多次的替换需要对每个命中位置重复执行。7.3 四个实测失败模式Failure Modes技能特别强调以下四种失败模式都会静默损坏文档且全部是实践中真实观测到的失败模式现象对策首块 Range 选择键入字符被反转Hi, 变成 ,iHLexical 每次按键都把 caret 重置到偏移 0使用原生鼠标三击然后键入MetaArrowUp不可靠无法可靠到达文档开头内容被追加到当前块末尾改为三击目标块同次evaluate()内读坐标scrollIntoView之后坐标是陈旧的点击落在错误的块上按键损坏无关小节滚动后sleep(600)在第二次evaluate()中重新读取 rect有激活 Range 时按 Enter直接删除被选中的文本先按End或Home7.4 键入前的 caret 校验在键入前必须确认 caret 确实落在目标块中const ok await page.evaluate(() { const sel window.getSelection(); const blocks [...document.querySelector(.ContentEditable__root).children]; const target blocks[TARGET_INDEX]; const anchorBlock sel.anchorNode ? (sel.anchorNode.nodeType 1 ? sel.anchorNode : sel.anchorNode.parentElement ).closest(.ContentEditable__root *) : null; return anchorBlock target; });如果返回false应点击目标块文本的水平中点而非左边缘。7.5 结构修复后的扫描完成任何结构性修复后必须扫描所有块清理游离的空段落、重复的问候语、残留的/或/image文本。八、插入图片slash 菜单与文件选择器8.1 完整操作流图片插入通过正文的 slash 菜单触发原生文件选择器。技能要求先武装监听器再打开菜单const fcPromise page .waitForEvent(filechooser, { timeout: 15000 }) .catch(() null); await page.keyboard.type(/, { delay: 200 }); await sleep(700); await page.keyboard.type(image, { delay: 120 }); await sleep(700); const btn await page.evaluate(() { const menu [...document.querySelectorAll(div.fixed)].find((el) el.className.toString().includes(z-[100]), ); const img menu [...menu.querySelectorAll(button)].find( (b) b.textContent.trim() Image, ); const r img.getBoundingClientRect(); return { cx: r.x r.width / 2, cy: r.y r.height / 2 }; }); await page.mouse.click(btn.cx, btn.cy); const fc await fcPromise; await fc.setFiles(/abs/path/to/image.png);8.2 关键操作要点caret 必须位于空段落中/的键入延迟必须 150否则会键入一个字面/菜单是一个可滚动的div.fixed.z-[100]未过滤时MEDIA 分组下的 Image 项位于可视滚动区之外点击其报告的坐标会点到页面背景并静默关闭菜单——因此先键入image过滤列表使其进入视野Enter与ArrowDownEnter都不能激活该项只有鼠标点击有效轮询直到img.src包含images.vialoops.com以确认上传完成图片插入会消耗掉那个空段落所以插入后要重新补一个尾部空段占位。8.3 替换与恢复替换图片点击选中图片块 → 按 Backspace → 重新执行上述流程。由于编辑过程中图片可能被误删技能要求在编辑前先捕获所有images.vialoops.comURL这样被删的图片可以重新下载并恢复。九、章节配图Section ArtMidjourney 风格生成9.1 家装风格提示词邮件小节的配图使用 Midjourney 按既有house style生成dithered. [short concept]. bright white sunshine, cheerful, high key. --ar 4:3 --profile aofpoq2技能给出的风格约束目标是明亮、高调、通透、浅色背景的效果拒绝昏暗或 dystopian 输出优先场景构图阳光房间里的物体不要扁平网格或 UI 线框图——网格与现有配图集合不匹配Personalize 的 P 开关可能激活失败data-activefalse把--profile aofpoq2直接追加到提示词文本即可生效并产生 profile chip轮询完成状态观察\d% Complete从document.body.innerText中消失。9.2 全分辨率下载cdn.midjourney.com对 Node 侧的fetch()会返回 Cloudflare 质询因此必须在已认证的浏览器标签页内下载全分辨率图jobId来自网格缩略图 URLconst b64 await mjPage.evaluate(async (u) { const r await fetch(u); const blob await r.blob(); return await new Promise((res) { const fr new FileReader(); fr.onload () res(fr.result.split(,)[1]); fr.readAsDataURL(blob); }); }, https://cdn.midjourney.com/${jobId}/0_${variant}.png);十、发送前审计Pre-Send Audit发送前必须逐项运行审计并对每一项报告 pass 或 fail。10.1 自动化检查项版本字符串在主题行与正文中保持一致且正文中不残留任何旧版本号changelog 中的每个条目都在邮件文案中有对应呈现包括来自 Fastrepl 组织之外贡献者的致谢所有 H3 小节都满足SP,IMG,SP模式所有图片都满足complete naturalWidth 0即加载完整、非零宽度无残留瑕疵/image、孤立的/、双空格、重复的问候语签名块完好。10.2 人工判断项Sender / From / Reply 字段正确。特别要标记任何 reply-to 变更——因为正文承诺个人回复任何招募测试者的呼吁都路由到同一个地址预览文本长度客户端在约 90140 字符处截断重要内容必须前置Download 按钮 URL它存在于编辑器状态而非 DOM 中需要点击按钮块后在右侧边栏的 Link 文本框里读取除非同时检查了 Audience、Schedule 和 Goals否则必须明确声明仅审计了 Compose 步骤。10.3 与 changelog 的质量要求呼应发送前审计中changelog 每一条目都要有对应呈现与 packages/changelog/content/AGENTS.md 的规则形成闭环changelog 本身必须对应用用户值得一读、排除内部重构与 CI 噪音来自组织外 PR 的贡献者致谢要放在条目末尾author_association不为MEMBER/OWNER/COLLABORATOR且非 bot 时致谢且致谢不进入summary。邮件写作直接继承这一事实链保证用户在邮件里读到的与网站上看到的一致。十一、报告Reporting规则技能要求编辑完成后按以下方式汇报用平实的语言重述改了什么引用新的文案内容附上已编辑小节的截图主动披露任何自我造成的文档损坏及其修复过程而不是隐瞒。十二、沉淀这套流程对自动化 Agent 的可复用要点product-update-newsletter技能本身就是一个可被 Agent 逐步执行的操作手册其可复用要点可以归纳为三层事实层一切文案以已发布 changelogpackages/changelog/content/version.md为源增量同步、不做全量重写稳定版与 Nightly 严格分渠道Nightly 公告需先验证安装包、更新源与下载页再行宣传。写作层产品邮件风格契约开门见山、事实与数字、主动态短句、90140 字符预览文本 固定的H3 → SP → IMG → SP → P块结构配合 Playwright 脚本做结构校验。操作层针对 Lexical 编辑器总结了实测有效的 Range 替换、caret 校验、slash 菜单插图的自动化方案并把四种静默损坏的失败模式与对策固化进流程最后以自动化 人工的双层审计收尾。这套方案的价值在于它把一封高质量的发布邮件从依赖人的临场发挥变成了有事实源、有风格契约、有结构校验、有失败预案、有发送前审计的可重复工程流程——这正是 Agent 能在 Loops 里稳定产出并维护产品更新邮件的原因所在。相关仓库路径速查技能权威文档.agents/skills/product-update-newsletter/SKILL.md技能兼容入口.claude/skills/product-update-newsletter/SKILL.mdNightly 公告文案草稿.agents/skills/product-update-newsletter/nightly-announcement.mdchangelog 生成技能.agents/skills/new-changelog/SKILL.md版本发布技能.agents/skills/release-new-version/SKILL.md网站 changelog 内容packages/changelog/contentchangelog 写作规则与自定义标签packages/changelog/content/AGENTS.md真实 changelog 示例packages/changelog/content/1.4.8.mdchangelog 渲染流水线packages/changelog/src/process.tsNightly 累积更新说明packages/changelog/nightly.md【免费下载链接】anarlogOpen source Granola AI Alternative项目地址: https://gitcode.com/GitHub_Trending/hy/anarlog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表