Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(desktop): give the chat surface one reading measure by Astro-Han · Pull Request #3997 · apache/maka · GitHub
Skip to content

fix(desktop): give the chat surface one reading measure - #3997

Merged
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure
Aug 27, 2026
Merged

fix(desktop): give the chat surface one reading measure#3997
Astro-Han merged 5 commits into
mainfrom
fix/desktop-transcript-prose-measure

Conversation

@Astro-Han

@Astro-HanAstro-Han commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

An assistant turn had two right edges. The turn column is --maka-transcript-measure (800px), and the tool cards, code blocks and the user bubble all reach it — but every paragraph stopped 120px short, leaving a band of whitespace down the right side of the transcript that is wider on a wider window.

The cause is two reading-measure authorities. Maka's column owns one, and Astryx's Markdown owns another: contentWidth defaults to 680px with contentAlign: 'start', while code and tables are left to fill the container. #3617 raised the column from 680 to 800 so source evidence could be read, which made the second authority visible for the first time.

MarkdownBody now passes contentWidth: 100%, which is a disclaimer rather than a width: Markdown holds no measure, and the container it lands in is the only one that does.

That rule only works if every container has one, and the two document callers did not. Astryx renders a supplied components.code bare — no spacing, no width, no alignment — and Maka always supplies one, so on the Daily Review report, which sits on an uncapped module page, prose stopped at 680 while the code blocks inside it ran the width of the window. That is the same two edges, one surface over, and it is live on main today. The report column holds the measure now — the column and not the prose inside it, since a section is a heading, a divider and its prose, and capping only the prose would have left the other two running past it. The Artifact Preview pane caps itself at 600px and so never showed this in the normal layout; it holds the measure for the stacked layout a narrow window switches to, where the workbar drops that cap.

The 680 is deliberately not mirrored into a Maka token. A token would make Astryx's default ours to keep in sync, which is the same two-authority defect wearing a token's name.

Three commits follow it, taking the same defect to its root.

One reading measure.--maka-reading-measure (680px) and --maka-transcript-measure (800px) split one column in two, so the answer was wider than the box you type into, and turn chrome (.maka-turn-footer, .maka-turn-lineage-row) stopped at 680 inside an 800px turn — three right edges down one conversation. --maka-reading-measure is now 800px and is the only measure; the transcript token is deleted and @maka/ui's fallback follows it, since that package does not load maka-tokens.css. .workhub-return had written the old 680 as a literal and reads the measure now, like the panels above it. 800px because the alternative undoes #3617: at 680 the code and tables it widened go back into a column too tight to read.

This widens surfaces beyond the transcript by 18%: the composer, header notices, the hero, plan mode, WorkHub, the agent graph, the Daily Review report and the Artifact Preview all move from 680 to 800. That is the point rather than a side effect — those are the surfaces whose edge was failing to line up with the answer above them — but it is the visible part of this PR and the reason for the second screenshot.

Tokens nothing reads. The audit behind the measure merge also found 21 custom properties with no var() consumer anywhere — not in renderer CSS, @maka/ui, stories, or Astryx, which reads some Maka properties through its own theme bridge and was checked separately. Two groups are more than single tokens: the CSS icon scale mirrored ICON_SIZE in icons.tsx (209 consumers there, two here) and keeps only its two CSS-clamped rungs; the z-index ladder listed four rungs no layer sits on. Four comments naming a deleted token as live are corrected with it. The unread --elevation-raised / --elevation-drag stay: DESIGN.md §5 names the three-step tier as the vocabulary product CSS must use and the Floating Recipe requires --elevation-overlay by name, so retiring part of a published tier is a design decision rather than a sweep. --foreground-8 stays beside --foreground-alpha-* — the first mixes into the background and is opaque, the second is a real alpha channel.

What the merge made redundant. Two comments elsewhere stated the old split as current — the composer "stayed at 680px", and the first-run hero's content was pinned at "~680px" to explain a flex bug whose argument does not need the number; a number repeated in prose is the same second authority in a form no search finds. The assistant bubble set width: 100%; max-width: none from product CSS, in chat-message.css and again at higher specificity in workhub.css; Astryx's published width prop does exactly that, and both call sites already pass the variant="ghost" its docs pair it with, so the two CSS blocks become two props, and the markdown stories pass it too. Turn chrome's max-width: var(--maka-chat-measure, 800px) and its auto margins bound while the chrome was 680 inside an 800px turn; under one measure a descendant of an 800px box cannot exceed 800, so they can never apply, and the 800px fallback leaves with them, along with the Marker doc comment that promised that geometry. A documentation block in chat-message.css with no rules under it, restating geometry documented where those rules live, goes too.

One name.--maka-chat-measure stopped being about chat once it governed the Daily Review report and the Artifact Preview too, and a name that describes a subset of what a token governs is how the next surface concludes the token is not for it and writes a second one. It is --maka-reading-measure at all twenty-four call sites. DESIGN.md gains the rule in §7, where the other two named typography rules live — one reading column, one token, held by the container and never by a component — and §11's list of rulers nobody may duplicate gains "reading measure" beside spacing, radius, icons and the text axis.

Refs #3617

Screenshots

Same conversation, same 1400px viewport.

Before — three right edges: the paragraph wraps 120px inside the code card, and the composer stops 120px inside both:

image

After — one: prose, code card, user bubble and composer all stop at the same edge:

image

Verification

All of the following on the final tree.

  • e2e/transcript-measure.spec.ts, e2e/session-workbar.spec.ts — 8 passed. The second renders the WorkHub assistant bubble, whose product CSS this replaces with the width prop.
  • e2e/composer-plus-menu-stability.spec.ts, e2e/prompt-rail.spec.ts, e2e/link-color-contract.spec.ts, e2e/settings-row-focus-ring.spec.ts — 19 passed. The first two cover the composer at the widened measure; the last two assert computed color and focus-ring geometry, the surfaces closest to the removed color and shadow tiers.
  • New E2E apps/desktop/e2e/transcript-measure.spec.ts: sends a message at a 1400px viewport and asserts the assistant paragraph's right edge meets the turn column's right edge. Reverting contentWidth to 680 fails it at exactly 120.
  • Token consumer search covered apps, packages, native, scripts (css/ts/tsx/js/mjs/html) plus @astryxdesign/core/dist and theme-neutral, excluding build output and caches; re-run after the deletions and after the rename, no var() reference and no bare mention of a removed or old name survives. Dynamic access checked separately: only --background and --maka-drawer-tooltip-x go through setProperty / getPropertyValue.
  • @maka/ui and @maka/desktop typecheck, npm --workspace @maka/desktop run build:with-deps, and npm run format — all clean.
  • Not run: the repository-wide suite and Storybook visual smoke. CI covers both.
  • No test covers the two document containers' caps. The invariant that regresses loudly — Markdown carrying a measure of its own — is what transcript-measure.spec.ts asserts; losing a container cap degrades line length rather than breaking behavior, and driving E2E to the Daily Review report to assert it was judged not worth its cost.

Root cause

The defect reproduces in Astryx alone, with no Maka code: ChatLayout density="spacious" gives an 800px message area, ChatMessageBubble variant="ghost" width="100%" (the documented pattern for rich content) fills it, and a default Markdown inside stops its prose at 680px while its code blocks fill the bubble.

Astryx already solves exactly this in Layout, which publishes its contentWidth as the inheritable --layout-content-width and has LayoutHeader / LayoutFooter read it back as var(--layout-content-width, none). Neither Markdown nor ChatLayout participates: both carry hardcoded values instead. Reported upstream as facebook/astryx#5598. If Astryx adopts the inheritance, this prop can be deleted.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosis, the fix, the token audit, the E2E, and this description. Reviewed and verified by the contributor before opening.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 757f86f to 1d67f03CompareAugust 27, 2026 09:27
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Aug 27, 2026
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 2 times, most recently from 167ee41 to bb568f1CompareAugust 27, 2026 09:57
@Astro-HanAstro-Han changed the title fix(desktop): let transcript prose reach the turn column edgefix(desktop): give the chat surface one reading measureAug 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review August 27, 2026 11:52
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch 3 times, most recently from 08c256b to 86f33cfCompareAugust 27, 2026 12:50
The turn column is `--maka-transcript-measure` (800px), and the tool cards,
code blocks and the user bubble all reach it — but every paragraph stopped 120px
short, leaving a band of whitespace down the right side of the transcript that
grows with the window.
The cause is two reading-measure authorities. Maka's column owns one, and
Astryx's `Markdown` owns another: `contentWidth` defaults to 680px. #3617 raised
the column from 680 to 800 so source evidence could be read, which made the
second authority visible for the first time.
`MarkdownBody` now passes `contentWidth: 100%`, which is a disclaimer rather
than a width: Markdown holds no measure, and the container it lands in is the
only one that does.
That rule only works if every container has one, and the two document callers
did not. Astryx renders a supplied `components.code` bare — no spacing, no
width, no alignment — and Maka always supplies one, so on the Daily Review
report, which sits on an uncapped module page, prose stopped at 680 while the
code blocks inside it ran the width of the window. The report column holds the
measure now, and it is the column and not the prose inside it: a section is a
heading, a divider and its prose, so capping only the prose would have left the
other two running past it. The Artifact Preview pane caps itself at 600px and so
never showed this in the normal layout; it holds the measure for the stacked
layout a narrow window switches to, where the workbar drops that cap.
Also corrects the neighbouring `--maka-chat-measure` comment, which still named
the conversation and tool output as its consumers; both moved to the transcript
measure in #3617.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from 86f33cf to dde2322CompareAugust 27, 2026 13:19
Twenty-one custom properties in `maka-tokens.css` have no `var()` consumer
anywhere — not in renderer CSS, not in `@maka/ui`, not in stories, and not in
Astryx, which reads a handful of Maka properties through its own theme bridge
and is checked separately here. A token nobody reads still has to be kept
consistent with the palette, the theme blocks, and every audit that walks the
file, so it costs maintenance and returns nothing.
Removed: the checked-control colors (`--control`, `--control-foreground`), four
unread wash tiers, `--border-width-accent`, `--foreground-alpha-10`, `--space-0`,
`--opacity-pending`, `--ease-in-out-strong`, `--maka-text-display-2`, and
`--h-control-xl` / `--h-control-2xl`.
Two groups are more than single tokens:
- The icon scale mirrored `ICON_SIZE` in `@maka/ui`'s `icons.tsx` by its own
admission. `ICON_SIZE` has 209 consumers and the CSS mirror had two; the two
CSS-clamped rungs stay and the rest go, including `--icon-size`, an alias
marked "deprecated, one release", and `--icon-chrome`, whose only reader was
that alias.
- The z-index ladder kept four rungs no layer sits on. Reserving unused floors
invites the next reader to pick by name rather than by stacking, so the
ladder now lists what exists: sticky, titlebar, tooltip, overlay, plus the
two micro tiers.
`--h-control-xl` overrides a recorded decision rather than collecting an
oversight, and should be read as one: #1879 found the rung had no reader, wrote
that in the comment, and kept it anyway because Astryx defines it and a
prominent button is a plausible future need. A rung held for a need nobody has
yet is the same reserved floor the z-index ladder just lost, and it is one line
to add back the day a call site wants it.
Four comments that named a deleted token as live are corrected with it.
Two survivors that look unread are not. `--elevation-raised` / `--elevation-drag`
carry no consumer, but DESIGN.md §5 names the three-step tier as the vocabulary
product CSS must use and the Floating Recipe requires `--elevation-overlay` by
name; retiring part of a published tier is a design decision, not a sweep.
`--foreground-8` stays beside `--foreground-alpha-*`: the first mixes into the
background and is opaque, the second is a real alpha channel, and the file
already records why the two cannot substitute for each other.
Generated-by: Claude Code
`--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two. #3617 introduced the second so transcript code, tables and tool
output could be read, and every surface the user answers with — composer, header
notices, hero, plan mode, WorkHub — stayed at the narrower one. The answer was
therefore wider than the box you type into, and turn chrome (`.maka-turn-footer`,
`.maka-turn-lineage-row`) stopped at 680 inside an 800px turn: three right edges
down one conversation.
`--maka-chat-measure` is now 800px and is the only measure. The transcript token
is deleted, `.maka-turn` reads the shared one, and `@maka/ui`'s fallback follows
it — that package does not load `maka-tokens.css`, so its fallback is the value
that actually renders there.
`.workhub-return` had written the old 680 as a literal, so unifying the tokens
alone would have left it 120px narrower than the WorkHub panels above it. It
reads the measure now, like its siblings.
800px because the alternative undoes #3617: at 680 the code, tables and tool
output it widened go back into a column too tight to read. The composer, hero,
notices, plan mode, WorkHub and the agent graph gain 120px.
Generated-by: Claude Code
Four removals the audit of this branch turned up, three of them created by the
branch itself.
The assistant bubble set `width: 100%; max-width: none` from product CSS, in
`chat-message.css` and again at higher specificity in `workhub.css`. That is
what Astryx's published `width` prop does: it sets the width and drops the
default `max(80%, 280px)` cap in one place, and both call sites already pass
`variant="ghost"`, which its docs pair it with. The two call sites pass the prop
now, the markdown stories pass it too, and the two CSS blocks go.
Turn chrome carried `max-width: var(--maka-chat-measure, 800px)` with
`margin-right: auto`. Those bound while the chrome was 680 inside an 800px turn;
now that one measure governs both, a descendant of an 800px box cannot exceed
800, so the cap and the auto margins can never apply. The 800px fallback leaves
with them, and with it the second place the number was written. The `Marker` doc
comment that promised that geometry is corrected rather than kept.
`chat-message.css` also held a documentation block with no rules under it,
restating the bubble geometry already documented where those rules live.
Two comments elsewhere stated the old split as current — the composer "stayed at
680px" in `chat-header.css`, and `shell-layout.css` pinned the first-run hero's
content at "~680px" to explain a flex bug whose argument does not need the
number. Both are corrected; a number repeated in prose is the same second
authority in a form no search finds.
Generated-by: Claude Code
`--maka-chat-measure` stopped being about chat two commits ago: it now governs
the Daily Review report and the Artifact Preview as well, and its own comment
calls it "one reading column, and the only one". A name that describes a subset
of what a token governs is how the next surface concludes the token is not for
it and writes a second one — the defect this branch exists to remove, one
release later. It is `--maka-reading-measure` now, at all twenty-four call
sites, and the two comments that said "the chat measure" in prose say the same
thing the token does.
The Artifact Preview comment loses a number for the same reason. It had written
the workbar's 600px cap out as a literal, which is a second copy of a value
`SESSION_WORKBAR_MAX_WIDTH` already owns and nothing keeps in sync; it names the
constant instead.
DESIGN.md gains the rule, in §7 because line length is a typographic decision
and §7 is where the other two named typography rules live: one reading column,
one token, held by the container and never by a component. §11's list of rulers
nobody may duplicate gains "reading measure" beside spacing, radius, icons and
the text axis, which is the sentence that would have stopped #3617 from adding
the second one.
Generated-by: Claude Code
@Astro-Han
Astro-Hanforce-pushed the fix/desktop-transcript-prose-measure branch from f62b88b to 35f37e3CompareAugust 27, 2026 13:43

@YayoiNanokaYayoiNanoka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — I found no reachable P0/P1 blocker at 35f37e327d7ee42544da0987f49111880867dad0.

The change removes the nested 680px prose authority and leaves reading measure ownership with the containing surface. The transcript, composer, WorkHub, Daily Review, and stacked Artifact Preview paths all retain an explicit bounded container. The deleted token names have no remaining consumers in apps, packages, native, or scripts.

Verification on a clean merge with current main:

  • @maka/ui and @maka/desktop typechecks passed.
  • The renderer production build and third-party notice check passed.
  • e2e/transcript-measure.spec.ts passed in Electron and confirmed that assistant prose reaches the transcript edge.
  • No temporary test was committed or pushed; the original workspace was unchanged.

The hosted test was still pending when I reviewed; this approval records the requested P0/P1 code-risk threshold.

点击展开中文

已批准——在 35f37e327d7ee42544da0987f49111880867dad0 上未发现真实可达的 P0/P1 阻塞问题。

该改动移除了组件内部 680px 的第二重正文宽度权威,把阅读宽度的所有权留给承载它的容器。transcript、composer、WorkHub、Daily Review,以及堆叠布局下的 Artifact Preview 路径都仍有明确的有界容器。被删除的 token 名称在 appspackagesnativescripts 中没有剩余消费者。

已在与当前 main 的干净合并结果上验证:

  • @maka/ui@maka/desktop typecheck 通过。
  • renderer 生产构建及第三方 notice 检查通过。
  • Electron 中的 e2e/transcript-measure.spec.ts 通过,确认 assistant 正文到达 transcript 右边界。
  • 没有提交或推送临时测试;原工作区未改动。

审查时托管测试仍在等待;本次批准表示已满足要求的 P0/P1 代码风险阈值。

@jackwenerjackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. No blocking issues found. One caveat about verification at the end, which is about this branch's CI rather than about the change.

The token sweep is clean — I checked it mechanically

The risk in a change like this is not the layout reasoning, it is a missed reference: a token whose definition is deleted but whose var() call site survives, resolving to nothing and silently dropping a declaration. So I enumerated every custom property whose definition this diff removes and never re-adds — 23 of them — and searched the whole tracked tree (.css, .ts, .tsx, .js, .mjs, .cjs, .html, .scss) for surviving consumers.

Zero surviving var() consumers, and zero textual mentions of --maka-chat-measure or --maka-transcript-measure anywhere in the tree. The rename across all call sites is complete.

One methodology note, because it nearly produced a false report on my side: a naive word-boundary search matches --space-0 inside var(--space-0-5) and --z-panel inside var(--z-panel-action), since - counts as a boundary. Both of those are live tokens that this PR does not touch. Anyone re-running this audit should anchor on "not followed by another name character or hyphen", or they will get three false positives.

Other things I verified

  • --maka-reading-measure has exactly one definition (maka-tokens.css:914, 800px) and 24 consumers, all in apps/desktop. Nothing in @maka/ui reads it, which is consistent with the description: the .maka-turn-footer cap was deleted rather than renamed, so no stale 680px fallback is left behind in the package that does not load maka-tokens.css.
  • The max-width and margin removal lands on the shared .maka-turn-lineage-row, .maka-turn-footer rule, so it covers both rows the description names, not just the footer.
  • The remaining literal 680s in the renderer are unrelated — a dialog width in mcp-page.tsx and a dialog height in settings/form.css. Neither is a reading measure.
  • The new E2E test guards against a false pass properly. Asserting turnWidth > 680 before rightGap <= 1 means the probe is shown able to detect the regression before it is trusted to report its absence. A test that only asserted the gap would pass on a narrow viewport where both boxes are equally constrained.

The caveat: CI has not run on this head

35f37e3 has a single check, test, and it has been queued since 13:43Z — roughly eight hours as I write this, never started. Nothing has executed on this commit.

That matters here specifically because of what your Verification section defers:

Not run: the repository-wide suite and Storybook visual smoke. CI covers both.

Storybook visual smoke is exactly the check that would catch a regression in a change that moves eight surfaces from 680 to 800 and edits four stories. So the verification this PR relies on is currently missing, not merely pending review.

My approval covers the code review above and does not stand in for that run. GitHub still lists this as BLOCKED with the required check outstanding, so nothing can merge until test goes terminal green — please treat that as the real gate. If the queue is stuck rather than slow, it is worth re-running before reading the green as meaningful.


Posted by an automated review agent operated by @jackwener. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @jackwener 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@M4n5terM4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at exact head 35f37e327d7ee42544da0987f49111880867dad0: I found no P0–P3 issue.

This is a real simplification rather than a directory or token rename. The second reading-measure authority (--maka-chat-measure / --maka-transcript-measure) and duplicate assistant-bubble width override disappear; MarkdownBody no longer owns a hidden 680px cap, while each production caller is bounded by its containing surface. Exact-reference scans also found no live consumer for any of the 21 removed CSS tokens.

Verification on this head:

  • Core, Storage, MCP, Runtime, Runtime Host, Computer Use, UI, and the complete Desktop main/preload/overlay/renderer build passed.
  • The complete UI unit suite passed 230/230.
  • The focused Electron geometry regression passed at a 1400px viewport and proved assistant prose reaches the turn edge beyond Astryx's former 680px cap.
  • Biome and git diff --check passed for the changed files.
  • The current-main synthetic merge was clean.
  • Hosted exact-head checks are terminal green.

Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。

@Astro-Han
Astro-Han merged commit d64923d into mainAug 27, 2026
1 check passed
@Astro-Han
Astro-Han deleted the fix/desktop-transcript-prose-measure branch August 27, 2026 14:45
saltand pushed a commit to saltand/maka-agent that referenced this pull request Aug 31, 2026
An assistant turn had two right edges. The turn column was 800px and the tool
cards, code blocks and user bubble all reached it, but every paragraph stopped
120px short: Astryx's `Markdown` carries its own `contentWidth`, defaulting to
680px, so Maka's column and the component each held a measure. apache#3617 raised the
column from 680 to 800 so source evidence could be read, which made the second
authority visible.
`MarkdownBody` passes `contentWidth: 100%` — a disclaimer rather than a width.
Markdown holds no measure; the container it lands in does. Two containers did
not have one: Astryx renders a supplied `components.code` bare, and Maka always
supplies one, so the Daily Review report showed prose at 680 with code blocks
running the width of an uncapped module page. The report column and the Artifact
Preview hold the measure now.
The branch then takes the same defect to its root:
- `--maka-chat-measure` (680px) and `--maka-transcript-measure` (800px) split one
column in two, so the answer was wider than the box you type into and turn
chrome stopped at 680 inside an 800px turn. One measure now, at 800px, because
680 would undo apache#3617. The composer, header notices, hero, plan mode, WorkHub,
the agent graph and both document surfaces gain 120px.
- Twenty-one custom properties with no `var()` consumer anywhere are removed.
`--elevation-*` and `--foreground-8` stay, with the reasons recorded.
- What the merge made redundant goes with it: the assistant bubble's duplicated
width CSS (Astryx's `width` prop does it), the now-unreachable turn-chrome cap,
a documentation block with no rules under it, and three comments stating the
old split as current.
- The token is `--maka-reading-measure`, since it stopped being about chat, and
DESIGN.md §7 gains The One Measure Rule so the next surface reads the policy
instead of inferring it from a name.
Reported upstream as facebook/astryx#5598: Astryx already publishes an
inheritable `--layout-content-width` in `Layout`, and neither `Markdown` nor
`ChatLayout` participates.
Refs apache#3617
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Astro-Han@jackwener@M4n5ter@YayoiNanoka