Skip to content

tracking(desktop): rebuild the chat surface on Astryx compositions #5793

Description

@Colafornia
English

Problem

Scope reviewed against upstream main 7c90bac2d on 2026-10-04. Counts below describe the original audit, not the remaining work.

The Desktop chat surface already uses the Astryx chat primitives that the official ai-chat template uses: ChatLayout, ChatMessage, ghost ChatMessageBubble, ChatToolCalls, ChatMessageMetadata, ChatComposer, and Markdown. It still reads as rough and heavy next to the template, and its CSS is expensive to change.

A side-by-side capture (production Product/Shell Official AppShell stories against the template preview, 1440×1000) and a CSS audit point to one cause with two effects.

  • Layout is written by hand. The template has 0 raw layout elements, 2 className props, and 9 Astryx Stack calls in 763 lines. Product TSX has 557 raw layout elements, 597 className props, and 133 Stack calls. Every class needs a CSS rule, so renderer CSS grows with product structure: 66 files, 13,262 lines, 356 display: flex/grid declarations.
  • At the original audit, nothing compared pixels. test(desktop): add storybook pixel-diff capture/compare tool #5847 has since added scripts/storybook-visual-diff.mjs; scripts/storybook-visual-smoke.mjs still checks render completion, focus, and the accessibility tree only. At that time, visual fixes landed as local CSS patches with long rationale comments (34% of renderer CSS lines are comments).

The audit also rules out two suspected causes. Private .astryx-* overrides are few (159 occurrences, mostly in the sidebar and composer). Tokens are used consistently: font sizes, radii, and spacing almost always go through tokens.

The most visible defects on the chat surface are:

  • The turn process region reads like a log table. Intermediate commentary and reasoning split tool calls into many one-call ChatToolCalls cards. Each card is 800px wide with its chevron far from its content, and 12px muted rows alternate with 14px body text.
  • Error feedback uses four channels with no rule for choosing one: toast.error (154 call sites), Banner (138 uses in 51 files), hand-written role="alert" (29 uses in 21 files), and in-transcript notices. The failed-turn banner uses the page-level container="section" variant, so it renders as a square, full-bleed red block inside the message column.

#4679 aligns shell chrome and settings with Astryx. It does not cover the chat transcript, and its non-goals exclude tool preview cards and the ChatReasoning eject. This tracker owns the chat surface: transcript, turn chrome, composer, and the error feedback these surfaces show.

Goal

The chat surface is composed the way the Astryx template composes it: layout through Astryx components and their props, with product CSS only where Maka adds product behavior. Every visual change on the surface is verified against a before/after pixel capture during implementation.

Work items

Verification loop

Lossless layout refactor

Process region

Error feedback

Independent items

Order

A0 is available. D can land before C1. The remaining A1 surfaces can proceed with the existing capture loop, outside the areas B and C1 redesign. C2 starts after C1 lands. Base Composer work on #5927 and #5954. Coordinate transcript-frame and long-group scrolling changes with #5942; preserve scroll ownership and rerun dynamic scrolling checks. B and C1 attach their own before/after captures in their PRs.

Coordinates with

Non-goals

  • A new palette or type scale.
  • Changes to transcript projection, streaming, or scroll ownership.
  • Changes to plugin slot contracts. Any composer change that touches conversation.composer.toolbar needs its own issue.
  • A bulk removal of CSS comments.

Upstream already uses @astryxdesign/core 0.6.3; #5839 refreshed the patches and #5860 corrected the Spinner animation after the re-port. The former 0.6.3 deferral no longer applies.

Verification

  • Every PR in A1 attaches before/after captures produced by the A0 loop and shows zero pixel difference, or lists each accepted difference with its cause.
  • Every PR in B, C1, C2, and D includes before and after captures in light and dark produced by the A0 loop.
  • docs/astryx-surface-file-inventory.md stays at blocker 0.
中文

问题

2026-10-04 已按 upstream main 7c90bac2d 核对范围。下方统计来自原始审计,不代表当前剩余工作量。

桌面端对话界面已经使用了 Astryx 官方 ai-chat 模板所用的同一套对话原语:ChatLayout、ChatMessage、ghost 形态的 ChatMessageBubble、ChatToolCalls、ChatMessageMetadata、ChatComposer 和 Markdown。但和模板相比,它看起来仍然粗糙、笨重,CSS 的修改成本也很高。

我们把生产环境的 Product/Shell Official AppShell 故事和模板预览放在 1440×1000 下对比截图,并审计了 CSS。结论是一个根因造成了两个结果。

  • 布局是手写的。模板 763 行里没有原生布局元素,只有 2 个 className 和 9 处 Astryx Stack。产品 TSX 里有 557 个原生布局元素、597 个 className,Stack 只有 133 处。每个 class 都需要一条 CSS 规则,所以渲染层 CSS 随产品结构线性增长:66 个文件,13,262 行,356 条 display: flex/grid 声明。
  • 原始审计时没有像素对比。test(desktop): add storybook pixel-diff capture/compare tool #5847 此后已加入 scripts/storybook-visual-diff.mjs;scripts/storybook-visual-smoke.mjs 仍只检查渲染完成、焦点和无障碍树。当时视觉修正以局部 CSS 补丁的形式落地,并附有很长的理由注释(渲染层 CSS 有 34% 的行是注释)。

审计同时排除了两个被怀疑的原因。私有 .astryx-* 覆盖很少(159 处,主要在侧栏和输入框)。token 使用一致:字号、圆角和间距几乎都走 token。

对话界面上最显眼的问题是:

  • 每轮的过程区读起来像日志表格。中间的说明文字和思考把工具调用切成许多只有一个调用的 ChatToolCalls 卡片。每张卡 800px 宽,展开箭头离内容很远;12px 的灰色行和 14px 的正文交替出现。
  • 错误提示有四种渠道,却没有选择规则:toast.error(154 处调用)、Banner(51 个文件共 138 处)、手写的 role="alert"(21 个文件共 29 处),以及对话流内的提示。失败轮次的横幅用的是页面级的 container="section",所以在消息栏里显示成直角、满宽的红色色块。

#4679 负责让外壳和设置页对齐 Astryx。它不覆盖对话流,其非目标还明确排除了工具预览卡片和自研的 ChatReasoning。本追踪 issue 负责对话界面:对话流、轮次外框、输入框,以及这些界面上的错误提示。

目标

对话界面按 Astryx 模板的方式组合:布局交给 Astryx 组件及其属性,产品 CSS 只用于 Maka 自己增加的产品行为。界面上的每一次视觉修改,都在实施过程中用前后截图对比来验证。

工作项

验证工具

无损布局重构

过程区

错误提示

独立工作项

顺序

A0 已可用。D 可以先于 C1 合并。剩余 A1 区域使用现有截图流程推进,只处理 B 和 C1 不会重新设计的区域。C2 在 C1 合并后开始。输入框工作基于 #5927 和 #5954;对话流外框和长工具组滚动变更需与 #5942 协调,保留滚动控制权并重跑动态滚动检查。B 和 C1 在各自的 PR 里附上前后对比截图。

协同

非目标

  • 新的调色板或字号阶梯。
  • 修改对话流投影、流式输出或滚动控制权。
  • 修改插件槽契约。任何涉及 conversation.composer.toolbar 的输入框改动都需要单独的 issue。
  • 批量删除 CSS 注释。

上游已使用 @astryxdesign/core 0.6.3;#5839 更新了补丁,#5860 修正了重新移植后的 Spinner 动画。原先的 0.6.3 延期说明已不适用。

验证

  • A1 的每个 PR 附上 A0 流程产出的前后截图并做到零像素差异,或逐条列出接受的差异及原因。
  • B、C1、C2 和 D 的每个 PR 附上 A0 流程产出的浅色和深色模式前后对比截图。
  • docs/astryx-surface-file-inventory.md 保持 blocker 为 0。

Activity

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

Metadata

Metadata

Assignees

Labels

trackingTracking or umbrella issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions