feat: connect conversations with Magic Notes

Let users retain useful assistant replies or complete conversations without
leaving their chat workflow. Preview and edit captured text, choose an existing
note or atomically create a note with its first entry, and return to the source
conversation or message from saved records.

Add an application-scoped Notes workbar tab with title/body search and quick
text appends. Preserve drafts across conversation switches and guard closing,
replacement and disabling. Schema 48 stores optional source metadata without
rewriting file-backed bodies; source deletion retains the saved note. Older
clients cannot reopen an upgraded database without a pre-upgrade backup.

Release note: 可将助手回答或完整会话预览、编辑后加入魔法笔记,并从笔记返回原会话或消息。右侧快速笔记支持搜索和追加文字,切换会话保留草稿;采集本身不调用模型,保存后自动评论仍遵循已有设置。

Validation: isolated HEAD-based candidate passed 22 files / 930 focused tests,
plus 20 gateway tests after including its create-result fixture adjustment.
Real Electron App/preload/IPC/SQLite acceptance passed for all 502 historical
messages, exact-entry/source navigation, native keyboard input in a 214px
panel, reopen and source-deletion retention, with zero capture model calls.
Repository lint and web TypeScript passed. Cached whitespace and secret-pattern
checks passed; native-client changes and unrelated IPC extraction are excluded.

Validation limits: the isolated source tree reuses installed node_modules,
where a parallel task upgraded DSH from the committed 0.1.2-rc.1 to 0.1.7-rc.2.
Full typecheck reports 14 DSH errors in three unchanged files; the full-suite
attempt with --bail=1 also fails in deepseek-harness-host.test.ts. These are not
all-green repository or release-package results. Earlier execution-time full
suite failures and fixture repairs remain recorded in the feature progress doc.
This commit is contained in:
mesalogo
2026-09-27 08:17:54 +08:00
parent 55efca3ee1
commit 1094433a7d
51 changed files with 1949 additions and 56 deletions
+18 -1
View File
@@ -26,9 +26,26 @@ context and protects unsaved editor changes. A successful save followed by no
further edits does not prompt again on return. Narrow note layouts use an index
drawer and bounded bottom AI pane.
Conversation capture and the compact Notes workbar panel are implemented. Users
can preview and edit one assistant response or the complete conversation text,
then append it to an existing note or create a note with its first entry. Quick
notes opens the same panel for search, browsing and text appends. Saved entries
carry structured conversation sources with return navigation. The panel and full
workspace share storage and change notifications; drafts remain in App memory.
Real Electron acceptance passed through the App UI, production preload, IPC and
SQLite. Repository validation is not all green; the [progress record](./progress.md)
separates focused passes, repaired schema fixtures and execution-time failures.
## Documents
- [Technical design](./technical-design.md): file storage, schema 38 migration,
- [Conversation integration PRD](./prd.md): scope and acceptance for
conversation capture and the compact workbar panel.
- [Conversation integration logic](./logic-design.md): capture boundaries, source
lifetime, panel state, draft protection and application availability.
- [Conversation integration UI](./ui-design.md): implemented entry points, compact
panel, capture preview and source navigation, following the root UI system.
- [Technical design](./technical-design.md): file storage, schema 38 body migration,
schema 48 source metadata, desktop search and atomic initial-entry creation,
backup boundaries, database notifications, process boundaries, canvas and AI
contracts, refresh lifecycle and regression coverage.
- [Progress](./progress.md): implementation and validation evidence.
+35
View File
@@ -0,0 +1,35 @@
# 会话联动逻辑设计
状态:已按当前实现核对,验证进度见 [progress.md](./progress.md)。需求编号来自 [PRD](./prd.md)。
## 内容与来源
FR-2、FR-3:单条采集读取所选助手消息的非空正文;整段采集先加载该会话完整历史,再按消息顺序收录用户和助手的非空正文,保留角色分隔。预览建立后,切换会话或收到新消息不会替换正文及来源标识。生成中的消息不可采集,停止或失败后已有正文可保存,单条预览注明回答未完成。整个会话正在生成时禁用整段采集,提示等待完成或停止生成。
首版按文字保存,保留原始 Markdown 文本、换行和代码文本,不承诺还原聊天渲染效果。推理、工具调用日志、系统提示、附件二进制和图片不进入正文;预览持续说明保存范围。用户可编辑预览,来源仍指向本次采集的会话。读取完整会话失败时不以屏幕上已有消息代替。
FR-5:来源独立于可编辑正文。单条来源包含会话和消息标识;整段来源包含会话标识、此次收录的消息标识及采集时间。预览使用采集时的会话标题和项目名称;保存时主进程校验消息归属,并以当时数据库中的会话标题和项目名称写入来源,无项目时显示全局。若预览期间源会话或消息已删除,保存失败并保留预览。保存完成后,修改或删除源消息不回写笔记正文和来源。
点击来源时读取完整会话。消息不存在但会话仍在时打开会话并提示“原消息已不存在”;确认会话不存在后保留来源文字,并在当前来源条禁用跳转。其他读取失败显示可重试错误。打开未渲染的来源消息时扩大聊天历史显示范围,再滚动定位并聚焦。编辑笔记正文不移除来源;删除笔记不影响源会话。
## 面板与草稿
FR-1、FR-4:笔记应用为可关闭、可排序的单实例工作栏 Tab,新布局默认不打开。再次触发入口激活现有 Tab;笔记选择属于应用级状态,切换项目或会话不改写它。列表按置顶优先、最近更新时间排列,搜索匹配标题与记录文字,同一笔记只显示一次。当前应用会话内保留最近选择,重启不恢复笔记选择或草稿。该笔记已删除时回到列表,清除失效保存目标并保留待保存文字。
FR-2、FR-3:面板有浏览、采集编辑、保存中三个状态。触发采集进入编辑态;选择目标只改变写入位置;明确点击“加入笔记”才写入。每次提交新增一条记录,不覆盖旧记录。新建目标时先填写标题,会话标题作为可修改默认值;提交一次创建笔记和首条记录,取消不遗留空笔记。普通“新建笔记”仍可显式创建空笔记。
保存中禁用重复提交和面板离开操作,结果返回后可再次操作。成功后清除本次草稿,显示响应返回的新增记录;失败保留预览、标题和目标。目标已删除时提示重新选择。容量校验使用现有文字记录限制,超限由用户缩减正文后重试;一次提交始终对应一条完整记录。
关闭 Tab、返回面板列表、从面板打开完整工作区、禁用应用或以另一条采集替换草稿前,显示“继续编辑 / 放弃草稿并切换”确认。普通主页面、项目和会话切换以及隐藏工作栏保留 App 持有的草稿及来源。取消采集只在正文或标题相对预览初值有修改时确认;未修改预览可直接取消。完整工作区自身的编辑草稿仍由其离开确认保护。
FR-6:成功写入触发现有通知刷新视图;面板重新挂载或工作栏重新展开时读取最新数据。面板挂载期间保留搜索词;笔记选择和草稿由 App 保留,不受搜索响应或后台刷新覆盖。既有记录编辑继续使用原修订号处理冲突。此处同步仅指本机共享存储的视图更新。
## 启用与评论
FR-1~FR-4:遵循魔法笔记应用的启用状态。禁用时隐藏会话采集、快速笔记及工作栏目录入口,并移除笔记 Tab;禁用前处理草稿。外部设置变更要求禁用时,选择继续编辑会尝试恢复启用设置,失败显示设置错误。应用未常驻不影响快速入口或工作栏可用性。设置继续由应用中心管理。
会话采集和快速追加本身不调用模型。保存后沿用现有 AI 评论模式;只有已有设置要求保存后自动评论时才触发,失败不撤销保存,也不自动重新追加。
## 完整性检查
当前实现覆盖首次创建、追加、取消、重复点击、写入失败、目标删除、来源删除、跨会话切换及刷新与草稿的关系。完整历史读取、来源定位和存储接口已接入;产品范围无待决项。真实 Electron 已验证采集、保存、定位、窄面板键盘操作和持久化,具体范围见进展记录。全仓测试和类型检查仍有执行时记录的失败,聚焦复跑通过不等于全仓通过。
+32
View File
@@ -0,0 +1,32 @@
# 魔法笔记与会话联动
状态:会话联动前后端已实现,真实 Electron 验收通过;全仓验证未全绿。聚焦结果、fixture 修复后复跑及执行时的全仓失败见 [progress.md](./progress.md)。
## 目标与范围
用户在阅读回答时,可将内容保存到已有笔记或新笔记,并从笔记返回原会话。会话界面提供文字预览和保存位置选择,与已有 Agent 笔记工具共用存储。
独立工作区继续承载完整编辑、画布、待办和 AI 评论;右侧笔记面板提供浏览和快速追加。笔记仍属于全局,不因入口所在项目改变归属。
## 功能要求
| 编号 | 要求 |
| --- | --- |
| FR-1 | 右侧助手工作栏增加“笔记”应用,支持搜索、打开已有笔记、新建笔记、查看记录摘要、快速追加文字,以及打开对应完整工作区。 |
| FR-2 | 助手消息操作栏提供“加入笔记”,打开可编辑预览,用户选择已有笔记或新建后明确提交。 |
| FR-3 | 会话标题的更多菜单提供“保存当前对话到笔记”,按触发时的会话内容生成预览,保存为目标笔记中的一条记录。 |
| FR-4 | 左侧底部提供“快速笔记”,侧栏收起时由聊天页头提供同名图标入口;打开右侧面板并恢复当前应用会话中最近选择的笔记,首次使用显示列表。此入口不隐式保存当前对话。 |
| FR-5 | 从会话保存的记录保留结构化来源,显示会话名称、所属项目(如有)和采集时间,支持返回原会话及单条来源消息。源会话删除后保留笔记内容。 |
| FR-6 | 面板、完整工作区和 Agent 写入使用同一份笔记数据,成功写入后更新已打开视图,同时保护未保存草稿。 |
首版不包含自动总结、自动分类、自动选择保存目标、选中文本采集、多条消息勾选、附件文件复制或跨设备同步。“总结后加入”和选区采集作为后续扩展,不预留不可用按钮。
## 产品验收
- 首次使用且没有笔记时,可从一条助手回答创建笔记并保存首条记录;已有笔记时可搜索并追加,原记录保持不变。
- 保存当前对话包含未在屏幕上渲染的历史正文;预览范围明确,超出容量时提示缩减内容,不静默截断。
- 保存成功后显示目标笔记并定位新增记录;取消不写入,失败保留内容和目标供重试。
- 从来源条可返回对应会话;会话已删除时显示“原会话已不存在”,已保存正文仍可阅读和编辑。
- 面板追加后完整工作区可见,Agent 修改后面板可见;后台刷新和切换会话不覆盖未保存文字。
状态与内容范围见 [逻辑设计](./logic-design.md),入口和操作细节见 [界面设计](./ui-design.md),接口与存储见 [技术设计](./technical-design.md#conversation-integration)。
+73
View File
@@ -1,5 +1,78 @@
# Magic Notes Progress
## 2026-09-26: Conversation Capture and Compact Notes Panel
- FR-1/FR-4: `notes` is an application-scoped optional singleton in the workbar.
The compact panel supports title/body search, browsing, text appends and full
workspace navigation. Quick notes uses the same tab; app enablement controls
availability independently of sidebar pinning.
- FR-2/FR-3: Assistant-message and conversation-header actions open editable text
previews. Whole-conversation capture loads complete history. App owns drafts
and selection; close, replacement and disable actions use the draft guard.
Success focuses the returned entry ID; failed saves retain input.
- FR-5: Schema 48 adds nullable source metadata. Main validates message ownership
and resolves display labels at save time. Panel and workspace share source
navigation, including missing-message and missing-conversation handling.
- FR-6: Desktop search, preload/IPC and note-level SQL results are connected.
Creating a note with initial content commits note/entry membership in one
transaction. Both views use existing change notifications; file reconciliation
and workspace optimistic revisions retain their existing boundaries. See
[the implemented contract](./technical-design.md#conversation-integration).
Validation reported by implementation subagents in this session:
| Scope | Reported result | Evidence boundary |
| --- | --- | --- |
| Backend focused checks | 362 tests passed | Subagent handoff; not a repository-wide result |
| Frontend focused checks | 8 files / 592 tests passed | Subagent handoff; not real Electron acceptance |
| Web TypeScript and lint | Passed | Subagent handoff; does not establish full-repository typecheck/lint |
The coordinating agent subsequently reported real Electron acceptance passing.
[magic-notes-capture.electron.test.ts](../../../tests/magic-notes-capture.electron.test.ts)
and its [Main driver](../../../tests/support/magic-notes-capture-main.ts) /
[renderer](../../../tests/support/magic-notes-capture-renderer.tsx) mount the real
App UI and use production preload, registered IPC and SQLite/file storage.
Unrelated services use test dependencies; the renderer bridge is not replaced.
- Saving an assistant response to an existing note retains its earlier entry;
whole-conversation capture creates a new note with its first entry.
- All 502 historical messages are compared verbatim in the preview and saved
content, including history initially outside the rendered timeline.
- Full-workspace navigation locates the exact saved entry; source navigation
restores the conversation and focuses the source message. The coordinating
agent also reports source-history expansion coverage.
- Native Electron keyboard input covers returning to the list, opening a note
and appending text in a measured 214px panel, without horizontal overflow.
- SQLite close/reopen preserves both notes. Deleting the source conversation
retains their saved content and source metadata. Model calls: **0**.
The combined Electron, `canvas-ipc.integration`, `MagicNotesPanel` and
`ChatTimeline` run passed **4 files / 70 tests**. Lint and web TypeScript passed.
This validates the App capture path in a test Electron window with isolated data;
it does not establish release-package or cross-platform acceptance.
Repository validation and subsequent fixture repairs:
| Check | Result at execution time | Follow-up |
| --- | --- | --- |
| `npm test` | 457 files / 5,359 cases: 5,272 passed, 4 failed, 83 skipped | No all-green full-suite rerun reported |
| Three schema-fixture failures | Activity-history and two worker fixture variants omitted `DROP COLUMN source_json` when reconstructing old schemas | Fixed; the five-file regression run below passed |
| Remaining test failure | `tests/build-release.test.ts`: missing DSH resources | Unrelated to notes; not fixed in this validation pass |
| Full-repository typecheck | Failed on parallel SSH mocks missing `forwardLoopback`, an IPC native-terminal fixture referencing undefined `terminalManager`, and mismatched arguments in `obsidian-runtime-acceptance` | Execution-time findings; later concurrent changes may alter them |
After fixture repairs, **5 files / 58 tests passed**:
`src/main/assistant/activity-history-io.test.ts`,
`tests/assistant-storage-worker.test.ts`,
`src/main/assistant/assistant-storage-upgrade.test.ts`,
`src/main/magic-notes/magic-note-storage.test.ts` and
`src/main/magic-notes/canvas-ipc.integration.test.ts`.
This focused rerun does not replace the failed full-suite/typecheck results.
Status: **implemented; real Electron acceptance passed; repository validation is
not all green**. Results above come from the session handoffs, not a rerun by this
documentation task. Later fixes require their own verification evidence; older
Electron/full-suite results below do not validate this integration.
## 2026-09-24: Resizable Todo List and Collapsible Note Groups
- Todo list/detail uses a 1px divider with a transparent 9px pointer target and
+119 -1
View File
@@ -449,6 +449,124 @@ These note tools run in the desktop gateway. Remote gbagent ACP sessions
currently inject only the image MCP server, so this change requires no
daemon implementation update.
## Conversation Integration
The desktop API and renderer integration are implemented. Scope and behavior
are owned by the [PRD](./prd.md), [logic design](./logic-design.md) and
[UI design](./ui-design.md). Real Electron acceptance passed; focused results,
fixture repairs and non-green repository checks are recorded in [progress](./progress.md).
### Workbar and Capture
`WORKBAR_APP_DEFINITIONS` registers `notes` as an optional, closable, reorderable
singleton with application scope, no `targetRef` and `defaultOpen: false`.
`RightAssistantSidebar` opens or activates it through the existing
[workbar tab model](../assistant-workbar/terminal-tabs-prd.md), and removes it when
Magic Notes is disabled. Sidebar pinning does not control this availability.
`MagicNotesPanel` renders the compact view; `WorkbarShell` supplies the shared tab
controls. The footer shortcut and collapsed-sidebar chat-header shortcut both
activate the same instance.
`App.captureToNote` receives the message identity from `ChatTimeline`, or calls
`ensureConversationHistory` for whole-conversation capture. It freezes text and
source IDs before opening the preview and waits for queued conversation persistence
so Main can validate newly completed messages. Whole-conversation text includes
nonempty user/assistant bodies with role headings. It excludes reasoning, tool
logs and attachment binaries, and rejects streaming conversations.
`useMagicNoteDraft` lives in App and owns the draft, selected note, saving state
and one shared confirmation promise. Selection and drafts survive panel remounts
and conversation/project switches, but are not persisted across app restarts.
The guard rejects leaving while saving and confirms discarding pending input;
explicit cancellation compares text/title with their initial preview values.
Application disablement and tab closing call the same guard. Workspace navigation
also passes through the full workspace's existing leave check.
`capturedNoteContent` converts text into v1 Quill string inserts, preserving
newlines and adding the terminal newline when needed. It splits inserts at the
200,000-code-unit operation limit without splitting surrogate pairs; the complete
record still passes the shared rich-content schema. Markdown stays literal text.
No summarization or attachment copying runs during capture. New-note titles are
limited to 100 characters. A synchronous submission ref prevents duplicate writes.
`magicNotes.create({ title, content?, source? })` returns `MagicNoteCreateResult`,
with `createdEntryId` when initial content exists. `createMagicNote` inserts the
note, first entry, source and derived todos inside one SQLite transaction; failure
leaves no committed empty note and sends no success notification. This atomicity
applies to database membership; filesystem writes retain the reconciliation
boundary in [File Storage and Writes](#file-storage-and-writes).
`magicNotes.createEntry({ noteId, content, source? })` always returns the exact
`createdEntryId`. The panel uses that ID to scroll, focus and briefly highlight the
new record. Opening the full workspace passes `{noteId, entryId?, requestId}` into
its existing guarded note-navigation path.
`magicNotes.search({ query, limit? })` is exposed by `DesktopApi`, preload and
`magic-notes:search`. Trusted-sender and shared-schema validation precede
`AssistantDatabase.searchMagicNoteSummaries`. The trimmed query has a 1,000-character
limit; result limits are 1-200, defaulting to 200. The panel requests 100 results
and debounces nonempty queries by 180 ms. SQL searches note titles or indexed entry
text using `EXISTS`, so each note occurs once before `LIMIT`. Empty queries list
notes; ordering is pinned first, then updated time and row ID descending.
`%`, `_` and backslashes are escaped for literal matching. Agent `note_search`
retains its separate entry-level output and 1-100 limit.
### Source Metadata
`magicNoteSourceSchema` defines `kind` (`message` or `conversation`),
`conversationId`, nonempty unique `messageIds`, ISO `capturedAt`,
`conversationTitle`, and optional `projectId` / `projectName`. A message source
requires exactly one message ID. Create/create-entry inputs accept `source`;
note creation requires initial content when source is supplied. Entry reads
return it independently of editable content, while update inputs cannot replace it.
The IPC helper `resolveMagicNoteSource` loads the stored conversation and verifies
that every message ID belongs to it; a single-message source must identify an
assistant message. It replaces renderer-supplied title/project labels with current
database values while retaining the supplied capture time and IDs. Preview labels
therefore describe capture time, but stored labels describe save time. Missing
source rows reject creation; later source deletion does not block note reads or edits.
Schema 48 adds nullable `magic_note_entries.source_json` in a transaction and
advances `PRAGMA user_version`. Existing entries read without a source. It adds no
conversation foreign key or deletion cascade, and does not rewrite file-backed
bodies. Schema 38 remains the historical body migration. Structure-only upgrade
does not independently trigger body conversion or VACUUM; see the
[database migration guide](../../development/database-migrations.md). Coordinated
SQLite/files backups include the source metadata.
`MagicNoteSource` is shared by panel summaries and workspace records. Its callback
`App.openNoteSource` reads `conversations.get`, then navigates through the workspace
leave guard. Message navigation increases the mounted timeline range before
scrolling and focusing. A missing message opens its conversation with a notice;
a confirmed missing conversation disables that source bar's jump buttons. Other
read errors remain retryable. No deleted-source flag is stored.
### Refresh and Validation
Both views use the same Main store and `magic-notes:changed` notification. The
panel reloads search and selected detail when active, and ignores superseded
responses. Search/loading state belongs to the mounted panel; input and selected
note belong to App. A deleted selected note clears the selection and matching
target ID while preserving draft text. Read and save failures have local recovery
feedback. The full workspace retains its existing revision and dirty-editor rules.
After a successful save, only `after-save-auto` starts entry analysis using the
returned `createdEntryId` and configured comment format. Analysis errors notify
without undoing the save or recreating the entry. Other comment modes perform no
panel analysis.
Regression cases are in `MagicNotesPanel.test.tsx`, `App.test.tsx`,
`ChatTimeline.test.tsx`, `MagicNotesWorkspace.test.tsx`, workbar contract tests,
database/storage tests and production preload/IPC integration tests.
`tests/magic-notes-capture.electron.test.ts` mounts the real App with production
preload and capture IPC, backed by SQLite/files. It validates existing/new-note
saves, verbatim 502-message history, workspace/source navigation, native keyboard
input in a narrow panel, database reopen and retention after source deletion,
with zero model calls. Failed writes and external refresh retain their focused
regression coverage; this Electron result does not claim every failure path.
Repository test/typecheck failures and repaired migration fixtures are documented
separately in [progress](./progress.md).
## Validation
- `magic-note-storage.test.ts` uses real files and SQLite for migration equality,
@@ -476,6 +594,6 @@ daemon implementation update.
coverage includes portal placement, keyboard navigation, dismissal, delete
confirmation, target selection, revision failures and draft preservation.
Schema 38 and the file layout above govern current persistence; refresh
Schema 48 adds source metadata to the schema 38 file-backed body layout; refresh
notifications need no separate storage or network service. Dated validation
results and remaining repository checks are owned by [progress](./progress.md).
+50
View File
@@ -0,0 +1,50 @@
# 会话联动界面设计
状态:已接入前端,真实 Electron 验收通过;全仓验证未全绿,结果见 [progress.md](./progress.md)。遵循根目录 [UI-DESIGN.md](../../../UI-DESIGN.md),需求和行为分别由 [PRD](./prd.md) 与 [逻辑设计](./logic-design.md)定义。独立工作区布局继续由根文档 13.7 节维护。
## 入口
| 位置 | 文案与动作 |
| --- | --- |
| 助手工作栏“+”菜单 | 增加“笔记”,打开或激活单个笔记 Tab。 |
| 助手消息底部,复制旁 | 图标按钮“加入笔记”,进入该消息的采集预览。 |
| 会话标题更多菜单 | “保存当前对话到笔记”,加载完整历史后进入整段采集预览;生成、采集加载或保存期间禁用。 |
| 左侧底部,应用中心与设置操作组上方 | “快速笔记”,打开面板;侧栏收起时在聊天页头显示带同名提示的图标。 |
| 面板笔记标题旁 | “在完整工作区打开”,进入当前笔记;有待保存文字时先处理草稿。 |
左侧主导航中的“魔法笔记”继续打开独立工作区,两处入口通过名称说明不同目的。快速笔记不读取文本选区,不根据选区改变动作。
## 紧凑面板
面板按单列显示列表或笔记详情,不嵌入完整工作区的三栏布局。搜索位于列表顶部,“新建笔记”在列表之后;笔记行显示标题、置顶状态、两行摘要和更新时间。无笔记时提供新建动作;搜索无结果时保留搜索词并允许创建。
详情顶部提供返回列表、笔记标题、全局范围标识和打开完整工作区。中间以可滚动记录摘要供浏览,每条文字摘要最多显示前 600 个字符,画布显示首页缩略图及页数;记录按钮可在完整工作区定位该记录。底部提供快速追加文字输入区与“加入笔记”按钮,画布编辑、待办管理和 AI 评论阅读仍在完整工作区。
从会话触发时,面板切到采集编辑视图:
```text
加入笔记
来自:项目 / 会话标题 · 单条回答或当前对话
保存范围:用户与助手正文,不含推理、工具日志和附件文件
待加入内容
[可编辑文字预览]
保存到
[搜索或选择已有笔记]
[新建笔记 → 标题输入]
[取消] [加入笔记]
```
范围说明随单条或整段来源调整。预览初始包含完整待保存文字,可滚动编辑。新建目标标题默认取会话标题前 100 个字符,可修改;已有目标与新建目标使用共享 `SegmentedControl` 切换。采集内容为空或超限、缺少目标、新建标题为空或超限时就地提示,并禁用保存;普通新建允许创建空笔记。
读取失败显示就地重试按钮;保存失败保留输入并在提交区显示错误,用户可再次点击“加入笔记”。成功通过应用通知反馈,切回目标笔记详情,滚动定位、聚焦并高亮新增记录约 2.4 秒。仅“保存后自动评论”模式发起后续分析,分析失败另行通知,已保存内容保留。
## 来源与可访问性
记录摘要和完整工作区的已保存记录均显示“来自会话”来源条,内容含保存时标题、项目及采集时间。单条来源提供返回会话和定位原消息按钮,整段来源提供返回会话按钮。点击后确认原会话不存在才显示对应文案并禁用跳转;其他错误提供就地重试。来源条与正文分开,编辑正文时仍可识别来源。
Tab 使用工作栏现有的共享页签、焦点和关闭模式。搜索有持久标签,列表用可键盘访问的按钮;打开采集后聚焦预览,取消返回触发按钮,触发按钮已不可见时尝试返回会话标题菜单按钮。新建标题出现后聚焦输入框。面板中的 Escape 取消当前草稿,或从详情返回列表;需要放弃输入时先显示草稿确认。确认框初始聚焦“继续编辑”,限制 Tab 焦点范围,Escape 保留草稿并关闭确认。
面板服从工作栏现有宽度和停靠规则,以单列切换列表、详情和采集编辑。按钮组可换行,文字摘要保留换行并折行长文本;Markdown 和代码以原始文字显示。头部与快速追加区固定,中间内容独立滚动;完整预览输入区可纵向调整大小。配色、按钮、焦点环、通知和确认使用共享组件与令牌。真实 Electron 已在实测 214px 面板验证无横向溢出,以及原生键盘返回列表、打开笔记和追加保存。