fix: give notes and todos dedicated workspace layouts
GoodBuddy Agents / Validate Agent source (push) Canceled after 0s
GoodBuddy Agents / Build darwin arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux x64 Agent (push) Canceled after 0s
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s

Replace the crowded note sidebar with a card overview and full note detail. Keep tasks in a stable split view with source content and AI comments, compact header navigation, and search-adjacent status filters. Preserve drafts and return context.

Validation: 93 focused tests, typecheck, lint, and isolated Electron renderer checks passed. Full suite was interrupted; renderer probes used in-memory APIs.

Release note: Notes now open from a card overview, while todos keep a stable task list beside their details. Compact view and filter controls leave more room for reading and editing.
This commit is contained in:
mesalogo
2026-09-18 21:22:58 +08:00
parent 5aad0cf5f7
commit a8d1dbc11f
11 changed files with 1386 additions and 2474 deletions
+11 -6
View File
@@ -105,9 +105,9 @@ records are listed separately and do not introduce another feature status.
managed SSH project with bounded output, resizing, termination, and explicit
reconnection. Closing a terminal tab ends its Shell; restarting the app
restores only an ended tab description and never restarts the Shell. The
main sidebar and Magic Notes list support pointer and keyboard resizing;
the notes list can be hidden, remembers its layout, and stacks at narrow
widths.
main sidebar and Magic Notes editor's AI pane support pointer and keyboard
resizing. The AI pane remembers its visibility and width, and stacks below
the editor at narrow widths.
- [ ] **Project Agent Space** (planned): Unifies roles, knowledge, Skills/MCP,
models, approval policy, budgets, and timeouts in a Project, with reusable
templates.
@@ -599,10 +599,15 @@ records are listed separately and do not introduce another feature status.
demand or before every response, show zero-result, degraded, failed, and
cancelled states, and expose cited context or safely open its source.
- [x] **Magic Notes**: A local-first notes and todo workbench with scope
management, editing, filtering, and controlled AI comments. The todo view
displays the source entry inside the selected item's details, without
management, editing, filtering, and controlled AI comments. Notes open from a
responsive card overview. The separate To-dos tab offers search, status filters,
grouped tasks and direct completion, with instructions, source entries and AI
comments in a right detail pane beside a stable task list. Narrow views offer
on-demand detail with an explicit return to the list. Content-sized tabs sit
beside New note in the header; status filters follow search. Source-note
navigation returns to the same task context, without
showing the previous item's source after a selection change. Failed reads
use application notifications, and missing sources have an explicit fallback. The left
use application notifications with inline retry, and missing sources have an explicit fallback. The left
navigation can show the incomplete-todo count, and create, save, and comment
results use application-wide notifications. Agent/MCP note writes automatically
refresh the open workbench while preserving selection and unsaved drafts.
+2 -2
View File
@@ -28,7 +28,7 @@
- [x] **工作区文件与 Git 管理**:支持文件和目录的新建、重命名、移动、删除、属性查看,以及本地/远程分支搜索与切换、新建分支、显式 Fetch、提交历史和单文件提交差异。工具按文件/Git 视图分组,分支搜索使用统一紧凑表单,子目录保留文字导航而根目录不再显示孤立图标。提交历史贴底,首次展开占 Git 内容区一半,支持调整比例、独立滚动和统一刷新;切换项目自动检测 Git,不沿用其他项目状态。移动限于工作区内,删除须确认,分支冲突不自动 stash 或丢弃改动;托管 SSH 操作需要 Agent `0.11.23`。
- [x] **富文本回答**:支持 GitHub Flavored Markdown、LaTeX 数学公式、受控 Mermaid 图表和会话内 HTML 静态预览。Agent 完成回复后,完整 HTML 与 HTML 代码块可在原位置预览,并通过图标按钮查看源码或打开全屏预览;该能力默认开启,可在“平台功能 / 通用设置”关闭,预览不执行脚本、联网、表单提交或窗口操作。
- [x] **AI 回复与完整会话复制**:已完成的 AI 回复可从消息底部复制不含推理、工具日志和引用元数据的 Markdown 原文;完整会话复制复用同一条经过 Preload/Main 校验的剪贴板路径。
- [x] **助手工作栏、多终端与可调布局**:工作栏开关位于明暗主题按钮旁;右侧工作栏使用持久“+”能力目录和应用 Tab,任务中心与工作区为不可关闭的单实例,浏览器可打开多个独立实例。任务中心可切换当前项目和所有项目,范围随布局保存;无项目任务在所有项目中标注“未绑定项目”。用户可为当前本机或托管 SSH 项目打开多个独立终端,获得有界输出、调整尺寸、结束与显式重连。关闭终端 Tab 会结束 Shell,应用重启只恢复已结束的 Tab 描述,不自动重启 Shell。主侧栏和魔法笔记列表支持鼠标与键盘调宽,魔法笔记列表可隐藏并记住布局,窄宽度下自动堆叠。
- [x] **助手工作栏、多终端与可调布局**:工作栏开关位于明暗主题按钮旁;右侧工作栏使用持久“+”能力目录和应用 Tab,任务中心与工作区为不可关闭的单实例,浏览器可打开多个独立实例。任务中心可切换当前项目和所有项目,范围随布局保存;无项目任务在所有项目中标注“未绑定项目”。用户可为当前本机或托管 SSH 项目打开多个独立终端,获得有界输出、调整尺寸、结束与显式重连。关闭终端 Tab 会结束 Shell,应用重启只恢复已结束的 Tab 描述,不自动重启 Shell。主侧栏和魔法笔记编辑器的 AI 评论栏支持鼠标与键盘调宽;AI 评论栏记住显示状态及宽度,窄窗口下移至编辑器底部。
- [ ] **项目 Agent Space**(规划中):在 Project 中统一角色、知识、Skills/MCP、模型、审批策略、预算和超时,并支持模板复用。
- [ ] **应用中心与导航**(整体验收待完成):底部应用中心向上展开轻量锚定菜单,无模态遮罩,只列已启用应用,不按打开历史或常驻筛选。点击应用行关闭菜单,本机推理监控打开保留底层工作区的独立 Modal,其余应用打开主内容区;底部“管理应用”打开可搜索卡片及设置详情,布局与交互见 [UI 设计](./docs/features/application-tool-navigation/ui-design.md)。四张应用卡片均支持上下移动和拖动排序,不受启用或常驻状态限制;卡片、菜单和经过过滤的侧栏共用一份保存顺序。知识库和智能心跳始终启用并常驻,标注“始终显示”,提供“打开”和排序,不提供启用、常驻开关或通用空设置;原工作区配置和心跳单条计划 enabled 不变。可选启用、常驻和共同设置仅适用于魔法笔记、本机推理监控。旧可选应用顺序补齐默认项并保留已有相对顺序;未发布的 `knowledgeEnabled`、`heartbeatEnabled` 已移除,不增加开关键迁移。设置持久化后的事件同步各入口,包括工具配置写入;重开中心刷新期间锁定修改,新快照覆盖迟到的旧读取。`local-inference` Modal 直接显示服务列表,不展示任务历史或外部连接;向量服务显示独立进程 CPU 与工作集内存,ASR/OCR 说明共享进程无法独立统计的原因。ASR 就绪状态未知,不从活动请求推断运行中。受支持的服务操作保留影响确认,失败后刷新列表并要求重新确认;TTS 显示不可用。取消中的推理在 Worker 确认或退出前仍计入活动任务及服务停止影响。此前类型检查和 `npx eslint src` 通过;完整 `npm test` 为 4,448 项通过、67 项跳过、2 项失败,仍为未改动的心跳迁移 `duplicate column name: pinned`;全仓 lint 仍有无关 story-graph Demo 的 22 个 `document` 错误。8 个 Electron fixture 主题/尺寸场景覆盖键盘、焦点、几何、原生视图遮挡及真实设置 Store 持久化,不代表完整生产 App 验收。最新验证及剩余边界见[验证进度](./docs/features/application-tool-navigation/progress.md)。
- [ ] **通用助手工作栏与执行空间后续能力**(规划中):在现有工作栏和多终端基础上继续加入监督、统一 Runtime、受管进程、静态安全 HTML 预览、可固定目标的工作区/浏览器/成果实例、底部停靠与独立窗口。Task Center 保持 Task 的单例索引,附件与知识库继续由会话输入区管理,未来的记忆与历史执行上下文归入关联 Task。详见 [Feature PRD](./docs/features/assistant-workbar/prd.md)。
@@ -90,7 +90,7 @@
- [x] **分块、维护与评估**:支持固定、结构化和父子分块,分块维护、可取消重建及双语检索评估。
- [x] **受控知识本体**:每个知识库可定义实体、关系、别名和端点约束,保留证据偏移、置信度和抽取来源,并显式提示图谱重建。
- [x] **强制检索与引用上下文**:对话可按需或每次先检索,显示零结果、降级、失败与取消状态,并可查看引用上下文或安全打开来源。
- [x] **魔法笔记 / Magic Notes**:提供本地优先的笔记与待办工作台、范围管理、编辑、筛选和受控 AI 评论;来源记录直接显示在所选待办的详情中,切换事项不会混入上一项的来源内容,读取失败使用应用通知,来源缺失有明确提示。左侧入口可按设置显示未完成待办数量,创建、保存和评论结果使用统一应用通知。Agent / MCP 写入后,已打开的工作台自动更新,并保留当前选择与未保存草稿。
- [x] **魔法笔记 / Magic Notes**:提供本地优先的笔记与待办工作台、范围管理、编辑、筛选和受控 AI 评论。笔记从自适应卡片总览打开;独立待办页提供搜索、状态筛选、分组列表和直接勾选,宽屏列表稳定在左侧,任务说明、来源记录及 AI 评论在右侧同一区域显示,窄屏按需显示详情并提供返回列表。紧凑页签放在页头新建按钮左侧,筛选放在搜索右侧。打开原笔记再返回可恢复任务上下文;切换任务不会混入上一项的来源内容,读取失败使用应用通知并提供就地重试,来源缺失有明确提示。左侧入口可按设置显示未完成待办数量,创建、保存和评论结果使用统一应用通知。Agent / MCP 写入后,已打开的工作台自动更新,并保留当前选择与未保存草稿。
- [ ] **MCP Server Control Plane**(规划中):统一 MCP 生命周期、健康检查、重连、Schema 缓存、隔离、审批和审计。
- [ ] **可追溯笔记摘录与 AI 编辑**(规划中):从对话、知识和网页收集带来源的摘录,并提供需确认的总结、改写和整理操作。
+9 -8
View File
@@ -714,20 +714,21 @@ GoodBuddy 是可调整窗口大小的桌面应用。响应式设计优先保证
### 13.7 魔法笔记
- “笔记 / 待办”属于同一工作台内的同级内容面板,使用 `PageTabs` 的 `segmented` 视觉变体,与模型设置的分段控件保持同一外观。
- “笔记 / 待办”属于同一工作台内的同级内容面板,使用 `PageTabs` 的 `segmented` 视觉变体,放在页头“新建笔记”按钮左边,不另占一行导航。按内容宽度显示,不拉伸;窄窗口操作组可换行到标题下方,保留控件高度。
- 页签切换保留 `tablist`、`tab` 和 `tabpanel` 语义;待办状态仍使用独立的 `SegmentedControl`,不得与内容页签合并。
- 笔记编辑器保留 Quill 原生列表快捷输入:输入 `-`、`*`、`1.`、`[ ]` 或 `[x]` 后按空格,分别转换为项目符号、编号或待办清单。快捷输入只生成现有 Delta 富文本,不引入 Markdown 源码模式、第二套持久化格式或第三方 Markdown 插件;编辑区附近持续提供简短提示。
- 左侧笔记与待办列表在双栏布局中允许在 `180px` 至 `360px` 范围内通过指针或键盘调整,
也可从页面标题区隐藏和恢复;宽度与显示状态均记住用户选择。分隔条保留 `separator`
语义及方向键、Home、End 操作,窄窗口堆叠布局不显示拖拽分隔条。
- 左侧笔记列表依次显示标题、最多两行内容预览,以及同一行的记录数和本地化更新时间。记录数靠左、更新时间靠右,窄宽度下均保持单行省略,不挤压标题或扩大列表栏。
- 整篇笔记的置顶、取消置顶和删除放在列表项的“更多”菜单,标题编辑区不重复提供入口。按钮在悬停、键盘聚焦或菜单展开时显示,触屏设备常显;菜单沿用会话列表样式,通过 Portal 避免滚动区域裁切,支持方向键、Home、End 和 Escape。删除在菜单内二次确认并说明笔记标题及全部记录;打开菜单不切换笔记,置顶或删除其他笔记不丢弃当前草稿。
- 默认进入笔记总览,不自动打开第一篇笔记。笔记以自适应卡片网格平铺,卡片显示标题、最多两行内容预览、记录数和本地化更新时间。点击笔记进入详情,详情不保留内部左列表;“返回总览”恢复搜索、滚动位置和入口焦点。新建入口在笔记总览与待办页可见,创建成功后进入笔记详情。
- 待办页是独立任务视图:搜索任务标题、说明或来源笔记,搜索框右侧同一工具栏放置“全部 / 未完成 / 已完成”筛选,显示匹配数与总数;任务按来源笔记分组。列表独立滚动,页头、搜索和筛选保持可见,窄屏工具栏空间不足时换行。直接勾选完成或恢复未完成,不自动选择任务;状态变化后按当前筛选更新列表。
- 待办内容容器宽于 `700px` 时,任务列表稳定在左侧,右侧显示当前任务说明、来源记录和 AI 评论;未选择时右侧提示选择任务。点击任务只更新右侧,不改变列表宽度、行位置或滚动位置,再次点击取消选择。AI 不增加第三栏。容器不超过 `700px` 时,按需详情替换同一内容区域,并提供“返回待办列表”;列表保持挂载,返回恢复滚动和任务行焦点,不将列表与详情上下堆叠。任务按钮提供 `aria-expanded` 和 `aria-controls`。
- 待办 AI 评论保留方向选择、流式输出、重新分析和已有结果;来源加载失败通过应用通知提示,并提供就地重试。从待办打开原笔记后,“返回待办”恢复任务选择、搜索、筛选和列表滚动;宽屏焦点返回任务行,窄屏返回待办详情中的返回按钮。
- 笔记详情保留可隐藏的 AI 点评栏,宽度和显示状态记住用户选择。宽布局分隔条保留 `separator` 语义及方向键、Home、End 操作;内容容器不超过 `800px` 时 AI 移至底部,高度不超过可用布局的 40% 且最多 `280px`,不显示分隔条。
- 整篇笔记的置顶、取消置顶和删除放在卡片的“更多”菜单,标题编辑区不重复提供入口。按钮在悬停、键盘聚焦或菜单展开时显示,触屏设备常显;菜单沿用会话列表样式,通过 Portal 避免滚动区域裁切,支持方向键、Home、End 和 Escape。删除在菜单内二次确认并说明笔记标题及全部记录;打开菜单不进入详情。
- 左侧“魔法笔记”入口可显示未完成待办数量。数量为 0 时隐藏徽标,超过 99 时显示 `99+`,可访问名称仍说明精确数量;勾选、取消勾选以及 Agent / MCP 对笔记清单的写入都必须刷新数量。
- 未完成待办徽标的高度不得超过主导航图标;数量从 0 变为可见或再次隐藏时,主导航项行高和相邻菜单位置必须保持不变。
- 在待办面板勾选或取消勾选后,当前缓存中的源笔记正文必须立即同步对应清单状态,不得依赖离开工作区后重新加载。
- Agent / MCP 或其他入口成功写入笔记后,已打开的工作台自动更新笔记列表、当前详情、待办及来源记录,不增加刷新按钮。保留仍存在的笔记与待办选择、搜索和筛选,以及未保存的标题、输入区和记录编辑草稿;普通后台刷新不重建编辑器。
- 外部删除当前笔记时,无草稿则选择剩余笔记;有草稿则保留编辑区并提示先复制草稿。外部删除正在编辑的记录时,同样保留该编辑器并明确提示记录已删除;保存失败不得清空草稿。
- 当前记录草稿非空时,切换笔记、待办或内容面板必须先在编辑器旁就地确认;继续编辑时保留草稿并恢复编辑焦点,只有明确选择放弃后才切换。
- 外部删除当前笔记时,无草稿则返回总览;有草稿则保留编辑区并提示先复制草稿。外部删除正在编辑的记录时,同样保留该编辑器并明确提示记录已删除;保存失败不得清空草稿。
- 当前记录草稿非空或标题尚未保存时,返回总览必须先就地确认;编辑另一条记录等会丢弃正文草稿的操作沿用同一保护。继续编辑时保留草稿并恢复编辑焦点,只有明确选择放弃后才切换。
- 创建、保存、更新、删除和 AI 评论完成等短期结果进入应用级通知,不在编辑区或列表上方堆放页内通知。
- 标题或正文校验、删除确认、同步进度和可就地恢复的错误仍靠近对应编辑器或操作呈现。
+9
View File
@@ -5,6 +5,15 @@ actions and authorized Agent/MCP tools write to the same desktop SQLite store.
The open workbench subscribes to successful writes so users can see external
changes without leaving the page or clicking a refresh button.
The workbench opens on a responsive note-card overview. Opening a note replaces
the overview with its detail and optional AI comments. The separate To-dos tab
keeps search, status filters and grouped tasks on one page, with direct completion
and a stable left list/right detail layout for instructions, source content and AI
comments. Narrow containers use on-demand detail with an explicit return to the
mounted list. Content-sized tabs sit in the page header immediately before New
note; status filters sit beside search and wrap when needed. Returning from a source note restores the task
context and protects unsaved editor changes.
## Documents
- [Technical design](./technical-design.md): database notifications, process
+65
View File
@@ -1,5 +1,70 @@
# Magic Notes Progress
## 2026-09-18: Stable Todo Split View and Header Navigation
- Supersedes the inline task expansion described in the earlier entry below.
Wide containers now keep the grouped task list on the left and instructions,
source and AI in one right detail pane. Narrow containers retain the mounted
list and offer on-demand detail with an explicit return. Source-note return
preserves task context. Header tabs precede New note; filters follow search.
- Focused workspace, editor and shared-primitives suites passed all 93 tests.
`npm run typecheck` and targeted ESLint passed. No full `npm test` was run.
- Reused the temporary Electron renderer probe at 1280x820, 600x760,
600x520 dark and 420x640. The 134x36 header switch precedes New note at all
four sizes. Search/filter share a row at 1280 and 600; filters wrap at 420.
The wide list's width, top, scroll and adjacent row coordinates remain equal
before and after task selection/switching. Narrow returns preserve nonzero
list scroll and restore focus. No horizontal overflow or console errors.
- Also verified source-note round trips at all sizes, actual Quill draft
confirmation, note-card return, AI visibility, task completion/status filters,
AI fixture results, creation and Chromium keyboard activation.
- Visible-window capture initially failed with Electron `UnknownVizError`.
Final probe uses Electron offscreen rendering at scale 1, pointer input and
Chromium DevTools keyboard input. It runs production React/Quill/CSS with
in-memory API fixtures, not the full App/Main/SQLite/model path. Model calls: 0.
Evidence remains under the temporary `opencode` directory in
`magic-notes-render-results.json` and `magic-todos-*-expanded.png`.
## 2026-09-18: Independent Todo Task View
- Replaced todo full-page navigation with a grouped task list and one inline
expansion for instructions, source content and AI comments. Completion works
directly in each row. Search/status controls stay above the scrolling list;
source-note navigation retains expansion, filters and initiating focus.
- Kept the note-card overview and note editor/AI layout. Notes/To-dos PageTabs
now size to their contents at desktop and narrow widths. Source failures offer
an inline retry alongside the existing notification.
- Focused command: `npx vitest run src/renderer/src/MagicNotesWorkspace.test.tsx src/renderer/src/MagicNoteEditor.test.tsx src/renderer/src/WorkspacePrimitives.test.tsx`:
93 tests passed. `npm run typecheck` and ESLint on the workspace, its tests and
both changed locale modules passed. Full `npm test` was not rerun, as requested.
- Reused the isolated Electron renderer probe at requested content sizes
1280x820, 600x760, 600x520 (dark) and 420x640. All four todo views retained
18 tasks, inline expansion, independently scrolling lists and no horizontal
overflow or detail/AI sidebar. Tabs measured approximately 133x35 CSS pixels.
Note-card navigation, actual Quill draft confirmation, AI visibility, source
navigation, direct completion, status filters and inline AI fixture output passed;
the renderer reported no console errors.
- The probe uses production React, Quill and CSS with in-memory API fixtures and
isolated Electron sessions; it does not validate Main/SQLite or a live model.
Model calls: 0. Scripts, screenshots and JSON results remain in the existing
temporary `opencode/magic-notes-render-*` probe location.
## 2026-09-18: Card Overview and Detail Navigation
- Replaced the persistent inner list with a responsive card overview and explicit
detail navigation. Search, todo filters, overview scroll and initiating focus
survive a round trip. Creation opens the new note; todo source navigation returns
to the todo overview. Back navigation protects entry and title drafts.
- Kept AI visibility and resizing preferences, removed obsolete list resizing,
and capped stacked AI height so short windows retain usable editor space.
- Focused workspace, editor and shared UI suites passed 90 tests. Typecheck and
full lint passed. The first full test invocation exceeded its 200-second limit.
- Isolated Electron rendering exercised the actual workspace, Quill and CSS at
1280x820, 600x760, 600x520 (dark), and 420x640. Navigation, creation, todo-source
jumps, draft confirmation, AI visibility, scroll and focus restoration passed.
These checks used in-memory API fixtures, not Main/SQLite integration; no real
model calls were made. Canvas functionality is outside this layout change.
## 2026-09-17: Note List Action Menu
- Moved pin/unpin and whole-note deletion from the editor header to each note's
+41 -5
View File
@@ -22,6 +22,15 @@ objects and returns a function removing that listener. The existing
## Refresh Lifecycle
The overview's `libraryView` and the optional note-only `detailView` are independent:
opening a todo's source note does not lose the originating task view.
The overview remains mounted but hidden while detail is open, retaining scroll
position and filters. Returning restores the initiating control's focus and
invalidates outstanding detail requests. Initial loading fetches summaries and
todos without selecting the first note or task. Navigation away from unsaved content or
an unsaved title uses the existing draft confirmation; active writes finish
before navigation. No new persistence or IPC contract is required.
`MagicNotesWorkspace` subscribes on mount and coalesces notifications with a
100 ms debounce. Pending notifications wait for an active local save or analysis
to finish. Cleanup removes the listener, clears its timer and invalidates pending
@@ -45,20 +54,47 @@ Read failures use the existing retryable refresh error and retain successful
data and drafts. Retry uses the same draft-preserving loader. Interaction rules
are owned by [the UI design system](../../../UI-DESIGN.md#137-魔法笔记).
## Todo Task View
The To-dos panel has its own search/status toolbar and independently scrolling
task list, grouped by source note. `selectedTodoId` controls one sibling detail pane;
the selected item is derived from the filtered list. Completion updates the
existing item and source cache without selecting or opening another task. Items
that no longer match the status filter leave the list. A removed focused control
returns focus to an available list/filter control.
Detail content includes instructions, the source entry, its existing note
navigation action, and AI controls/comments. AI requests still use the existing
analysis options and streaming subscription; failed analysis retains saved
comments. Source reads are guarded against superseded selections, report failures
through notifications and offer inline retry. The grid reserves both columns even
without a selection, so selecting or switching tasks cannot move list rows. The
detail is keyed by task ID to start each newly selected task at its top.
At a page container width of 700px or less, CSS hides the mounted list while a
task is selected and shows an explicit return button in the detail area. Returning
clears selection and restores row focus without scrolling; source-note return
retains selection and focuses this visible return button on narrow layouts.
There is no todo detail route, separate AI sidebar or resize handle. Note detail
retains its existing AI pane preferences.
The shared segmented `PageTabs` lives in `PageHeader.actions` before New note,
retaining tab/panel IDs, roving focus and arrow-key navigation. Its width follows
content at all sizes. The shared status `SegmentedControl` follows search in one
wrapping toolbar. These layout changes do not change Main, preload or storage.
## Note List Actions
Each note row has a selection button and a sibling action-menu button. The menu
Each overview card has an open-detail button and a sibling action-menu button. The menu
uses the conversation action styles and shared `DestructiveConfirmActions`, and
is portalled to `document.body`. Its position follows the trigger on scrolling,
window resizing and confirmation-size changes. Hiding the list, filtering out the
window resizing and confirmation-size changes. Entering detail, filtering out the
target or leaving the notes panel closes the menu.
Pinning uses the target summary's ID and revision through the existing update
IPC. It updates the sorted summary and matching selected detail without resetting
title, composer or entry-edit drafts. Deleting uses the explicitly confirmed
target ID; deleting another note uses the draft-preserving refresh path. Deleting
the selected note clears its entry drafts only after the write succeeds, then
selects a remaining note. These are renderer changes; database and Agent contracts
target ID and refreshes the overview after success, without opening another note.
These actions are available only in the overview. Database and Agent contracts
are unchanged.
## Agent Search Contract
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -28,8 +28,9 @@ export const magicNotes = {
analyzeAgain: 'Analyze again',
analyzing: 'Analyzing…',
openSourceNote: 'Open source note',
hideListPane: 'Hide left list',
showListPane: 'Show left list',
backToOverview: 'Back to overview',
backToTodos: 'Back to to-dos',
backToTodoList: 'Back to to-do list',
hideAiComments: 'Hide AI comments',
showAiComments: 'Show AI comments',
pinNote: 'Pin note',
@@ -104,8 +105,11 @@ export const magicNotes = {
listLabel: 'To-do list',
detailLabel: 'To-do details',
heading: 'All to-dos',
resultCount: '{{count}} / {{total}} items',
loadingSource: 'Loading source entry…',
retrySource: 'Retry loading source',
searchLabel: 'Search to-dos in the current scope',
searchPlaceholder: 'Search to-dos',
searchPlaceholder: 'Search tasks, instructions, or source notes',
filterLabel: 'Filter to-dos',
filters: {
active: 'Incomplete',
@@ -169,8 +173,6 @@ export const magicNotes = {
'Choose “Analyze with AI” on an entry to show comments here.'
},
accessibility: {
resizeListPane: 'Resize the note list and editor panes',
listPaneWidth: 'Left list, {{width}} pixels',
resizeAiPane: 'Resize the editor and AI comments panes',
aiPaneWidth: 'AI comments pane, {{width}} pixels'
},
@@ -24,8 +24,9 @@ export const magicNotes = {
analyzeAgain: '重新分析',
analyzing: '分析中…',
openSourceNote: '打开原笔记修改',
hideListPane: '隐藏左侧列表',
showListPane: '显示左侧列表',
backToOverview: '返回总览',
backToTodos: '返回待办',
backToTodoList: '返回待办列表',
hideAiComments: '隐藏 AI 评论',
showAiComments: '显示 AI 评论',
pinNote: '置顶笔记',
@@ -98,8 +99,11 @@ export const magicNotes = {
listLabel: '待办列表',
detailLabel: '待办详情',
heading: '全部待办',
resultCount: '{{count}} / {{total}} 项',
loadingSource: '正在加载来源记录…',
retrySource: '重试加载来源',
searchLabel: '搜索当前范围的待办',
searchPlaceholder: '搜索待办',
searchPlaceholder: '搜索任务、说明或来源笔记',
filterLabel: '筛选待办',
filters: {
active: '未完成',
@@ -157,8 +161,6 @@ export const magicNotes = {
manualHint: '在记录上点击“AI 分析”,评论会显示在这里。'
},
accessibility: {
resizeListPane: '调整笔记列表与编辑区宽度',
listPaneWidth: '左侧列表 {{width}} 像素',
resizeAiPane: '调整编辑区与 AI 评论宽度',
aiPaneWidth: 'AI 评论栏 {{width}} 像素'
},
+156 -217
View File
@@ -1260,31 +1260,19 @@
display: grid;
flex: 1;
min-width: 0;
min-height: 520px;
min-height: 0;
overflow: hidden;
border: 1px solid var(--border-default);
border-radius: var(--radius-card);
background: var(--surface-raised);
grid-template-columns:
var(--magic-notes-list-width, 220px) 9px
minmax(300px, 1fr) 9px
var(--magic-notes-ai-width, 280px);
}
.magic-notes-layout--ai-hidden {
grid-template-columns:
var(--magic-notes-list-width, 220px) 9px
minmax(300px, 1fr);
}
.magic-notes-layout--list-hidden {
grid-template-columns:
minmax(300px, 1fr) 9px
var(--magic-notes-ai-width, 280px);
}
.magic-notes-layout--list-hidden.magic-notes-layout--ai-hidden {
grid-template-columns: minmax(300px, 1fr);
.magic-notes-layout--ai-hidden,
.magic-notes-layout--overview {
grid-template-columns: minmax(0, 1fr);
}
.magic-notes-layout--resizing {
@@ -1292,7 +1280,6 @@
user-select: none;
}
.magic-notes-list-resize-handle,
.magic-notes-ai-resize-handle {
position: relative;
z-index: 2;
@@ -1303,14 +1290,6 @@
touch-action: none;
}
.magic-notes-list-resize-handle {
background: linear-gradient(
to right,
var(--surface-subtle) 0 4px,
var(--surface-raised) 4px 100%
);
}
.magic-notes-ai-resize-handle {
background: linear-gradient(
to right,
@@ -1319,7 +1298,6 @@
);
}
.magic-notes-list-resize-handle::after,
.magic-notes-ai-resize-handle::after {
position: absolute;
top: 0;
@@ -1333,25 +1311,20 @@
background var(--motion-fast) ease-out;
}
.magic-notes-list-resize-handle:hover::after,
.magic-notes-list-resize-handle:focus-visible::after,
.magic-notes-ai-resize-handle:hover::after,
.magic-notes-ai-resize-handle:focus-visible::after,
.magic-notes-layout--list-resizing
> .magic-notes-list-resize-handle::after,
.magic-notes-layout--ai-resizing
> .magic-notes-ai-resize-handle::after {
width: 2px;
background: var(--accent);
}
.magic-notes-list-resize-handle:focus-visible,
.magic-notes-ai-resize-handle:focus-visible {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
.magic-notes-list-pane,
.magic-notes-overview,
.magic-notes-stream-pane,
.magic-notes-ai-pane {
min-width: 0;
@@ -1359,37 +1332,32 @@
overflow: auto;
}
.magic-notes-list-pane,
.magic-notes-ai-pane {
background: var(--surface-subtle);
}
.magic-notes-list-pane[hidden],
.magic-notes-overview[hidden],
.magic-notes-ai-pane[hidden] {
display: none;
}
.magic-notes-list-pane {
.magic-notes-overview {
display: flex;
padding: var(--space-4);
flex-direction: column;
gap: var(--space-3);
}
.magic-notes-list-pane > .page-tabs--segmented {
width: 100%;
}
.magic-notes-list-pane > .page-tabs--segmented .page-tabs__tab {
flex: 1;
justify-content: center;
padding-inline: var(--space-2);
.magic-notes-page > .page-header .page-tabs {
flex: 0 0 auto;
align-self: flex-start;
width: fit-content;
}
.magic-notes-library-panel {
display: flex;
min-height: 0;
flex: 1;
flex: 0 0 auto;
flex-direction: column;
gap: var(--space-3);
}
@@ -1571,11 +1539,6 @@
background: var(--surface-muted);
}
.magic-todo-list-item--active {
border-color: var(--accent-selected);
background: var(--accent-subtle);
}
.magic-todo-list-item__check {
display: grid;
width: 28px;
@@ -1603,6 +1566,130 @@
cursor: pointer;
gap: var(--space-1);
text-align: left;
grid-template-columns: minmax(0, 1fr) auto;
}
.magic-todo-list-item__content > svg {
grid-column: 2;
grid-row: 1 / 3;
align-self: center;
color: var(--text-muted);
}
.magic-todo-list-item--completed strong {
text-decoration: line-through;
color: var(--text-muted);
}
.magic-todo-toolbar {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-3);
}
.magic-notes-overview--todos {
overflow: hidden;
}
.magic-notes-overview--todos .magic-notes-library-panel {
flex: 1;
}
.magic-notes-overview--todos .magic-notes-pane-heading,
.magic-todo-toolbar {
flex: 0 0 auto;
}
.magic-todo-toolbar .magic-notes-search {
flex: 1 1 240px;
min-width: 0;
}
.magic-todo-task {
min-width: 0;
border-bottom: 1px solid var(--border-subtle);
}
.magic-todo-task:has([aria-expanded='true']) {
border-radius: var(--radius-control);
background: var(--surface-subtle);
}
.magic-todo-workspace {
display: grid;
flex: 1;
min-height: 0;
min-width: 0;
grid-template-columns: minmax(280px, 34%) minmax(0, 1fr);
overflow: hidden;
}
.magic-todo-workspace > .magic-notes-list {
padding-right: var(--space-3);
}
.magic-todo-detail {
display: grid;
min-width: 0;
min-height: 0;
overflow: auto;
align-content: start;
border-left: 1px solid var(--border-subtle);
padding: var(--space-3) var(--space-4) var(--space-4);
gap: var(--space-4);
}
#magic-todo-back {
display: none;
}
@container magic-notes-page (max-width: 700px) {
.magic-todo-workspace {
grid-template-columns: minmax(0, 1fr);
}
.magic-todo-workspace--selected > .magic-notes-list,
.magic-todo-detail--empty {
display: none;
}
.magic-todo-detail {
border-left: 0;
padding: var(--space-3) 0;
}
#magic-todo-back {
display: inline-flex;
}
}
.magic-todo-detail h3,
.magic-todo-instructions {
margin: 0;
font-size: var(--font-body);
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.magic-todo-detail > button {
justify-self: start;
}
.magic-todo-comments {
display: grid;
min-width: 0;
gap: var(--space-2);
}
.magic-todo-comments .magic-notes-ai-controls {
display: flex;
align-items: end;
flex-wrap: wrap;
}
.magic-todo-comments .magic-notes-ai-controls > small {
flex-basis: 100%;
}
.magic-todo-list-item__content strong {
@@ -1687,25 +1774,30 @@
.magic-note-list-item {
display: grid;
width: 100%;
padding: var(--space-3);
border: 1px solid transparent;
border-radius: var(--radius-control);
background: transparent;
height: 100%;
min-height: 160px;
padding: var(--space-4);
border: 1px solid var(--border-default);
border-radius: var(--radius-card);
background: var(--surface-raised);
color: var(--text-secondary);
cursor: pointer;
gap: var(--space-1);
gap: var(--space-3);
grid-template-rows: auto 1fr auto;
text-align: left;
}
.magic-notes-card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
align-content: start;
gap: var(--space-4);
}
.magic-note-list-item:hover {
background: var(--surface-muted);
}
.magic-note-list-item--active {
border-color: var(--accent-selected);
background: var(--accent-subtle);
}
.magic-note-list-item__title {
display: flex;
overflow: hidden;
@@ -1760,127 +1852,6 @@
gap: var(--space-3);
}
.magic-todo-detail {
display: flex;
min-height: 100%;
flex-direction: column;
gap: var(--space-4);
}
.magic-todo-detail > header {
display: grid;
min-width: 0;
align-items: start;
padding-bottom: var(--space-3);
border-bottom: 1px solid var(--border-subtle);
gap: var(--space-3);
grid-template-columns: auto minmax(0, 1fr) auto;
}
.magic-todo-detail__check {
display: grid;
width: 36px;
height: 36px;
padding: 0;
border: 0;
border-radius: var(--radius-control);
background: var(--accent-subtle);
color: var(--accent);
cursor: pointer;
place-items: center;
}
.magic-todo-detail__check:hover {
background: var(--accent-selected);
}
.magic-todo-detail > header > div:nth-child(2) {
display: grid;
min-width: 0;
gap: var(--space-1);
}
.magic-todo-detail > header span {
color: var(--text-muted);
font-size: var(--font-caption);
}
.magic-todo-detail h2 {
margin: 0;
color: var(--text-primary);
font-size: 18px;
line-height: 1.35;
overflow-wrap: anywhere;
}
.magic-todo-detail__actions {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: var(--space-2);
}
.magic-todo-detail__actions button,
.magic-todo-detail__content .secondary-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-1);
}
.magic-todo-detail__content {
display: grid;
align-content: start;
padding: var(--space-4);
border: 1px solid var(--border-default);
border-radius: var(--radius-card);
background: var(--surface-subtle);
gap: var(--space-4);
}
.magic-todo-detail__content p {
margin: 0;
color: var(--text-primary);
font-size: 14px;
line-height: 1.7;
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.magic-todo-detail__content .secondary-button {
width: fit-content;
}
.magic-todo-detail__editor {
display: grid;
gap: var(--space-4);
}
.magic-todo-detail__editor label {
display: grid;
color: var(--text-secondary);
font-size: var(--font-body);
gap: var(--space-2);
}
.magic-todo-detail__editor input,
.magic-todo-detail__editor textarea {
width: 100%;
padding: var(--space-2) var(--space-3);
border: 1px solid var(--border-control);
border-radius: var(--radius-control);
background: var(--surface-raised);
color: var(--text-primary);
resize: vertical;
}
.magic-todo-detail__editor > div {
display: flex;
justify-content: flex-end;
gap: var(--space-2);
}
.magic-notes-ai-source {
color: var(--text-muted);
font-size: var(--font-caption);
@@ -2263,14 +2234,13 @@
@container magic-notes-page (max-width: 800px) {
.magic-notes-layout {
grid-template-columns:
var(--magic-notes-list-width, 210px) 9px
minmax(320px, 1fr);
grid-template-rows: minmax(0, 1fr) auto;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr) minmax(0, min(40%, 280px));
}
.magic-notes-layout--list-hidden {
grid-template-columns: minmax(320px, 1fr);
.magic-notes-layout--overview,
.magic-notes-layout--ai-hidden {
grid-template-rows: minmax(0, 1fr);
}
.magic-notes-ai-resize-handle {
@@ -2286,28 +2256,6 @@
}
@container magic-notes-page (max-width: 720px) {
.magic-notes-layout {
min-height: 0;
overflow: visible;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
}
.magic-notes-list-resize-handle {
display: none;
}
.magic-notes-list-pane {
max-height: 240px;
border-right: 0;
border-bottom: 1px solid var(--border-subtle);
}
.magic-notes-ai-pane {
max-height: none;
grid-column: auto;
}
.magic-note-composer > footer,
.magic-note-entry > header {
align-items: stretch;
@@ -2320,15 +2268,6 @@
flex-direction: column;
}
.magic-todo-detail > header {
grid-template-columns: auto minmax(0, 1fr);
}
.magic-todo-detail__actions {
justify-content: flex-start;
grid-column: 1 / -1;
}
}
* {