mcpField
P
penpot-rename-layers

penpot-rename-layers

github.com/penpot设计与 UI108117 次安装3 周前更新
代码仓库

关于 penpot-rename-layers

penpot-rename-layers 是用于 Penpot 的设计技能,为图层推断语义 HTML 元素或 kebab-case 角色名,并按检查点分批重命名。它强调保留人工命名、跳过主组件图形,并在写入后验证结果。

主要功能

  1. 01识别自动生成、语义及自定义名称
  2. 02推断语义元素与角色名称
  3. 03分批应用并记录重命名
  4. 04跳过主组件图形
  5. 05导出图像检查结果

适用场景

  1. 01为无障碍审计整理图层名称
  2. 02为设计交付和代码审查统一命名

MCP 相关

该技能通过 Penpot MCP 工具读取图层结构、执行名称修改并导出图形供检查。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/penpot/penpot-ai-kit --skill penpot-rename-layers

安装后在 Claude Code 中输入/penpot-rename-layers确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
01-inspection.md
02-semantic-inference.md
03-renaming-strategy.md
scripts/
inspectLayerStructure.js
renameLayer.js

详细介绍

语义层重命名

1. 标题 + 工作原理

此技能会重命名 Penpot 文件中的图层,让每个图层都带有其代表的语义 HTML 元素名称(nav、header、main、section、article、button、input、label、h1–h6、p、ul、li、img),或者在没有合适元素时,使用kebab-case 角色名称(card-grid、button-group、field-row)。语义名称是进行无障碍审查(只能从命名为 h1–h6 的图层读取标题层级)、设计转代码审查(审查者将 button 对应到 <button>)和顺利交接的前提条件。

所有修改都通过 execute_code 完成;使用 export_shape 进行视觉验证;使用 penpotUtils.shapeStructure 读取结构(完整工具列表:shared/penpot-mcp-tool-reference.md)。重命名只需执行 shape.name = "..."——没有 renameShape() API。

2. 最重要的一条规则

切勿一次性处理整个文件。 先只读检查,将每个图层归入三类之一——自动命名(可安全自动修复)、有意义的名称(需要审核)、含义不明确(需要询问用户)——然后分小批次重命名并逐批验证。重命名自动命名的图层(Rectangle 12 → button)属于安全范围,可以直接执行,无需询问。重命名已有有意义名称的图层需要判断,且始终需要审核。默认禁止重命名主组件形状(这会改变所有实例的名称)。每次 execute_code 调用只处理一个逻辑批次;批次之间设检查点。

3. Penpot MCP 工具参考

完整工具列表:shared/penpot-mcp-tool-reference.md。与此领域相关的调用:

调用用途
penpotUtils.findShapes(pred, root) / findShapeById(id)收集清单;解析要重命名的形状 ID。
penpotUtils.analyzeDescendants(root, evaluator, maxDepth)遍历树,并将父级上下文传递给分类器。
shape.name = "..."(通过 execute_code)执行重命名——直接写入属性;不存在重命名方法。
export_shape(shapeId, 'png', 'shape')对已重命名区域进行视觉检查。
penpot_api_info('Board')在使用 name、isComponentMainInstance()、isComponentCopyInstance() 前进行验证。

4. 插件 API 要点

相关领域的事实与注意事项(完整列表见 shared/plugin-api-gotchas.md):

  • shape.name 是可直接写入的字符串。 使用 shape.name = "button" 重命名。没有重命名方法。写入是同步的——与应用令牌不同,可以在同一次调用中读取 shape.name 来确认。
  • 重命名不会影响几何属性——不会移动、缩放或重新设置父级。这正是自动命名图层的重命名可逆且安全的原因。
  • 组件主形状: 使用 shape.isComponentMainInstance() 检测——主实例及其内部嵌套的每个形状都会返回 true。重命名其中任何一个,都会为所有副本重命名该组件——超出安全范围。可以重命名副本实例(isComponentCopyInstance() 为 true)。注意:主实例本身也是一个实例,因此 isComponentInstance() 对它也会返回 true——不要用 isComponentInstance() === false 检测主形状(这是一个真实发生过的 bug)。在分支处理前,使用 penpot_api_info('Board', 'isComponentMainInstance') 验证。
  • #5 width/height/parentX/parentY 为只读——与重命名无关;处理时不要“修复”几何属性(这是另一项技能,绝不可自动修复)。
  • 返回小型结构化对象(数量 + ID + 前后对照)。
  • 不确定任何签名时,请调用 penpot_api_info——猜测是导致静默失败的首要原因。

5. 了解令牌的简报约定

重命名前,先将请求重述为一份约定。请以资深设计系统工程师的身份行事,将图层名称视为设计与代码之间的约定,绝不交付自动生成的名称,也绝不未经询问就覆盖人工精心设置的名称。

  • 背景——产品与界面(例如“营销落地页”“设置界面”);接下来会使用这些名称的人(无障碍审查、代码审查、交接)。
  • 目标——单一且具体:“将当前页面上所有自动命名的图层重命名为其语义 HTML 元素名或 kebab-case 角色名。”
  • 输入——范围(当前页面/所选画板/整个文件)、Phase 0 中的实时图层树,以及 shared/naming-conventions.md(图层命名部分)。
  • 约束——绝不重命名主组件形状;绝不修改几何属性;除非用户选择加入,否则保留已有明确含义的名称;语义 HTML 名称原样使用,角色名称使用 kebab-case;图层名称不得使用 PascalCase(该格式用于组件)。
  • 验收标准(量化)——范围内剩余的自动生成名称数为 0;100% 充当标题的文本图层都带有 h1–h6 名称;每个交互容器都命名为 button / input / select / label;每个列表容器都命名为 ul/ol,并包含 li 子项;每个被更改的、原本有意义的名称都记录了修改理由;重命名的主组件形状数为 0。

6. 强制工作流

Phase 0 — 探查(只读)
  • **目标:**加载指导文档并建立完整的图层清单;分类每个图层的名称状态。
  • **步骤:**调用一次 high_level_overview。然后使用 scripts/inspectLayerStructure.js 执行 execute_code,逐个形状收集:id、name、type、nameStatus(auto-generated | semantic | custom)、位置/尺寸提示、子项类型、文本属性(fontSize/fontWeight/characters)、填充/描边标记,以及 isComponentInstance()。将清单缓存到 storage。
  • **退出条件:**生成一份扁平清单,包含每个图层的 nameStatus 和统计数据(autoGenerated、alreadySemantic、custom、componentInstances、textNodes)。
  • ✋ **检查点:**展示清单与统计数据;在进行推断前确认范围(页面/画板/文件)。
Phase 1 — 语义推断(分析,不写入)
  • **目标:**生成重命名计划,列出更名前后的名称、置信度,以及每行所属类别。
  • **步骤:**在本地将 references/02-semantic-inference.md 中的推断规则应用于缓存的清单。为每行指定类别:安全(自动命名 → 重命名)、需审核(名称有意义 → 提议更改)、有歧义(置信度低 → 询问)。为每行记录一句理由。
  • **退出条件:**生成重命名映射 { shapeId: { old, new, bucket, reason, confidence } },并单独列出有歧义的行。
  • ✋ 检查点:按类别展示完整的更名前后对照表;就需审核和有歧义的行征求批准。(在自动修复模式下,安全项已预先批准,但仍须展示。)
Phase 2 — 重命名(写入,分批进行)
  • **目标:**自上而下(父级在子级之前),通过幂等操作按批准的映射执行重命名,每次调用处理一批。
  • **步骤:**将已批准的 RENAME_MAP 粘贴到 scripts/renameLayer.js。该脚本会跳过主组件形状、跳过名称已符合目标的图层,并返回更名前后的名称对。每次调用最多处理 100 项。每批处理后写入日志。
  • **退出条件:**每个已批准的行都已应用或明确跳过(并注明理由);错误数为 0,否则报告错误。
  • ✋ **检查点:**执行 export_shape('page','png','shape')(或导出已重命名的画板),并提供重命名数量摘要;完成签核。

7. 关键规则

  1. 写入前先展示完整的重命名计划。 图层名称会影响交接、代码导出和审计;名称错误会在下游工作流中悄无声息地造成问题。
  2. 自动修复仅会自动应用 auto-generated → semantic 重命名。 任何对已有有意义名称的图层所做的更改都必须审核。
  3. 绝不重命名主组件形状。 根据 isComponentMainInstance()(主实例及其内部结构均返回 true)进行分支;跳过这些形状并在报告中说明。副本实例可以重命名。
  4. 自上而下重命名。 先处理父级,再处理子级,这样运行过程中树结构始终清晰,日志也易于阅读。
  5. 幂等。 对已使用目标名称的图层重新运行时,必须不做任何更改。
  6. 此处不得触碰几何属性。 此技能只写入 shape.name,不做其他操作。不得调用 resize(),不得重新设置父级。
  7. 语义化 HTML 名称原样使用,角色名称使用 kebab-case,绝不使用 PascalCase。 使用 h1、nav、button、card-grid,而非 H1、CardGrid。
  8. 报告范围限制。 如果进行过抽样、限制为前 N 项或跳过页面,必须在最终报告中说明。

8. 领域架构

此技能生成的内容:

名称状态分类(清单的骨架):

  • auto-generated — 匹配 ^(Board|Frame|Rectangle|Group|Ellipse|Text|Path|Bool|Image|Component|Vector)\s*\d*$。安全集;可自动修复。
  • semantic — 已是有效的 HTML 元素名称或已知角色名称。除非有误,否则保持不变。
  • custom — 由人工编写的非语义化名称(Hero copy v2)。覆盖前须审核。

重命名映射行: { shapeId, old, new, bucket: 'safe'|'review'|'ambiguous', reason, confidence: 0..1 }。

命名输出词汇:

  • 结构:header、nav、main、section、article、aside、footer、form、dialog、figure。
  • 交互:button、input、select、label、a。
  • 文本:h1–h6、p、small、caption、span。
  • 列表/媒体:ul、ol、li、img、svg、icon、hr。
  • 角色容器(kebab-case):card-grid、button-group、field-row、avatar-stack、nav-list。
  • 同级元素使用相同元素名称时,用于区分的描述符:button-primary、button-ghost、li-pricing。

9. 模式与策略

参见 shared/modes-and-policies.md。此技能的 mode-default 为自动修复,但范围有限:

  • 建议: 仅生成重命名计划,不做任何更改。
  • 审核(审核后应用): 对任何已有有意义名称的图层,以及所有含糊不清的行,默认采用此模式。在 Phase 1 检查点之后应用。
  • 自动修复(仅限安全集): 将未命名/自动命名的图层重命名为语义化名称——这种更改不会造成破坏、可撤销且明确无误,是唯一无需询问即可自动应用的更改。其他所有情况均转为审核。主组件形状绝不会自动重命名(完全排除在外)。几何属性、变体/组件重构、detach() 和新令牌均不在此范围内,绝不自动修复。

10. 状态管理

参见 shared/state-management.md。使用 setSharedPluginData(命名空间 penpot-ai)维护权威日志,以 RUN_ID 为键(例如 rename-2026-06-05-a);使用 storage 缓存会话数据。

日志键:

  • ${RUN_ID}.phase — "0"|"1"|"2"。
  • ${RUN_ID}.ledger — JSON { runId, phase, scope, renameMap, created:[], decisions:[], assumptions:[], pendingReview:[] }。
  • storage.run.inventory — 缓存的 Phase 0 清单。
  • storage.run.renameMap — 已批准的映射。

恢复:重新读取文件内日志,通过 shapeStructure 重新推导实时树,然后从 ledger.phase 继续。幂等性(跳过已使用目标名称的图层)确保批量操作可安全重新运行。

11. 用户检查点

阶段之后显示的产物我们询问的内容
0 — 探索图层清单 + 名称状态统计;已确定的范围“范围是否正确(页面 / 画板 / 文件)?是否继续推断?”
1 — 推断按类别(安全 / 需审核 / 有歧义)分组的完整更名前→后表格,每行包含置信度 + 原因“是否批准需审核和有歧义的重命名?是否有要覆盖的名称?”
2 — 重命名已重命名区域的 export_shape + 重命名 / 跳过 / 错误计数“名称看起来正确吗?是否批准此批次并继续下一批?”

12. 命名约定

权威来源:shared/naming-conventions.md(Layers 部分)。领域特定规则:

  • 优先直接使用语义 HTML 元素名称;仅在没有合适元素时,才使用 kebab-case 角色名称。
  • 当同级元素共享同一元素名称时,添加 kebab-case 描述词:button-primary、button-secondary、li-home、li-about。
  • 标题级别应符合页面的视觉层级,而不只是字体大小——标题级别排序请参阅 references/02-semantic-inference.md。
  • 绝不交付 Rectangle 12、Group 4、Board。图层名称绝不使用 PascalCase(PascalCase 仅用于组件)。

13. 反合理化对照表

LLM 给出的借口错误原因确定性应对措施
“这个图层已经有名称了,我顺手改进一下。”人为有意设置的名称不属于安全集;悄悄覆盖会丢失原有意图,且没有台账就无法撤销。将其归入需审核。不要自动应用。在第 1 阶段检查点显示旧名称→新名称,并等待批准。
“这显然是个按钮——我顺便调整一下它的内边距 / 尺寸。”此技能只写入 shape.name。几何属性变更绝不自动修复,应由其他技能处理。停止。仅重命名。将几何属性观察结果记为审核备注;不要调用 resize() / setParentXY。
“重命名组件的主图形就等于重命名实例。”重命名主图形会更改文件中所有实例所用的组件名称——这是共享资源编辑,绝不自动修复。根据 isComponentMainInstance() 分支处理。跳过主实例及其内部的所有内容;报告为 skipped: main component。
“只看字体大小的话,我会把每个大号文本都标为 h1。”多个 h1 会破坏标题层级,也不满足此技能旨在实现的无障碍前提条件。按视觉显著性排列标题:每个区域一个 h1,依次递减为 h2 / h3。使用 references/02-semantic-inference.md 中的级别规则。
“这三个重复的卡片各自都是一个 section。”列表中的重复同级元素应是 ul 中的 li,而不是独立的 section;错误标注会破坏代码审查映射。根据同级元素数量 + 结构匹配情况检测重复项;将容器命名为 ul,子项命名为 li(并添加描述词)。
“为了快,我会在一次 execute_code 调用中重命名整个树。”一次性处理会绕过检查点,并使错误推断在执行过程中无法恢复。每次调用最多处理 100 项,自上而下进行,并在批次之间写入台账。

14. 辅助代码片段

分类名称(用于检查):

const isAutoGenerated = n =>
  /^(Board|Frame|Rectangle|Group|Ellipse|Text|Path|Bool|Image|Component|Vector)\s*\d*$/i.test(n || "");
const isSemantic = n =>
  /^(header|footer|nav|main|section|article|aside|form|dialog|figure|button|input|select|label|a|h[1-6]|p|small|caption|span|ul|ol|li|img|svg|icon|hr)([-_ ].*)?$/i.test(n || "");
const nameStatus = n => isSemantic(n) ? "semantic" : isAutoGenerated(n) ? "auto-generated" : "custom";

安全地重命名一个图形(幂等,跳过主组件):

const shape = penpotUtils.findShapeById("REPLACE-ME-SHAPE-ID");
let result;
if (!shape) result = { error: "not found" };
else if (shape.isComponentMainInstance && shape.isComponentMainInstance())
  result = { skipped: "main component", name: shape.name };  // true for the main instance AND its internals
else if (shape.name === "button") result = { skipped: "already named", name: shape.name };
else { const old = shape.name; shape.name = "button"; result = { old, new: shape.name }; }
return result;

15. 参考资源

  • penpot_api_info('Board') — 确认 name 可写,并检查 isComponentMainInstance()、isComponentCopyInstance()、detach()。
  • penpot_api_info('PenpotPage') 和 penpotUtils.shapeStructure,用于遍历树结构。
  • shared/naming-conventions.md — 规范的图层命名规则。
  • shared/modes-and-policies.md — 此技能所依赖的精确安全集定义。
  • 相关技能:penpot-audit-accessibility(使用标题名称)、penpot-design-to-code-review(使用语义名称)。请先运行此技能。

16. 支持文件

参考资料(渐进式披露)
文件阅读阶段涵盖内容
references/01-inspection.md阶段 0只读遍历、名称状态分类、组件检测、范围选择。
references/02-semantic-inference.md阶段 1推断规则(结构/交互/文本/媒体/列表)、按标题级别排序、歧义处理。
references/03-renaming-strategy.md阶段 2自顶向下分批处理、幂等性、跳过主组件、验证、记录表与恢复。
脚本(粘贴到 execute_code 中)
脚本阶段用途
scripts/inspectLayerStructure.js0只读清单,包含 nameStatus 和推断信号。
scripts/renameLayer.js2幂等地应用已批准的 RENAME_MAP;跳过主组件;返回操作前后结果。

规范路径。 在原生安装中,shared/… 和 policies/… 会解析到此资源包内(由安装程序一并安装);在 Claude Code 插件安装中,它们位于插件根目录 — ${CLAUDE_PLUGIN_ROOT}/shared/…,也就是本文件往上两级目录。

评论

支持 Markdown