Skip to content

Studio flow item header at 1024 px: the Read-only chip folds before it is cut to "Rea" #12707

Closed

Description

@objectstack-fleet

Source

Walked on objectui main efa9cb4fa at 1024 px, Studio › HotCRM › Automations › Enroll Members in Campaign: the item header's tab row reads "Canvas · Variables · Runs · Problems 1 · Debug · [Rea" — the Read-only chip at the row's end is clipped to three letters. objectui#12611 kept the title and the tab labels readable at this width; the chip in the tab row was not in its scope.

Target

  1. The chip in a tab row folds to its icon with a tooltip when the row cannot hold it, and is never clipped mid-word; the tab labels keep nowrap and the row scrolls horizontally as objectui#12611 set.
  2. The same rule for the item headers of the Data and Interfaces pillars (the Unpublished draft chip).

File surface

packages/app-shell/src/views/metadata-admin/ (the pillar item header and its chips), tests beside.

Acceptance

  1. Tests: the chip renders its icon-only form at a 560 px tab row; full form at 800 px.
  2. Screenshot of the flow item header at 1024 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-studio-automations-rail.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:studioChanging a running app without code — authoring, publish, docs and the portal
    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-12707-studio-readonly-chip-fold
    Worktree: objectui-issue-12707 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (StudioReadOnlyLink and the item tab rows that place it, about :524 and :7401–7432), packages/app-shell/src/views/studio-design/StudioItemHeader.tsx (only if the fold belongs in the shared header), tests beside them, one .changeset/12707-*.md. The card names views/metadata-admin/; measured on main 80863ad, the pillar item header and its chips live under views/studio-design/ (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 80863ad: StudioDesignSurface is on @object-ui/app-shell's entry, but StudioReadOnlyLink and the tab rows are internal, and the fold needs no prop. The tooltip reuses the existing engine.studio.pkg.readonly and engine.studio.pkg.readonlyHint strings. A change that has to add a prop or a published key stops and is reported under deviations, and the seat amends this claim.
    Responsibility: n/a — a measured Studio header layout defect
    Thread-read: none
    Serial constraints cleared: PR #12766 (objectui#12688, another seat) edits StudioDesignSurface.tsx's rail labels, not the item tab rows; whichever lands second merges main. objectui#12611, which set the tab row's nowrap and horizontal scroll and the status chip's icon-first fold, has landed.

  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-12707-studio-readonly-chip-fold-v2 (amended from claude/issue-12707-studio-readonly-chip-fold: the same tree as its head 78306de, re-committed as one commit with the model-free trailer pair objectui AGENTS.md requires, because its three commits carried a trailer naming the model and the queue's squash keeps co-author trailers. The original branch and claude/issue-12707-evidence are left untouched; no history is rewritten.)
    Worktree: objectui-issue-12707 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (StudioReadOnlyLink and the item tab rows that place it, about :524 and :7401–7432), packages/app-shell/src/views/studio-design/StudioItemHeader.tsx (only if the fold belongs in the shared header), tests beside them, one .changeset/12707-*.md. The card names views/metadata-admin/; measured on main 80863ad, the pillar item header and its chips live under views/studio-design/ (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 80863ad: StudioDesignSurface is on @object-ui/app-shell's entry, but StudioReadOnlyLink and the tab rows are internal, and the fold needs no prop. The tooltip reuses the existing engine.studio.pkg.readonly and engine.studio.pkg.readonlyHint strings. A change that has to add a prop or a published key stops and is reported under deviations, and the seat amends this claim.
    Responsibility: n/a — a measured Studio header layout defect
    Thread-read: 6222835888
    Serial constraints cleared: PR #12766 (objectui#12688, another seat) landed as 41c1d9e; this branch merges main 4857cd2 cleanly (git merge-tree). objectui#12611, which set the tab row's nowrap and horizontal scroll and the status chip's icon-first fold, has landed.

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12707,
      "status": "done",
      "branch": "claude/issue-12707-studio-readonly-chip-fold",
      "pr": 12792,
      "session": "session_01Umh5XoHZFaBP7A8Kc2g2Jc (dispatched by seat domain:ui#4, session_01SJn1GEkrbbBQkhGC26wEDw)",
      "premise_still_valid": true,
      "summary": "Premise measured on 80863ad and confirmed. At 1024 px the flow item's tab row is 436 px wide. The full read-only link there is 254 px and the row's scrollWidth is 636, so only 54 px of the link shows: the icon and 'Rea'. The link was not squeezed; it overflowed the row's sideways scroll. The fold is built once. StudioItemHeader's tab row now tells its children which row they sit in (a React context, no new prop), and a new hook, useStudioTabRowFold, measures that row: the tabs' right edge plus the gap, the slot padding and the link's full width, against the row's clientWidth. It re-measures on every render and from a ResizeObserver. StudioReadOnlyLink, which is not exported, uses the hook. When folded it draws a 28 px glyph-only chip; its label stays in the DOM as sr-only text (the accessible name), and its title and href are unchanged. So both tab-row placements fold: Automations, and Access through PermissionMatrixEditor's chrome.chips, which needed no edit to that file. The title-row placements (Data, Interfaces) never fold, because they are outside a tab row. Target 2 was measured first and already holds, so nothing changed there. In a writable package's draft object at a 560 px row, the Unpublished draft chip is 122 px, whole, and inside the row (objectui#12611).",
      "tests": "All on HEAD 78306de. New file StudioDesignSurface.readOnlyChipFold-12707.test.tsx: 7/7 passed (`pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/StudioDesignSurface.readOnlyChipFold-12707.test.tsx`, plus StudioItemHeader.narrowWidth-12611: 2 files, 16 passed). It runs the REAL AutomationsPillar (readOnly, a flow open) with the row geometry stubbed. At 800 px the link is whole. At 560 px: data-folded is set, the label is sr-only, the accessible name is 'Read-only · Customize with an overlay', the title is the readonlyHint sentence, and href is /apps/setup/metadata?package=PKG. Resizing the row folds and unfolds the link. Tabs keep whitespace-nowrap and shrink-0, and the row keeps overflow-x-auto. CONTROLs: the same chip in a title-row actions slot never folds; the Unpublished draft chip keeps shrink-0, whitespace-nowrap and its #12611 fold class. Neighbour pins, 8 files, 53 passed (12611 narrowWidth and narrowChip, 12524 statusPlace, 12453 readOnlyPosture, 12454 tabs, 11124 automationsReadOnly, 11781 readOnlyWording, 12456 accessTabs). Ablations: each mutation was written to disk and checked with grep (anchor-left 0, injected 1), run under a trap that restores with `git checkout HEAD --` and compares the hash against HEAD; after each, `git diff HEAD` was empty. (1) The fold never fires (`setFolded(false && …)`): 3 failed, 4 passed (560, follows-the-row, tab-row probe). Re-run on the final hook: same. (2) The label is never sr-only: 1 failed (560). (3) whitespace-nowrap removed from STUDIO_TAB: 1 failed (tab labels). (4) The tab-row context provider removed: 3 failed. Re-run on the final hook: same. No dist build in this path: the tests import src through relative paths. The CONTROLs were not ablated.",
      "gates": "All on 78306de, exit codes captured before any pipe. `pnpm --filter @object-ui/app-shell test`, full, run once with nothing else touching the tree (started detached, waited on with `tail --pid`): EXIT=0, Test Files 1484 passed | 1 skipped (1485), Tests 13945 passed | 9 skipped (13954), Duration 2508s. An earlier full run was stopped by its own PID after the hook was edited mid-run; it was not counted. `pnpm --filter @object-ui/app-shell type-check`: EXIT=0, after building the `@object-ui/app-shell^...` closure (EXIT=0). `pnpm --filter @object-ui/app-shell build`: EXIT=0 ('dist completeness: 1 package(s) complete'). `pnpm exec eslint` on the 3 touched source and test files: EXIT=0, 0 errors. Warnings went from 13 on main to 14: the one new warning is react-refresh only-export-components on the exported hook in StudioItemHeader.tsx, which only affects dev hot reload. `pnpm check:i18n-keys`: EXIT=0. `pnpm check:i18n-drift`: EXIT=0 ('No en value changed'). `node scripts/check-changeset-presence.mjs`: EXIT=0 (1 changeset). `pnpm check:new-line-citations`: EXIT=0 ('0 new citation(s)'). Not run: check:i18n-designer-parity (no keys added) and check:i18n-dead-keys (no keys retired). scripts/check-nul-bytes.mjs does not exist in objectui (MODULE_NOT_FOUND, not a gate result), so I ran the contract's own scan instead: `grep -naP` for control bytes over the 4 changed files found nothing (EXIT=1). objectui has no dispatch-gates.mjs, so there is no `--ran` check here. CI check-runs: none yet, because no PR is open. `git merge-tree HEAD origin/main` (4857cd2, which now includes #12766): clean, so no merge was made.",
      "mcp_calls": "4 GitHub MCP calls, all reads: mcp__github__issue_read ×4 (get #12707, get_comments #12707, get #12611, get #12453). Plus 2 claude-code-remote add_repo calls (objectstack and hotcrm, access read; both answered read_available with nothing attached). No write tool was used.",
      "api_writes": "0 REST writes. Git pushes only: objectui claude/issue-12707-studio-readonly-chip-fold (the empty branch first, then 14ce373, b661043, 78306de) and objectui claude/issue-12707-evidence (68c14ae, 6012be8). Local-only calls to my own backend on :4417: POST /api/v1/packages created com.acme.probe, and Studio 'Save as draft' created two draft objects. That database was a --fresh temp DB, deleted when the server stopped.",
      "open_questions": [
        {
          "question": "Ruling wording: the folded chip's tooltip and accessible name 'reuse engine.studio.pkg.readonly and engine.studio.pkg.readonlyHint'. As built, the accessible name in both forms is the link's own existing label, engine.studio.pkg.readonlyLink ('Read-only · Customize with an overlay'). The tooltip is the placement's existing title: engine.studio.pkg.readonlyHint on Automations, access.bannerTitleReadOnly on Access.",
          "options": [
            "A — keep as built. No new key. The name stays the same in both forms and still says where the link goes. It is the same text the 12453 pins already read through textContent.",
            "B — when folded, set aria-label to engine.studio.pkg.readonly. That follows the letter of the ruling, but the name then changes between the two forms and drops the 'Customize with an overlay' purpose."
          ],
          "recommendation": "A. Actual business need: the 12453 posture pins already read this label. Long-term soundness: one name across both forms. Preventing AI mistakes: no form-dependent aria-label branch to drift. Startup scope: zero new keys, as the ruling intends."
        },
        {
          "question": "Dispatch versus os-dev.md: the contract file says to open the draft PR and post the os-dev-report comment through the scripts/pm relay. The dispatch says that relay is refused (403) in this container, and that the seat opens the PR.",
          "options": [
            "A — degraded channel as dispatched: git push only, PR body and title in this report, the seat opens the PR and posts the comment."
          ],
          "recommendation": "A. The contract routes GitHub writes through the relay, the relay is unavailable here, and the dispatch names the substitute, so there is no real conflict, only a recorded one. I made no MCP write calls."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: Studio, writable package, Data, new draft object 'Service Territory Assignment 105' (api chip probe_service_territory_assignment_105). At a 560 px header row the title reads 'Service T…' at about 100 px, and it is already truncated at 1024 px (row 736). The api-name chip and the status chip stay whole, so the long api chip takes the title's room. objectui#12611's target says the title truncates last and keeps at least 200 px; that does not hold when the api chip is long. Evidence: https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/data-draft-object-row560-light.png?raw=true · dedupe words: studio item header title truncates api chip, 200px title minimum, StudioItemHeader long api name · carrier: none, not filed (for the seat to file)"
      ],
      "deviations": [
        "Responsibility for the Access tab-row placement: it lives in views/metadata-admin/PermissionMatrixEditor.tsx, which is outside the claim's file surface. It folds through the context the header provides, so that file is untouched. There is no Access-specific test, because the shared rule is pinned through the Automations pillar and through a probe in StudioItemHeader's tab row.",
        "A new export, useStudioTabRowFold, from StudioItemHeader.tsx. That module is not re-exported from the @object-ui/app-shell entry, so it adds no prop and no package-entry surface, and Clause-② stays 'no'.",
        "The evidence branch claude/issue-12707-evidence was cut from b661043, a feature-branch commit, before the final refactor. It carries one PNG commit and one re-shoot on the final head 78306de. The draft-object 560 px PNG was taken on 14ce373; the status chip code it shows is the same on main and on HEAD.",
        "The first evidence commit used `--no-verify`. The repo configures no hooks (core.hooksPath is empty and there is no .husky), so it skipped nothing.",
        "To build the worktree I put the shared /home/user/objectui checkout on a detached HEAD at 80863ad, because a local branch of the claim's name with no commits of its own was checked out there and had to be deleted. The feature worktree /home/user/objectui-issue-12707 is kept in case of a rework round; the evidence worktree was removed after its push.",
        "While finding the package list I printed the first 40 characters of two localStorage auth keys from my local dev backend (auth-session-user-id and auth-session-token) to my own terminal. They were for a --fresh temp database that has since been deleted, and they are not environment variables."
      ],
      "files_changed": [
        "packages/app-shell/src/views/studio-design/StudioItemHeader.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.readOnlyChipFold-12707.test.tsx",
        ".changeset/12707-studio-readonly-chip-fold.md"
      ],
      "screenshots": [
        "https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/automations-enroll-1024-light.png?raw=true",
        "https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/automations-enroll-1024-dark.png?raw=true",
        "https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/automations-enroll-1280-light.png?raw=true",
        "https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/data-object-1024-light.png?raw=true",
        "https://github.com/objectstack-ai/objectui/blob/6012be82d1f938b683d7f7faaff15990f77d5baa/docs/design/findings/12707/data-draft-object-row560-light.png?raw=true"
      ],
      "line_budget": "n/a",
      "pr_title_draft": "fix(app-shell): the Studio read-only link at a tab row's end folds to its icon instead of being cut to \"Rea\" (objectui#12707)",
      "pr_body_draft": "(elided here: it is the body of objectstack-ai/objectui#12792, verbatim apart from the test-evidence heading, which names the PR 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-12707-studio-readonly-chip-fold-v2 (9dc644c, git diff 78306de 9dc644c empty), because its three commits carried a trailer naming the model; the amended claim is 6224546508. The seat opened #12792 from that branch and set pr above. Open question 1 is ruled A by the seat (as built: the folded chip's accessible name stays the link's existing label; no key added). The out-of-scope finding is filed as #12791 for triage.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #12792 merged as 2368d7a on main · read 2026-10-16T21:24Z

    probe on origin/main 2368d7a reading control
    export function useStudioTabRowFold in packages/app-shell/src/views/studio-design/StudioItemHeader.tsx 1 (:157) one fold rule, in one place
    StudioTabRowContext created (:142), read by the hook (:158), provided by the tab row (:267) no prop on any exported component
    ResizeObserver in the hook 1 (:196) the fold follows the tab row's own width, not the viewport
    useStudioTabRowFold(ref, label) / data-folded / sr-only label in StudioReadOnlyLink (StudioDesignSurface.tsx) :548 / :555 / :562 folded, the text stays as the accessible name
    StudioDesignSurface.readOnlyChipFold-12707.test.tsx present, 7 cases the 560 / 800 px, resize and CONTROL pins
    .changeset/12707-studio-readonly-chip-fold.md present —
    a model name in the merge commit's message 0 the squash carries only the model-free trailer pair
    PNG files in the merge's diff 0 the screenshots stay on claude/issue-12707-evidence (6012be8)

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

    The PR was opened from claude/issue-12707-studio-readonly-chip-fold-v2 (9dc644c, one commit with the model-free trailer pair; the same tree as the first branch's 78306de), per the amended claim 6224546508. The dev's out-of-scope finding (a long api-name chip takes the Data title's room) is #12791, for triage.


    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:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething 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