关于 hub-creator
hub-creator 是用于在分支上编写新 Datex Studio Hub 配置的技能。它指导创建和验证带筛选器、标签页、挂载组件、工具栏操作与流程的 Hub,并检查引用契约。
主要功能
- 01创建新的 Hub 配置
- 02设置筛选器、标签页和挂载组件
- 03配置工具栏按钮与流程
- 04检查组件引用契约
- 05验证并推送 Hub 配置
适用场景
- 01构建带网格标签页的筛选 Hub
- 02添加可打开表单的工具栏操作
- 03创建带访问权限控制的 Hub
- 04推送前验证组件绑定
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill hub-creator安装后在 Claude Code 中输入/hub-creator确认已加载。
附带文件evals/evals.jsonreferences/hubs.md
详细介绍
Hub 创建器
在分支上编写一个新的 Datex Studio hub 配置(configurationTypeId=2)——包含筛选器、分组选项、标签页(可挂载网格/编辑器/表单/自定义 Angular 组件)的顶层 UI 容器、工具栏按钮和点击流程。
另请参阅:
hub-editor——在分支上修改现有 hub 的工具栏/流程(此技能用于编写新 hub)。
参考资料
- ../datex-studio-shared/branch-setup.md — 分支/连接选择(多个技能共用)
- references/hubs.md — 权威的 hub 编写参考:文件结构、运行时全局变量、调用约定、常见模式、发布前检查清单
- ../datex-studio-conventions/file-format.md —
configurationTypeId表格和 TypeScript 表达式编码规则 - ../datex-studio-conventions/naming-conventions.md —
_hub后缀、文件名主体匹配规则、显示名称规则 - ../datex-studio-runtime/runtime-globals.md — hub 代码中可用的平台注入全局变量(
$flows、$shell、$utils等) - ../datex-studio-runtime/calling-conventions.md — UI 层调用规则(调用函数,绝不调用 action;通过
$shell打开对话框) - ../component-wiring-check/references/component-wiring.md — 宿主引用约定、vars 必须声明规则、moduleId 规则
依赖项
requirements-gathering技能 — 如果当前对话上下文中还没有需求简述,则调用此技能生成一份grid-creator/selector-creator/form-creator/editor-creator技能 — 如果 hub 引用的标签页网格、筛选器对应的选择器,或对话框表单/编辑器尚未存在于分支上,则调用相应技能component-wiring-check技能 — 推送前审查configParameters↔ 目标inParams约定(避免无效连线)
CLI 生命周期
Hub 编写通过 dxs configuration 完成——这是适用于所有平台配置类型的通用 CRUD 基元。没有 dxs hub 子命令,也不支持字段级补丁;你需要构建(或获取并提取)完整的 JSON 正文,进行编辑,然后将完整内容推回。
创建新的 hub:
# 1. Build body.json from scratch (see references/hubs.md → Minimal Valid Skeleton)
# 2. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
dxs configuration validate hub -b <branchId> -D body.json
# 3. Create
dxs configuration upsert hub -b <branchId> -D body.json
编辑现有 hub(仅当范围从“新建”扩展到“编写过程中修改”时):
# 1. Fetch — note the envelope wrapper
dxs configuration get hub <configId> -b <branchId> -O envelope.json
# 2. EXTRACT THE INNER BODY (round-trip footgun guard — see "Round-trip rule" below)
jq .json envelope.json > body.json
# 3. Edit body.json
# 4. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
dxs configuration validate hub -b <branchId> -D body.json
# 5. Push
dxs configuration upsert hub -b <branchId> -D body.json
如果只是修改工作流(修改现有 hub 的工具栏/流程),请在此处停止并切换到 hub-editor 技能——它包含工具栏/点击流程编辑模式和角色门控方案。
往返规则(重要)
编辑现有配置时,绝不要将 envelope.json 直接通过管道传给 dxs configuration upsert——这会悄无声息地破坏配置内容。上方修正后的步骤(在编辑前使用 jq 提取内部 .json)是任何往返操作的必需步骤。规范的往返流程及其底层错误详见 ../datex-studio-shared/configuration-roundtrip.md。
工作流
[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?]
+-----+-----+
| |
YES NO -> invoke `requirements-gathering`
| |
+-----+------+
|
[Phase 2: Author hub body]
Decide what the hub IS:
- which filters scope the experience
- which tabs (grids / other components) mount inside it
- role-gating, on_init access guard, hub-local flows
Consult references/hubs.md for file shape, $hub runtime,
required top-level fields, common patterns
|
[Phase 3: Wire toolbar / flows]
Toolbar buttons + click flows; dialog openers via $shell
Audit dead-wiring trap (hub filter -> tab configParameters
-> grid inParams MUST stay in sync) — invoke
`component-wiring-check` if mounted grids/selectors
need extension
|
[Phase 4: Validate + push]
dxs configuration validate hub -b <branchId> -D body.json
|
+----+----+
| |
CREATE MODIFY-EXISTING
| |
| use the corrected round-trip
| (get -O envelope -> jq .json -> body)
| |
+----+----+
|
v
dxs configuration upsert hub -b <branchId> -D body.json
(upsert creates or updates by referenceName — one command for both)
|
[Phase 5: Verify in Studio (optional)]
Reload the hub in the running app; confirm filters render,
tabs query, toolbar buttons fire
|
[invoke `post-edit-verification`; then `component-validator`]
阶段详情
阶段 1:设置 + 需求
- 按照 ../datex-studio-shared/branch-setup.md 选择分支和连接。绝不要假定分支 ID——请让用户确认。
- 检查当前对话上下文中是否已有需求简述(由
requirements-gathering或其他调用技能生成)。- 已有简述——使用它。简述会说明 hub 的用途、用户需要的范围筛选条件、其中应挂载的标签页/网格、角色门控规则以及任何工具栏操作。
- 没有简述——先调用
requirements-gathering技能。Hub 是顶层入口;一开始就确定筛选器集合和标签页布局,可以减少返工。
阶段 2:编写中心主体
先确定中心的定位,再构建 body.json:
- 文件基础信息。 遵循下方的 预检清单 和 ../datex-studio-conventions/universal-checklist.md;有关
-hub.json文件结构,请参阅 references/hubs.md → 文件位置与命名。 - 筛选器。 每个筛选字段的
configId/moduleId都必须解析到一个真实的选择器(*-selector.json)。如果分支上还没有该选择器,请先调用selector-creator。每个选择器的configParameter都必须在筛选器的dropdownConfig.configParameters中有对应条目(不适用的参数使用value: "")。 - 选项卡。 每个选项卡都必须声明一个
contentConfig,指向分支上的网格(或其他组件)。如果目标网格尚不存在,请先调用grid-creator。选项卡的configParameters数组必须与目标的inParams完全一致——请参阅阶段 3 的连线缺失检查。 vars数组。 中心流程代码中每个$hub.vars.<id>都必须在顶层vars数组中声明。请参阅 references/hubs.md → 运行时全局变量 和 ../component-wiring-check/references/component-wiring.md。onInitFlowConfig。 常用于设置初始筛选器默认值、加载上下文,以及实现访问控制中心模式(权限检查 → 拒绝时调用$hub.close())。请参阅 references/hubs.md → 常见模式。- TypeScript 表达式编码。
hubTitle、hubDescription以及任何value/tooltip/placeholder/label都必须遵循三种编码规则——显示文本用反引号括起:"`Widget overview`"。请参阅 ../datex-studio-conventions/file-format.md → 声明式字符串值是 TypeScript 表达式。
阶段 3:接入工具栏和流程
-
工具栏按钮和点击流程。 每个工具栏按钮条目都有一个
clickFlowConfig,指向中心本地流程或外部函数。从中心代码调用函数时使用$flows.<Package>.<fn>,打开表单或编辑器时使用$shell.<Package>.open<referenceName>Dialog(...)。切勿直接调用操作——应将其封装在函数中。有关引擎切换、配置选项对话框、访问控制的on_init和共享本地流程模式,请参阅 ../datex-studio-runtime/calling-conventions.md 和 references/hubs.md → 常见模式。 -
检查无效接线陷阱。 中心最常见的错误是:中心筛选器绑定到某个选项卡的
configParameters中,但对应 ID 并未在已挂载网格的inParams中声明。绑定看起来已接通,但网格实际上收不到该值。规则:选项卡
configParameters中的每个绑定都必须在已挂载网格的inParams中声明;网格声明的每个inParam也必须在选项卡的configParameters中有对应条目(未使用的条目使用value: ""或value: null)。如果中心筛选器用于限定某个选项卡网格的范围(例如,
projects筛选器通过project_ids限定规则网格,或contract筛选器通过contract_id限定文档网格),请在同一次编辑中检查已挂载网格的顶层inParams。如果需要某个绑定,而网格未声明匹配的 inParam,请在同一次编辑中扩展网格(以及底层数据源,因为网格流程在构建数据源调用时会读取$grid.inParams.<id>)。推送前调用
component-wiring-check,审核完整的引用契约——包括 moduleId、configParameters 镜像和已声明的变量。请参阅 references/hubs.md → 调用契约 和 ../component-wiring-check/references/component-wiring.md。 -
工具栏和选项卡 ID 在中心内必须唯一。 流程代码通过
id寻址它们($hub.toolbar.save.control...、$hub.tabs.rules.hidden = ...)——ID 冲突会导致内容被静默覆盖。
阶段 4:验证并推送
# Validate the body locally against the branch. Exit 1 = validation found errors
# (read validation_errors, fix body.json, re-run) — not a broken CLI. Do not push on exit 1.
dxs configuration validate hub -b <branchId> -D body.json
# For a new hub
dxs configuration upsert hub -b <branchId> -D body.json
# For modify-existing (round-trip — never skip the jq extract)
dxs configuration get hub <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json
# ... edit body.json ...
dxs configuration upsert hub -b <branchId> -D body.json
验证会在推送前发现必填字段缺失、configParameters 结构格式错误以及选择器/网格引用错误。但它无法发现无效接线陷阱(configParameters 中的 id 不存在于已挂载网格的 inParams 中)——这是两个组件之间的契约问题,需通过 component-wiring-check 和上述阶段 3 规则进行审核。
阶段 5:在 Studio 中验证(可选)
在运行中的应用里重新加载中心:
- 筛选器正常显示,下拉列表已填充(选择器接线正确)。
- 筛选器变化时选项卡会查询(选项卡
configParameters↔ 网格inParams契约成立)。 - 工具栏按钮会触发其点击流程;对话框打开器会返回;
$hub.refresh()会传播状态。 - 未经授权的用户看不到受角色限制的选项卡(访问控制的
on_init流程已运行)。
如果无法使用运行中的应用,请重新获取配置,并与 body.json 进行差异对比(使用修正后的 jq .json 提取模式),以确认推送已生效。
发布前检查清单
推送前,请完整检查 references/hubs.md → 发布前检查清单。快速检查如下:
- 文件基础信息:
configurationTypeId: 2,referenceName以_hub结尾,并完成通用检查(../datex-studio-conventions/universal-checklist.md)。 - Tab 包含完整的
configParameters契约(与已挂载网格的inParams完全一致,不多不少)。 - 筛选器绑定完整符合契约(选择器引用均可解析;每个选择器
configParameter都有对应条目)。 - 已声明 Vars(流程代码中的每个
$hub.vars.<id>都已在顶层vars中声明)。 - 符合调用层级规则(函数通过
$flows.<Package>.<fn>调用;对话框通过$shell.<Package>.open<referenceName>Dialog(...)打开;不得直接调用操作)。 - 工具栏和 Tab ID 在 Hub 内唯一。
- TypeScript 表达式字符串包装正确;动态工具提示通过已声明的
$hub.vars.<name>设置。
常见错误
| 错误 | 修正方法 |
|---|---|
Tab 的 configParameters 绑定了网格未声明为 inParam 的 ID | 这是无效连线,值会被静默丢弃。删除该绑定,或在同一次编辑中扩展网格的 inParams(及底层数据源)。参见阶段 3。 |
直接将 dxs configuration get -O envelope.json 的输出传给 dxs configuration upsert -D envelope.json | 会静默破坏配置内容。编辑前务必先运行 jq .json envelope.json > body.json。参见上文“往返规则”。 |
在流程代码中写入 $hub.vars.<id> = ...,却未在顶层 vars 数组中声明 <id> | 该变量未声明,写入会静默失败或导致运行时错误。请声明每个变量。 |
在 Hub 代码中直接调用操作($flows.<Package>.<action_name>(...)) | UI 层规则:只能调用函数;请将操作封装在函数中。参见 ../datex-studio-runtime/calling-conventions.md。 |
在流程代码中为筛选器或工具栏按钮的 .control.tooltip 赋值 | 动态工具提示不会生效,必须改为绑定到已声明的 $hub.vars.<name>。参见 references/hubs.md → 发布前检查清单第 7 项。 |
description 超过 100 个字符 | SQL 列长度限制,推送时验证会失败。请缩短描述。 |
referenceName 未以 _hub 结尾,或与文件名主体不匹配 | 导入或查找会出错。请使用 snake_case、_hub 后缀,并确保文件名主体匹配。 |
Tab 的 moduleId 设置为 Hub 的 package,而非已挂载网格的 package | 跨组件引用规则:moduleId 始终是目标组件的 package。参见 ../component-wiring-check/references/component-wiring.md。 |
两个工具栏按钮(或两个 Tab)使用相同的 id | 会静默覆盖,流程代码只能访问其中一个。请确保 Hub 内的 ID 唯一。 |
编辑完成后,请调用 post-edit-verification,以发现描述、JSON 或架构违规。最终审查时,请调用 component-validator。