Repository navigation
console rendering, from the HotCRM pass: column label precedence, star rating widget, reference rail (nameField, refresh), gantt year, approval drawer approver and headline, public form heading and editor hints #12110
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchand removed
on Oct 10, 2026 objectstack-fleet commented
on Oct 11, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 (all seven items, one PR, a pin per item, as the card asks)
Session:session_01TYgwmFK1q4KJ6Qq2WRLzsD
Account:zhuangjianguo
Branch:claude/issue-12110-hotcrm-rendering
Worktree:objectui-issue-12110
Domain:domain:ui
Seat:domain:ui#2
File surface:- item 1:
packages/plugin-grid/src/ObjectGrid.tsx(the column label precedence); - item 2:
packages/components/src/renderers/form/form.tsx(the unregistered-widgetfallback) andpackages/fields/src/index.tsx(aratingcell); - items 3 and 4:
packages/plugin-detail/src/renderers/record-reference-rail.tsx(pickDisplayName, the fetch, and the invalidation subscription).RecordDetailView.tsxis read only, unless the bus measurably needs a post from there; - item 5:
packages/plugin-gantt/src/GanttView.tsx(the date formats); - item 6:
apps/console/src/pages/system/ApprovalsInboxPage.tsx(formatIdentityanddecisionAmountEntryonly); - item 7:
apps/console/src/components/FormPage.tsx(loadPublicForm's heading) andpackages/fields/src/widgets/RichTextField.tsx(the editor hints on the public surface); - their tests, the docs pages the changes describe, and
.changeset/12110-*.md.
(stop on breach; explain in the report)
Container & model:M(seven small items, one PR),mode:subagent,model: default tier — dispatch-gates --tier --repo objectstack-ai/objectui: "no path-derived mandate"
Clause-②: no
Responsibility:objectui renderers: grid column label, form widget fallback, reference rail, gantt date format, approval drawer, public form heading and editor hints, each rendering a wrong or incomplete face of metadata it already receives | none needed: each item is a renderer reading what the spec already declares (column label, the type renderer fallback, nameField, the data-invalidation bus, the object label) | every HotCRM-style app; measured in the maintainer's HotCRM browser pass (objectstack-ai/hotcrm#2058, 17.7.0)
Thread-read: none
Serial constraints cleared: none blocking. Read at 2026-10-11T10:54Z:ObjectGrid.tsx,form.tsxandfields/src/index.tsxmoved today with landed PRs objectui#12132, fix(components): a boolean with a CEL default is left to the server on create (objectui#12121) #12133 and fix(plugin-grid,fields,app-shell): a promoted bulk action's field-backed param resolves through the shared action-param resolver (objectui#12105) #12119. The dev starts from that merged code.- This seat's in-flight objectui#12082 round 2 may edit
RecordDetailView.tsx's feed handlers. This card only reads that file, and if item 4 has to edit it, the later lander mergesmain. - This seat's in-flight objectui#12106 edits
plugin-detail'srecordActivityFeed.ts, which is not on this surface. - No open PR touches any file above.
Clause-②: nois a prediction. If an item adds a locale key to@object-ui/i18n's packs or a new export, the published surface widens; the report says so, and the seat corrects the line and runs the review atCONTRACT_REVIEW_TIER.
Generated by Claude Code
- item 1:
objectstack-fleet commented
on Oct 11, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 12110, "status": "needs_decision", "branch": "claude/issue-12110-hotcrm-rendering", "pr": "https://github.com/objectstack-ai/objectui/pull/12151", "session": "session_01TYgwmFK1q4KJ6Qq2WRLzsD — the seat's id (mode:subagent: the parent's)", "premise_still_valid": true, "summary": "Draft PR #12151 (head fd4059c, merged with main 158c75d) lands items 1 to 6 and the heading half of item 7, one commit and one pin per item, each pin red on BASE c9fc10b1ec first. Item 1: an authored column label is the header as written. Item 2: a widget hint is taken only when it can render (registered field widget, built-in control, native email/password input or secret refusal), else the type renderer, per the spec text of FieldSchema.widget (checked in installed spec 17.7.0 and on objectstack main b7cd1af9df; star_rating is not a spec-declared widget, so fallback, not registration); rating cells draw stars (module-private renderer, no new export). Items 3 and 4: the reference rail names rows by the target nameField and refetches in place on the invalidation bus (parent record, entry objects, star); RecordDetailView not touched. Item 5: six gantt faces add the year when not the current one. Item 6: position approvers read the registry label via useMetadata().ensureType('position') (the store #12089 / #7611 already uses), and the headline prefers a declared currency field and never headlines a name-matched zero. Item 7 heading: object label before API name. STOPPED: item 7 second half (editor hints on the public surface) needs a contract decision; the PR first line is Part of #12110 and names it. Clause-2 stays no (no locale key, no new export).", "tests": "Post-merge at fd4059c: turbo type-check of plugin-grid, components, fields, plugin-form, plugin-detail, plugin-gantt green (41 of 42 tasks; console cut by the cap behind the dep rebuild), then console alone 36/36 green; pins + main neighbours (pagerButtonNames-12124, affordanceGrantMap-12082) + column-identity ratchet: 9 files, 82 tests passed; packages/plugin-detail/ 4 shards: 255 passed, 1 skipped file; packages/components/ 6 shards: 375 passed, 1 skipped file; scripts/__tests__/ 3 shards: 180 passed, 2 skipped files. Pre-merge at 50c7747: plugin-grid 202 passed; plugin-gantt 99 passed, 1 skipped file; fields 245 passed, 1 skipped file; plugin-form 175 passed; apps/console 181 passed. Red on base (one run, base source): item 1 headers [#, Account Name, Industry] and [#, 客户名称, 行业]; item 2 no rating probe, ObjectForm zero stars, cell zero stars; item 3 CS-0001 not found; item 5 3/2 where 3/2/25 belongs; item 6 chip positi…ager, lead child_account_revenue; item 7 heading ats_inquiry. Item 4 ablation (fix committed, base rail blob written over it, restored with git checkout HEAD, blob hash equal to HEAD, diff HEAD empty): both item 4 legs and the item 3 leg red, 2 controls green. Item 7b measured on base: the anonymous /f/SLUG page shows Format: markdown (throwaway test, deleted, never committed). Eager closure: NOT MEASURED as the console eager closure (needs two console builds); proxy dist/index.js base vs head: fields +776 B raw / +170 B gzip, components +218 B raw / +79 B gzip, both builds proven landed (marker count 1 to 2, sha changed).", "mcp_calls": "1 — mcp__claude-code-remote__add_repo (objectstack-ai/hotcrm, access read; answered read_available, nothing attached; used for one shallow read-only clone into the scratchpad, since deleted). No GitHub MCP tool called.", "api_writes": "2 relay strokes (fleet-write, landing as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12151/assignees [zhuangjianguo], read back 13366/13366 bytes identical; (2) this os-dev-report comment = POST /repos/objectstack-ai/objectui/issues/12110/comments. Plus git push (not REST). Zero label writes, no PR-body PATCH.", "open_questions": [ { "question": "Item 7, second half: hide the rich-text editor hints (Format: markdown, Rich text editor (basic)) on the anonymous public form. RichTextField cannot tell it renders there: FormPage knows its mode, but FieldWidgetComponentProps has no such member and no context carries it. Which route?", "options": [ "A — a new optional member on the widget contract (FieldWidgetComponentProps), produced only by FormPage in public mode, read by RichTextField. About 40 lines + pin; @object-ui/fields published type widens (Clause-2 yes, minor). Business need: measured (HotCRM A-09/B-08, reproduced on main). Long-term: grows a widget contract for one producer and one reader, and sets a precedent for per-surface chrome flags. AI-safety: every widget, including AI-authored ones, may now receive a key it must keep off its DOM (toDomProps whitelist). Startup focus: a new declared surface with one consumer.", "B — drop both hint lines from RichTextField's editable header on every surface (the field's own help text and placeholder remain where authored guidance lives). About 10 lines + pin; no contract change, no export. Business need: the basic-editor line describes the implementation and informs no user anywhere; the format label is the only loss, for internal authors, with no measured demand for it. Long-term: removes chrome rather than adding a switch. AI-safety: nothing new to learn or misuse. Startup focus: shrinks the surface. Cost: internal console forms lose the two lines too, a change the card did not ask for.", "C — a scoped React context (for example exported from @object-ui/fields or @object-ui/react) that FormPage public mode provides and RichTextField reads. About 40 lines; a new public export (Clause-2 yes); a context nobody else reads; the dispatch's no-global-flag line argues against it.", "D — leave the hints and close this half with the reading. Zero cost; anonymous visitors keep seeing editor chrome." ], "recommendation": "B, because on all four axes it is the only option that fixes the measured defect without widening a contract: the hints carry no information a visitor or most users need, it adds no prop or export an AI-authored widget could mishandle, and it shrinks rather than grows the surface. If the maintainer wants the syntax shown to internal authors, D for the public half is the fallback, not A or C." } ], "out_of_scope_findings": [ "carrier: none · noted, not filed — ObjectForm's numeric formField.step now reaches the DOM only through a widget: input hint (or a host with no field widgets registered); a dormant producer after item 2. In the PR's Acceptance notes.", "carrier: none · noted, not filed — the gantt shift-mode header labels each shift-day with month and day only and shift mode has no year tier; same family as item 5, not measured at a public door. In Acceptance notes.", "carrier: whoever next touches packages/app-shell/src/utils/approverIdentity.ts · noted, not filed — the record page approval panel names a position from sys_position rows (useApproverDirectory, the spec APPROVER_VALUE_BINDINGS source) while the inbox now reads the position registry; a registry-only position reads differently on the two. Unexercised drift. In Acceptance notes." ], "gates": "All at fd4059c unless noted. type-check: 6 lib packages green + console 36/36 green. vitest: pins + neighbours + column-identity ratchet 9 files / 82 tests; plugin-detail 255+1 skipped; components 375+1 skipped; scripts/__tests__ 180+2 skipped (includes one-authority-per-exported-name-6273); pre-merge at 50c7747: plugin-grid 202, plugin-gantt 99+1 skipped, fields 245+1 skipped, plugin-form 175, apps/console 181. node scripts/check-changeset-presence.mjs exit 0 (23 source files of 7 released packages, 1 changeset); check:changeset-claims 0; check:pending-changeset-literals 0; check:new-line-citations 0 (0 new citations); check:control-bytes 0; check:test-path-roots 0; check:vi-mock-specifiers 0; check:vi-mock-inherit 0; check:vi-mock-override-shape 0; check:phantom-deps 0; check:doc-json 0; check:doc-fences 0. i18n family: not run, no locale key changed. eslint: 22 changed TS files, 0 errors (narrowed, see deviations). CI: in_progress at report time (not awaited).", "line_budget": "Against merge-base 158c75d: 28 files, +1289 / -90 (1379 changed lines, tests included); non-test files 13, +380 / -51. No line budget was declared by the claim or the dispatch.", "deviations": [ "One console tsc --noEmit ran outside the verify lock (to read a type error quickly); re-run at once under the lock through turbo type-check, green.", "File surface exceeded, each forced by an item: plugin-form ObjectForm.tsx (a comment item 2 made false) and two plugin-form tests that relied on the retired unregistered-widget route (re-pointed at widget: input); ApprovalsInboxPage.tsx beyond formatIdentity / decisionAmountEntry (usePositionLabels hook, label map threaded through approverDisplay / approverChips); form.tsx cascade-clear reader; five existing pins re-pointed by item 5 (displayLocale-10668, inclusiveEnd-11141, catalogPlans-11141, objectGanttInputs-11168 clock pin) and one by item 6 (summaryFaces-11677 lead-label leg on a billed invoice); FormPage.publicHeading pin moved one arm down by item 7. Docs (pre-authorised): plugin-grid.mdx, plugin-form.mdx, plugin-gantt.mdx, guide/public-forms.md.", "eslint was run on the 22 changed TS files only, not as the package-level eslint . form; the config enables no type-aware linting, so unchanged files cannot change verdict. Four new no-explicit-any warnings sit in two new test files.", "Eager-closure delta reported as a package-dist proxy, not the console eager closure.", "One verify-lock attempt ended queue-timeout (99, never acquired) and was re-entered on the same slot; one invocation was refused by the vitest guard (overlapping filters) and one (a mistyped path) — both re-run correctly; none counted as a measurement.", "Interrupted by the API usage wall around 14:15Z; resumed after the worker restart from the pushed head 50c7747, merged main 158c75d, re-ran what the merge touches.", "Cleanup done: worktree /home/user/objectui-issue-12110 removed (no --force), its node_modules deleted, the scratch hotcrm clone deleted; no background process of this run remains." ], "files_changed": [ ".changeset/12110-hotcrm-rendering.md", "apps/console/src/components/FormPage.tsx", "apps/console/src/components/FormPage.publicHeading.test.tsx", "apps/console/src/pages/system/ApprovalsInboxPage.tsx", "apps/console/src/pages/system/ApprovalsInboxPage.approverHeadline-12110.test.tsx", "apps/console/src/pages/system/ApprovalsInboxPage.summaryFaces-11677.test.tsx", "content/docs/guide/public-forms.md", "content/docs/plugins/plugin-form.mdx", "content/docs/plugins/plugin-gantt.mdx", "content/docs/plugins/plugin-grid.mdx", "packages/components/src/renderers/form/form.tsx", "packages/components/src/renderers/form/__tests__/form-unregistered-widget-type-fallback-12110.test.tsx", "packages/fields/src/index.tsx", "packages/fields/src/__tests__/cellRenderers.ratingCell-12110.test.tsx", "packages/plugin-detail/src/renderers/record-reference-rail.tsx", "packages/plugin-detail/src/renderers/__tests__/record-reference-rail.nameFieldRefresh-12110.test.tsx", "packages/plugin-form/src/ObjectForm.tsx", "packages/plugin-form/src/__tests__/objectFormNumericStep-9574.test.tsx", "packages/plugin-form/src/__tests__/objectFormUnregisteredWidget-12110.test.tsx", "packages/plugin-form/src/__tests__/sectionEntryOverrides-10475.test.tsx", "packages/plugin-gantt/src/GanttView.tsx", "packages/plugin-gantt/src/GanttView.displayLocale-10668.test.tsx", "packages/plugin-gantt/src/__tests__/GanttView.dateYear-12110.test.tsx", "packages/plugin-gantt/src/__tests__/GanttView.inclusiveEnd-11141.test.tsx", "packages/plugin-gantt/src/__tests__/ObjectGantt.catalogPlans-11141.test.tsx", "packages/plugin-gantt/src/__tests__/objectGanttInputs-11168.test.tsx", "packages/plugin-grid/src/ObjectGrid.tsx", "packages/plugin-grid/src/__tests__/ObjectGrid.authoredColumnLabel-12110.test.tsx" ] }
Generated by Claude Code
Filing gate ①: seven small rendering defects measured at a public door (findings A-02, A-03, B-13, B-14, B-20, C-18, A-09, B-08). Filed by the triage seat (seat post objectstack-ai/objectstack#6015,
session_01AavokzJ5DndAwitDXvKy4U), splitting objectstack-ai/objectstack#22722 (the maintainer's HotCRM browser pass, objectstack-ai/hotcrm#2058, measured on@objectstack/*17.7.0). ⛔ Not a claim.One card on purpose: each item is a few lines in one file, all are
domain:ui, and none needs a decision. One PR, with a pin per item.Items (read on objectui
maince991bd70f)labelloses to the field label (A-02).packages/plugin-grid/src/ObjectGrid.tsxabout:3508–:3511passescol.labelas the fallback of a translated field-label lookup.type: ratingwithwidget: 'star_rating'renders as a text box (A-03).packages/components/src/renderers/form/form.tsxresolveswidgetfirst (about:3131), finds nofield:star_rating, and falls to the default text input (about:4480).typerenderer".packages/fields/src/index.tsx(about:3769) mapsratingcells to a number.typerenderer, and giveratinga rating cell.nameField(B-13).packages/plugin-detail/src/renderers/record-reference-rail.tsxpickDisplayName(about:226–:245) uses a fixed ladder, and the fetch (about:440–:460) keeps only.fieldsof the target schema.refreshAfter: truedoes not refresh the reference rail (B-14).parentId::entriesSig(about:304,:370–:377) and does not subscribe to the data-invalidation bus.RecordDetailView.tsxnotifyRecordChanged(about:557,:1116) posts only there.packages/plugin-gantt/src/GanttView.tsxformats{ month, day }at about:3978,:4000,:4013,:4302,:4522and:4837. Show the year at least when it is not the current one.apps/console/src/pages/system/ApprovalsInboxPage.tsx:formatIdentity(about:222–:228) cuts a long id in the middle ("positi…ager"). Aposition:<p>approver should show the position's label.decisionAmountEntry(about:632–:656) takes the first key matchingAMOUNT_KEY_RE, even a zero "Child Account Revenue". Prefer the object's declared amount field, and never headline a zero from an unrelated key.3409fe89e4, after the 17.7.0 pin) draws them throughRecordFieldFace. console (17.7.0): seven UI defects measured in one full browser pass of a metadata app — missing Edit, capped calendar, page-only footer sum, ignored password, and three affordances shown to users who cannot use them #12081 item 7 can close against it once checked.apps/console/src/components/FormPage.tsxloadPublicForm(about:1436) falls back to the object's API name. Use the object's label.packages/fields/src/widgets/RichTextField.tsxabout:417–:418shows "Format: markdown" and "Rich text editor (basic)" to anonymous visitors. Hide editor hints on the public surface.Not in this card: a completed task's due date shown as "Overdue" (C-19) is #11815, on hold until objectui installs a spec release with
settledWhen.domain:ui· p3.