You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: defer @rows registration (no clean cross-port home)
Neither candidate home for @rows on view.textarea works: ui.json's extends
throws in the non-TS ports where view.textarea is deregistered, and core
view.json violates the deliberate FR-033 invariant that core registers zero own
attrs on any view subtype (enforced by view-definition-completeness +
metamodel-docs golden tests). Attaching an attribute to a TS-only view subtype
needs its own cross-port design, out of scope for form controls.
This cycle ships the textarea dispatch with a fixed rows={4} default;
configurable @rows becomes a documented Deferred-work item. Spec Unit A + the
plan's Task 1 are marked deferred; the dispatch task and its render test drop
the @rows read and assert rows={4}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGQ7oSuNcjhsMHWwZzhBwr
Copy file name to clipboardExpand all lines: docs/superpowers/plans/2026-07-18-form-controls-view-dispatch.md
+24-16Lines changed: 24 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,9 +2,9 @@
2
2
3
3
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
4
5
-
**Goal:** Make the generated `<Entity>Form` render the right control for each field's declared view kind (enum→`<select>`, `view.textarea`→`<textarea>`, `view.checkbox`, `view.radio`) instead of a bare `<input>` per scalar, and register the two attributes the codegen already reads — `@rows` and `@formExclude`.
5
+
**Goal:** Make the generated `<Entity>Form` render the right control for each field's declared view kind (enum→`<select>`, `view.textarea`→`<textarea>`, `view.checkbox`, `view.radio`) instead of a bare `<input>` per scalar, and register `@formExclude` (which the codegen already reads).
6
6
7
-
**Architecture:**Three units. Unit A registers`@rows`on `view.textarea` via `spec/metamodel/view.json` (TS-registration-only). Unit B registers `@formExclude` on the `field.*` wildcard via `spec/metamodel/ui.json` (cross-port, data-driven — JSON sync + regen, no non-TS code). Unit C upgrades the `renderFormFile` template with a view-kind dispatch. Cross-port ports are data-driven: they load the spec JSON, so Units A/B are JSON edits + regeneration, not per-port code.
7
+
**Architecture:**Two implemented units (Unit A /`@rows`is deferred — see Task 1). Unit B registers `@formExclude` on the `field.*` wildcard via `spec/metamodel/ui.json` (cross-port, data-driven — JSON sync + regen, no non-TS code). Unit C upgrades the `renderFormFile` template with a view-kind dispatch (textarea uses a fixed `rows={4}`). Cross-port ports are data-driven: they load the spec JSON, so Unit B is JSON edits + regeneration, not per-port code.
8
8
9
9
**Tech Stack:** TypeScript (Bun test runner, ts-poet templates), the `@metaobjectsdev/metadata` loader + registry, the `metaobjects-ui` / `metaobjects-core-types` metamodel providers, `fixtures/registry-conformance` cross-port gate. Design spec: `docs/superpowers/specs/2026-07-18-form-controls-view-dispatch-design.md`.
10
10
@@ -24,8 +24,8 @@
24
24
25
25
## File Structure
26
26
27
-
**Unit A — `@rows` (view.json):**
28
-
- Modify: `spec/metamodel/view.json` — add `rows` int attr to the `view.textarea` entry.
27
+
**Unit A — `@rows` (view.json): DEFERRED — not implemented this cycle (see Task 1).**
28
+
-~~Modify: `spec/metamodel/view.json` — add `rows` int attr to the `view.textarea` entry.~~
- Consumes: `VIEW_TEXTAREA_ATTR_ROWS` (Task 1), `FIELD_ATTR_FORM_EXCLUDE` (Task 2), and the existing `VIEW_SUBTYPE_{TEXTAREA,DROPDOWN,CHECKBOX,RADIO}`, `FIELD_SUBTYPE_ENUM`, `FIELD_ATTR_{VALUES,REQUIRED}` constants — all from `@metaobjectsdev/metadata`.
254
+
- Consumes: `FIELD_ATTR_FORM_EXCLUDE` (Task 2) and the existing `VIEW_SUBTYPE_{TEXTAREA,DROPDOWN,CHECKBOX,RADIO}`, `FIELD_SUBTYPE_ENUM`, `FIELD_ATTR_{VALUES,REQUIRED}` constants — all from `@metaobjectsdev/metadata`. (`@rows`/`VIEW_TEXTAREA_ATTR_ROWS` is deferred — Task 1; textarea uses a fixed `rows={4}`.)
246
255
- Produces: the upgraded generated form output (final task; nothing downstream depends on it).
@@ -596,4 +604,4 @@ Note the issue URL/number in the commit that closes out the cycle (or reply to t
596
604
597
605
**3. Type consistency:**`viewKindFor(field: MetaField): string | null`; `fieldControlFor(field: MetaField): string`; `labelAndError(f: string, control: string)`; `scalarBlock(f: string)` (existing, name-string arg — matched). `field.views()[0]?.attr(...)`, `field.attr(...)` return `unknown`, narrowed with `as` to the expected shapes. Constant names match their definitions in Tasks 1/2. ✓
598
606
599
-
**Dependency note:** Task 3's render test loads a fixture using `view.textarea @rows` and `field.string @formExclude`; under the strict loader those must be registered first, so Tasks 1 and 2 must complete before Task 3. Task 4 is independent.
607
+
**Dependency note:** Task 1 (`@rows`) is DEFERRED. Task 3's render test loads a fixture using `field.string @formExclude`; under the strict loader that must be registered first, so Task 2 must complete before Task 3. Task 4 is independent.
0 commit comments