docs: spec for moving AI cell buttons into native Cell toolbar
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c919c95842
commit
9e7c36e323
@@ -0,0 +1,74 @@
|
||||
# AI 操作按钮迁入原生 Cell Toolbar — 设计
|
||||
|
||||
- 日期: 2026-07-23
|
||||
- 状态: 已批准(用户于 2026-07-23 确认)
|
||||
|
||||
## 背景与问题
|
||||
|
||||
当前 `✨ 优化` / `🐛 排错` / `🪄 编辑` 三个按钮渲染在每个 cell **底部** 的 `ICellFooter` 里,链路为:`installOpenCodeEverywhere` 替换每个 notebook 的 `contentFactory` → `OpenCodeCellContentFactory.createCellFooter()` → `OpenCodeCellFooter` widget。
|
||||
|
||||
问题:按钮位置不符合预期 —— 应出现在每个 cell **右上角**、JupyterLab 原生 cell toolbar 的上移/下移按钮(`move-cell-up` / `move-cell-down`)旁边。
|
||||
|
||||
## 已确认的决策
|
||||
|
||||
| 问题 | 决策 |
|
||||
|---|---|
|
||||
| 可见性语义 | 跟随原生 toolbar:只在 **active cell** 右上角显示(与上移/下移按钮行为严格一致) |
|
||||
| 底部 footer | **删除**,三个按钮全部上移 |
|
||||
| 点击交互 | 本次不变:`🪄 编辑` 仍用 `window.prompt`;结果仍走 `Notification`;inline prompt box / diff 面板留待后续 |
|
||||
| 作用范围 | 仅 `CodeCell`;Markdown 等 cell 不显示 AI 按钮(现状 footer 挂在所有 cell 上,属顺带修正) |
|
||||
|
||||
## 机制(JupyterLab 4.6 真实扩展点,已核实源码)
|
||||
|
||||
- 原生 cell toolbar 由内置 `@jupyterlab/cell-toolbar-extension` 提供,toolbar factory 名为 `'Cell'`,settings 驱动;默认按钮(含 `move-cell-up` / `move-cell-down`,rank 均为默认 50)由其 schema 的 `jupyter.lab.toolbars` 贡献。
|
||||
- 第三方扩展通过 `IToolbarWidgetRegistry.addFactory<Cell>('Cell', '<itemName>', factory)` 注册 widget factory;**factory 收到具体的 `Cell` 实例**,toolbar 由 tracker 按 cell model 缓存。
|
||||
- 自己的 `schema/plugin.json` 顶层加 `"jupyter.lab.toolbars": { "Cell": [...] }` 即可把该项贡献进原生 toolbar,无需 DOM 注入或 CSS 定位。
|
||||
- 原生 toolbar 只渲染在 active cell 内(`activeCellChanged` 时移动),空间不足时自动隐藏 —— 我们的按钮随它一起获得这些行为。
|
||||
|
||||
## 设计
|
||||
|
||||
### 组件改造
|
||||
|
||||
- `src/components/opencode_cell_footer.ts` → 改造为 `src/components/opencode_cell_actions.ts`:
|
||||
- `OpenCodeCellActions extends Widget`,**构造函数直接接收 `CodeCell`**(factory 传入),不再在 `onAfterAttach` 里靠 `this.parent instanceof CodeCell` 解析宿主。
|
||||
- `model.contentChanged` / `stateChanged` 订阅保持,`onBeforeDetach` 摘除。
|
||||
- 渲染逻辑不变:`✨ 优化` / `🐛 排错`(无 error output 时禁用) / `🪄 编辑`;loading 时全部禁用。
|
||||
- 错误提示统一走 `Notification`,widget 内不再渲染 error span(toolbar 空间小)。
|
||||
- 模块级 `setOpenCodeRuntime()` 运行时注入机制不变。
|
||||
- 删除 `src/components/opencode_cell_factory.ts`、`src/components/opencode_installer.ts`。
|
||||
|
||||
### 注册与配置
|
||||
|
||||
- `src/index.ts`:
|
||||
- `optional` 增加 `IToolbarWidgetRegistry`(来自 `@jupyterlab/apputils`,已是依赖)。
|
||||
- activate 中:`toolbarRegistry.addFactory('Cell', 'opencode-cell-actions', (cell) => cell instanceof CodeCell ? new OpenCodeCellActions(cell) : new Widget())`;非 CodeCell 返回空 widget。
|
||||
- 移除 `installOpenCodeEverywhere` 调用及 import。
|
||||
- `schema/plugin.json` 顶层增加:
|
||||
```json
|
||||
"jupyter.lab.toolbars": {
|
||||
"Cell": [{ "name": "opencode-cell-actions", "rank": 100 }]
|
||||
}
|
||||
```
|
||||
默认按钮 rank 为 50,我们排 100 → 出现在 delete-cell 右侧,紧邻上移/下移按钮组。
|
||||
- `style/base.css`:新增 `.opencode-cell-actions` 紧凑按钮样式(适配原生 toolbar 高度)。
|
||||
|
||||
### 上下文提取(不变)
|
||||
|
||||
widget attach 后仍用现有 `extractCellContextFromCell`(沿 `cell.parent` 链 duck-typing 找 `NotebookPanel`)。cell 实例改由构造参数传入,比现在更可靠。
|
||||
|
||||
### 测试与文档
|
||||
|
||||
- `src/__tests__/opencode_cell_footer.spec.ts` → `opencode_cell_actions.spec.ts`:构造时直接传 cell,删除 `Object.defineProperty(footer, 'parent', ...)` 相关 hack,断言不变(三按钮渲染、禁用态)。
|
||||
- `design.md` 第 2 节交互描述更新:悬浮 toolbar → 原生 cell toolbar(仅 active cell 显示)。
|
||||
|
||||
## 兼容性
|
||||
|
||||
- 纯前端 UI 搬迁;REST 契约、Python server 端零改动。
|
||||
- `cell-toolbar-extension` 被禁用时,我们的按钮与原生按钮一起消失(行为一致,可接受)。
|
||||
- 移除 contentFactory 覆写后,不再受"已打开的 cell 需 reload 才生效"的限制。
|
||||
- `IToolbarWidgetRegistry` 声明为 `optional`,registry 缺失时插件仍可激活(按钮不显示)。
|
||||
|
||||
## 验证
|
||||
|
||||
- `jlpm test`、`jlpm lint:check`、`jlpm build` 全部通过。
|
||||
- 手动:`jupyter lab` 打开 notebook,active cell 右上角出现三个按钮,位于 delete 按钮右侧;无错误的 cell 上 `🐛 排错` 禁用;切换 active cell 按钮随之移动。
|
||||
Reference in New Issue
Block a user