Skip to content

Commit a8f2afa

Browse files
skills(ui-merge): move the objectui skill bundle into the root skills/ catalog (decision C) (#26097)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} --> _Requested by **Tesla** · [project thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoUZLA31GTDTu7xXLQYnV3cw)_ Fixes #25832 Part of #25677 (decision C aftercare). Clause-②: no Metadata-protocol: none **Tier H** (`skills/**`). This PR stays a draft until an authorized GOVERNED_APPROVERS review. It also carries two maintainer-only ratchet entries, listed under 维护者速读 below. ## 维护者速读(草稿) **改了什么**:objectui 的技能包从 `ui/skills/objectui` 搬进仓根 `skills/objectui`,去掉 `metadata.internal: true`,`@objectstack/skills` 从此带上 `objectui` 这个技能(共 11 个)。切换 PR 里因为撞门禁被回退的 J 系列 19 号补丁在 `main` 上重新落地,读这个包的 ui 测试和脚本跟着改路径。 **为什么改**:你裁的 C 是一个技能目录服务两个产品。切换时用 `internal: true` 把包藏起来,现在从合并后的仓装技能的 agent 拿不到任何 objectui 技能。 **风险与代价(含回滚)**: - **要你点头的第一项(token 棘轮)**:`scripts/check-skills-token-ratchet.mjs` 新增 27 行 `CEILINGS`,每行按落地计数定价、零余量,发布目录多出 50,614 token;不抬任何已有的上限。 - **要你点头的第二项(角色词基线)**:`scripts/role-word-baseline.json` 新增 1 行 `skills/objectui/guides/auth-permissions.md: 13`。「role」保留词 38 处里改写 24 处,1 处放进 better-auth 线格式围栏,剩下 13 处是 `@object-ui/permissions` 真实 API 的 `roles` 键和 D3 改名的历史说明。 - 回滚就是 revert 本 PR,包回到 `ui/skills` 并重新隐藏。 **席位意见**: **你要做的**:批准本 PR,就等于同意上面两项入账(27 行定价、角色词基线 1 行 13 处)。如果不同意其中一项,在评论里说明,我按你的意见改。 ## What changed - **The move (patch 19 of the cutover series, re-applied on `main`).** `git mv ui/skills/objectui skills/objectui` (27 renames). `ui/scripts/skill-bundle-root.mjs` decides where the bundle lives (the ui root in fixtures, else the monorepo root above it), and the ui gates (`check-skills-paths`, `check-skill-examples`, `check-skill-eval-tokens`, `check-doc-json-fences`, `check-shell-escape-residue`), their tests, `markdown-test-inputs`, `doc-version-claims`, `layered-read-declared-path-4016` and four package tests read it through the helper. `@objectstack/spec`'s `check-skill-examples` leaves `skills/objectui` to the ui gate, which judges it against the built `@object-ui/*` types. `scripts/check-skill-identifier-liveness.mjs` indexes `ui/packages`, where the two identifiers the bundle cites are implemented. The one rejected hunk (`doc-version-claims.test.ts` import) was re-applied by hand, because `main` had gained a `root-ci` import there since the patch was cut. - **`skills/objectui/SKILL.md`.** `metadata.internal: true` is removed. `compatibility:` now reads `Requires @objectstack/spec 18.x; …`, and `metadata.version` is stamped by `check-skill-compatibility-version.mjs --fix` (`2.0` → `18.1.0`). - **Reserved word (ADR-0090 D3).** Expression examples gate on `data.status`, `user.email` or a position instead of a `role` field. The testing guide's evaluator example reads `user.position`. Prose says "positions", "grant key" or "permission checks". The `@object-ui/permissions` example renames its local array to `definitions` (the `roles` prop and keys are the package's real API and stay). `UserMenu`'s comment no longer claims it shows a role, because the component renders none. The better-auth display fields move into a fenced block marked `os:vendor-wire better-auth`. `ui/packages/permissions/src/__tests__/skill-guide-permission-config.test.tsx` pins the guide example verbatim, so it carries the same edits. - **`visibleOn`.** `guides/schema-expressions.md`'s "Combined conditions" example uses `visibleWhen`, the canonical key in `@object-ui/types` `BaseSchema` (`visibleOn` there is `@deprecated ADR-0089 — use visibleWhen`). - **`plugin-development.md`.** The color input passes `value ?? ''` instead of a hard-coded black hex fallback. `check:pm-skill-id-lint` read the all-decimal hex as an issue id. This keeps the epic PM's ruling on patch 19, option (a). - **Token ratchet.** 27 `CEILINGS` rows, each pinned at its landed count with zero headroom, under a comment block that cites decision C. No existing row moves. - **Role-word baseline.** One row was added: `"skills/objectui/guides/auth-permissions.md": 13`. The `--update` diff touches no other row. - **Readers.** `skills/README.md` points to `./objectui/SKILL.md` instead of the objectui repository. `ui/skills-lock.json` points to `../skills/objectui`. - **Changeset.** `@objectstack/skills` patch (`.changeset/25832-objectui-skill-in-catalog.md`). ## The five gates on the card, before → after "Move" is the raw move commit `0c57048f` (patch 19 plus the flag removal, nothing else). "Head" is this PR's head. | Gate | `main` `bbf70614` | Move `0c57048f` | Head | |---|---|---|---| | `node scripts/check-skills-token-ratchet.mjs` | 0 (bundle not in `skills/`) | **1**: 27 of 91 files unpriced | **0**: 81 authored files within ceilings, 10 generator-owned | | `… --self-test` | 0 | **1**: 2 failures (unpriced files; SKILL.md ceilings 10 vs 11) | **0**: 79 cases | | `pnpm check:role-word` | 0 | **1**: 7 files, 38 new uses | **0** | | `@objectstack/spec` repo test `src/ui/visibility-alias-keys-retirement.test.ts` | — | **1 failed / 11 passed** (`skills/objectui/guides/schema-expressions.md authors "visibleOn"`) | **12 / 12** | | `node scripts/check-ci-filter-parity.mjs` (+ `--self-test`) | 0 / 0 (120 assertions) | 0 / 0 | 0 / 0: no count to update, because `skills/**` is a `@objectstack/skills#build` input covered by `core` on `main` | | `pnpm --filter create-objectstack test` (template-consistency "skills catalog boundary") | 0 (bundle hidden by `internal: true`) | — | **0**: 18 files / 269 tests, flag removed | The visibility row's "before" was measured on head with only `schema-expressions.md` restored from `0c57048f`. The restore leg was checked with `git diff HEAD` (empty) and blob `9b97e3c4a6`. Role-word split: 38 → 24 rewritten, 1 fenced (`os:vendor-wire better-auth`), 13 baselined. The 13 are `auth-permissions.md`'s `@object-ui/permissions` API (`ObjectPermissionConfig.roles`, the `roles` prop and keys, about 9 uses) and the paragraph recording the D3 `roles` → `positions` retirement (4 uses). ## `skills/**` readings (lines are the measure; token counts from the ratchet's convention) - **Whole bundle:** 5428 → 5434 lines (+6). `auth-permissions.md` 409 → 416 (the vendor-wire fence). `SKILL.md` 143 → 142 (the `internal` line). The other 25 files are unchanged in length. Raw bytes/4 50582 → 50619. - **Changed files:** `SKILL.md`, `guides/architecture.md`, `guides/auth-permissions.md`, `guides/page-builder.md`, `guides/plugin-development.md`, `guides/schema-expressions.md`, `guides/testing.md` and `rules/protocol.md`. All except the two above keep their line count. `skills/README.md` stays at 133 → 133. - **Catalog SKILL.md sum:** 4383 → 4525 lines (+142, the objectui `SKILL.md`). - **Priced catalog:** ratcheted subtotal +50,614 tokens (the 27 new rows). Bundle total 206,118 tokens. The `@objectstack/skills` build copies 92 files across 11 skills. ## Verification (head 12e779c) - `skills` CLI: `npx skills@1.7.2 add ./skills --list` → "Found 11 skills", `objectui` listed. `pnpm --filter @objectstack/skills build` → 92 files across 11 skills, read back byte-identical. - Skills family: `check:skill-compatibility`, `check:skill-identifier-liveness`, `check:skill-frame-sync`, `check:skill-top-level-keys`, `check:pm-skill-id-lint` 0. `@objectstack/spec` `check:skill-refs`, `check:skill-docs`, `check:skill-examples` 0 (after `@objectstack/spec` and the `client-react` / `client` closures were built). - ui gates (`ui/scripts`): `check-skills-paths`, `check-skill-examples` (after the scoped build its `--build-filter` names), `check-skill-eval-tokens`, `check-doc-json-fences`, `check-shell-escape-residue` all 0. - ui tests: `ui/scripts/__tests__/` 180 files passed, 2 skipped / 5273 tests passed. The 14 package test files that read the bundle: 159/159. **Derived gates (head `12e779cd`):** `node scripts/pm/dispatch-gates.mjs --commands` derives 107 families (100 commands at `67d25683` plus 7 changeset-family commands after the changeset commit). 106 exit 0. `--ran` reconciliation: 107 of 107 accounted, 0 unrun. `check-plugin-teardown-shape --self-test` first exited 3 because its pinned commit `621a4876` was missing from the shallow clone. After `git fetch origin 621a487… --depth=1` it exits 0 (48 cases). **NOT MEASURED:** `pnpm check:dual-build-cjs-loads`, exit 3 (prerequisite: every published package needs a `dist/`, so it needs a full workspace build). The diff changes no package's build output except `@objectstack/skills`' copied catalog, so it is left to CI's Lint & Repo Gates. **Push-environment battery (head `12e779cd`):** `GITHUB_ACTIONS=true GITHUB_EVENT_NAME=push node scripts/pm/check-dispatch-gates.mjs`: 2182 cases pass (1901 fast + 265 slow = 2166 partitioned, plus the census), 0 failed, exit 0. ## Acceptance notes - **The generated catalog index omits `objectui`.** `packages/spec/scripts/build-skill-docs.ts` admits only `objectstack-*` directories, so the `skills/README.md` index table and the skills-reference page list 10 skills. The CLI, the package and the README's hand-written routing line all see 11. Admitting a non-`objectstack-` skill there is a generator change, outside this card. Carrier: the epic PM. - **A `skills/objectui/**`-only PR does not trigger the ui lanes.** The ci.yml `filter` job's `ui` glob is `ui/**`, so the ui skill gates ported into Lint UI no longer see the bundle's own edits. This is bill item 35. Its owner is the 4b ci.yml work (#25712, Tier H). This PR does not touch `.github/workflows/**`. - **The `ui/skills/**` register row is now empty.** `GOVERNED_SURFACES`, the CODEOWNERS `/ui/skills/` line and AGENTS.md Prime Directive #14 still name `ui/skills/**`. The root `skills/**` row governs the bundle now. Dropping the row is an AGENTS.md / pm-dispatch SKILL.md edit at zero line headroom, so it is left to the 4b governance rewrite. - **`@object-ui/permissions` still spells its grant keys `roles`.** That is objectui's own API, older than ADR-0090 D3. Renaming it is a code change, not a guide change, and the 13 baselined uses go away with it. --- _Generated by [Claude Code](https://claude.ai/code/session_01XB8hLKWX18hti3qKrQAJfm)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1bbb7bf commit a8f2afa

51 files changed

Lines changed: 320 additions & 116 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@objectstack/skills': patch
3+
---
4+
5+
docs(skills): the `objectui` skill joins the published catalog, so `@objectstack/skills` ships the `@object-ui/*` authoring skill beside the `objectstack-*` ones
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
- **What ships.** `skills/objectui/` (its `SKILL.md`, 11 guides, 3 rules, 11 evals and a README) moves in from the objectui repository's own `skills/` tree. A project that syncs `@objectstack/skills` now gets an `objectui` skill in its agent directory, and `npx skills add objectstack-ai/objectstack/skills` lists it on the `next` channel.
11+
- **Stamped like the others.** Its `compatibility:` line now reads `Requires @objectstack/spec 18.x`, and `metadata.version` carries the workspace version, as on every catalog skill.
12+
- **Content changes on the way in.** The guides use the platform's vocabulary: expression examples gate on `data.status` or a user position, not on a `role` field, and the expressions guide gates a combined condition with `visibleWhen` instead of the deprecated `visibleOn`. The `@object-ui/permissions` example keeps its real `roles` keys, and the plugin guide's color input passes `value ?? ''` instead of a hard-coded black fallback.

‎packages/spec/scripts/check-skill-examples.ts‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,18 @@ const DOCS_DIR = path.resolve(REPO_ROOT, 'content/docs');
415415
const SDK_DOCS_PAGES = ['api/client-sdk.mdx', 'kernel/runtime-services/data-service.mdx'];
416416

417417
const SKILLS_DOCS_ROOTS: SourceRoot[] = [
418-
{ dir: path.resolve(REPO_ROOT, 'skills'), ext: '.md', label: 'skills', marker: '<!-- os:check -->' },
418+
{
419+
dir: path.resolve(REPO_ROOT, 'skills'),
420+
ext: '.md',
421+
label: 'skills',
422+
marker: '<!-- os:check -->',
423+
// The objectui bundle joined this catalog at the cutover (objectstack#25803)
424+
// with its own reading of the same marker: it marks `json` fences as well as
425+
// `ts`/`tsx`, and compiles them against `@object-ui/*`. Its gate is
426+
// `ui/scripts/check-skill-examples.mjs`, which still judges every marked fence
427+
// in it; read here, its 70 `json` markers are orphans by this gate's rule.
428+
exclude: [path.resolve(REPO_ROOT, 'skills/objectui')],
429+
},
419430
{
420431
dir: DOCS_DIR,
421432
ext: '.mdx',

‎scripts/check-skill-identifier-liveness.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ const HERE = dirname(fileURLToPath(import.meta.url));
257257
const REPO_ROOT = join(HERE, '..');
258258

259259
const ROOTS = ['skills'];
260-
const IMPL_ROOTS = ['packages'];
260+
const IMPL_ROOTS = ['packages', 'ui/packages'];
261261
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.turbo']);
262262
const EXTENSIONS = new Set(['.md']);
263263
const IMPL_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json']);

‎scripts/check-skills-token-ratchet.mjs‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,47 @@ export const CEILINGS = new Map([
680680
['skills/objectstack-platform/references/operations.md', 3125],
681681
['skills/objectstack-platform/references/plugin-development.md', 3137],
682682
['skills/objectstack-upgrade/references/examples-upgrade.md', 1197],
683+
684+
// ── 2026-10-26 the objectui bundle joins the catalog — decision C, #25832 ──
685+
// The maintainer ruled (decision C, 2026-10-25, recorded as item 17d of the
686+
// cutover card #25752) that objectui's published skill bundle moves from
687+
// `ui/skills/objectui` into this catalog, so one `@objectstack/skills` package
688+
// serves both products. The 27 files arrived from the objectui repository,
689+
// where they shipped unpriced by this gate. Each row is an INITIAL
690+
// measurement of the moved file on the PR that moves it, after that PR's own
691+
// edits (the reserved-word rewrite, the `visibleWhen` key, the stamped
692+
// `metadata.version`, whose line is not priced), pinned AT it — zero
693+
// headroom, on the same terms as the #12392 extension and the evals rows.
694+
// No existing row moves. Adding the rows is the pricing act the header
695+
// reserves to the maintainer; the PR that adds them is Tier H and lands only
696+
// on the maintainer's approval, which is that word.
697+
['skills/objectui/README.md', 735],
698+
['skills/objectui/SKILL.md', 1852],
699+
['skills/objectui/evals/app-composition.json', 810],
700+
['skills/objectui/evals/auth-permissions.json', 366],
701+
['skills/objectui/evals/data-integration.json', 471],
702+
['skills/objectui/evals/i18n.json', 439],
703+
['skills/objectui/evals/mobile.json', 452],
704+
['skills/objectui/evals/page-builder.json', 560],
705+
['skills/objectui/evals/plugin-development.json', 492],
706+
['skills/objectui/evals/project-setup.json', 786],
707+
['skills/objectui/evals/protocol.json', 761],
708+
['skills/objectui/evals/schema-expressions.json', 536],
709+
['skills/objectui/evals/testing.json', 466],
710+
['skills/objectui/guides/app-composition.md', 1079],
711+
['skills/objectui/guides/architecture.md', 1045],
712+
['skills/objectui/guides/auth-permissions.md', 3866],
713+
['skills/objectui/guides/data-integration.md', 4451],
714+
['skills/objectui/guides/i18n.md', 1413],
715+
['skills/objectui/guides/mobile.md', 1349],
716+
['skills/objectui/guides/page-builder.md', 3411],
717+
['skills/objectui/guides/plugin-development.md', 4184],
718+
['skills/objectui/guides/project-setup.md', 2727],
719+
['skills/objectui/guides/schema-expressions.md', 6571],
720+
['skills/objectui/guides/testing.md', 3101],
721+
['skills/objectui/rules/composition.md', 1624],
722+
['skills/objectui/rules/protocol.md', 4368],
723+
['skills/objectui/rules/styling.md', 2699],
683724
]);
684725

685726
/**

‎scripts/role-word-baseline.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@
4242
"skills/objectstack-query/rules/filters.md": 2,
4343
"skills/objectstack-ui/rules/list-views.md": 1,
4444
"skills/objectstack-ui/rules/navigation.md": 1,
45-
"skills/objectstack-upgrade/references/examples-upgrade.md": 1
45+
"skills/objectstack-upgrade/references/examples-upgrade.md": 1,
46+
"skills/objectui/guides/auth-permissions.md": 13
4647
}

‎skills/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ A few common decision points where the right skill isn't obvious:
123123
**objectstack-data**.
124124
- **Labels vs. bundles** — a `label` you want translated is **objectstack-i18n**.
125125
- **Upgrade vs. platform** — a protocol-major move is **objectstack-upgrade**.
126-
- **Rendering this metadata** — the consuming UI is
127-
[objectui `skills/objectui/`](https://github.com/objectstack-ai/objectui).
126+
- **Rendering this metadata** — the consuming UI is the `@object-ui/*`
127+
packages, and their own skill is [`objectui`](./objectui/SKILL.md) in this catalog.
128128

129129
---
130130

File renamed without changes.
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
name: objectui
33
description: Universal Server-Driven UI (SDUI) engine for building JSON-driven React interfaces with Shadcn design quality. Use for schema-driven page building, plugin development, expression bindings, data integration, testing, auth/permissions, i18n, mobile responsiveness and project setup with the `@object-ui/*` packages. Triggers on ObjectUI, SchemaRenderer, JSON UI schemas, SDUI, metadata-driven UIs, `@object-ui/*`. Do NOT use for server-side ObjectStack concerns (data modelling, API endpoints, automation, formulas, agents) — those belong to the `objectstack-*` skills.
44
license: Apache-2.0
5-
compatibility: Tracks the @objectstack/spec range each @object-ui/* package declares in its own manifest; read it there. This file states no version literal, per the doc-version-claims ratchet.
5+
compatibility: Requires @objectstack/spec 18.x; each @object-ui/* package declares its exact @objectstack/spec range in its own manifest.
66
metadata:
7-
internal: true
87
author: objectstack-ai
9-
version: "2.0"
8+
version: "18.1.0"
109
domain: ui
1110
tags: sdui, schema-renderer, json-ui, react, shadcn, tailwind, plugin, expression
1211
user-invocable: false
@@ -31,7 +30,7 @@ kanbans, CRUDs, forms, grids.
3130
| Start a new project — CLI, Vite, Tailwind, config files | [`guides/project-setup.md`](./guides/project-setup.md) |
3231
| Write unit / DOM / E2E tests for components, schemas and plugins | [`guides/testing.md`](./guides/testing.md) |
3332
| Responsive behaviour, breakpoints, touch gestures | [`guides/mobile.md`](./guides/mobile.md) |
34-
| Auth, roles, tenants, client-side permission guards | [`guides/auth-permissions.md`](./guides/auth-permissions.md) |
33+
| Auth, positions, tenants, client-side permission guards | [`guides/auth-permissions.md`](./guides/auth-permissions.md) |
3534
| Multi-language text and formatters | [`guides/i18n.md`](./guides/i18n.md) |
3635

3736
**Rules — read before writing schemas.** These are the non-negotiables, and they
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)