Skip to content

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

Open
2 of 6 issues completed
Open

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。

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