feat: implement new session behavior to clear selection and show empty state

- Added bilingual notes for the new session feature, detailing the transition to an empty state upon session creation.
- Updated `SessionsService` to include a `clear()` method that resets the current selection and persists the empty state.
- Enhanced the `EmptyState` component to reflect the new design, including workspace selection and input handling.
- Modified CSS styles for improved layout and visual consistency in the empty state.
- Updated tests to cover the new session clearing functionality and its effects on the UI.
This commit is contained in:
07akioni
2026-07-24 14:09:00 +08:00
parent a4b4a4c53d
commit aeb8b1f486
16 changed files with 532 additions and 135 deletions

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-24-new-session-clears-to-empty-state.md: d730f3e0b658ea66b6026593f37a97893e32a4db
2026-07-24-new-session-clears-to-empty-state.zh.md: 602a2b774b569cfef0adcc253fe751f86b14f895

View File

@@ -0,0 +1,23 @@
# Agent Note: New Session clears onto the empty-state launch
Status: implemented
English | [中文](2026-07-24-new-session-clears-to-empty-state.zh.md)
## Problem
Sidebar "New Session" created and opened a blank session immediately, so the center column showed `ConversationRoot` with an empty transcript and the resident composer. The Figma NEW SESSION screen (`EmptyState` + shared `InputBar` hero) only rendered when `sessions.current` was already undefined, so the launch page was unreachable from the primary creation control.
## Decision
`SessionsService.clear()` wipes the persisted selection and `list.current`. Top-level sidebar creation entries (`onCreate()` with no cwd — New Session and New Workspace) call `clear()` so `AppFrame` renders `conversation.empty`. The empty state's first send still runs `conversation.startSession` (create → open → send) and reuses the same `InputBar` component as the resident composer (`variant="hero"`). Per-project "+" (`onCreate(cwd)`) keeps create-then-open until the empty-state picker can accept a seeded cwd.
## Alternatives considered
**Keep create-then-open for New Session and add a second empty chrome inside ConversationRoot when the transcript is empty.** Rejected: that duplicates the launch InputBar and breaks the empty→content ruling that one InputBar moves position rather than swapping components.
**Route New Session through a dedicated route or slot outside selection.** Rejected for this pass: `conversation.empty` already owns the launch UI; clearing `current` is the existing empty branch.
## Consequences
New Session no longer mints a host session until the first send. Reloading after clear stays on the empty state. Project-scoped "+" still creates immediately. `EmptyState` stacks the Figma hero as fish + title, a Menu-backed workspace chip ("New Workspace" / basename / free-form path) above the card, then shared `InputBar` (`variant="hero"`), with a soft ellipse glow (figma 313:14109) centered behind the picker + card and width-locked to the card (`1051/776`) so it scales with it. `InputBar` paints the bottom chrome (attach / Plan / Read-only / model) with local native `<select>` state only — host plan, access, and model seams remain unwired.

View File

@@ -0,0 +1,23 @@
# Agent Note: New Session clears onto the empty-state launch
Status: implemented
[English](2026-07-24-new-session-clears-to-empty-state.md) | 中文
## Problem
侧栏「New Session」会立即创建并打开空白会话因此中间栏显示带空 transcript文本记录与常驻 composer 的 `ConversationRoot`。Figma 的 NEW SESSION 屏(`EmptyState` + 共用的 `InputBar` hero仅在 `sessions.current` 已为 undefined 时渲染,因而主创建控件无法到达启动页。
## Decision
`SessionsService.clear()` 清除持久化选中项与 `list.current`。顶层侧栏创建入口(无 cwd 的 `onCreate()`——New Session 与 New Workspace调用 `clear()`,使 `AppFrame` 渲染 `conversation.empty`。空态的首次发送仍走 `conversation.startSession`create → open → send并复用与常驻 composer 相同的 `InputBar` 组件(`variant="hero"`)。按项目的「+」(`onCreate(cwd)`)继续 create-then-open直到空态选择器能接受预填的 cwd。
## Alternatives considered
**为 New Session 保留 create-then-open并在 transcript 为空时于 ConversationRoot 内再加一套空态 chrome。** 否决:这会重复启动页的 InputBar并破坏 empty→content 的约定——同一 InputBar 应移动位置,而非互换组件。
**将 New Session 路由到选中状态之外的专用 route 或 slot。** 本轮否决:`conversation.empty` 已拥有启动 UI清除 `current` 即是既有的空态分支。
## Consequences
New Session 在首次发送前不再创建 host 会话。clear 后重新加载仍停留在空态。项目范围的「+」仍立即创建。`EmptyState` 按 Figma 堆叠英雄区:鱼标 + 标题、卡片上方的 Menu 工作区 chip「New Workspace」/ 路径 basename / 自由输入路径),再接共用的 `InputBar``variant="hero"`选择器与卡片背后居中铺一层柔光椭圆figma 313:14109宽度按卡片锁定为 `1051/776`,随卡片缩放。`InputBar` 绘制底栏 chrome添加 / Plan / Read-only / 模型),仅用本地原生 `<select>` 状态——host 侧的 plan、access、model 接缝仍未接线。