Skip to content

App bar: the Setup › System › Marketplace breadcrumb folds at 1024 px instead of cutting each segment to three letters #12702

Closed

Description

@objectstack-fleet

Source

Walked on objectui main efa9cb4fa at 1024 px, Setup › Browse Marketplace (/apps/setup/system/marketplace): the app bar reads "S… / PREVIEW / Sys… / Market…" — the Setup pill, the PREVIEW chip and two breadcrumb segments share the space left of the search box, and every segment is cut to two or three letters. The same route at 1280 px is readable; every other Setup page draws "Setup ▾ PREVIEW" because its route adds no breadcrumb segments.

Target

  1. The app-bar breadcrumb folds from the left: at a width where the segments do not fit, the middle segments collapse to one "…" menu that lists them, the app pill keeps its full label and the last segment keeps its full text; nothing is cut to under one word.
  2. The PREVIEW chip moves after the breadcrumb (or into the app menu) when the row is narrow.
  3. The console search box keeps its width down to 960 px; below that it becomes an icon.

File surface

packages/app-shell/src/layout/AppHeader.tsx (the breadcrumb and the pill row), tests beside.

Acceptance

  1. Tests: three segments at a 320 px breadcrumb width render pill + "…" + last segment with full text.
  2. Screenshots of the Marketplace route at 1024 and 1280 px.
  3. pnpm --filter @object-ui/app-shell test green.

Evidence

Screenshots on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit 0f4e3f4ee, never merged): r4-marketplace-skeleton-breadcrumb.jpg.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 fourth review: objectui main efa9cb4fa, HotCRM 4f82b815 on platform 18.0.0-next.2, the vite console on :5180 against objectstack dev on :4001, the maintainer's browser pane at 1024 × 768 (dark, en). The maintainer asked for every finding to be filed on the repository it belongs to, verbatim: 「全部立卡,平台问题到 objectui,审计日志核查到 objectstack,HotCRM 转化流程到 hotcrm。」

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    on Oct 16, 2026
  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (priority:p2; filed by the epic PM session from the 2026-10-16 fourth review, on the maintainer's 「全部立卡,平台问题到 objectui…」)
    Session: session_01SJn1GEkrbbBQkhGC26wEDw
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12702-app-bar-crumb-fold
    Worktree: objectui-issue-12702 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/app-shell/src/layout/AppHeader.tsx (the left group's crumbs and the Preview chip, and the search breakpoint), tests beside it under packages/app-shell/src/layout/__tests__/ (including the objectui#12472 and objectui#12461 pins where the card changes what they pin), one .changeset/12702-*.md (stop on breach; explain in the report)
    Container & model: M, mode:cloud, model: opus (cloud on the maintainer's stance 「可以的话,ui 后续开发尽量用云 session,并且要求截图给我看」; lane scope on 「你也可以接ui车道的卡」; batch 3 on 「当前任务处理完,后续并发降到3」, this session's chat, 2026-10-16)
    Clause-②: no
    Clause-② reason: measured on main e219a3d: AppHeader is on @object-ui/app-shell's entry, but the fold is internal markup and needs no prop. The overflow menu is named by the existing common.more key, so no @object-ui/i18n key (and no TranslationKeys widening) is added. A change that has to add a prop or a key stops and is reported under deviations, and the seat amends this claim.
    Responsibility: n/a — a measured app-bar layout defect
    Thread-read: none
    Serial constraints cleared: no open objectui PR touches AppHeader.tsx (read at dispatch: objectui#12740, #12747, #12749, #12750). objectui#12605, #12601 and #12625, the last cards on the app bar, are closed. This seat's objectui#12705 edits PageHeader.tsx (the page header, not the app bar) and objectui#12695 edits plugin-list.

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · amended (branch: the same tree re-committed without a model-named trailer) (priority:p2; filed by the epic PM session from the 2026-10-16 fourth review, on the maintainer's 「全部立卡,平台问题到 objectui…」)
    Session: session_01SJn1GEkrbbBQkhGC26wEDw
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12702-app-bar-crumb-fold-v2 (amended from claude/issue-12702-app-bar-crumb-fold: the same tree as its head 6204915, re-committed as one commit with the model-free trailer pair objectui AGENTS.md requires, because commit 7140ba8 carried a trailer naming the model and the queue's squash keeps co-author trailers. The original branch and claude/issue-12702-evidence are left untouched; no history is rewritten.)
    Worktree: objectui-issue-12702 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/app-shell/src/layout/AppHeader.tsx (the left group's crumbs and the Preview chip, and the search breakpoint), tests beside it under packages/app-shell/src/layout/__tests__/ (including the objectui#12472 and objectui#12461 pins where the card changes what they pin), one .changeset/12702-*.md (stop on breach; explain in the report)
    Container & model: M, mode:cloud, model: opus (cloud on the maintainer's stance 「可以的话,ui 后续开发尽量用云 session,并且要求截图给我看」; lane scope on 「你也可以接ui车道的卡」; batch 3 on 「当前任务处理完,后续并发降到3」, this session's chat, 2026-10-16)
    Clause-②: no
    Clause-② reason: measured on main e219a3d: AppHeader is on @object-ui/app-shell's entry, but the fold is internal markup and needs no prop. The overflow menu is named by the existing common.more key, so no @object-ui/i18n key (and no TranslationKeys widening) is added. A change that has to add a prop or a key stops and is reported under deviations, and the seat amends this claim.
    Responsibility: n/a — a measured app-bar layout defect
    Thread-read: 6221829301
    Serial constraints cleared: no open objectui PR touches AppHeader.tsx (read at dispatch: objectui#12740, #12747, #12749, #12750). objectui#12605, #12601 and #12625, the last cards on the app bar, are closed. This seat's objectui#12705 edits PageHeader.tsx (the page header, not the app bar) and objectui#12695 edits plugin-list.

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12702,
      "status": "done",
      "branch": "claude/issue-12702-app-bar-crumb-fold",
      "pr": 12776,
      "session": "session_017aFZFX9y1Rf6r4St2vTfrj — dispatched by seat domain:ui#4 (session_01SJn1GEkrbbBQkhGC26wEDw)",
      "premise_still_valid": true,
      "summary": "On current main, PM assumptions 1-4 all held. The crumbs, the PREVIEW chip and the lg-keyed search are where the card said, and no route draws more than two crumbs. The crumbs after the app pill now fold, measured from the left group's own width: a ResizeObserver on the group and its children, comparing natural widths that add back what any truncated descendant hides. Every crumb but the last goes into one menu whose trigger is named by common.more (aria-label and title) and whose items are plain text. The last crumb keeps its full text, and the PREVIEW chip moves after the crumbs. The fix lives in an internal AppBarCrumbTrail in AppHeader.tsx: no new prop, no i18n key, nothing new on the package entry. The centered search, its zone, the cluster sizing and the icon twin all switch at one min-[960px] breakpoint instead of lg. One finding changed the plan. At 1024 px on Setup › System › Marketplace the left group is 388 px wide, and the folded row with the chip needs 406. So I added a third layout, recorded under deviations: folded, with the chip not drawn. With it, nothing is cut at 1024, 1100, 1280, 960 or 940 px. The feature head is 6204915 (on base 2dbe5f5). Since then origin/main moved to 80863ad, which touches layout/ through objectui#12705 (PageHeader), but merge-tree reports no conflict, so I did not merge it.",
      "tests": "All at feature head 6204915. (1) Full package run, foreground, through os-verify-lock: `pnpm --filter @object-ui/app-shell test` gave VERDICT command-exit 0, `Test Files 1478 passed | 1 skipped (1479)`, `Tests 13918 passed | 9 skipped (13927)`, Duration 2486.83s on a shared box. (2) Targeted run over every AppHeader*.test.tsx plus HomeLayout.searchOpensPalette-12601: exit 0, `Test Files 22 passed (22)`, `Tests 191 passed (191)`. (3) The new file AppHeader.crumbFold-12702.test.tsx has 10 cases: three segments at a 320 px left group render pill + More + the last segment in full, and the menu lists the two folded segments as plain text with no links; folded at 400 px puts the chip after the last crumb; with room, every segment is in full, the chip sits beside the pill and there is no More; the fold follows resizes 900→400→320→400→900; a group with no width yet keeps every crumb; through the real AppHeader on /apps/crm/system/marketplace, 340 px gives More + Marketplace with the chip after and the menu lists System, 300 px gives More + Marketplace with no chip, and with room both crumbs show with the chip beside the pill; CONTROL: /apps/crm/lead draws no crumb and no More and keeps the chip beside the pill at 320 px; the search field, its zone, the icon and the icon group all switch at min-[960px] only. (4) objectui#12472 pins changed, every lg assertion moved to min-[960px]: 'the two side zones grow…' (cluster min-[960px]:flex-1 / justify-end / min-w-max, middle zone hidden + min-[960px]:flex); 'the trigger itself is unchanged' (hidden + min-[960px]:flex, w-48, xl:w-64); 'the cluster's search group … leaves at 960 px' (group min-[960px]:hidden and the two min-[960px]:[&>[data-topbar-search]+[data-topbar-group]] rules); CONTROL 'below 960 px the search is the icon button…' (icon min-[960px]:hidden); CONTROL 'a system/* route … centers the search' (cluster sizing and group min-[960px]:hidden); CONTROL 'the studio variant keeps the two-zone bar' (not.toContain min-[960px]:flex-1). Describe and it names that said `lg` now say 960 px. HomeLayout.searchOpensPalette-12601 'from 960 px up the field is the bar's middle zone…' pins the shared zone's min-[960px]:flex. (5) Ablations: 11 mutations of AppHeader.tsx, each through objectstack's scripts/ablation-replace.mjs (literal anchor that must hit, restore by HEAD blob). All went red; the failed-test count follows each name. A1 never fold: 5. A2 chip never drawn after the crumbs: 3. A3 chip in the wrong slot, CONTROL included: 8. A4 no third layout: 3. A5 menu lists nothing: 2. A6 trigger aria-label and title removed: 1. A7 field back on lg: 2. A8 icon back on lg: 2. A9 zone back on lg: 3. A10 cluster sizing back on lg: 2. A11 icon group back on lg: 3. Every restore printed 'blob == HEAD (44b45ca3acf3) and git diff HEAD is empty', and `git diff HEAD --stat` came back empty after each one. The tests import ../AppHeader from src, so no dist build was involved.",
      "gates": "Local, at 6204915. `pnpm --filter @object-ui/app-shell type-check`: exit 0 through the lock (VERDICT command-exit 0). It needed `turbo run build --filter=@object-ui/app-shell^... --concurrency=2` first (VERDICT 0); before that build it failed with missing @object-ui/fields types, which was not a code red. `pnpm --filter @object-ui/app-shell build`: exit 0, 'dist completeness: 1 package(s) complete (1130 emitted files verified)'. `eslint` on the 4 touched source and test files: exit 0, 0 errors. The 17 warnings on AppHeader.tsx match origin/main's copy of the file (17 there too), and the new test file has none. `pnpm check:i18n-keys` exit 0. `pnpm check:i18n-drift` exit 0 ('No en value changed in this range.'). `pnpm check:new-line-citations` exit 0. `node scripts/check-changeset-presence.mjs` exit 0 ('4 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'). Control-byte self-scan with `grep -naP` over AppHeader.tsx, the new test and the changeset: no hits (exit 1). `node scripts/check-nul-bytes.mjs`: MODULE_NOT_FOUND, because the script is not in objectui (it lives in objectstack). That is not a gate result. Not run: check:i18n-designer-parity and check:i18n-dead-keys, since no key was added or retired. CI families: NOT MEASURED, because no PR is open (the PM opens it), so no check-runs exist to cite.",
      "mcp_calls": "4 — mcp__claude-code-remote__add_repo ×2 (objectstack and hotcrm, access read; both answered read_available and attached nothing), mcp__github__issue_read ×2 (get and get_comments on #12702). No GitHub write tool.",
      "api_writes": "0 REST writes. git push only: claude/issue-12702-app-bar-crumb-fold (empty probe at 2dbe5f5, then 7140ba8, 01b04fc, 6204915) and claude/issue-12702-evidence (7c40ce3). No PR, no comment, no label, no assignee written.",
      "files_changed": [
        "packages/app-shell/src/layout/AppHeader.tsx",
        "packages/app-shell/src/layout/__tests__/AppHeader.crumbFold-12702.test.tsx (new)",
        "packages/app-shell/src/layout/__tests__/AppHeader.centeredSearch-12472.test.tsx",
        "packages/app-shell/src/console/home/__tests__/HomeLayout.searchOpensPalette-12601.test.tsx (outside the claimed surface; see deviations)",
        ".changeset/12702-app-bar-crumb-fold.md"
      ],
      "deviations": [
        "Third layout beyond the ruling: where even the folded row (pill + More + last crumb + chip) does not fit, the chip is not drawn. Measured at 1024 px on Setup › System › Marketplace: the left group is 388 px; the children at natural width are trigger 32, mark 32, rule 19, pill 98, More 45, Marketplace 111 and chip 69, so 406 with the chip. Without this layout the pill read 'Se…' and the last crumb 'Marketpl…' at 1024 and 960 px, which fails target 1 ('nothing is cut to under one word'). The chip is still drawn beside the pill when the crumbs fit (1280 px) and after the crumbs when the folded row has room (1100 px). It is not moved into the app menu, and AppSwitcher.tsx is untouched. The seat or the maintainer may prefer a different give (see open_questions).",
        "File surface: HomeLayout.searchOpensPalette-12601.test.tsx sits under console/home/__tests__/, outside the claim's layout/__tests__/. It pins the same shared middle-zone class (`hidden lg:flex`) that the ruling's 'move every rule … to one 960 px breakpoint' changes; the edit is two lines (the class and the it name). No other file is outside the claim.",
        "The new test exercises three segments by rendering the module-internal AppBarCrumbTrail (exported from AppHeader.tsx, not from the package entry, marked @internal) inside a left group of its own, because no route draws three crumbs on current main (system/* draws two, a report route one). That confirms PM assumption 4. The Marketplace route goes through the real AppHeader.",
        "The search breakpoint moved for every variant that draws the desktop trigger: the centered app/home zone and also the non-centered orgs/studio cluster trigger. Field and icon are one element pair with shared classes, so moving one without the other would let both show or both hide between 960 and 1024 px.",
        "Commit 7140ba8 ends with the harness reminder's `Co-Authored-By: Claude Opus 5.5` trailer. objectui AGENTS.md asks for the model-free pair, and that rule takes precedence. Later commits (01b04fc, 6204915, 7c40ce3) use the model-free pair. History is not rewritten, since force-push is banned and the squash merge keeps one message.",
        "Contract conflict, recorded per os-dev.md 'where the order and that file disagree, the file wins': os-dev.md has the dev open the draft PR and post the os-dev-report comment, while this dispatch forbids both because the fleet-write relay is refused here (403). I followed the dispatch: no PR, no comment, pr_body_draft below. The file cannot be honoured on this point without the refused write path.",
        "Setup note: the shared checkout /home/user/objectui held a zero-commit local branch claude/issue-12702-app-bar-crumb-fold checked out. I detached it to origin/main (2dbe5f5) and deleted that branch before creating the worktree, as the order instructs. The shared checkout is now on a detached HEAD."
      ],
      "screenshots": [
        "1024 light (folded, no chip; pill 'Setup', crumb 'Marketplace' not cut, More trigger named 'More', search field visible, icon hidden): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/1024-light.png?raw=true",
        "1024 light, More menu open (lists 'System'): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/1024-light-menu-open.png?raw=true",
        "1024 dark (same readings as 1024 light; html.dark true): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/1024-dark.png?raw=true",
        "1280 light (unfolded; pill 'Setup', chip beside the pill, crumbs 'System' and 'Marketplace' both in full, no More, field visible, icon hidden): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/1280-light.png?raw=true",
        "1100 light (extra shot: folded with the chip after the crumbs; pill 'Setup', More 'More', 'Marketplace', PREVIEW after it, field visible): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/1100-light.png?raw=true",
        "960 light (folded, no chip; pill 'Setup', More 'More', 'Marketplace' not cut; search FIELD visible, icon hidden): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/960-light.png?raw=true",
        "940 light (search is the ICON, field hidden; the left group is wider without the middle zone, so it is unfolded: pill 'Setup', chip beside it, 'System' and 'Marketplace' in full, no More): https://github.com/objectstack-ai/objectui/blob/7c40ce36b66c7dda3289ff55df0d83df2cffae8b/docs/design/findings/12702/940-light.png?raw=true"
      ],
      "line_budget": "n/a",
      "open_questions": [
        {
          "question": "At 1024 px the folded Marketplace row is 18 px short of the 388 px left group when the PREVIEW chip is drawn. What should give way?",
          "options": [
            "A (shipped) Drop the chip only in that layout. Cost: on this route at 960–~1090 px the stage chip is not shown; every other route and width is unchanged.",
            "B Keep the chip and let the pill and the last crumb truncate, as before (fails target 1, 'nothing cut to under one word').",
            "C Give the left zone more than half the bar (asymmetric centering). This reverses objectui#12472's centered-search design and is out of this claim.",
            "D Move the chip into the app menu. AppSwitcher.tsx is outside the claim and the ruling refused it."
          ],
          "recommendation": "A. Business need: the maintainer's finding is unreadable crumbs, and A is the only in-claim option that makes them readable at 1024 px (measured). Long-term soundness: it is one measured layout, not a viewport hack, and it adapts to any language's label widths. Hard to get wrong: no new prop or key, so nothing can declare a capability the runtime ignores. No scope spread: no new surface. It is a small extension of 'the chip moves after the crumbs', so the seat should confirm it."
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — on the HotCRM dev backend, /apps/setup/system/marketplace shows 'Failed to load marketplace' (visible in the menu-open screenshot), most likely because the container has no route to the catalog. Not this card's surface; nothing was reproduced outside this container."
      ],
      "pr_title_draft": "fix(app-shell): the app bar's crumbs fold into one menu instead of cutting every segment (objectui#12702)",
      "pr_body_draft": "(elided: it is the body of objectstack-ai/objectui#12776, opened from it verbatim by the seat, with one test-evidence heading noting the v2 head)"
    }

    Relayed by seat domain:ui#4 (session_01SJn1GEkrbbBQkhGC26wEDw) from the cloud session's final message (degraded channel: the session pushed and returned pr: null). At the seat's request the session then re-committed the same tree as one commit on claude/issue-12702-app-bar-crumb-fold-v2 (d1f6eb7, git diff 6204915 d1f6eb7 empty), because commit 7140ba8 carried a trailer naming the model; the amended claim is 6223509973. The seat opened #12776 from that branch and set pr above.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #12776 merged as 4857cd2 on main · read 2026-10-16T20:23Z

    probe on origin/main 4857cd2 reading control
    AppBarCrumbTrail in packages/app-shell/src/layout/AppHeader.tsx defined (:256), used once (:891) one fold, in one place
    ResizeObserver in the trail 1 (:234) the fold is measured from the left group's own width, not the viewport
    aria-label={moreLabel} / title={moreLabel} on the ⋯ trigger, fed by t('common.more') 1 each (:289–290, :893) no new i18n key
    max-w-[160px] on a crumb label 0 (was 1 at :726 on 0171c24) a crumb is no longer capped at 160 px
    hidden lg:flex / lg:hidden on the search and its icon twin 0 (were 3 on 0171c24: :595, :793, :834/:843) all four rules now key on min-[960px]: (:766, :956, :970, :997)
    AppHeader.crumbFold-12702.test.tsx present, 10 cases the fold, menu, chip and CONTROL pins
    .changeset/12702-app-bar-crumb-fold.md present —
    PNG files in the merge's diff 0 the screenshots stay on claude/issue-12702-evidence (7c40ce3)

    State change: the card closed as completed through Fixes #12702, and pm:dispatched is removed in this act. The cloud session session_017aFZFX9y1Rf6r4St2vTfrj is archived. No contract review is owed (Clause-②: no). The ACCEPT of record is 6223553080 (on the PR); the landing note is 6223740959.

    The PR was opened from claude/issue-12702-app-bar-crumb-fold-v2 (d1f6eb7, one commit with the model-free trailer pair; same tree as the first branch), per the amended claim 6223509973.


    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:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions