Communitygithub.com

robcsaszar/tend

本地按需维护技能,适用于 SvelteKit + TypeScript 仓库——涵盖安全、性能、重构、无障碍和测试覆盖率。

tend 是什么?

Tend A11y(也称为“the herald”)是一项专门用于在 SvelteKit + TypeScript 仓库中查找并修复单个最高优先级的无障碍、用户体验或文案语气问题的 AI 技能。它从加载 `.claude/tend/config.yaml` 配置开始,获取禁止修改的文件列表和用户说明。随后,它通过读取 `references/scan-core.md` 进行优先级排序,分析仓库的组件库约定,并按照严格定义的扫描顺序(从原始 HTML 缺失组件库替代品开始,到文案语气违规结束)逐项检查,一旦发现第一个真实问题即停止。修复阶段强制要求每次运行仅做一次原子更改(最多 50 行结构性修改,最多 10 行纯文案修改),并优先使用已有组件库组件而非手动编写原始 HTML。最后,它会重新运行 lint/类型检查以验证修改未引入新错误,然后输出差异供人工审查,绝不提交或创建拉取请求。该技能支持 Claude Code 等平台,其严格的单问题处理原则和预先配置的规则确保了差异的可审查性,并防止回归。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add robcsaszar/tend

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Tend A11y — 传令官

查找此仓库标记中单个最高优先级的无障碍、用户体验或文案语气问题,以最小化方式修复、验证,并将差异交回审查。每次运行仅处理一个问题。

0. 加载配置

  • 读取 .claude/tend/config.yaml。使用 skills.a11y(禁止修改的文件列表、说明)。本技能没有功能模块——完全跳过模块门控步骤,此处没有 modules: 门控步骤。
  • 没有配置? 按照核心层级运行:核心 SvelteKit + TS 假设,保守的内置防护规则(绝不碰锁文件、CI、.env、配置)。输出一次:“运行 tend-onboard 以优化。”然后继续。

1. 初步评估

必须阅读 references/scan-core.md。

  • 确定禁止修改的文件集合:配置中的 skills.a11y.off-limits 加上内置防护规则(绝不碰锁文件、CI 配置、.env、项目配置或后端/API 路由逻辑——此技能仅处理表示层)。
  • 确定入口点:此仓库的标记文件——.svelte 组件、+page.svelte / +layout.svelte 路由,或堆栈实际使用的任何模板文件。检查 skills.a11y.notes 中是否有命名的组件库目录(例如 src/lib/components/ui)——如果存在,其导出将是第 2 阶段的“使用此替代原始 HTML”目标列表。
  • 在扫描之前,先阅读 1-2 个现有组件,以了解仓库实际的组件库和状态/加载约定——你需要先掌握真实模式,才能将偏离它的行为视为违规。

完成标准:已知禁止修改的文件集合,已识别组件库约定(如果有),已识别入口点 glob 模式。

2. 扫描——按优先级顺序,在第一个真实命中处停止

按最高价值(对用户最无声)排序——在第一个有证据支持的真实命中处停止:

  1. 原始交互式 HTML,但仓库中存在组件库等效替代品——仓库其他位置存在 Button/Link/Input 导出,却使用原始 <button>/<a>/<input>。
  2. 仅图标或图标为主的交互元素缺少可访问名称——没有 aria-label,没有视觉隐藏文本,没有 title 后备。
  3. <img> 缺少 alt——缺少属性是违规;用于装饰性图像的刻意空 alt="" 不是违规。
  4. 表单输入没有关联标签——没有 label for=、aria-label 或组件库标签属性。审计渲染后的数量,而不仅仅是模板:在循环({#each} 或等效)内生成的输入在运行时产生 N 个匿名控件。
  5. role="button"(或非交互元素上使用裸 onclick)缺少配对的键盘处理程序——缺少 Enter + Space 的 onkeydown。原生 <button> 自带此功能;此规则仅针对使用原始元素转义的情况。
  6. 异步成功/错误/加载反馈以普通、无声明的元素呈现——没有 role="alert"/role="status",没有 aria-live,并且仓库其他位置没有已使用的现有组件库横幅/提示框原语。
  7. 破坏性操作(删除/移除/重置)在没有确认步骤的情况下生效。
  8. 文案语气违规,根据配置驱动的允许/拒绝列表(skills.a11y.notes,或它指向的项目语气文档)进行检查。如果不存在仓库特定的列表,则回退到通用默认值:在验证/错误指令前使用强制软化词如“请”(“请输入名称” vs “输入名称”),或在常规确认/说明文案中使用不必要的感叹号。扫描渲染后的标记文本和 <script> 块内的字符串字面量——分配给变量、传递给 toast/alert 调用或通过 .textContent/.innerText 设置的文案存储在脚本块中,而不仅仅是标记中,仅扫描标记的 grep 会错过真实的验证字符串。

3. 修复——一次原子更改

在编辑之前,回答以下问题:

  1. 这对真实用户(屏幕阅读器、纯键盘用户或阅读语气的用户)来说,是否真的不清楚或不可访问——而不是我个人的风格偏好?
  2. 修复是否仅涉及表示层/文案——没有逻辑、没有后端、没有新依赖?
  3. 此模式是否已存在组件库等效替代品?如果是,则使用它而不是手动编写原始 HTML 修复(如果仓库已经有一个携带 role="alert" 的状态/横幅组件,则不要将 role="alert" 硬塞到原始 <div> 上)。

基线验证:在编辑前运行仓库的 lint/类型检查(如果快速,则运行测试套件)——注意任何预先存在的失败,以免后来错误地归因。

大小预算:标记/结构性修复不超过 50 行更改,纯文案修复不超过 10 行;每次运行一个组件或页面。

绝不碰禁止修改的路径。如果实际修复需要触碰其中一个,则停止并报告原因,而不是强行在其他地方实现。

4. 验证并呈现

重新运行 lint/类型检查(以及测试,如果你在第 3 步中运行了它们)——仅当你的更改引入新失败时才中止;预先存在的失败不是你来修复的。显示差异。停止——不要提交,不要打开拉取请求。

切勿

  • 切勿标记或修复每次运行超过一个问题 应改为: 在第一个真实命中处停止扫描,修复它,呈现它。 原因: 批量处理的无障碍/文案差异难以单独审查,并且掩盖了哪个特定修复导致了回归。

  • 切勿在存在组件库等效替代品时手动编写原始 HTML 修复 应改为: 使用仓库自己的 Button/Input/Link/状态横幅组件。 原因: 并行的单次修复会创造第二个不一致的模式,而不是收敛到仓库其余部分已经依赖的模式——下次审计将再次将其标记为漂移。

  • 切勿发明不受 skills.a11y.notes 或通用明确标记的默认值支持的文案语气规则 应改为: 使用配置驱动的允许/拒绝列表,或明确声明你正在回退到通用默认模式。 原因: 现场发明的规则在下一次运行时不可重用或不可审计,并且可能违反仓库的实际内部风格。

  • 切勿仅扫描标记而跳过 <script> 块中的文案字符串 应改为: 也 grep <script> 块内的字符串字面量——验证和反馈文案经常在那里分配,而不是直接写在模板中。 原因: 真实面向用户的字符串通常是插值到模板中的变量;仅扫描标记的 grep 匹配的是插值位置,而不是实际的违规文本,并且报告不出任何要修复的内容。

  • 切勿触碰禁止修改的路径或提交/打开拉取请求 应改为: 尊重 skills.a11y.off-limits 加上内置防护规则;在呈现差异后停止。 原因: 此技能的工作结束于“已验证的差异,可供人工审查”——提交或触碰排除的路径会移除整个工作流所依赖的审查关口。

文件

  • references/scan-core.md——核心检查(在第 1 阶段加载)
  • evals/——ai-forge-eval 断言

相关技能