You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#363 is closed. That issue was about file boundaries: move unrelated responsibilities out of sink files before any visual polish. The work landed through #370, #372, #377, #378, #381, #383, and #385.
That gives us a cleaner codebase to change, but it does not make the UI easier to judge. The next phase needs a different habit: put the important states of each surface into Storybook first, then polish against those states.
This issue exists to make UI polish reviewable. If a PR changes spacing, hierarchy, copy density, focus treatment, or responsive behavior, reviewers should be able to see the affected states without driving the whole app into that state by hand.
It also keeps boundaries clear. The app-shell.tsx boundary cleanup is already separate in-flight work and should stay non-visual. It may unlock renderer-owned fixtures for command/search/settings stories, but it should not block stories for components that already live under packages/ui.
Current main has clearer file boundaries and a Storybook baseline. It does not yet have enough product-surface stories for polish work. Several user-facing surfaces have states that are hard to compare safely in the running app alone:
Surface
Why it needs Storybook before polish
Sidebar / SessionListPanel
Dense navigation, empty/search/filter states, row actions, blocked/running/stale status, long titles, and narrow width.
Chat / ChatView + Composer
Empty chat, streaming, tool activity, branch banners, import actions, and disabled/pending composer states.
Keyboard-heavy surfaces with grouped results, empty/loading/error/disabled states, and content search results.
Settings pages
Bot, memory, provider, and permission-center pages have async state, validation, pending actions, and long copy.
Calibration counter-example: a large file or component does not automatically belong here. A surface enters this issue only when Storybook can expose user-visible states that would otherwise be hard to inspect, compare, or regression-test.
Order Of Work
Keep the app-shell.tsx cleanup separate and non-visual. It is not a global blocker for Storybook work. packages/ui surfaces can use local fixture data now; command/search and settings stories may wait for extracted renderer-shell fixtures if needed.
Storyboard one product surface at a time. Add or extend stories for real states before changing visuals.
Pair polish with covered states. Once a surface has a state board, refine spacing, hierarchy, copy density, affordances, and responsive behavior for that same surface.
Keep PRs surface-scoped. One PR should cover one surface or one tight family of states, with screenshots or Storybook references in the PR body.
Keep labels sequential. Use PR1, PR2, PR3, and so on. Do not use sub-labels for issue tracking.
Invariants
Storybook is a design and regression aid, not a replacement for production tests.
Do not redesign unrelated surfaces while polishing one surface.
Do not add visual-only abstractions before stories prove the pattern repeats.
Cover important states first: empty, loading, error, disabled, pending, streaming, long content, narrow viewport, and destructive/confirmation flows where relevant.
PR4: Command/search storyboard. Shipped in test(ui): add command search stories #402. Cover command palette and content search modal as one keyboard/modal family: empty, loading, grouped results, disabled command, error, blocked privacy state, keyboard-focused selection, and no-results.
PR5: Settings critical-page storyboard. Shipped in test(ui): add provider settings stories #401 for the provider/OAuth settings family. Start with the highest-risk settings page, and keep the PR scoped to one page or one tight settings family. Cover bot settings, memory settings, provider/OAuth details, or permission center only where async state or validation makes polish risky.
PR6: First paired surface-scoped polish PR. In progress in refactor(ui): migrate sidebar visual properties to cva variants #403. After one surface's stories exist, polish that same surface with screenshots/story references and narrow verification. Later settings/storyboard or polish work should continue with the next integer PR label.
Context
#363 is closed. That issue was about file boundaries: move unrelated responsibilities out of sink files before any visual polish. The work landed through #370, #372, #377, #378, #381, #383, and #385.
That gives us a cleaner codebase to change, but it does not make the UI easier to judge. The next phase needs a different habit: put the important states of each surface into Storybook first, then polish against those states.
This issue exists to make UI polish reviewable. If a PR changes spacing, hierarchy, copy density, focus treatment, or responsive behavior, reviewers should be able to see the affected states without driving the whole app into that state by hand.
It also keeps boundaries clear. The
app-shell.tsxboundary cleanup is already separate in-flight work and should stay non-visual. It may unlock renderer-owned fixtures for command/search/settings stories, but it should not block stories for components that already live underpackages/ui.Completed precedent:
packages/ui/src/components.tsxinto focused UI files.ProvidersPanel.tsxinto provider settings sibling files.SettingsModal.tsxinto settings shell/page files.renderer/main.tsxinto a thin renderer entry and renderer shell/helper files.main/main.tsinto focused main-process orchestration/service/IPC modules.Current Evidence
Current
mainhas clearer file boundaries and a Storybook baseline. It does not yet have enough product-surface stories for polish work. Several user-facing surfaces have states that are hard to compare safely in the running app alone:SessionListPanelChatView+ComposerToolActivityCalibration counter-example: a large file or component does not automatically belong here. A surface enters this issue only when Storybook can expose user-visible states that would otherwise be hard to inspect, compare, or regression-test.
Order Of Work
app-shell.tsxcleanup separate and non-visual. It is not a global blocker for Storybook work.packages/uisurfaces can use local fixture data now; command/search and settings stories may wait for extracted renderer-shell fixtures if needed.PR1,PR2,PR3, and so on. Do not use sub-labels for issue tracking.Invariants
Slices
PR1: Sidebar/session-list storyboard. Shipped in test(ui): add sidebar session-list stories #393. Cover
SessionListPanelstates: empty, long list, search/filter, active row actions, blocked/running/stale status, long titles, and narrow width.PR2: Chat surface storyboard. Shipped in test(ui): add chat surface stories #394. Cover
ChatView+Composerstates: empty chat, streaming, tool activity present, branch banner, pending/disabled composer, import actions, and long messages.PR3: ToolActivity storyboard. Shipped in test(ui): add tool activity stories #395. Cover core tool-result variants: terminal, file diff, web search, subagent, explore agent, office document, errors, truncation, overlay preview, and copy feedback.
PR4: Command/search storyboard. Shipped in test(ui): add command search stories #402. Cover command palette and content search modal as one keyboard/modal family: empty, loading, grouped results, disabled command, error, blocked privacy state, keyboard-focused selection, and no-results.
PR5: Settings critical-page storyboard. Shipped in test(ui): add provider settings stories #401 for the provider/OAuth settings family. Start with the highest-risk settings page, and keep the PR scoped to one page or one tight settings family. Cover bot settings, memory settings, provider/OAuth details, or permission center only where async state or validation makes polish risky.
PR6: First paired surface-scoped polish PR. In progress in refactor(ui): migrate sidebar visual properties to cva variants #403. After one surface's stories exist, polish that same surface with screenshots/story references and narrow verification. Later settings/storyboard or polish work should continue with the next integer PR label.
Out Of Scope
References
中文对照
背景
#363 已经关闭。那个 issue 处理的是文件边界:先把 sink files 里混在一起的职责拆开,再进入视觉打磨。相关工作已经通过 #370、#372、#377、#378、#381、#383 和 #385 落地。
这让代码更好改,但不等于 UI 更好判断。下一阶段要换一种工作方式:先把每个产品表面的关键状态放进 Storybook,再对着这些状态做打磨。
这个 issue 是为了让 UI polish 变得可 review。如果一个 PR 改了 spacing、层级、文案密度、focus 处理或响应式行为,reviewer 应该能直接看到受影响的状态,而不是手动把整个 app 开到那个状态。
这也用来保持边界清楚。
app-shell.tsx的边界治理已经是单独进行中的工作,并且应该保持非视觉。它可能会为 command/search/settings stories 解出 renderer-owned fixtures,但不应该阻塞已经在packages/ui里的组件 stories。已经完成的前置工作:
packages/ui/src/components.tsx拆成了更聚焦的 UI 文件。ProvidersPanel.tsx拆成了 provider settings sibling files。SettingsModal.tsx拆成了 settings shell/page files。renderer/main.tsx拆成了很薄的 renderer entry,以及 renderer shell/helper files。main/main.ts拆成了 main-process orchestration/service/IPC modules。当前证据
现在的
main已经有更清楚的文件边界,也有 Storybook baseline。但要进入 UI polish,还缺产品表面的状态 stories。几个用户经常接触的区域,只靠运行中的 app 很难稳定比较这些状态:SessionListPanelChatView+ComposerToolActivity校准反例:文件大或组件大,不代表它自动属于这个 issue。只有当 Storybook 能暴露用户可见状态,而且这些状态在 running app 里难以检查、比较或回归验证时,这个 surface 才进入这里。
工作顺序
app-shell.tsx治理保持独立,并且保持非视觉。它不是所有 Storybook 工作的全局 blocker。packages/ui里的 surface 现在就可以用 local fixture data 做 stories;command/search 和 settings stories 如果需要 renderer-shell fixtures,可以等对应抽取落地。PR1、PR2、PR3这种,不用子编号。不变约束
拆分切片
PR1: Sidebar/session-list storyboard。已由 #393 合并。覆盖
SessionListPanel的 empty、long list、search/filter、active row actions、blocked/running/stale status、长标题和窄宽度状态。PR2: Chat surface storyboard。已由 #394 合并。覆盖
ChatView+Composer的 empty chat、streaming、tool activity present、branch banner、pending/disabled composer、import actions 和 long messages。PR3: ToolActivity storyboard。已由 #395 合并。覆盖核心 tool-result variants:terminal、file diff、web search、subagent、explore agent、office document、errors、truncation、overlay preview 和 copy feedback。
PR4: Command/search storyboard。已由 #402 合并。把 command palette 和 content search modal 作为一组 keyboard/modal family 覆盖:empty、loading、grouped results、disabled command、error、blocked privacy state、keyboard-focused selection 和 no-results。
PR5: Settings critical-page storyboard。已由 #401 合并,覆盖 provider/OAuth settings family。从风险最高的 settings page 开始,并且把 PR 限定在一个页面或一组关系很近的 settings family。只在 async state 或 validation 让 polish 有风险的地方覆盖 bot settings、memory settings、provider/OAuth details 或 permission center。
PR6: 第一个配对的 surface-scoped polish PR。#403 进行中。有某个 surface 的 stories 之后,再打磨同一个 surface,PR 里带 screenshots/story references,并做窄范围 verification。后续 settings/storyboard 或 polish 工作继续用下一个整数编号。
不在范围内
参考