You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Studio shell header: the pillar segmented control and Changes overlap below 640 px #12509
Measured on objectui main d4bc81eab (after #12459 and #12452) in a 558 × 326 viewport: the shell header draws its three groups on one 48 px row; the segmented control's fourth segment (Access) sits under the Changes button and the Publish button is clipped at the right edge. The "Studio is built for a desktop screen" note (engine.studio.desktopHint) shows below the header, but the header itself is still broken. The header grid is grid-cols-[1fr_auto_1fr] from studio-tokens.ts; below xl the segments are icon-only already, which is not enough below sm.
Target
Below the sm breakpoint (640 px) the header stacks: row one is home, app chip, Changes, Publish; row two is the segmented control at full width with icon-only segments. Nothing overlaps from 360 px to 640 px.
From sm to xl the single row stays with icon-only segments, as today; xl and above shows labels.
The mobile note stays as it is.
File surface
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (shell header), studio-tokens.ts (STUDIO_HEADER), a test beside them.
Acceptance
Screenshots at 375 px and 560 px, light and dark: no overlap, Publish fully visible.
A test asserts the header's stacked classes below sm (the token string) and the single-row classes above.
StudioDesignSurface.*.test.tsx green.
Constraints
Tailwind utilities only.
The More overflow does not return; objectui#12452's ruling stands.
Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-15 Studio test pass: objectui main d4bc81eab, HotCRM 63db83e2, the vite console on :5180 against objectstack serve --dev on :4001, viewport 1482 × 1119, dark theme with a light-theme check.
Evidence
Screenshots from the test pass, kept on the temporary branch claude/studio-test-pass-evidence-20261015 of objectstack-ai/objectui (commit 72115588c, never merged: the maintainer ruled that screenshots do not enter main, and asked for a temporary branch referenced from the card). The branch's docs/design/studio-redesign/findings/2026-10-15/README.md maps every file to its card. Pane captures, 800 × 604 of a 1482 × 1119 viewport, dark unless named light.
Body refreshed 2026-10-15T15:21Z by the epic PM session: the Evidence section, first added at 2026-10-15T14:42Z, now names the temporary branch the screenshots live on instead of a pull request to main.
Claim: PM loop round 1 (domain:ui lane queue)
Session: session_01SJn1GEkrbbBQkhGC26wEDw
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-12509-studio-header-narrow
Worktree: objectui-issue-12509 (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 (region: the shell header only — home, app chip, PILLARS segmented control, Changes, Publish), packages/app-shell/src/views/studio-design/studio-tokens.ts (STUDIO_HEADER), new tests beside them, the screenshots under docs/design/studio-redesign/after/ named 12509-*.png, one .changeset/12509-*.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 5 on 「上限提到 5,提速」, this session's chat, 2026-10-15)
Clause-②: no
Responsibility: n/a — layout defect, no data path
Thread-read: none
Serial constraints cleared: in flight on StudioDesignSurface.tsx at claim time, all this seat: objectui#12455 (InterfacesPillar), objectui#12488 (the AutomationsPillar inspector mount), objectui#12511 (the DataPillar header, claimed alongside). All are disjoint from the shell header. objectui#12452's ruling (no More overflow) stands, as the card says. objectui#12453 (the app chip's read-only posture) follows this card in the header region. No open PR touches studio-tokens.ts.
os-dev-report
{
"issue": 12509,
"status": "done",
"branch": "claude/issue-12509-studio-header-narrow",
"pr": null,
"session": "session_01KQyLt9mekyay9X1dPEawfd (dispatched by PM seat domain:ui#4, session_01SJn1GEkrbbBQkhGC26wEDw)",
"premise_still_valid": true,
"summary": "Premise re-checked on origin/main b512428, live in the console against HotCRM 63db83e: at 375 and 558 px the switcher overlapped Changes (558: nav right edge 353 vs Changes left edge 328) and the Create app icon sat under Access. The single row ALSO overlapped at exactly 640 px (Create app left edge 370 vs nav right edge 394), because the 1fr right column is narrower than Create app + Changes + Publish (about 258 px) until about 710 px. So the card's 'single row from sm up, as today' was not overlap-free on its own. Fix: below sm, STUDIO_HEADER is a two-column auto-height grid. Row one holds home, the chip, Create app, Changes and Publish. Row two is the switcher (new token STUDIO_HEADER_PILLAR_NAV: order-last col-span-2), whose segments (new token STUDIO_HEADER_PILLAR) each take an equal share and stay icon-only, with names kept as accessible names. From sm up: h-12, three columns minmax(0,1fr) auto minmax(max-content,1fr). The right column never drops below its content, so a tight row moves the switcher left and the chip truncates; the chip trigger got min-w-0 so it can shrink. 1280 px is unchanged (every probed coordinate identical before and after). Tailwind only, no JS width read, no inline style, no More overflow, testids, i18n keys and desktopHint untouched.",
"tests": "On final head 744b899, from the repo root: pnpm exec vitest run --maxWorkers=2 on narrowHeader-12509, desktopHint-11795, accessSegment-12452, pillarNavGuard, packageLessFlows-11553, interfacePolish -> 'Test Files 6 passed (6) / Tests 38 passed (38)', exit 0. All 78 StudioDesignSurface..test.tsx files (the new file included) in three batches on the same code (the commits after it add only PNGs and the changeset): 27 files/129 tests, 26/170, 25/227, all passed, each exit 0. Ablation, once per mutation, both through objectstack scripts/ablation-replace.mjs with an EXIT/INT/TERM trap restoring from HEAD; imports resolve from source, so no build leg. (a) STUDIO_HEADER restored to the old one-row string: anchor x1 -> x0, blob f85c85c3 -> 89157cb4; the 2 token pins went red ('expected [grid, h-12, ...]' and 'expected [] to deeply equal ArrayContaining'), the render pin stayed green; restored blob == HEAD f85c85c3, git diff HEAD empty. (b) The nav back to its old inline class: blob fbe82cc5 -> 40568e9a; the render pin went red ('toHaveClass(order-last col-span-2 ...)'), 2 green; restored blob == HEAD, git diff HEAD empty. Live measurement (Playwright, /opt/pw-browsers/chromium, header rects): 360/375/558/639 -> header 91 px tall, nav full width on row two, no rect overlap; 640/700/768/1024 -> 48 px, nav right edge left of the Create app left edge (640: 354 vs 366); 1280 -> identical to before.",
"gates": "Each exit captured by redirect-then-$? before any pipe, on 744b899 unless noted. pnpm check:i18n-keys 0; pnpm check:i18n-drift 0 ('No designer-table en value changed in this range'); node scripts/check-changeset-presence.mjs 0 ('declares 1 changeset(s): .changeset/12509-studio-header-narrow.md'); node scripts/check-changeset-no-major.mjs 0; pnpm check:changeset-claims 0; pnpm check:new-line-citations 0 ('0 new citation(s)'); pnpm check:test-path-roots 0; pnpm check:pending-changeset-literals 0. i18n not touched, so check:i18n-designer-parity and check:i18n-dead-keys were not owed. No new Intl. call, so the machine-locale census reads nothing new. Closure build: pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 -> 28/28 successful, exit 0 (on b0cf28c, same source). pnpm --filter @object-ui/app-shell run type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json') exit 0; tsc --listFilesOnly shows the new test file in tsconfig.test.json. pnpm --filter @object-ui/app-shell run build exit 0 ('dist completeness: 1 package(s) complete'). eslint on the 3 touched source/test files: exit 0, 0 errors; 14 warnings, all in StudioDesignSurface.tsx lines outside the changed hunks. objectui has no dispatch-gates derivation; this list is hand-derived. No PR exists, so no check-runs to cite; CI convergence is the PM's after opening.",
"deviations": [
"Write channel: os-dev.md asks for the report as an issue comment and for pr_create; the dispatch order's degraded channel forbids both (the fleet-write relay returns 403 from here). I followed the order: git push only, PR body as pr_body_draft. Flagged as a conflict between the file and the order.",
"objectui has no scripts/pm/os-verify-lock.sh; builds and tests ran directly. I was the only dev in this container.",
"Mechanism assumption 1 holds only in part: the token plus the group wrappers carry the stacking with no JS, but it needed two new tokens (STUDIO_HEADER_PILLAR_NAV, STUDIO_HEADER_PILLAR, same file) and min-w-0 on the package chip trigger (inside PackageSwitcher, i.e. the 'app chip' of the claimed region); without it the chip ran under Create app at 375 px.",
"Card target 2 ('sm to xl single row as today') was not overlap-free at 640 to about 710 px (measured). The right column became minmax(max-content,1fr): above about 710 px it is still 1fr, so the switcher stays centred and 1280 px is unchanged.",
"Deleted the stale overflow-x-auto comment above the header (objectui#12452's out-of-scope note); it sits in this card's region.",
"Commit trailers are the AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named line.",
"Screenshot backend: hotcrm 63db83e, objectstack dev --fresh on :4519, console on :5519. HotCRM is read-only, so a local writable package 'Studio Test' (com.default.studio-test) was created through Studio's New package dialog, plus one draft object (Ticket), so the header shows Create app and a Changes count. Both servers were stopped by PID; the --fresh database was removed on exit; the worktree was removed after push (git status clean)."
],
"files_changed": [
".changeset/12509-studio-header-narrow.md",
"docs/design/studio-redesign/after/12509-header-1280-light.png",
"docs/design/studio-redesign/after/12509-header-375-dark.png",
"docs/design/studio-redesign/after/12509-header-375-light.png",
"docs/design/studio-redesign/after/12509-header-560-dark.png",
"docs/design/studio-redesign/after/12509-header-560-light.png",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.narrowHeader-12509.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/studio-tokens.ts"
],
"line_budget": "n/a: no skills/** surface",
"mcp_calls": "5, all reads or session plumbing: claude-code-remote add_repo x2 (objectstack, hotcrm, access read; both answered read_available, nothing attached); github issue_read x3 (12509 get, 12509 get_comments, 12452 get_comments). No write tool.",
"api_writes": "0 REST writes. git push x4 to objectui branch claude/issue-12509-studio-header-narrow (empty branch, then 02e293d, b0cf28c, 744b899). Zero label writes, no PR, no comment.",
"open_questions": [
{
"question": "The card asks for the single row from sm (640 px) 'as today', but measured, today's single row overlaps from 640 to about 710 px. How should 640 to 710 px be fixed?",
"options": [
"A: keep sm as the stack breakpoint; the right column becomes minmax(max-content,1fr), so the switcher moves left and the chip truncates on a tight row (implemented)",
"B: stack below md (768 px) instead of sm",
"C: hide the Changes label between sm and md"
],
"recommendation": "A. Real need: it fixes the overlap actually measured at 640 px, with 1280 px unchanged. Long-term fit: one class-only token, no JS width read, consistent with the epic's token skeleton. AI-error axis: the test pins both halves of the token, so a later edit back to 1fr on the right goes red (ablation a). Startup focus: no new capability or gate; B changes the card's stated breakpoint, and C changes the Changes button's look, which nobody asked for."
}
],
"out_of_scope_findings": [
"class: a (visible UX defect) · reach: public door, Studio Data pillar at 375 px, measured live (docs/design/studio-redesign/after/12509-header-375-light.png): the item header drops the object title 'Ticket' to zero width beside the api chip and 'Unpublished draft' badge · region: DataPillar item header, not this card's · carrier candidate: objectui#12511 (DataPillar header, same seat) if its scope covers the narrow width; otherwise it needs a card · dedupe words: Studio item header narrow, object title hidden 375, DataPillar header truncation",
"NOT MEASURED: the pending-app pill (engine.studio.app.pending) on a narrow screen. The live package showed the Create app button instead. Under minmax(max-content,1fr) a long pill widens the right column. carrier: none · noted, not filed"
],
"pr_title_draft": "fix(app-shell): the Studio header stacks below 640 px instead of overlapping (objectui#12509)",
"pr_body_draft": "(elided by the seat: opened verbatim as the body of PR #12549, read back identical)"
}
Relayed verbatim by seat domain:ui#4 (session session_01SJn1GEkrbbBQkhGC26wEDw) from the cloud session's final message, the degraded write channel. The seat opened the draft PR #12549 from pr_title_draft and pr_body_draft, with assignee os-sales. "pr": null above is the session's own value at report time.
Activity
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1 (domain:ui lane queue)
Session:
session_01SJn1GEkrbbBQkhGC26wEDwAccount:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12509-studio-header-narrowWorktree:
objectui-issue-12509(in the cloud session's own container)Domain:
domain:uiSeat:
domain:ui#4File surface:
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx(region: the shell header only — home, app chip,PILLARSsegmented control, Changes, Publish),packages/app-shell/src/views/studio-design/studio-tokens.ts(STUDIO_HEADER), new tests beside them, the screenshots underdocs/design/studio-redesign/after/named12509-*.png, one.changeset/12509-*.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 5 on 「上限提到 5,提速」, this session's chat, 2026-10-15)Clause-②: no
Responsibility:
n/a — layout defect, no data pathThread-read: none
Serial constraints cleared: in flight on
StudioDesignSurface.tsxat claim time, all this seat: objectui#12455 (InterfacesPillar), objectui#12488 (theAutomationsPillarinspector mount), objectui#12511 (theDataPillarheader, claimed alongside). All are disjoint from the shell header. objectui#12452's ruling (no More overflow) stands, as the card says. objectui#12453 (the app chip's read-only posture) follows this card in the header region. No open PR touchesstudio-tokens.ts.objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 12509,
"status": "done",
"branch": "claude/issue-12509-studio-header-narrow",
"pr": null,
"session": "session_01KQyLt9mekyay9X1dPEawfd (dispatched by PM seat domain:ui#4, session_01SJn1GEkrbbBQkhGC26wEDw)",
"premise_still_valid": true,
"summary": "Premise re-checked on origin/main b512428, live in the console against HotCRM 63db83e: at 375 and 558 px the switcher overlapped Changes (558: nav right edge 353 vs Changes left edge 328) and the Create app icon sat under Access. The single row ALSO overlapped at exactly 640 px (Create app left edge 370 vs nav right edge 394), because the 1fr right column is narrower than Create app + Changes + Publish (about 258 px) until about 710 px. So the card's 'single row from sm up, as today' was not overlap-free on its own. Fix: below sm, STUDIO_HEADER is a two-column auto-height grid. Row one holds home, the chip, Create app, Changes and Publish. Row two is the switcher (new token STUDIO_HEADER_PILLAR_NAV: order-last col-span-2), whose segments (new token STUDIO_HEADER_PILLAR) each take an equal share and stay icon-only, with names kept as accessible names. From sm up: h-12, three columns minmax(0,1fr) auto minmax(max-content,1fr). The right column never drops below its content, so a tight row moves the switcher left and the chip truncates; the chip trigger got min-w-0 so it can shrink. 1280 px is unchanged (every probed coordinate identical before and after). Tailwind only, no JS width read, no inline style, no More overflow, testids, i18n keys and desktopHint untouched.",
"tests": "On final head 744b899, from the repo root: pnpm exec vitest run --maxWorkers=2 on narrowHeader-12509, desktopHint-11795, accessSegment-12452, pillarNavGuard, packageLessFlows-11553, interfacePolish -> 'Test Files 6 passed (6) / Tests 38 passed (38)', exit 0. All 78 StudioDesignSurface..test.tsx files (the new file included) in three batches on the same code (the commits after it add only PNGs and the changeset): 27 files/129 tests, 26/170, 25/227, all passed, each exit 0. Ablation, once per mutation, both through objectstack scripts/ablation-replace.mjs with an EXIT/INT/TERM trap restoring from HEAD; imports resolve from source, so no build leg. (a) STUDIO_HEADER restored to the old one-row string: anchor x1 -> x0, blob f85c85c3 -> 89157cb4; the 2 token pins went red ('expected [grid, h-12, ...]' and 'expected [] to deeply equal ArrayContaining'), the render pin stayed green; restored blob == HEAD f85c85c3, git diff HEAD empty. (b) The nav back to its old inline class: blob fbe82cc5 -> 40568e9a; the render pin went red ('toHaveClass(order-last col-span-2 ...)'), 2 green; restored blob == HEAD, git diff HEAD empty. Live measurement (Playwright, /opt/pw-browsers/chromium, header rects): 360/375/558/639 -> header 91 px tall, nav full width on row two, no rect overlap; 640/700/768/1024 -> 48 px, nav right edge left of the Create app left edge (640: 354 vs 366); 1280 -> identical to before.",
"gates": "Each exit captured by redirect-then-$? before any pipe, on 744b899 unless noted. pnpm check:i18n-keys 0; pnpm check:i18n-drift 0 ('No designer-table en value changed in this range'); node scripts/check-changeset-presence.mjs 0 ('declares 1 changeset(s): .changeset/12509-studio-header-narrow.md'); node scripts/check-changeset-no-major.mjs 0; pnpm check:changeset-claims 0; pnpm check:new-line-citations 0 ('0 new citation(s)'); pnpm check:test-path-roots 0; pnpm check:pending-changeset-literals 0. i18n not touched, so check:i18n-designer-parity and check:i18n-dead-keys were not owed. No new Intl. call, so the machine-locale census reads nothing new. Closure build: pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 -> 28/28 successful, exit 0 (on b0cf28c, same source). pnpm --filter @object-ui/app-shell run type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json') exit 0; tsc --listFilesOnly shows the new test file in tsconfig.test.json. pnpm --filter @object-ui/app-shell run build exit 0 ('dist completeness: 1 package(s) complete'). eslint on the 3 touched source/test files: exit 0, 0 errors; 14 warnings, all in StudioDesignSurface.tsx lines outside the changed hunks. objectui has no dispatch-gates derivation; this list is hand-derived. No PR exists, so no check-runs to cite; CI convergence is the PM's after opening.",
"deviations": [
"Write channel: os-dev.md asks for the report as an issue comment and for pr_create; the dispatch order's degraded channel forbids both (the fleet-write relay returns 403 from here). I followed the order: git push only, PR body as pr_body_draft. Flagged as a conflict between the file and the order.",
"objectui has no scripts/pm/os-verify-lock.sh; builds and tests ran directly. I was the only dev in this container.",
"Mechanism assumption 1 holds only in part: the token plus the group wrappers carry the stacking with no JS, but it needed two new tokens (STUDIO_HEADER_PILLAR_NAV, STUDIO_HEADER_PILLAR, same file) and min-w-0 on the package chip trigger (inside PackageSwitcher, i.e. the 'app chip' of the claimed region); without it the chip ran under Create app at 375 px.",
"Card target 2 ('sm to xl single row as today') was not overlap-free at 640 to about 710 px (measured). The right column became minmax(max-content,1fr): above about 710 px it is still 1fr, so the switcher stays centred and 1280 px is unchanged.",
"Deleted the stale overflow-x-auto comment above the header (objectui#12452's out-of-scope note); it sits in this card's region.",
"Commit trailers are the AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named line.",
"Screenshot backend: hotcrm 63db83e, objectstack dev --fresh on :4519, console on :5519. HotCRM is read-only, so a local writable package 'Studio Test' (com.default.studio-test) was created through Studio's New package dialog, plus one draft object (Ticket), so the header shows Create app and a Changes count. Both servers were stopped by PID; the --fresh database was removed on exit; the worktree was removed after push (git status clean)."
],
"files_changed": [
".changeset/12509-studio-header-narrow.md",
"docs/design/studio-redesign/after/12509-header-1280-light.png",
"docs/design/studio-redesign/after/12509-header-375-dark.png",
"docs/design/studio-redesign/after/12509-header-375-light.png",
"docs/design/studio-redesign/after/12509-header-560-dark.png",
"docs/design/studio-redesign/after/12509-header-560-light.png",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.narrowHeader-12509.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/studio-tokens.ts"
],
"line_budget": "n/a: no skills/** surface",
"mcp_calls": "5, all reads or session plumbing: claude-code-remote add_repo x2 (objectstack, hotcrm, access read; both answered read_available, nothing attached); github issue_read x3 (12509 get, 12509 get_comments, 12452 get_comments). No write tool.",
"api_writes": "0 REST writes. git push x4 to objectui branch claude/issue-12509-studio-header-narrow (empty branch, then 02e293d, b0cf28c, 744b899). Zero label writes, no PR, no comment.",
"open_questions": [
{
"question": "The card asks for the single row from sm (640 px) 'as today', but measured, today's single row overlaps from 640 to about 710 px. How should 640 to 710 px be fixed?",
"options": [
"A: keep sm as the stack breakpoint; the right column becomes minmax(max-content,1fr), so the switcher moves left and the chip truncates on a tight row (implemented)",
"B: stack below md (768 px) instead of sm",
"C: hide the Changes label between sm and md"
],
"recommendation": "A. Real need: it fixes the overlap actually measured at 640 px, with 1280 px unchanged. Long-term fit: one class-only token, no JS width read, consistent with the epic's token skeleton. AI-error axis: the test pins both halves of the token, so a later edit back to 1fr on the right goes red (ablation a). Startup focus: no new capability or gate; B changes the card's stated breakpoint, and C changes the Changes button's look, which nobody asked for."
}
],
"out_of_scope_findings": [
"class: a (visible UX defect) · reach: public door, Studio Data pillar at 375 px, measured live (docs/design/studio-redesign/after/12509-header-375-light.png): the item header drops the object title 'Ticket' to zero width beside the api chip and 'Unpublished draft' badge · region: DataPillar item header, not this card's · carrier candidate: objectui#12511 (DataPillar header, same seat) if its scope covers the narrow width; otherwise it needs a card · dedupe words: Studio item header narrow, object title hidden 375, DataPillar header truncation",
"NOT MEASURED: the pending-app pill (engine.studio.app.pending) on a narrow screen. The live package showed the Create app button instead. Under minmax(max-content,1fr) a long pill widens the right column. carrier: none · noted, not filed"
],
"pr_title_draft": "fix(app-shell): the Studio header stacks below 640 px instead of overlapping (objectui#12509)",
"pr_body_draft": "(elided by the seat: opened verbatim as the body of PR #12549, read back identical)"
}
Relayed verbatim by seat
domain:ui#4(sessionsession_01SJn1GEkrbbBQkhGC26wEDw) from the cloud session's final message, the degraded write channel. The seat opened the draft PR #12549 frompr_title_draftandpr_body_draft, with assigneeos-sales."pr": nullabove is the session's own value at report time.Generated by Claude Code
fix(app-shell): the Studio header stacks below 640 px instead of over…