Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console shell: the page-header star and the sidebar pin become one "Pin to sidebar" action in the page overflow menu, landing in the Pinned section at the top; the app sidebar's bottom Favorites group goes #12427

Closed

Description

@objectstack-fleet

Filing gate ③, a task the maintainer dispatched in person (chat, 2026-10-15, session session_019YFzJp4o8Ck4NsT1toC4UP, seat account os-bill). The maintainer's words, verbatim: 「用户个人收藏,左侧菜单也有一个 pin 按钮,目前点击pin 会到顶部,但是点击右上角的收藏没有任何效果。包括这个收藏需要保留吗」, then, on the seat's proposal to merge the two into one Pinned section: 「合并为 Pinned 可以,但是这个功能常用吗?需要放在列表页右上角的明显位置吗?你的设计图我也没看到这个按钮」. The design this follows is the prototype at https://claude.ai/artifact/8JLqDFmcuK82RS1Cb8219f (private to the maintainer; the page header's ⋯ menu on the main artboard).

Blocked-by: #12423

Serial after #12423: that card rewrites the same page-header region (PageHeader.tsx, the header call site in ObjectView.tsx) and keeps the star for now; this card removes the star once #12423 has landed, so the two never edit the header in parallel.

Reader who acts: the domain:ui lane, one dev round in @object-ui/app-shell plus the ten @object-ui/i18n packs, after #12423 merges.

Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T04:58Z): "favorites star pinned sidebar nav pin object page header" → 5 (#7044, #3631, #3999, #1055, #702, all closed; #1055 is the hover rule for the sidebar pin icon and stays in force; #3631 is the pin storage-key observation, closed); "Favorites group sidebar bottom not visible Recent" → 0, a zero read in the same run as the first query's five hits, so the channel was live. None is this card.

The problem

The console has two personal "keep this handy" controls that write the same store and land in different places. The sidebar's pin control writes a type: 'nav' favorite and the item appears in the Pinned section at the top of the app navigation, which the user sees at once. The star at the top right of an object list page (and of a record page) writes a type: 'object' or type: 'record' favorite, and that appears in a Favorites group rendered after the whole navigation tree and after Recent, at the bottom of the sidebar. On an app with a long navigation the group is below the sidebar's viewport, so the star looks dead. For an object that already has a navigation item the two controls express the same wish twice, and the one with the worst feedback is the one in the page header's most prominent slot. Pinning is a once-and-forget action, not a daily one; it does not deserve that slot.

Readings (objectui origin/main fc528c3, read 2026-10-15T04:50Z)

  1. One store, two buckets: packages/app-shell/src/context/FavoritesProvider.tsx — localStorage key objectui-favorites scoped per user with write-through to the UserDataAdapter slot ui.favorites; FavoriteItem.type is one of object, dashboard, page, report, record, nav (line 56); the nav bucket and the non-nav bucket are capped separately (130–134).
  2. Sidebar pins: packages/app-shell/src/hooks/useNavPins.ts 45–80 — a pin is a type: 'nav' favorite with pinned: true and id nav:<navId>; NavigationRenderer draws pinned items in the Pinned section at the top of the app navigation, in the user's order (objectui#12059).
  3. Where the star's favorite lands: packages/app-shell/src/layout/UnifiedSidebar.tsx — in the app context the Favorites group (favorites.some(f => f.type !== 'nav'), up to 8) is rendered after the navigation tree and after Recent (the block around 565–575); the console-home sidebar has a separate Starred group for object, dashboard and page favorites (653–661).
  4. The star buttons: packages/app-shell/src/views/ObjectView.tsx 1609 (useFavorites) and 3895–3915 (the header button, testid object-favorite-btn-<object>, id object:<name>); packages/app-shell/src/views/RecordDetailView.tsx 572 (the record page's star).
  5. Other readers of the store: HomePage.tsx 243 (the Home page's favorites); CommandPalette.tsx does not read favorites (it reads the app's nav items only).
  6. Measured 2026-10-15T04:48Z, console fc528c3 at 1440×1000 against the HotCRM demo, driven by Playwright: the star flips aria-pressed to true and a Favorites group appears in the sidebar DOM at y=1244 while the sidebar's scroll viewport spans y=56–1000; nothing changes in view until the sidebar is scrolled to its bottom. localStorage gains {"id":"object:crm_lead","label":"Leads","href":"/apps/app.objectstack.hotcrm/crm_lead","type":"object"}.

What to build

  1. The star button leaves the object list header and the record page header. In its place the page's overflow menu (the ⋯ next to New and Import that console list page: the toolbar's settings cluster folds into one Display popover, view tabs size to their width and carry the view's type icon, the row-number cell yields to the checkbox on hover, and the page header is one row #12423 keeps in the one-row header) gets one entry, "Pin to sidebar" / "Unpin from sidebar", reflecting the current state. New keys in all ten locale packs.
  2. Semantics of that entry: when the current app's navigation has an item for this page's target (an object item with this objectName, or a dashboard / page item with this name), it toggles that item's pin through the existing useNavPins().togglePin, so the result is the Pinned section at the top, the same as the sidebar's own pin control. Otherwise (a record; an object the app does not list) it toggles the existing non-nav favorite, and that group renders directly under the Pinned section at the top of the app sidebar, never after Recent.
  3. The Favorites group at the bottom of the app sidebar is removed; its content is what 2 renders at the top. The console-home sidebar's Starred group and the Home page's favorites are unchanged. The store, its keys and the adapter slot are unchanged; no migration: an existing object: or record: favorite simply renders in the new place.
  4. The sidebar's hover pin control stays the primary way to pin a navigation item (objectui#1055's hover rule unchanged).

Acceptance

  • On the Leads list of an app whose navigation lists crm_lead, "Pin to sidebar" writes one nav:<id> favorite with pinned: true and no object:crm_lead favorite; the Pinned section shows Leads inside the sidebar's visible top; the entry now reads "Unpin from sidebar" and a second click removes the pin.
  • On a record page, the entry writes a record: favorite and the group that shows it sits directly under Pinned (in the HotCRM demo at 1440×1000 its label's bounding box lies inside the sidebar's viewport without scrolling), not after Recent.
  • The list header and the record header render no star button (the object-favorite-btn-* pins are updated deliberately, not deleted silently); pnpm test from the repo root green on the affected files; i18n parity green; a changeset (minor) for every published package touched.

Out of scope

  • The Home page and the console-home Starred group; the command palette reading favorites; pin ordering (objectui#12059 landed it).
  • Any change to the favorites store shape or to packages/spec.

Attribution: written by the domain:ui seat in session session_019YFzJp4o8Ck4NsT1toC4UP (account os-bill) on the maintainer's instruction quoted above.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Addendum 2026-10-15T04:55Z by the filing seat (session_019YFzJp4o8Ck4NsT1toC4UP, os-bill), two maintainer follow-ups in the same chat, verbatim: 「之前 pin 是左侧菜单划过的实现显示,你的意思是去掉,换到右上角的下拉菜单?」 and 「如果两个概念合并,那叫收藏是不是更好」, plus a proposal: 「是否建议类似 Claude code,左侧菜单划过时,加上下拉,很多功能可以放进去。比如设计对象等。」

    Naming (replaces "Pinned" wherever this card says it). The merged section at the top of the app sidebar is called Favorites (zh-CN 收藏), with the star icon; the sidebar label "Pinned" is retired. Reasons: the store is already favorites, the i18n keys common.addToFavorites / common.removeFromFavorites and sidebar.favorites already exist in all ten packs, the Home page and the console-home sidebar already call the same items favorites, and "pin" describes a position while this feature is a personal collection that happens to be shown at the top (Notion and Linear name the same section Favorites). type: 'nav' stays an internal storage detail; nothing in the store changes. The sidebar's hover control therefore becomes a star, not a pin icon, and the page overflow entry reads "Add to favorites" / "Remove from favorites".

    Where the control lives (answering the first question). The sidebar's hover-revealed control stays and stays primary; what goes is only the always-visible star in the page header. The page overflow entry is the same action for pages that have no sidebar item to hover (records; objects the app does not list).

    Scope extension (the proposal; same files, same card). The hover-revealed control on a sidebar navigation item becomes a small ⋯ menu (also opened by right-click), and the star joins it as its first entry instead of being its own icon. Entries derive from the item's type, never from a product (ADR-0060): "Add to favorites" / "Remove from favorites"; "Open in new tab"; "Copy link"; and, only for a principal who may author metadata (isAdmin && canAuthorMetadata, the gate PageView.openInStudio already uses), a "Design" entry that opens the item's designer: a page item goes to /apps/APP/metadata/page/NAME exactly as PageView.tsx 129–132 does today, an object item to the object designer, a dashboard item to the dashboard designer (the dev finds each route in the console's metadata-admin router rather than from this comment). Items with no designer (url, component, separator) show no Design entry. The menu is one shared component for all item types; objectui#1055's rule (hover only, nothing permanently visible) carries over to the ⋯ trigger.

    Acceptance adds: hovering a nav item shows one ⋯ trigger and no standalone pin icon; the menu for an object item lists exactly the four entries above for an admin and three for a non-admin; "Design" on the Leads item of the HotCRM demo lands on the object designer for crm_lead; right-click opens the same menu.

    Reading time 2026-10-15T04:55Z.

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2
    Session: session_019YFzJp4o8Ck4NsT1toC4UP
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-12427-favorites-sidebar-menu
    Worktree: objectui-issue-12427
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: packages/app-shell/src/layout/UnifiedSidebar.tsx (the Favorites group, the hover control, the new per-item ⋯ menu and its wiring), one new shared menu component under packages/app-shell/src/layout/ or components/ with its tests, packages/app-shell/src/hooks/useNavPins.ts and packages/app-shell/src/context/FavoritesProvider.tsx (readers only unless a read helper is missing; the store shape is frozen), packages/app-shell/src/views/ObjectView.tsx and packages/app-shell/src/views/RecordDetailView.tsx (the page-header overflow entry only; see the serial note below), packages/i18n/src/locales/*.ts, one .changeset/12427-*.md (stop on breach; explain in the report)
    Container & model: M — one new shared menu component plus two header call sites and a sidebar group move; design judgment in the menu's entries per item type, not mechanical, mode:subagent, model: TIER_DEFAULT (opus) — read from scripts/pm/dispatch-gates.data.mjs at objectstack 16abea8 (TIER_DEFAULT = opus, TIER_FLOOR = sonnet); the sister-repo --tier verdict with explicit paths refuses in this checkout with MODULE_NOT_FOUND (objectstack node_modules absent), so the constants file is the reading; ceiling CONTRACT_REVIEW_TIER not reached: no MANDATORY_TIER_GLOB_ROWS path on this surface
    Clause-②: yes
    Responsibility: n/a — not a defect card
    Thread-read: 6184739946
    Serial constraints cleared: domain:ui in-flight claims read 2026-10-15T06:52Z — objectui#12433 (plugin-detail record:details sections, sunhaolin): disjoint surface; objectui#12423 (this seat): its PR #12436 is ACCEPTed with a contract-review PASS, mergeable_state clean, and waits only on the maintainer's ready + auto-merge click; it edits ObjectView.tsx (the header actions where this card's overflow entry goes) and nothing else on this surface. Handled by ORDER, not by waiting: the dev builds the sidebar half first and touches ObjectView.tsx / RecordDetailView.tsx only after origin/main carries #12436 (the merge check is in the dispatch brief); not there when reached ⇒ stop and report blocked. Same-day merges on the surface, all on origin/main 6fcb2ce already: 6fcb2ce (#12437, app opens on the first shown navigation entry), 63079f4 (#12430), 4b0a087 (#12414). No queued sibling shares a hot file; objectui#12429 (sidebar collapse toggle, pm:blocked on this card) and objectui#12440 (tab strip into the list toolbar, blocked on #12423) are serial behind.
    Resume-from: none

    Blocked-by #12423 is lifted for dispatch on the maintainer's word in chat (2026-10-15, verbatim: 「你可以继续开发」) after the seat reported that #12436's landing stroke was refused by the container's classifier; the overlap is handled by order as above, and the card's own text stands with its addendum (comment 6184739946: Favorites naming, the sidebar item's ⋯ menu with the Design entry).

    Maintainer direct-dispatch channel, verbatim authorisation (chat, 2026-10-15): 「按这个方案在 objectui 开一个 issue,使用 dispatch 技能,然后你负责派发开发。」 and the follow-ups quoted in the card and its addendum. Routing (domain:ui, area:devpath, priority:p2) was written by this seat under that channel; triage may regrade.

    Reading time 2026-10-15T06:55Z.

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12427,
    "status": "blocked",
    "branch": "claude/issue-12427-favorites-sidebar-menu",
    "pr": "#12443",
    "session": "session_019YFzJp4o8Ck4NsT1toC4UP — the Claude-Session id this subagent was stamped with (the parent seat's)",
    "premise_still_valid": true,
    "summary": "Neither half is complete. What landed is the in-surface groundwork, at adb45f8 in draft PR #12443 (body starts 'Part of #12427'). That is SidebarItemMenu (packages/app-shell/src/layout/SidebarItemMenu.tsx, with 15 tests), the one per-entry ⋯ menu for every entry type: Add/Remove favorites; Open in new tab and Copy link under the router basename, with an off-console URL used verbatim; Design for object/dashboard/page entries, gated isAdmin && canAuthorMetadata and routed to /apps/APP/metadata/TYPE/NAME; hover-only trigger; right-click opens it. Six new console.nav keys in all ten packs, and a minor changeset. BLOCKED 1, file surface: the hover pin control and the top Favorites section are not in UnifiedSidebar.tsx. NavigationRenderer in packages/layout/src/NavigationRenderer.tsx (@object-ui/layout) draws both: the pin is the SidebarMenuAction with the Pin/PinOff icon and the console.nav.pinItem label, and the section is its favoritesSection. No prop lets a host replace the per-row control or add rows to that section. The claim says stop on breach, so that file is untouched and UnifiedSidebar.tsx is unchanged (wiring the menu, merging the non-nav favorites to the top and deleting the group after Recent all need the layout slot). BLOCKED 2: #12436 is not yet on origin/main. The grep for 'No favorite star here since objectui#12423' on origin/main ObjectView.tsx printed 0 at 431cece; the control on the PR head 4ba299c printed 1. ObjectView.tsx and RecordDetailView.tsx are untouched. Premise note: on main the top section is already titled Favorites (console.nav.favorites, 收藏, star icon). Only the hover control still says pin.",
    "tests": "At adb45f8. (1) pnpm exec vitest run packages/app-shell/src/layout/tests/SidebarItemMenu-12427.test.tsx printed 'Tests 15 passed (15)'. The tests cover: object entry shows four entries to an admin who may author metadata (Design last), three to a non-admin and three to an admin without manage_metadata; Design navigates to /apps/crm/metadata/object/crm_lead; the favorites entry reads 'Remove from favorites' and toggles once; Open in new tab calls window.open('/_console/apps/crm/crm_lead','_blank','noopener,noreferrer'); Copy link writes the origin plus /_console/apps/crm/crm_lead; an off-console URL is used verbatim; a url entry has no Design; an action entry shows only the favorites entry; right-click opens the menu with the default prevented; sidebarItemDesignPath for page/object/dashboard, and null for url/component/separator. (2) pnpm exec vitest run packages/i18n/ (with the menu test) printed 'Test Files 84 passed (84)' and 'Tests 1336 passed | 13 skipped (1349)'. A verbose rerun of all-locales-key-parity, en-zh-key-parity and the menu test printed '63 passed (63)'. (3) pnpm --filter @object-ui/i18n --filter @object-ui/app-shell run type-check: VERDICT command-exit 0. It ran after building app-shell's dependency closure ('Tasks: 28 successful, 28 total'), and tsc -p tsconfig.test.json --listFilesOnly lists both new files. (4) Two ablations through objectstack scripts/ablation-replace.mjs; the test imports the source, so no dist is involved. Dropping canAuthorMetadata from the Design gate (anchor 1 to 0, blob 045e33c to d2ff3d7) failed exactly one test, 'lists exactly three for an admin the server refuses metadata authoring'. Dropping the absolute-URL test from offConsole (blob 045e33c to a5e449c) failed exactly one test, 'an external entry opens and copies its URL verbatim'. Each run was restored to the HEAD blob 045e33c with git diff HEAD empty. The first run of the menu test found a real bug (an absolute url entry without target was joined under the basename), fixed before commit.",
    "gates": "Local subset. All were run before any pipe and all exited 0: check:i18n-keys, check:i18n-dead-keys, check:i18n-drift ('6 key(s) added, 0 removed'), check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:new-line-citations, check:control-bytes, check:test-path-roots, node scripts/check-changeset-presence.mjs ('12 source file(s) of 2 released package(s) changed, and this change declares 1 changeset'), and node scripts/check-changeset-no-major.mjs. objectui has no dispatch-gates.mjs, so there is no --ran reconciliation. I derived this list by hand from package.json check:* and the files the diff touches: locales, a test with vi.mock, new source, a changeset. CI check-runs on adb45f8 (36), read once at report time without polling: success for Changeset Bump Policy, Changeset Declaration, Changeset Fixed Group Check and label; skipped for Test (coverage), Test (coverage shard), dependabot; in_progress for Type Check, Lint, Repo Gates, Line Citation Gate, Governed Surface Queue Guard, Test (shard 1-16 of 16), Test (dist pins), Build & E2E, Build Docs, Bundle Analysis, Changeset Claim Re-read, Changeset Overwrite Report, Spec Main Shape Gate and Live E2E. CI convergence is the seat's.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches. One was pr_create: the relay ran POST /repos/objectstack-ai/objectui/pulls (draft) and then POST /repos//issues/12443/assignees with os-bill; the read-back was 6826 of 6826 bytes, identical. The other is this os-dev-report comment, which the relay posts as POST /repos//issues/12427/comments. Two git pushes went outside REST: the empty-branch probe and adb45f8. No label writes: the brief named none, and the objectui labeler owns path labels.",
    "open_questions": [
    {
    "question": "The sidebar half needs packages/layout/src/NavigationRenderer.tsx, which is outside the claimed surface. How should the next round get it?",
    "options": [
    "A: extend the surface to NavigationRenderer.tsx plus one layout test. Add two generic additive props: a per-row slot the host fills, drawn in place of the pin action, and host rows appended inside the Favorites section, which then renders when either kind of row exists. Hosts passing neither keep today's behaviour. The existing tests that click 'Pin NAME' by name are updated deliberately: UnifiedSidebar.pinnedOrder-12059.test.tsx, navItemVisibleEvaluated.test.tsx and the layout pin tests. Size S-M; resume from this branch.",
    "B: UnifiedSidebar draws the whole Favorites section itself and NavigationRenderer's section is switched off. This still needs a layout prop and an export of PinnedNavigationList, or else it loses the objectui#12059 drag order, so it is a bigger surface and duplicates rows.",
    "C: re-scope so that this card only moves the non-nav group, and the ⋯ menu goes to a later card. This is not workable either: merging into the top section needs the layout's favorites slot anyway."
    ],
    "recommendation": "A, because it is the smallest generic change, keeps one renderer and the pinned drag order, and SidebarItemMenu on this branch already fits it as is."
    },
    {
    "question": "Should Design also appear on report and doc entries? The metadata-admin router serves metadata/report/NAME and metadata/doc/NAME with editors, but the addendum names only page, object and dashboard.",
    "options": [
    "A: keep the three the addendum names (the branch does this)",
    "B: add report, and maybe doc"
    ],
    "recommendation": "A. It stays inside the addendum's enumeration, and adding a type later is one line in sidebarItemDesignPath plus one test."
    },
    {
    "question": "Two dashboard designers exist: metadata/dashboard/NAME, the metadata-admin router, and design/dashboard/NAME, DashboardDesignPage, which no in-tree link points at. Which one should Design open?",
    "options": [
    "A: metadata/dashboard/NAME (the branch does this)",
    "B: design/dashboard/NAME"
    ],
    "recommendation": "A, because the brief says to use the metadata-admin router and it is the route PageView already uses for pages."
    },
    {
    "question": "The merged section's title and the labels of non-nav rows are not decided.",
    "options": [
    "A: title the merged section with console.nav.favorites (already Favorites / 收藏 with a star). A record or object favorite row shows its stored label (refreshLabel self-heals it) with a type icon, as the bottom group does today, and carries the same ⋯ menu, where the toggle removes it. Design shows for object, dashboard and page favorites (derived from the id), never for record or report. sidebar.favorites becomes unread and is deleted from ten packs; sidebar.removeFromFavorites stays for the console-home Starred group.",
    "B: resolve non-nav labels live, as useRecentItemLabel does"
    ],
    "recommendation": "A. There is no store change and no migration, and the labels match what Home shows."
    },
    {
    "question": "On mobile, enablePinning is off today, so there is no hover control. Should the ⋯ menu also be absent on mobile?",
    "options": [
    "A: absent on mobile, the same as today",
    "B: always visible on mobile"
    ],
    "recommendation": "A. It keeps the objectui#1055 hover-only rule and today's mobile behaviour."
    }
    ],
    "out_of_scope_findings": []
    }

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Scope note 2026-10-15T07:25Z from the dispatching seat (session_019YFzJp4o8Ck4NsT1toC4UP, os-bill) on the dev report 6186752694 (status blocked, draft PR #12443 at adb45f8). The stop was right: the claim's surface did not reach the file that draws the control. Five decisions; the dev reads them with the card, the addendum and the claim.

    1. Surface extended to packages/layout/src/NavigationRenderer.tsx and one new test under packages/layout/src/__tests__/, with @object-ui/layout (published; no private key) added to the changeset as minor. Readings at this writing (2026-10-15T07:25Z): the governed-surface guard answers NOT GOVERNED for the path; no origin/main commit has touched the file since 2026-10-14; no in-flight domain:ui claim names it. Shape = the dev's option A: two additive props on NavigationRendererProps — a per-row slot the host fills, drawn in place of the pin SidebarMenuAction (lines 1559–1577 and 1625–1643 on origin/main), and host rows appended inside favoritesSection (line 1762), which then renders when either kind of row exists. A host passing neither keeps today's behaviour, the pinned drag order (objectui#12059) included. The existing tests that click "Pin NAME" by name are updated deliberately, as the report lists them.
    2. Design entries: page, object and dashboard only (the addendum's enumeration); the dashboard designer is the metadata-admin route metadata/dashboard/NAME. Report and doc entries get no Design entry on this card.
    3. The merged section: titled by console.nav.favorites (already Favorites / 收藏 with the star on main). A non-nav favorite row shows its stored label (the store's refreshLabel self-heals it) with its type icon, carries the same ⋯ menu, and its favorites entry removes it; Design shows for object, dashboard and page favorites derived from the id, never for a record or report favorite. sidebar.favorites becomes unread and leaves all ten packs; sidebar.removeFromFavorites stays for the console-home Starred group. The Favorites group drawn after Recent in UnifiedSidebar.tsx (the block around lines 524–530) is removed.
    4. Mobile: no ⋯ trigger where enablePinning is off today; the objectui#1055 hover rule and today's mobile shape stand.
    5. Serial rule unchanged: ObjectView.tsx and RecordDetailView.tsx only once origin/main carries feat(list): Filter · Sort · Display · Search toolbar, width-fitted view tabs, one leading row cell, one-row page header #12436 (the same grep; feat(list): Filter · Sort · Display · Search toolbar, width-fitted view tabs, one leading row cell, one-row page header #12436 has been in the merge queue since 2026-10-15T07:18Z with the queue CI running). Reached with 0 ⇒ the PR stays Part of objectstack-ai/objectui#12427 and the report says blocked on that one item; nothing else waits on it.

    Resume-from: claude/issue-12427-favorites-sidebar-menu@adb45f8 — same worktree, same branch, same draft PR #12443. When both halves are in, the PR body's first line becomes Fixes objectstack-ai/objectui#12427 (relay issue_patch on the pull's number, body otherwise kept) and the seat re-reads it before ready.
    Thread-read: 6186752694


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12427,
    "status": "blocked",
    "branch": "claude/issue-12427-favorites-sidebar-menu",
    "pr": "#12443",
    "session": "session_019YFzJp4o8Ck4NsT1toC4UP — the Claude-Session id this subagent was stamped with (the parent seat's)",
    "premise_still_valid": true,
    "summary": "Resumed from adb45f8 under scope note 6186841419. The head is 0bc0189, draft PR #12443, still 'Part of #12427'. LANDED, sidebar half: NavigationRenderer gets two additive props. renderItemAction is a host control drawn on every leaf and action row in place of the pin action. extraFavorites are host rows appended inside the Favorites section, which renders when either kind exists. A host passing neither keeps today's behaviour, drag order included. UnifiedSidebar fills the slot with SidebarItemMenu: one hover-revealed ⋯, right-click opens it, the favorites entry toggles through useNavPins().togglePin, Design shows for object/dashboard/page via metadata/TYPE/NAME, and there is no trigger on a phone. The non-nav favorites become rows of the top section with the same menu (the toggle removes them; Design comes from object:/dashboard:/page: ids). The group after Recent is gone, sidebar.favorites leaves the ten packs, and the store is untouched. LANDED, header half: #12436 reached origin/main (the grep printed 1 at a2225f9) and was merged in with a merge commit. The list header's actions row now ends with an icon-only ⋯ (named by the existing detail.moreActions key) holding the shared FavoriteMenuItem. useObjectListFavorite pins the app's own object nav entry when the member's shown navigation has one: one nav:ID with pinned true and no object: favorite. Otherwise it keeps object:NAME. The record page's overflow leads with sys_favorite (record:), ahead of Share. BLOCKED on ONE item: the record header still draws its star. RecordTitleChip draws it from the page:header renderer in packages/components/src/renderers/layout/containers.tsx, which is outside the surface. showStar defaults to true from the schema alone. If RecordDetailView stopped passing isFavorite/onToggleFavorite, the star would stay and store nothing (probe: one 'Add to favorites' button, aria-pressed false). So the wired star is kept, and the PR stays 'Part of'. CI on 0bc0189: 34 success, 3 skipped.",
    "tests": "At 0bc0189. NEW: SidebarItemMenu-12427 (15); NavigationRenderer.hostItemAction-12427 (8): slot in place of the pin, context href/external/label, no slot on group/separator, drawn with pinning off, host rows after pinned rows, null/false/[] count as none, default kept; UnifiedSidebar.favoritesMenu-12427 (10): one ⋯ and no pin per row, 4 entries for an admin and 3 for a non-admin, right-click, Add writes one nav:nav_leads pinned and then reads Remove, no trigger at 375px, stored object:/record: favorites in the top section with localStorage byte-identical, group labels exactly ['Favorites','Recent'], one section for pin plus stored favorite, Design on an object favorite and not on a record, Remove removes; ObjectView.favoritesEntry-12427 (3): no star button and the last control is an icon-only 'More actions', one nav:nav_projects (type nav, pinned true) and no object:, then 'Remove from favorites', then [] after the second press, object:showcase_project with label Projects and href /apps/demo/showcase_project when unlisted; RecordDetailView.favoritesEntry-12427 (2): overflow [Add to favorites, Share, ...], writes record:crm_call:rec-call-1 and then reads Remove. UPDATED deliberately: UnifiedSidebar.pinnedOrder-12059 drives the ⋯ menu ('More actions for NAME', then Add/Remove) instead of 'Pin NAME'; the starred record now reads '📋Acme' after the pinned rows. navItemVisibleEvaluated and the layout pin tests drive NavigationRenderer without the slot and pass unchanged. ABLATIONS (ablation-replace, each landed and was restored to the HEAD blob, git diff HEAD empty): leaf slot replaced by null, 8 red; hasExtraFavorites=false, 6 red; useObjectListFavorite's 'if (entry)' made false, 1 red ('writes one nav pin and no object favorite...'). UNION on 0bc0189: packages/layout/ + packages/app-shell/src/layout/ + packages/i18n/ + 24 other tests naming UnifiedSidebar/NavigationRenderer/SidebarItemMenu gave 'Test Files 218 passed (218)' and 'Tests 2512 passed | 13 skipped (2525)'. The RecordDetailView* and ObjectView* prefixes gave 'Test Files 124 passed (124)' and 'Tests 961 passed (961)'. TYPE-CHECK: pnpm --filter layout/i18n/app-shell run type-check, VERDICT command-exit 0, after rebuilding app-shell's closure (28/28; layout dist .d.ts carries renderItemAction). The test tsconfigs list the new tests (layout 1, app-shell 5). CI FIX: on head 122909d, Test (shard 5/16) failed objectView-config-keys-retired-4730.test.ts 'the namespace root survives, with the same surviving key shape in every pack': expected [ 'moreActions', …(102) ] to have a length of 102 but got 103. That was my new console.objectView.moreActions key. Fixed in 0bc0189 by dropping the key from all ten packs and naming the list ⋯ with the existing detail.moreActions (the record header's ⋯ name). No key was added and the ledger is untouched. That file alone: 5 passed; packages/i18n/: 85 files, 1331 passed and 13 skipped. CI shard 5/16 on 0bc0189 is success.",
    "gates": "Local, on the final diff, all run before any pipe and all exit 0: check:i18n-keys, check:i18n-dead-keys, check:i18n-drift, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:new-line-citations, check:control-bytes, check:test-path-roots, check-changeset-presence ('21 source file(s) of 3 released package(s) changed, and this change declares 1 changeset') and check-changeset-no-major. objectui has no dispatch-gates.mjs, so there is no --ran reconciliation; I derived the list by hand. CI check-runs on 0bc0189 (37), read once: 34 success (Type Check, Lint, Repo Gates, Line Citation Gate, Governed Surface Queue Guard, Test shards 1-16 of 16, Test, Test (dist pins), Build & E2E, Build Docs, Bundle Analysis, the five Changeset checks, Spec Main Shape Gate, Live E2E, label), 3 skipped.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "This round: 1 relay dispatch, POST /repos/objectstack-ai/objectstack/dispatches, for the os-dev-report comment (POST /repos//issues/12427/comments). No PR body PATCH; see the open question. 3 git pushes, outside REST: 6d2dfc2, 122909d, 0bc0189 (the last one includes 2b1006d), with merge commits 97a9d97 and 61dcd99, and no force-push. Earlier round: 2 dispatches (pr_create with assignees, and report comment 6186752694).",
    "open_questions": [
    {
    "question": "Removing the record header star needs packages/components/src/renderers/layout/containers.tsx, which is outside the extended surface. How should the last acceptance item be closed?",
    "options": [
    "A: extend the surface to containers.tsx plus one components test. The page:header record chrome draws the star only when RecordContext carries onToggleFavorite (a star with no host toggle stores nothing). RecordDetailView drops isFavorite/onToggleFavorite, and the star's absence is pinned. The overflow entry is already in place. Size S; resume from 0bc0189.",
    "B: RecordDetailView sets showStar:false on the page:header nodes of the page it renders. This rewrites authored metadata at render time and fights an author's explicit showStar.",
    "C: keep the record star beside the overflow entry. This contradicts the card."
    ],
    "recommendation": "A, because it is one generic condition in the renderer, it removes the dead-star case for every host, and it leaves the authored showStar key meaning what it says."
    },
    {
    "question": "There is a conflict between the dispatch and os-dev.md on the PR body. The resume message and the scope note ask the dev to rewrite the PR body via relay issue_patch. os-dev.md says the dev writes the body once at pr_create and never PATCHes it; later changes are written by the seat. The body on #12443 still describes the stopped first round.",
    "options": [
    "A: the seat applies the replacement text I prepared at /tmp/claude-0/-home-user/b989e4d2-1086-5f1b-84ed-e7af367b27dd/scratchpad/issue-12427/12427-pr-body-v2.md (6429 bytes, first line 'Part of #12427', 'Clause-②: yes', no angle brackets, no closing keyword near another number)",
    "B: the dev patches it in a later round under an explicit exception"
    ],
    "recommendation": "A, because os-dev.md says it wins where the two conflict. I did not PATCH."
    },
    {
    "question": "Which navigation entry does the list header pin when several match?",
    "options": [
    "A (implemented): the first object entry with this objectName and no recordId, in the member-shown tree, areas in order and then app.navigation. A pin on an entry in an area other than the sidebar's active one does not draw until that area is active, as for sidebar pins today.",
    "B: prefer the entry whose viewName matches the open view"
    ],
    "recommendation": "A, because it is the plain reading of the card; B can come later if views get separate entries."
    },
    {
    "question": "Mobile: the non-nav favorite rows had an always-visible remove star below md. They now carry the ⋯ in the same place. Navigation rows get none, per decision 4. Keep that?",
    "options": [
    "A: keep it, so the phone keeps a way to remove a favorite from the sidebar",
    "B: no ⋯ on any row on a phone"
    ],
    "recommendation": "A, because it preserves today's mobile control and decision 4 names only the rows that enablePinning governs."
    }
    ],
    "out_of_scope_findings": [
    "carrier: objectui#12427 (its record-star item, open question 1) · RecordTitleChip, through the components page:header record chrome, draws a favorite star whenever schema showStar is not false. With no host onToggleFavorite it keeps the state locally and stores nothing. Measured once: the console record page passes the toggle, so the console itself is not dead today. Noted, not filed."
    ]
    }

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat verdict ACCEPT (Part of) on PR #12443 (head 0bc0189c273ca6ad700ade586dee73379fc184c3), written 2026-10-15T08:22Z: #12443 (comment). Contract review PASS on the same head: comment 6187751089. Governed-merges audit: not governed, 1,764 lines, ordinary queue. The PR body was replaced with the dev's prepared text by the seat (relay issue_patch). Remainder on this card after the merge: the record header star (@object-ui/components page:header chrome, containers.tsx), shape = option A of report 6187632953; the card returns to pm:queue at priority:p1 in the landing stroke. Landing: ready + auto-merge next.
    Thread-read: 6187632953


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing 2026-10-15T08:38Z: PR #12443 MERGED (Part of). Two readings, both taken after the merge event:

    reading value
    PR object merged: true, merged_at 2026-10-15T08:37Z, merged by objectstack-fleet[bot] out of the merge queue; head 0bc0189c273ca6ad700ade586dee73379fc184c3; merge commit a8e5b736456d5d9e8fc432f6deff05fc1b2c7c90
    origin/main tip a8e5b73 "feat(app-shell): the sidebar entry's ⋯ menu, one component for every entry type (part of objectui#12427) (#12443)"; packages/app-shell/src/layout/SidebarItemMenu.tsx present; renderItemAction in packages/layout/src/NavigationRenderer.tsx (13 hits); .changeset/12427-sidebar-item-menu.md present, awaiting the release PR

    Delivered by that PR: the sidebar's per-entry ⋯ menu (favorites, open in new tab, copy link, Design for metadata authors; right-click opens it; none on a phone), one Favorites section at the top with the non-nav favorites as rows after the pinned entries and the group after Recent removed, the two additive NavigationRenderer props, the list header's ⋯ with the favorites entry (pinning the app's own navigation entry when the member is shown one), the record page's overflow favorites entry, six console.nav.* keys in ten packs and sidebar.favorites retired.

    Remaining on this card (one acceptance item): the record header still draws its star, because @object-ui/components' page:header chrome (packages/components/src/renderers/layout/containers.tsx, RecordTitleChip, showStar defaulting on) draws it whether or not the host wires a toggle. Shape, per the contract review on PR #12443 (comment 6187751089, ③) and the dev's report 6187632953 option A: the chrome draws the star only when RecordContext carries onToggleFavorite; RecordDetailView drops its isFavorite / onToggleFavorite props (its overflow entry already carries the action); the star's absence is pinned in a components test and the existing record-star pins are updated deliberately. Size S; @object-ui/components joins the changeset (minor). Branch from origin/main; no Resume-from.

    Status change in this stroke, on the maintainer's word (chat 2026-10-15: 「那后续的任务你放回队列,按 p1 标记」): pm:dispatched → pm:queue, priority:p2 → priority:p1, assignee cleared; the lane's next seat dispatches the remainder. Parent objectstack-ai/objectstack#25945 records the merge. The maintainer's post-merge acceptance (screenshots against the design reference) follows separately.
    Thread-read: 6187766259


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (the remainder after PR #12443, as the landing note 6188037096 hands it to the lane's next seat; priority:p1)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12427-record-star
    Worktree: objectui-issue-12427
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/components/src/renderers/layout/containers.tsx (the page:header record chrome's showStar / RecordTitleChip wiring, :1575 and :2533–:2545 on main a8e5b73) and one components test; packages/app-shell/src/views/RecordDetailView.tsx (the isFavorite / onToggleFavorite pass-through at :3455–:3456 only) and the existing record-star pins it updates; one .changeset/12427-*.md (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6188037096
    Serial constraints cleared: read at objectui main a8e5b73.

    • Predecessor: PR feat(app-shell): the sidebar entry's ⋯ menu, one component for every entry type (part of objectui#12427) #12443 (this card's first part) landed as a8e5b73.

    • Same file, different region: seat 2's objectui#12442 edits RecordDetailView.tsx's synthParts sections derivation (:2796), not the favorite pass-through at :3455. This follows the parallel rule the maintainer's 「12429 为什么不能并行?」 set for a same-file, different-region pair: branch from origin/main, merge origin/main once more before opening the PR, and whichever of the two lands second merges main again (a merge commit, never a rebase).

    • Disjoint: seat 2's objectui#12429 (UnifiedSidebar.tsx, AppHeader.tsx) and objectui#12440 (ListView.tsx, ObjectView.tsx), and this seat's objectui#12418 (ObjectView.tsx handlers, user-state wiring).

    • The shape carried: option A, as the contract review on PR feat(app-shell): the sidebar entry's ⋯ menu, one component for every entry type (part of objectui#12427) #12443 (6187751089, ③) and the landing note name it. The page:header chrome draws the star only when RecordContext carries onToggleFavorite. RecordDetailView stops passing its two favorite props, since its overflow entry already carries the action. The star's absence is pinned, and the existing record-star pins are updated deliberately.

    • Accept-set reading: the record chrome stops drawing a star that stores nothing. If the dropped props are part of a published @object-ui/* type, that is a narrowing: Clause-②: no, and one contract-review-tier review is owed before the queue.


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12427,
    "status": "done",
    "branch": "claude/issue-12427-record-star",
    "pr": "#12465",
    "session": "session_01JZnppgHRp4sREcouhkQYDB — the Claude-Session id this subagent was stamped with (the parent seat's)",
    "premise_still_valid": true,
    "summary": "Option A, as ruled: the page:header record chrome (packages/components/src/renderers/layout/containers.tsx) computes showStar as the authored flag AND the RecordContext carrying onToggleFavorite, so a host with no toggle draws no star, and an authored showStar: false still hides it where a host wires one. The two (ctx as any) reads became typed reads. RecordDetailView no longer passes isFavorite / onToggleFavorite to RecordContextProvider (a comment marks why). Its sys_favorite overflow entry from PR #12443 is unchanged and is now the record page's only favorites control. Draft PR #12465 at head 59c861e (fix cb68d1a plus a merge of origin/main cf430cd; objectui#12442 was not yet on main), assignee sunhaolin. PR body line 1 is the card's closing keyword, as the dispatch asked; line 2 is 'Clause-②: no', copied from the claim with no narrowing arm, because A2 measured that no published type member is removed. Measurements: A1 held. On the base the new pin drew one star with no context toggle: 2 red (the no-toggle cases), 3 green. A2: the props went to RecordContextProvider. RecordContextValue (@object-ui/react) keeps both members, as the host opt-in that RecordContext.valueShape.pin lists. RecordDetailView declares no such props. RecordTitleChipProps is unchanged. Nothing widened. A3 held, pinned. A4: RecordDetailView was the only in-tree host wiring a toggle. PagePreview (the metadata editor's record-page preview) wires none and loses a star that stored nothing. plugin-detail recordBinding wires none and wraps only record:* block bodies, never a page:header. No in-tree host wires a toggle after this change, so the CONTROL lives in the components pin. Changeset .changeset/12427-record-header-star.md: @object-ui/components minor, @object-ui/app-shell minor. The worktree was removed after the PR opened.",
    "tests": "NEW packages/components/src/tests/page-header-star-host-toggle-12427.test.tsx (5 cases), using the real SchemaRenderer and registry under an English I18nProvider. Each case first asserts the chip h1 'Acme' and its 'Copy record ID' button. Cases: no toggle gives no star; isFavorite but no toggle gives no star; CONTROL: a toggle draws one star 'Add to favorites' with aria-pressed false, and a click calls the host once; CONTROL: isFavorite true reads 'Remove from favorites' with aria-pressed true; authored properties.showStar false with a toggle gives no star. UPDATED deliberately: packages/app-shell/src/views/RecordDetailView.favoritesEntry-12427.test.tsx adds 'the record header draws no star, so the overflow entry is the one favorites control'. It asserts no button named Add to / Remove from favorites while the chip is drawn, that the overflow's only favorites entry is 'Add to favorites', and that there is still no star after choosing it. No other test pinned the header star (git grep over the components, plugin-detail, app-shell views, console and e2e tests). BASE RUN of the new pin at a8e5b73: 'Tests 2 failed | 3 passed (5)'. ABLATIONS via objectstack scripts/ablation-replace.mjs, wrap mode, on the committed cb68d1a; the subjects resolve to src through the root vitest alias, so no dist is involved. (1) containers.tsx '!!ctx?.onToggleFavorite &&' became 'true &&' (anchor 1 to 0, blob 04f5745 to 69a08ac): 'Tests 2 failed | 3 passed (5)', exactly the two no-toggle cases. Restored to the HEAD blob 04f5745, git diff HEAD empty. (2) RecordDetailView.tsx re-adds the two props (anchor 1 to 0, blob b18512c to e3ec47c): 'Tests 1 failed | 2 passed (3)', exactly the new no-star case ('expected [ button ] to have a length of +0 but got 1'). Restored to b18512c, git diff HEAD empty. The first attempt at (2) was a no-op: its replacement contained the anchor, the tool refused because the anchor count stayed at 1, ran nothing and restored. It was re-anchored on the provider's closing bracket. UNION on the final head 59c861e: pnpm exec vitest run from the repo root over 167 files (every test naming page:header, RecordTitleChip or onToggleFavorite, every RecordDetailView* suite, PagePreview*, packages/react/src/context/tests, and the console tests mounting RecordDetailView): 'Test Files 167 passed (167)', 'Tests 3386 passed (3386)', lock VERDICT command-exit 0. The same union on cb68d1a before the merge gave the same counts.",
    "gates": "Local subset. objectui has no dispatch-gates.mjs, so I derived the list by hand from package.json check:* and the lint, repo-gates, changeset-guard, changeset-presence and line-citation-gate workflows, for the 7 paths. There is no --ran reconciliation. Every exit code was captured to a file before any pipe. On 59c861e, each exited 0: check:new-line-citations ('0 new citation(s)'), check:control-bytes, check-changeset-no-major, check-changeset-overwrite, check-changeset-presence ('4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'), check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check-doc-links, check:doc-fences and check:doc-json. check:doc-json first exited 2 on the unbuilt tree ('the strict authoring face is not built'), a missing prerequisite rather than a measurement; it exited 0 after the build. On cb68d1a, after turbo build --filter='@object-ui/console...' --concurrency=2 ('Tasks: 35 successful, 35 total'): pnpm --filter @object-ui/components run type-check exited 0 and pnpm --filter @object-ui/app-shell run type-check exited 0, the latter again on 59c861e; tsc -p tsconfig.test.json --listFilesOnly lists both test files once each. check:eager-closure exited 0: 'Console eager closure is 3079.2 KB gzipped across 69 of 2252 chunks (budget: 3119.4 KB, headroom: 40.2 KB)'. check-governed-queue-guard --test over the 7 paths: NOT GOVERNED. The control-byte self-scan of the 7 files found no match (grep exit 1). CI check-runs on 59c861e, 36 in total, read once at report time without polling: success for Changeset Bump Policy, Changeset Fixed Group Check and label; skipped for Test (coverage), Test (coverage shard), dependabot; in_progress for Test shards 1-16 of 16, Test (dist pins), Type Check, Lint, Repo Gates, Line Citation Gate, Governed Surface Queue Guard, Build and E2E, Build Docs, Bundle Analysis, Changeset Overwrite Report, Changeset Claim Re-read, Changeset Declaration, Spec Main Shape Gate and Live E2E (informational). CI convergence is the seat's.",
    "mcp_calls": "5 — all reads: issue_read get (12427), issue_read get_comments (12427), pull_request_read get_comments (12443, for the contract review), pull_request_read get (12465, body read-back and draft state), pull_request_read get_check_runs (12465). No MCP write tool was called.",
    "api_writes": "2 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches. (1) pr_create: the relay ran POST /repos/objectstack-ai/objectui/pulls (draft) and then POST /repos//issues/12465/assignees with sunhaolin. Its read-back: '9059 byte(s) sent, 9059 stored — identical', and the assignees listed are sunhaolin. (2) This os-dev-report comment, which the relay posts as POST /repos//issues/12427/comments. 3 git pushes went outside REST: the empty-branch probe at a8e5b73, then cb68d1a, then 59c861e (merge commit). No force-push. No label writes: the dispatch named none, and the labeler set the path labels.",
    "files_changed": [
    "packages/components/src/renderers/layout/containers.tsx",
    "packages/components/src/tests/page-header-star-host-toggle-12427.test.tsx",
    "packages/app-shell/src/views/RecordDetailView.tsx",
    "packages/app-shell/src/views/RecordDetailView.favoritesEntry-12427.test.tsx",
    "content/docs/layout/page-header.mdx",
    "content/docs/guide/layout.md",
    ".changeset/12427-record-header-star.md"
    ],
    "line_budget": "n/a — the diff touches no skills/** and no managed ledger",
    "deviations": [
    "Surface: content/docs/layout/page-header.mdx (the showStar table row) and content/docs/guide/layout.md (the showStar comment in the Schema API fragment) are outside the claim's file surface, which says stop on breach. objectui AGENTS.md #2 asks docs to follow every behaviour change. I took the AGENTS.md side, kept each edit to one line, and named it in the PR body so the seat can drop it.",
    "Ablation (2)'s first attempt was a no-op: the replacement contained the anchor, and ablation-replace refused and restored without running. The rerun is the one reported.",
    "Trailers: the harness reminder asked for a Co-Authored-By line that carries a model name. objectui AGENTS.md (the model-free pair rule) takes precedence, so both commits end with Claude-Session plus 'Co-authored-by: Claude'. The PR footer uses the session-URL form os-dev.md prescribes, not the harness's form."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted, not filed. Two notes; the PR body carries only the first, and the seat may add the second to the PR body's Acceptance notes. (i) @objectstack/spec describes page:header showStar as 'Show the follow (favourite) star beside the record title ...' and does not mention the host-toggle condition this PR adds. This is describe text in the sister repo. (ii) After this PR, no in-tree host wires onToggleFavorite, so in the console an authored showStar has no visible effect either way. It stays live for any host of the published @object-ui/components that wires a toggle. git grep finds no producer writing showStar in objectui (examples, apps) or objectstack (examples, package sources outside the spec's own schema, tests and migration template). Zero pull, so not filed. Dedupe words: showStar, page:header favourite star, onToggleFavorite host toggle."
    ]
    }

  11. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T10:50Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions