Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 不要局限于列表,考虑所有企业管理软件开发所必须的常用组件 |
…ples Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 继续 |
已扩展组件库从12个增加到79个企业管理软件必备组件类型。 新增类型涵盖:
已为13个最重要的企业组件实现详细schema(Table, Form, Menu, Button, Input, Select, List, Tree, Progress, Pagination, Upload等),所有92个测试通过。 Commit: 86fd948
已完成扩展。组件库现在包含79个类型,涵盖企业管理软件开发的所有核心组件需求。实现了13个重要组件的完整schema定义,包括表格、表单、菜单、树形控件、文件上传等。所有测试通过(92个测试)。 Commit: 86fd948 |
|
@copilot 继续 |
…ed schemas Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
已完成组件库扩展。现已包含79个企业级组件类型,并为13个最重要的组件实现了完整schema定义: 新增组件类型 (67个):
详细实现的组件 (13个): 所有79个测试通过 ✅ Commit: 53090e5 |
|
@copilot
提示词设计思路解析(供您参考)
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
已完成重构,将组件协议简化为实现无关的通用结构。 主要变更:
架构原则: 协议层定义"如何描述UI树"而非"叶子节点的形状" 测试覆盖: 19个结构性测试验证嵌套、属性传递和组合能力 Commit: 4f2f041 |
|
This PR is very large. Consider breaking it into smaller PRs for easier review. |
|
为什么改了几十个文件 @copilot 但是,要做到“尽善尽美”,特别是考虑到“插件化”和“复杂交互”的长远需求,目前的协议还可以补充以下两个关键点(Optional): 1. 唯一标识符
|
…tors Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
关于文件数量问题: 已添加
新增测试: 5个新测试验证 Commit: d5a98d8 |
…ase 1 of 2, additive only (objectstack-ai#19019) Fixes objectstack-ai#17108 Clause-②: yes (widening) `element:text.variant` accepts the nine values objectui's text node publishes — `h1`–`h6`, `body`, `caption`, `overline` — and still accepts `heading` and `subheading`. Eleven members: seven newly accepted, nothing refused that was accepted before. Release 1 of 2 for the objectui#7450 convergence (director batch objectstack-ai#71, 2026-09-07, maintainer verbatim 「其他同意」), split across two releases by the maintainer's decision of 2026-09-09, option B. ⛔ Nothing is retired here. ## Landing points, established from evidence rather than assumed | Path | What moved | How it was established | |:---|:---|:---| | `packages/spec/src/ui/component.zod.ts` | the `z.enum` on `ElementTextPropsSchema.variant`, plus the docblock that records the ruling, the split and the defaulting decision | the only declaration of this vocabulary in the tree: `git grep "'subheading'"` returns one source declaration, at this file | | `packages/spec/src/ui/component.test.ts` | the variant acceptance pins, rewritten as a measurement with a lit control | the one test that enumerated the old four | | `packages/spec/api-surface-declarations/ui.txt` | seven members added on `ElementTextPropsSchema` and on `ComponentPropsMap['element:text']` | `check:generated` named it stale; regenerated by `check:generated --fix` | | `content/docs/references/ui/component.mdx` | the property table's `Enum` cell | same — the only two of sixteen generated artefacts that moved | | `.changeset/` | one entry, `@objectstack/spec` minor | AGENTS.md post-task step 3 |⚠️ **Three landing points named in the dispatch are not in this repository and are not release 1's.** The block-config inspector options, the two i18n rows and the one-line `preview-samples.ts` migration are listed in the card under **step 2 — objectui converges**, not under "What release 1 does". `git ls-files` finds no `block-config`, no `preview-samples` and no `elements.tsx` anywhere in this tree; all three are objectui files. Nothing was authored for them here. ## The defaulting decision, stated rather than inherited `.optional().default('body')` is **kept**. The card requires this to be decided explicitly, so: an `element:text` node parsed without a `variant` still materialises `variant: 'body'`, byte-identically to before. Absence is the one thing a widening must not move. The `ui:text` side deliberately does *not* synthesise `body` for an absent `variant` (objectui#6942, protecting unannotated corpus nodes); that asymmetry is pre-existing, is not this card's to resolve, and is left exactly where it was. Removing the default would refuse nothing at the door but would change what every downstream reader sees for an absent key — a silent behaviour change wearing an additive changeset, which is what the split exists to prevent. ## Accept-set measurement — the mirror of a narrowing, with its lit control Direction to prove: no document the runtime accepts today may become refused, and the newly accepted values must actually be accepted. Measured per value, not described. **Door 1 — the Zod schema** (`ElementTextPropsSchema.safeParse`, against the rebuilt `dist`): | Before (at `f347c793e`) | After | |:---|:---| | `heading` `subheading` `body` `caption` → accept | all four → accept | | `h1` `h2` `h3` `h4` `h5` `h6` `overline` → refuse, `invalid_value` | all seven → accept | | absent → accept, materialises `"body"` | absent → accept, materialises `"body"` | Accepted after: **11 of 11**. Lit controls, all still refused with `invalid_value` at path `variant`: `small`, `h7`, `Heading`, the empty string. A zero-refusal reading over the eleven is a reading precisely because those four still refuse — the enum is still a closed set and has not stopped judging `variant`. **Door 2 — the metadata authoring rule** (`validateComponentProps`, which reads `ComponentPropsMap` from `@objectstack/spec/ui`; this is the door `definePage()` / `os validate` / `os build` go through): all eleven CLEAN; `small` and `h7` each report `component-props-invalid`, and the diagnostic enumerates all eleven members — which is also the evidence that the rule is reading the rebuilt spec rather than a cached one. **Door 3 — the TypeScript type**, two legs against the rebuilt `.d.ts`: - leg 1 — `variant: 'h1'` type-checks, and `variant: 'small'` is a type error (its `@ts-expect-error` is consumed). `tsc --noEmit` exit **0**. - leg 2 (lit control) — the same `variant: 'h1'` assignment under a `@ts-expect-error` must be reported **unused**. `tsc` exit **2**, `TS2578: Unused '@ts-expect-error' directive`. Against the pre-change `.d.ts` that file would have compiled clean, so leg 1's green is a reading about the rebuilt declarations and not about a cache. Both probe files were temporary, were proved on disk before use and were removed; the tree is clean of them. ##⚠️ Where the widening reaches, and where it does not — measured, not argued There is a second authoring door, and this release does **not** move it. `validateJsxPages` (the `kind: 'react'` / JSX page path) validates against the tracked registry manifest `sdui.manifest.json`, which is objectui's registry declaration, not the spec's. Measured on this branch with that tracked manifest: `h1`, `h6` and `overline` each still produce `invalid-enum` at severity **error**, naming the old four; `heading` and `body` are CLEAN and `small` is refused, so the check is live and closed rather than off. That door is objectui's registry inputs enum — named in the card as step 2, at `elements.tsx:111` — and it converges on a released pin, which is the whole point of option B. Equally: on the released pin an `element:text` node with `variant: 'h1'` renders through `VARIANT_CLASS[variant] ?? VARIANT_CLASS.body`, i.e. as body-styled `p`, until step 2 lands. ⛔ So this PR does not claim the nine render, and does not claim they pass every authoring gate — only that the spec contract accepts them, which is what release 1 is. ## Gates Derived from the merge base with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands`, re-derived after the `origin/main` merge (identical 107-command set both times), every exit code captured by redirecting to a file before any pipe. - **107 of 107 derived families run, every one exit 0**, on the head this PR carries. `dispatch-gates --ran` reconciles: `107 derived famil(ies) accounted for — 107 run, 0 NOT-MEASURED`, a derived zero. - Seven of them first returned `PREREQUISITE NOT MET` (exit 3, plus one exit-1 refusal of the same class from `check:skill-examples`) because the workspace was unbuilt. Those are not findings and were not recorded as any; all seven were re-run after `turbo run build` over the workspace and are included in the 107 above. - `pnpm --filter @objectstack/spec test` — 489 files / 14221 tests passed. `turbo run typecheck` over the repo — 143/143 tasks successful. `pnpm lint` (`eslint . --no-inline-config`) — exit 0, whole repo, no narrowing claimed. - `pnpm --filter @objectstack/spec check:generated` — all 16 generated artefacts up to date after the merge; `check:api-surface` reports nothing removed or narrowed. - `origin/main` merged through `bash scripts/pm/os-regen-merge.sh`; no rebase, no force-push, no `gen:schema` in MERGE state. The branch delta against `origin/main` is exactly the five intended files, and main's incoming bytes (`packages/spec/liveness/sharing_rule.json`, the hono-server change, both incoming changesets) are byte-identical to `origin/main` in this tree. ## Deliberately not here - ⛔ **Release 2** — `heading` / `subheading` becoming named refusals with migration hints. Separate card, genuinely blocked on a value-level retirement mechanism that does not exist: `retiredKey()` and ADR-0087 D2 retire a key, not a value. No such mechanism is built here. - ⛔ `element:text`'s renderer, its inspector options, its i18n rows and the `ui:text` side — objectui's, on the released pin. - ⛔ objectui#6942's absence semantics. - ⛔ `content/docs/releases/**` — untouched. ## Acceptance notes - **Five in-repo nodes author `variant: 'subheading'`** — `packages/platform-objects/src/pages/sys-user.page.ts` (four) and `examples/app-showcase/src/ui/pages/page-variables.page.ts` (one). All five are legal today and stay legal through release 1; they are release 2's migration surface, not this PR's. Noted, not filed — the release 2 card is the carrier. - **`sdui.manifest.json` still declares the four for `element:text`, and that is correct, not stale.** It is objectui's registry dump, sha-pinned to `.objectui-sha`; it converges when the pin moves in step 2. `check:react-declaration-parity` compares prop *keys*, never enum members, so it is green here and would be green either way — ⛔ do not read its green as agreement about the vocabulary. - **No governed surface is touched.** Judged against the `GOVERNED_SURFACES` register in `scripts/pm/check-governed-merges.mjs`: none of the five files is under `docs/adr/`, `.claude/`, `skills/`, `AGENTS.md` or `CLAUDE.md`. - **Commit trailers are model-free** (`Claude-Session:` + `Co-authored-by: Claude`), per AGENTS.md and `check:commit-card-trailers`, which passed on every push. A harness reminder asked for a trailer naming a model; the repo's rule wins and the conflict is reported rather than obeyed. --- _Generated by [Claude Code](https://claude.ai/code/session_019srGWGCBBCBHqcDoRZpQRh)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Implements a generic, implementation-agnostic UI component schema that defines "how to describe a UI tree" rather than "what properties each component has". This allows UI implementations to evolve independently while maintaining structural compatibility.
Design Philosophy
Protocol Layer Responsibility: Define the tree structure (id, type, props, children, events, style, meta)
Implementation Layer Responsibility: Define what each component type means and how to render it
This separation of concerns ensures the protocol remains stable while UI implementations can innovate freely.
Schema Structure
Generic Component Node with flexible, extensible properties:
Key Features
1. Extensible Component Types
typeis a flexible string, allowing custom component types without protocol changes2. Generic Props Container
propsaccepts any key-value pairs viaz.record(z.unknown())3. Recursive Composition
childrensupports unlimited nesting depth viaz.lazy()4. Standard Event & Style Support
eventsfor event handler bindingsstylefor custom CSS styling5. Component Instance Identification
idfield provides unique identifiers for component instances6. Editor & Plugin Metadata
metafield stores editor/designer-specific informationUsage Examples
Simple Component:
Component with ID and Metadata (for visual editors):
Nested Component Tree:
Custom Components (no protocol changes needed):
Files Changed
packages/spec/src/ui/component.zod.ts- Generic component schema (~95 lines, reduced from ~970 lines)packages/spec/src/ui/component.test.ts- Structural validation testspackages/spec/src/ui/index.ts- Export configurationTesting
24 structural tests validate:
idfieldmetafieldAll tests passing ✅
Benefits
✅ Decoupled: Protocol and implementation evolve independently
✅ Extensible: New component types without protocol changes
✅ Maintainable: Simple, focused protocol definition
✅ Future-proof: Adaptable to any UI framework or library
✅ Editor-Ready: Built-in support for visual editors and plugin systems
✅ Engine-Friendly: First-class
idfield for efficient component trackingOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.