关于 nocobase-prototype-repro
用于将现有原型还原为 NocoBase 应用的技能,适合有明确视觉目标的构建任务。它协调数据建模和 UI 技能,映射区域与原生区块,并通过截图对比迭代。
主要功能
- 01将任务分发给相关 NocoBase 技能
- 02将原型区域映射到原生区块
- 03采用分阶段计划和确认节点
- 04通过截图对比迭代完善
- 05优先原生区块并按需使用 JS
适用场景
- 01还原截图或 HTML 原型
- 02改进与视觉目标不符的页面
- 03为原型区域选择 NocoBase 区块
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nocobase/ skills --skill nocobase-prototype-repro安装后在 Claude Code 中输入/nocobase-prototype-repro确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/block-recipes.mddecomposition-grammar.mdgotchas.mdhandoff.mdindex.mdprototype-authoring.mdspec-template.mdreferences/template-library/_index.mdautoRefresh.mdavatarText.mdcalendarHeatmap.mdcard.mdcharCounter.mdclickDistribution.mdcomboText.mdcommentFeed.mdconditionCards.mdconditionMenu.mdcopyFromField.mdcustomFilter.mddateRangeFilter.mddistribution.mddonutChart.mddueSoon.mdexportCsv.mdfacetFilter.mdformAutoFill.mdformCalc.mdformConcat.mdformDrivenFilter.md详细介绍
目标
将原型和一句话需求转化为忠实还原的 NocoBase 应用。这是一项元技能 / 编排技能——它会依次调用 nocobase-data-modeling、nocobase-ui-builder 和 nocobase-app-discipline,并补上决定还原度的两项内容:区域 → 原生区块映射和视觉收敛循环。它不会重新讲解 CLI,而是将具体操作交给相关技能,只负责与复现相关的判断。
适用场景 / 非目标
**硬性门槛(选择此技能前先检查):**必须有实际原型可供对照——HTML 文件、截图或链接均可。没有原型,也就没有还原度差距 → 不适用此技能;普通的“帮我构建一个应用 / 页面”请求应交给 nocobase-app-discipline(整个系统)或 nocobase-ui-builder(单页 / 编辑)。不要让此技能取代常规构建流程。
适用场景:
- 用户提供了原型(HTML 文件、链接、截图或可用 curl 访问的
public/prototypes/...URL),并希望在 NocoBase 中复现。 - 页面已经存在,但用户认为它单调 / 难看 / 与原型不符,或某个区域应该改成列表 / 卡片 / 看板,而不是表格——也就是说,存在一个视觉目标和还原度差距。
非目标——请转交处理,不要在此执行:
- 纯数据建模(没有视觉目标的集合 / 字段 / 关系)→
nocobase-data-modeling。 - 工作流 / 自动化 →
nocobase-workflow-manage。ACL / 权限 →nocobase-acl-manage。插件开发 →nocobase-plugin-development。 - 没有视觉目标和还原度差距的局部 UI 编辑(移动一个字段、重命名一个操作、调整一个联动反应)→ 直接交给
nocobase-ui-builder。只有在需要匹配原型的外观 / 行为时,使用此技能才值得付出额外开销;机械式的界面编辑应直接交给 ui-builder。 - 根据业务描述、在没有原型的情况下编写整个页面 → 先快速制作原型(prototype-authoring.md),再使用此技能;或者,如果用户只想要一个通用页面,则使用
nocobase-ui-builder的applyBlueprint。
路由 — 按任务类型选择 → 先阅读
选择一条路由,先阅读对应的“首先阅读”文档;只有该路由仍不足以解决问题时,才打开“然后按需阅读”中的文档。相关技能负责具体操作;此处的参考文件负责复现相关的判断。
| 任务类型 | 首先阅读 | 然后按需阅读 |
|---|---|---|
| 收到原型交付 → 端到端复现 | spec-template.md(Phase 1 SPEC) | decomposition-grammar.md、block-recipes.md、gotchas.md、visual-loop.md |
| 现有页面单调/难看/不对劲 | visual-loop.md | block-recipes.md、gotchas.md |
| “这个区域应该用哪个区块?” | 下方的 区域 → 原生区块 表 | decomposition-grammar.md、block-recipes.md |
| 需要小组件的 JS 主体(KPI 卡片、环形图、排行榜、即将到期提醒、进度条、趋势图、分面筛选器、卡片网格,……) | template-library/_index.md — 57 个可直接复制粘贴的小组件主体,每个都包含其 $p 输入契约 | block-recipes.md |
| 构建/编辑 JS、flow-surfaces、弹出窗口、图表的具体操作 + 可运行的 CLI | nocobase-ui-builder(其中的 js.md / popup.md / chart.md / runjs-* / page-archetypes.md) | — |
| 集合/字段/关系 | nocobase-data-modeling | — |
| 范围管理、种子数据标准、命名、最终报告 | nocobase-app-discipline | — |
| 未提供原型,必须自行创建 | prototype-authoring.md | — |
| 根据一行提示将构建任务交给另一个 Agent | handoff.md | — |
| 完整参考列表 | index.md | — |
保真度为何各不相同 — 关键因素(牢记)
在许多次复现中观察到的影响因素,按影响程度排序:
- 截图 → 对比 → 修复循环。 这是影响最大的单一因素。能渲染页面、将自己的截图与原型并排查看、列出差异并反复迭代的 Agent,最终能逐渐贴合原型。只构建页面并宣布完成的 Agent,则会停留在“没有错误,但很难看”的水平。纯文本验证只能证明“页面能渲染”;只有视觉检查才能证明“页面与原型相符”。参见 visual-loop.md。
- 预先加载易错点。 导致表现不佳的运行受阻的因素中,有 10–20% 几乎总是 alpha 版本的 JS 沙箱和 flow-surfaces JSON 契约。预先提供这些信息,可以省去约 10–20 次失败尝试,并避免 Agent 放弃后把整个页面压缩成一个大型 JS 区块。参见 gotchas.md。
- 明确限定目标。 “页面 uid X、区块 uid Y,完成这 N 项任务,完成前进行验证”比“修复这个页面”更有效。目标模糊会导致范围偏移,或只做到 CRUD 就停止。
- 为每个区域选择合适的区块。 到处都用表格,是页面“单调”的首要原因。原型通常需要卡片列表、看板、日历或网格。参见区域表和 block-recipes.md。
- 模型。 能力更强的模型更容易从契约错误中恢复,也可以担任视觉审核者;能力较弱的模型在范围明确、易错点预先提供的机械性任务上表现不错。提供上述关键因素,即使使用中等能力的模型,也能忠实复现。
工作流 — 分阶段进行,并设置用户确认关卡
按顺序执行。遇到每个 ▣ CONFIRM 关卡时,都要停下来,取得用户同意后再进入下一阶段。 除了小型的单区域调整,其他任务都应规划为多轮对话,而不是一次不作声地大规模执行——用户希望在每个重要步骤中掌握方向。
阶段 0 — 加载目标。 如果已有原型,直接加载;只有在用户给出的是没有原型的业务描述时,才创建原型(prototype-authoring.md)。使用 Curl 或读取原型(这是视觉目标;没有它,构建结果会退化为通用表格或一个巨大的 JS 代码块)。检查是否嵌有 <script type="application/nb-spec+json">——如果有,将其解析为权威规范(数据模型、各区域对应的区块、交互、JS 内核),并遵循其中的 notes/jsKernels,而不是自行推断。加载 block-recipes.md 和 gotchas.md。识别环境;每次调用 nb api 都传入 -e <env> -y;获取实时页面/区块 uid(flow-surfaces get / desktopRoutes),切勿相信文档中的 uid。
阶段 1 — 分析与规划 → SPEC ▣ CONFIRM。 根据 spec-template.md 生成结构化 SPEC(由 LLM 对照渲染后的原型进行判断,而非通过解析器生成):数据模型;页面列表,包括标志性页面;区域 → 区块映射(避免“所有内容都是表格”);以及交互检查清单——逐个区域检查并列出所有交互功能(分面/多选筛选器及计数、状态标签、搜索、排序、填满宽度的网格、点击→弹出窗口、内联编辑、拖动、实时刷新);每项功能都要对应一种配方,任何无法通过原生功能实现的内容都要标记为 JS 内核。展示 SPEC,并取得明确确认。
阶段 2 — 建模 + 原生 CRUD + 初始数据 ▣ CONFIRM。 一次性构建集合/字段/关系(nocobase-data-modeling);构建过程中切勿编辑。搭建纯原生后端(表格 + 筛选器 + 新增 + 查看/编辑;查看时打开包含详情和关联子表的抽屉,使用 associationName + sourceId={{ctx.view.inputArgs.filterByTk}})。为每个枚举分支添加初始数据,每个父项至少包含 2 个子项,公开演示的数据必须全部为英文,并确保数据足够充实(日历需填满 1–2 个月的数据——数据稀疏会显得功能异常)。确认 CRUD 可用。
阶段 3 — 逐个区域调整,使其符合原型。 优先使用原生功能。对于每个标志性区域,选择对应区块并构建;仅在原生区块无法实现某个内核时才添加 JS;切勿将整个页面折叠为一个 JS 区块。一次处理一个区域,确保每个区域都可验证。block-recipes.md 中提供了实现方式和可运行代码片段。
阶段 4 — 视觉收敛循环 ▣ CONFIRM + 报告。 渲染 → 截图 → 使用具备视觉能力的流程与原型进行对比 → 列出具体差异 → 修复 → 再次截图,直到匹配为止。审核者可以是进行自检的同一 Agent,也可以是单独的视觉模型——根据具体情况由模型选择。完整流程见 visual-loop.md。交付报告(受影响的 uid、变更内容、差异/权衡、截图)并确认。
区域 → 原生区块(反单调表)
原生优先阶梯——只在原型要求时才继续往上选。选择符合需求的最低一级。
- 原生区块 + 原生字段。 每个区域都先尝试这种方式。如果使用普通的原生字段的原生 Table / List / GridCard / Details / Kanban / Calendar / Chart,已经基本符合原型(数据正确、形态正确、布局足够接近),就直接交付并继续下一步。 不要给已经足够接近的区域强行添加 JS:原生字段可免费提供绑定 / 排序 / 筛选 / 格式化,也不会出现那些会导致保真度不足的 JS 数据绑定错误。“够用的原生实现”胜过“看似雄心勃勃、实际渲染为空的 JS”。
- 原生区块 + JS 项。 一旦原生字段无法满足需求,这就是推荐的默认做法。如果字段无法还原外观(样式化卡片、状态标签、进度条、KPI 数值、迷你图、环形图 / 仪表盘、丰富的首列),就保留原生容器(它仍负责资源绑定 / CRUD / 筛选 / 分页 / ACL),并在其中使用 JS 项 / JS 字段 / JS 列 / JS 操作渲染自定义外观。选择这种方式,而不是独立区块。不要从头手写主体内容——template-library/ 提供了适用于大多数此类场景的可用主体模板(KPI 卡片、环形图、排行榜、即将到期 / 库存不足提醒、进度条、趋势、切面、卡片网格);填写其
$p,将其粘贴到模型的runJs.code中,然后进行调整。 - 独立 JS 区块。 作为最后手段,仅在该区域完全没有数据容器时使用(发光地图、自助终端扫描器、独立仪表盘)。绝不要把有数据支撑的区域——或整个页面——合并成一个 JS 区块。
下表将每个原型区域对应到相应层级;“JS kernel?” 列指的是在原生容器中渲染的内容,绝不是对原生容器的替代。
| 原型区域看起来像…… | 使用 | 是否需要 JS 内核? |
|---|---|---|
| 表单 — 编写、创建或编辑,带自定义控件或实时预览 | 使用 原生 Form 块,并在其中嵌套 JS 项 / JS 操作(标签、计数器、绑定到表单值的实时预览)。不要使用独立的 JSBlock 表单。 | 是 — 项 / 预览 |
| 电子表格 / 密集的字段行 | Table | 可选:添加一个 JS 列(整条记录单元格)作为富内容首列 |
| 信息流 / 卡片列表、联系人、活动、“当前 X” | List + JS 项(每行渲染整条记录);单列卡片信息流 | 是 — 卡片主体 |
| 左侧筛选栏 + 状态标签 + 网格的目录 | 富内容目录范式:JS 筛选栏(多选 + 计数)+ 状态标签栏 + List + JS 卡片 + CSS 自动填充网格,并进行交叉筛选。block-recipes.md §3b | 是 — 筛选项、标签、卡片 |
| 填满可用宽度的响应式卡片网格 | List + JS 卡片 + CSS 自动填充(repeat(auto-fill, minmax(280px,1fr)))。block-recipes.md §3 | 是 — 卡片主体 |
| 普通的固定断点卡片网格(无筛选项、不自动填充) | GridCard + JS 卡片 — 在 GridCardItemModel 上运行 add-field --renderer js,移除同级 DetailsItemModel 节点,并设置 showLabel:false。block-recipes.md §3 | 是 — 卡片主体 |
| 照片 / 头像图库、人员目录(仅原生字段) | GridCard(原生字段,不使用 JS) | 可选 |
| 带状态列的看板、流水线 | Kanban,设置 groupField=<status>;卡片字段限制为 2 个 → 添加一个 JS 卡片字段 | 是 — 卡片 |
| 按天查看的日历 / 日程 / 房间预订 | Calendar(startField/endField/titleField) | 很少需要 |
| 图表、KPI、分析仪表板 | Chart(用于单表聚合的构建器;仪表盘 / 热力图使用自定义原始 ECharts)。大数字 KPI → 小型 JS 块 | 仅 KPI |
| 树形结构 / 组织架构图 / 嵌套分类 | Tree 块 | 否 |
| 驱动另一个区域的筛选栏 | FilterForm + 跨块筛选 | 有时需要 |
| 数据块上的快速筛选标签 / 自定义控件 | 数据块右上角工具栏中的 JS 项(add-action --use JSItemActionModel) | 是 — 工具栏控件 |
| 点击后打开详情抽屉 / 弹窗 | 通过真正的 ViewActionModel 打开原生弹窗(ctx.openView(<viewActionUid>, {filterByTk})) | 不适用 |
| 没有数据容器的自定义可视化:发光地图、自助服务终端、仪表盘、独立信息流 | JS 块(唯一合理的独立 JS 使用场景) | 是 |
容器 / 内容分离(核心规则)。 对于任何由数据支撑的区域,容器始终是原生块(Form/Table/List/GridCard/Kanban/Calendar)——它会自动提供资源绑定、CRUD、筛选、分页和 ACL。JS 只负责渲染该容器内部的内容:JS 项(表单字段 / 列表卡片)、JS 列(表格单元格)、JS 字段(整条记录卡片)、JS 操作(按钮),或右上角工具栏中的 JS 项(标签 / 自定义控件)。在原生容器内还原原型的准确外观;绝不要丢弃容器。独立的 JS 块仅用于没有数据容器的区域(地图、自助服务终端、仪表盘)。任何非原生或可交互元素都必须是 JS 项 / 块——绝不能省略,也不能用静态原生字段伪造(编写器中的实时手机预览是绑定到 ctx.form.getFieldsValue() + formValuesChange 的 JS 项,而不是静态卡片)。
硬性规则
- 容器原生,内容用 JS。 每个数据区域的容器都必须是原生区块;JS 只能在容器内部渲染。绝不能用独立的 JS 区块替代原生数据容器(独立 JS 区块仅用于无数据的视觉元素)。绝不能让一页只包含一个 JS 区块。
- 筛选运算符由元数据驱动。 在复制、改造或编写任何原生/JS 筛选条件之前,先加载主题为
filter的nocobase-utils技能,然后阅读 Filter Condition Format,解析终端字段当前的前端接口/类型,并从该字段组的允许列表中重新选择运算符。更改模板字段后,原运算符仍适用的假设即失效。日期比较绝不能使用$lt、$lte、$gt或$gte。 - 通过
curl flowModels:save编辑已部署的 JS(完整字段扁平 upsert,可保留parentId)。绝不能使用flowModels:update(会清除 parentId,导致节点消失)。 - 添加/移除任何区块后,都要一致地同步网格的 v2
props.layout+ legacyprops.rows+stepParams.gridSettings.grid,否则客户端会误报“Collection may have been deleted”。 - JS 沙箱:在 JSFieldModel 中使用
ctx.libs.React/antd/antdIcons(而不是ctx.antdIcons);不能使用window/document/localStorage;不能将局部变量命名为location;字体字符串中不能包含空格(SFMono-Regular);使用ctx.getVar('ctx.record')读取完整记录。完整列表见:gotchas.md。 - 每个 select→Tag/颜色映射都必须在遇到未知枚举时回退为原始值(否则渲染时会出现“Tag not found”)。
- 完成 = 已验证:在全新的无缓存浏览器中,通过 Playwright 注入
localStorage NOCOBASE_TOKEN,打开/admin/<pageSchemaUid>,确认每个区块都能渲染、没有控制台/页面错误、交互正常,并且与原型进行视觉检查。
参考索引
完整列表及“先阅读 / 再阅读”的导航见 index.md。复现专用文档:spec-template.md · decomposition-grammar.md · block-recipes.md · visual-loop.md · gotchas.md · prototype-authoring.md · handoff.md。可直接使用的组件主体:template-library/_index.md(57 个 JS 区块/项目/列主体及其 $p 契约)。每条筛选路径的运算符选择均由 Filter Condition Format 规定。