关于 platform-lightning-type-widget-coordinate
用于协调 Apex 支持的 Lightning Type 与 HXL widget 创建,或为现有 Lightning Type 添加 widget 的技能。它按依赖顺序调用专用技能,展示构建计划,并检查生成文件和 renderer wiring。
主要功能
- 01选择现有或新建 Lightning Type 路径
- 02发现并验证现有类型及 Apex 类
- 03按依赖顺序调用生成技能
- 04通过可见构建计划控制流程
- 05通过 renderer.json 连接 widget
- 06运行阻断式和提示式验证
适用场景
- 01根据新需求构建 Lightning Type 和 widget
- 02为现有 Apex 支持类型添加 widget
- 03检查 renderer wiring 和生成产物
- 04避免意外修改现有类型 schema
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-lightning-type-widget-coordinate安装后在 Claude Code 中输入/platform-lightning-type-widget-coordinate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/existing-lightning-type-with-widget-prompt.mdnew-lightning-type-with-widget-prompt.mdreferences/build-plan-format.mdlightning-type-discovery.mdvalidation-gates.md详细介绍
使用 Widget 构建 Lightning Type
协调以下两条路径中的 Lightning Type、Apex 类和 HXL widget 生成。此技能不会直接编写内容,而是按依赖顺序加载并调用叶子技能,在用户批准后继续,并在报告完成前运行验证关卡。
范围
仅限由 Apex 支持的 Lightning Type——根节点 lightning:type 的形式为 @apexClassType/<namespace>__<ClassName>(外部类)。类本身包含定义负载形状的 @AuraEnabled 字段;嵌套列表元素类型则是外部类上 List<Inner> 字段所引用的内部类。基于对象/JSON 的 Lightning Type(根节点为 lightning__objectType 且包含基本类型 properties)不在范围内;请分别将其交由 platform-custom-lightning-type-generate 和 platform-widget-generate 处理。
阶段图
| 阶段 | 用途 | 适用路径 | 输出 |
|---|---|---|---|
| 1 — 路径选择 | 根据用户提示选择路径(existing-lightning-type-with-widget · new-lightning-type-with-widget)。 | 所有路径 | path |
| 2 — Lightning Type 发现 | 优先检查本地项目;然后运行 sf project retrieve --metadata LightningTypeBundle:<name>;解决歧义;确认符合范围。 | 仅限 existing-lightning-type-with-widget | lightningTypeSchema(路径 + SHA-256 + Apex 类 FQN) |
| 3 — 构建计划 | 完整输出计划;除非下一条回复明确提出异议,否则继续。 | 所有路径 | 已输出的计划 |
| 4 — 生成 | 按路径加载并调用叶子技能。 | 所有路径 | 已写入的文件 |
| 5 — 验证 | 运行硬性关卡(阻止)和警告关卡(提示)。 | 所有路径 | 关卡报告 |
| 6 — 总结 | 文件、验证、预览就绪情况、后续步骤。 | 所有路径 | 总结 |
各阶段的步骤模式:
| 步骤 | 操作 |
|---|---|
| 1. 加载技能 | 调用指定技能。即使你记得其内容,也要重新加载最新版本,因为技能会不断演进。 |
| 2. 执行 | 按照已加载技能的工作流操作。 |
| 3. 验证 | 确认输出存在且符合规范。 |
| 4. 检查点 | 确认阶段已完成,再继续下一阶段。 |
阶段 1 — 路径选择
根据用户提示确定路径,并按对应顺序加载叶子技能:
| 路径 | 触发条件 | 阶段 4 子技能加载顺序 |
|---|---|---|
existing-lightning-type-with-widget | 提示中提到某个 Lightning Type,并将其视为现有类型(类型名称前没有 create、generate 或 new 修饰)。阶段 2 确认其存在且符合范围。 | platform-widget-generate(渲染器接线按阶段 4 的“Renderer.json 接线步骤”内联编写——无需单独加载技能) |
new-lightning-type-with-widget | 提示要求创建新的 Lightning Type(动词:create、generate、build、make a new),或阶段 2 未在本地项目或组织中找到该类型。 | platform-apex-generate → platform-custom-lightning-type-generate(编写架构)→ platform-widget-generate(之后按阶段 4 的“Renderer.json 接线步骤”内联编写渲染器接线) |
如果提示中完全没有提到 Lightning Type(只是要求使用提示中提供的字段或示例数据构建 widget),则不应触发此编排器——请直接将用户转交给 platform-widget-generate。
如果提示对两条路径的选择含糊,最多提出一个澄清问题,然后选择一条路径。new-lightning-type-with-widget 路径会自动执行 platform-apex-generate 步骤——不要提示用户确认是否使用 Apex。
阶段 2 — Lightning Type 发现(仅适用于 existing-lightning-type-with-widget)
对于 new-lightning-type-with-widget,跳过此阶段(Lightning Type 尚不存在)。
对于 existing-lightning-type-with-widget,首先阅读 references/lightning-type-discovery.md(必需——不得跳过;不得仅依据此摘要执行阶段 2),然后按步骤执行其中的查找 → 验证 → 确保类流程。 以下要点仅作提醒,不能替代参考文档:
- 优先检查本地项目:搜索
force-app/**/lightningTypes/<TypeName>/schema.json。 - 如果未找到,则针对已连接的组织运行
sf project retrieve --metadata LightningTypeBundle:<TypeName>。 - 如果出现多个候选项,列出其 FQN 和路径,并请用户选择。
- 找到架构后,验证其是否在范围内(根级
lightning:type以@apexClassType/开头)。如果类型基于对象/JSON,则说明这一点并停止。 - 确保本地项目中存在对应的 Apex 类。 从根级
@apexClassType/<ns>__<ClassName>中解析出<ClassName>。如果不存在<pkgDir>/classes/<ClassName>.cls,则运行sf project retrieve --metadata ApexClass:<ClassName>。无论 Lightning Type 是在本地找到还是从组织中检索到,都要执行此步骤——本地已有的 Lightning Type 仍可能引用缺失的类。如果该类在任何位置都不存在,则说明这一点并停止(该类型无法渲染)。完整流程请参阅参考文档。 - 如果检索失败,说明 CLI 错误,并提供以下选项:(a) 请用户手动运行检索后重新执行;或 (b) 在适当情况下改为
new-lightning-type-with-widget。不得静默降级。 - 如果检索无结果,继续之前请提示用户确认是否切换为
new-lightning-type-with-widget。
在此阶段结束时,记录 Lightning Type schema.json 的 SHA-256 值,以及 Apex 类 FQN(从 @apexClassType/... 解析得出)。阶段 5 的 lightning-type-unchanged 门禁会将该 SHA 与阶段 4 结束时磁盘上的 SHA 进行比较,以确保未静默修改架构。
过时性:不得维护跨会话缓存。每次都要重新读取本地项目,并在每个会话中重新从组织检索。
阶段 3 — 构建计划 + 审批门禁
使用 references/build-plan-format.md 中的模板打印构建计划。计划必须列出:
- 面向开发者的一句话构建内容摘要(模板中的
PLAN:行)。 - Lightning Type 名称和来源(本地项目中已有 · 从组织检索 · 新建),以及它引用的 Apex 类 FQN。
- 即将创建或修改的文件及其绝对路径。
- 审批后将运行的子技能。
- 生成后将运行的验证。
开发者会阅读此计划。内容应具体明确:列出相关制品、文件、子技能和验证。
完整打印计划,然后继续,除非用户的下一条回复明确表示反对。 明确反对包括 no、stop、wait、change X、use Y instead,或含义相同的拒绝/修改请求。欢迎用户明确批准(yes、approve、go、looks good、ok),但并非必需——沉默、无关的后续消息,或单轮评测中的自然继续,都视为默认批准。计划在对话记录中可见是不可变的要求;不得因等待交互式审批而阻塞。如果用户表示反对,则修改计划并重新打印,然后再继续。
阶段 4 — 生成
按照阶段 1 表格中所选路径对应的行,按顺序加载子技能。对每个子技能:
- 加载该技能。
- 根据阶段 3 的规范,执行叶子技能的创作工作流。叶子技能对其自身的交付物具有权威性。
- 验证输出是否符合构建计划的承诺。
- 在调用下一个子技能前创建检查点。
new-lightning-type-with-widget 交接约定:
- Apex 编写一个类,其
@AuraEnabled字段定义所需的 Lightning Type 形状。仅在嵌套列表元素类型中使用内部类。记录外部类 FQN(<namespace>__<ClassName>)。 - Custom Lightning Type 通过
lightning:type: "@apexClassType/<namespace>__<ClassName>"引用外部类。 - Widget 根据外部类的
@AuraEnabled字段确定基础结构,并通过{!$attrs.X}绑定属性。 - 编写完 widget 包后,按照下面的 renderer.json wiring step 配置 Lightning Type 的 renderer。
existing-lightning-type-with-widget 交接约定:
- 将 Lightning Type 的
schema.json路径以及阶段 2 中记录的 Apex 类 FQN 交给 widget 技能。widget 技能根据 Apex 类的@AuraEnabled字段推导出自己的schema.json(参见platform-widget-generate/references/schema-from-lightning-type.md)。 - 编写完 widget 包后,按照下面的 renderer.json wiring step 配置 Lightning Type 的 renderer。Lightning Type 的
schema.json不得修改(lightning-type-unchanged会强制执行这一点)——只编写renderer.json。
Renderer.json wiring step(两种流程均适用——绝不能省略):
首先,阅读 platform-custom-lightning-type-generate/references/widget-rendition.md(必需——不得跳过;不得凭记忆或复制现有项目示例来编写 renderer.json,因为示例可能采用已弃用的格式)。
widget 包存在后,使用 platform-custom-lightning-type-generate/references/widget-rendition.md 中记录的 widget-rendition 模式编写 <pkgDir>/lightningTypes/<TypeName>/renderer.json。renderer 文件是一个精简包装器——其第一个子项通过 "definition": "@widget/c/<widgetName>" 引用 widget,并将每个 widget 架构属性映射到 Lightning Type 实例中对应的属性,使用 {!$attrs.<schemaPropertyName>}。不要在 renderer.json 中重复 widget 主体;widget 包是渲染树的唯一真实来源。
现有 renderer 的处理方式(仅适用于 existing-lightning-type-with-widget):如果目标路径下已存在 renderer.json,请先读取。
- 如果它已引用同一个 widget(相同的
@widget/c/<widgetName>),且属性映射也相同,则保持原样。 - 如果它引用了不同的 widget,或使用了自定义 LWC 根节点覆盖(
c/<componentName>),则停止操作,并在覆盖前向用户说明冲突。不得悄悄替换用户现有的 rendition。 - 如果文件存在但并非 widget-rendition(例如,仅包含属性级覆盖),则说明这一情况,并询问用户是要合并还是替换。
缺少此 wiring,Lightning Type 就无法访问该 widget——widget 包将无法发挥作用。renderer-wires-widget 会强制检查其是否存在以及绑定是否正确。
阶段 5 — 验证门禁
阅读 references/validation-gates.md 并运行每项门禁。编排器只运行跨技能门禁;组件包内部检查(架构解析、根键、叶节点 lightning:type、{!$attrs.X} 解析、.uiwidget-meta.xml 格式正确性、<UiWidgetBundle> 根元素、<masterLabel>、<description> 和 <widgetType>JSON</widgetType>)由 platform-widget-generate 负责,并作为其自身自验证步骤的一部分运行。
硬性 — 失败时阻止:
lightning-type-unchanged— 仅限existing-lightning-type-with-widget。 重新计算磁盘上 Lightning Typeschema.json的 SHA-256,并与阶段 2 中记录的 SHA 进行比较。不匹配 = 编排器悄悄编辑了该类型。renderer-wires-widget— 两种路径均适用。 确认<pkgDir>/lightningTypes/<TypeName>/renderer.json存在、可解析为 JSON,并通过componentOverrides["$"].definition === "@widget/c/<widgetName>"接入此组件;同时确认componentOverrides["$"].attributes将每个组件架构属性绑定为{!$attrs.<schemaPropertyName>}。参见阶段 4 中的“renderer.json 接线步骤”和validation-gates.md,了解所需格式。
警告 — 提示性检查:
field-trace— 两种路径均适用。 运行references/validation-gates.md中的追踪流程(从外层 .cls 中 grep@AuraEnabled,用jq获取组件架构属性键,打印两份列表,并将其归类为 INVENTED 或 OMITTED)。在门禁报告中打印两份列表 — 未打印列表却断言pass属于严重违规。未提示的遗漏(Apex 字段既不在组件中,也不在阶段 3 的Properties omitted:计划中)将发出警告。deploy-check— 仅限new-lightning-type-with-widget。 运行sf project deploy --check-only --source-dir <pkgDir>/classes/<ClassName>.cls,<pkgDir>/lightningTypes/<TypeName>并报告结果。未运行此命令却报告pass属于严重违规。关于“尚未部署并非有效的跳过理由”规则,参见validation-gates.md。
在阶段 6 中按名称报告每项门禁结果(pass、fail (<reason>)、warn (<reason>)、not run)。不要总结为“全部通过” — 请逐项列出每个门禁。
阶段 6 — 摘要
报告结果。开发者会阅读此摘要 — 仅列出实际写入的文件;按组件包分组,方便开发者快速找到文件。
Lightning Type + Widget Build Complete: <widgetName>
FILES GENERATED:
Widget bundle:
<pkgDir>/uiWidgets/<widgetName>/<widgetName>.json
<pkgDir>/uiWidgets/<widgetName>/schema.json
<pkgDir>/uiWidgets/<widgetName>/<widgetName>.uiwidget-meta.xml
Lightning Type bundle:
<pkgDir>/lightningTypes/<TypeName>/schema.json # only when newly created
<pkgDir>/lightningTypes/<TypeName>/renderer.json # always — wires the Lightning Type to the widget
Apex (only when newly created):
<pkgDir>/classes/<ClassName>.cls
<pkgDir>/classes/<ClassName>.cls-meta.xml
VALIDATIONS:
widget self-validation (platform-widget-generate gates): <pass | fail — see sub-skill report>
Lightning Type schema unchanged from before this run: <pass | fail | n/a (newly created)>
Lightning Type renderer wires this widget: <pass | fail (<reason>)>
widget↔apex field trace (INVENTED + OMITTED lists printed): <pass | warn (<reason>) | fail (invented: <list>)>
sf project deploy --check-only: <pass | warn | n/a (no new Apex or Lightning Type to deploy)>
NEXT STEPS:
- Deploy: sf project deploy start --source-dir <pkgDir>
- Preview: <preview-surface guidance>
硬性规则(始终适用)
- 先制定计划,再继续。 在写入任何文件之前,打印完整的 Phase 3 构建计划。如果下一轮包含明确的拒绝或变更请求,则停止并修改计划;否则继续进入 Phase 4。关键在于计划必须出现在对话记录中,而不是等待人工交互式批准——因此,无论是手动聊天、Agent 间流程,还是没有后续用户消息的单轮评估运行,本规则都适用。
- 不得静默修改现有 Lightning Type 的架构。Phase 5 的
lightning-type-unchanged会对此进行强制检查,适用于existing-lightning-type-with-widget。 - 不得静默修改现有 Apex。如果 Phase 4 需要修改预先存在的类,必须在 Phase 3 中说明。如果叶技能在 Phase 4 中途遇到结构缺口,必须停止并报告给协调器,不得直接编辑
.cls——Phase 3 涵盖协调器事先已知的缺口;本条涵盖叶技能后来发现的缺口。 - 不得虚构字段,不得静默遗漏。 每个
{!$attrs.X}都必须对应到 widget 的schema.json,且 widget 的schema.json必须是 Apex 类@AuraEnabled字段的子集。每个 Apex 字段的默认处理方式都是包含;若要省略,必须在 Phase 3 构建计划的Properties omitted:部分列出该字段,并附上经用户批准的理由。field-trace会打印 APEX_FIELDS 和 WIDGET_PROPS 列表,并对静默遗漏发出警告。List<InnerClass>字段绝不可作为静默遗漏的候选项。 - Lightning Type 查找存在歧义时,最多澄清一次。
- 生成前始终加载叶技能。 不得凭记忆编写。
- 范围外类型必须让协调器停止。 如果 Phase 2 发现基于对象/JSON 的 Lightning Type,则应分别引导用户使用
platform-custom-lightning-type-generate和platform-widget-generate。 - 实际运行检查门禁,不要只描述。 Phase 5 门禁是具体的检查/命令。未实际执行检查门禁却报告
pass,属于严重违规;应报告not run。 - Lightning Type rendition 是必需项,绝非可选。 两条路径最终都必须通过
<pkgDir>/lightningTypes/<TypeName>/renderer.json,使用@widget/c/<widgetName>将 Lightning Type 连接到 widget,并按照 widget-rendition 模式映射属性。缺少此文件会导致 widget bundle 无法使用。renderer-wires-widget会检查文件是否存在及绑定是否正确。 - 不得使用会触发 Vibes 安全 shell 过滤器的 shell 元字符。 此协调器及其调用的任何叶技能发出的每个
Bash工具调用中,均不得使用命令替换($(…)或反引号)、进程替换(<(…)、>(…))、花括号展开({a,b,c}或{1..N})或eval/exec。即使处于 Bypass 模式,这些模式也会触发人工批准并导致评估停滞。应改为分别运行命令(使用mkdir -p a && mkdir -p b,而不是mkdir -p {a,b});使用单独的命令打印每个中间值并据此判断结果,而不是捕获值(单独运行jq … file,不要写X=$(jq … file));需要在多个命令间复用值时,使用普通 shell 变量(X=literal)或 here-string。
参考文件索引
| 文件 | 阅读时机 |
|---|---|
references/lightning-type-discovery.md | Phase 2 — 本地项目扫描、org retrieve、歧义处理、范围内验证,以及确保本地项目中存在对应的 Apex 类。 |
references/build-plan-format.md | Phase 3 — 模型在 STOP 之前填写的计划模板。 |
references/validation-gates.md | Phase 5 — 完整的硬性 / 警告门禁表,含错误→修复映射。 |
examples/existing-lightning-type-with-widget-prompt.md | Phase 3 — 起草构建计划前,阅读此文件以了解完整的 existing-lightning-type-with-widget 演练。 |
examples/new-lightning-type-with-widget-prompt.md | Phase 3 — 起草构建计划前,阅读此文件以了解完整的 new-lightning-type-with-widget 演练。 |