164 lines
8.1 KiB
Markdown
164 lines
8.1 KiB
Markdown
# opencode_bridge 交接文档
|
|
|
|
## 状态速览
|
|
|
|
**分支**:`main`(已切回,在 main 上操作)
|
|
**远端**:`http://101.43.40.124:3000/tao.chen/notebook-ai-extension.git`
|
|
**当前 HEAD (main)**:`d650736 chore: bump version to 0.1.2`
|
|
**Tag**:`v0.1.2` → `d650736`(已推到远端,CI 会自动 build + 发 Gitea release + Bark 通知)
|
|
|
|
```
|
|
d650736 chore: bump version to 0.1.2 ← main HEAD, v0.1.2
|
|
f9d52f7 docs: add HANDOVER.md for next session context
|
|
310d507 fix: SSE filter no longer drops content events for a different session
|
|
```
|
|
|
|
⚠️ **重要分歧**:`main` 这次的 v0.1.2 发布**只包含了 version bump**,没有功能改动。完整功能(per-cell → 全局 floating panel 重构)在分支 `feature/floating-ai-button` 上,**未合并**。git status 是干净的,如果你想继续 feature,先 `git checkout feature/floating-ai-button`。
|
|
|
|
```
|
|
feature/floating-ai-button HEAD:
|
|
12ec84a docs: refresh HANDOVER for floating panel work (d412130)
|
|
d412130 fix: hide+show cycles no longer accumulate prompt nodes in floating panel
|
|
c0eba7e feat: replace per-cell AI button with global floating panel
|
|
(已 push 到远端 + tracking 已设)
|
|
```
|
|
|
|
---
|
|
|
|
## 本次会话做了什么(按时间序)
|
|
|
|
1. **HANDOVER.md 初版**(上一任留下的)— 已读
|
|
2. **创建 `feature/floating-ai-button` 分支**
|
|
3. **重构**:把 per-cell 工具栏 AI 按钮(`OpenCodeCellActions`)整个换成全局右下角悬浮按钮 + 弹出 panel
|
|
- 新增 `src/components/opencode_floating_panel.ts`(Widget,挂 `document.body`)
|
|
- 删除 `src/components/opencode_cell_actions.ts`(逻辑搬上去)
|
|
- 改 `src/components/opencode_inline_prompt.ts` — 加 `getActiveCell?: () => CodeCell | null` 回调,3 处 cell 引用全用回调
|
|
- 改 `src/index.ts` — 删 `toolbarRegistry.addFactory`,接入 floating panel
|
|
- 改 `style/base.css` — 删 `.opencode-cell-actions`,新增 `.opencode-floating-*`(fixed 定位、z-index 1000)
|
|
- 重命名 + 重写 `src/__tests__/opencode_floating_panel.spec.ts`
|
|
4. **Bug fix (d412130)**:hide+show 循环累积 prompt 节点 — 用户手测报告,在 `_hidePrompt` 加 defensive DOM cleanup
|
|
5. **Commit + push** 到 `feature/floating-ai-button`(只到这,没合并)
|
|
6. **回 main**:**用户决定在 main 上单独发 v0.1.2**(只 bump 版本号,不含功能)
|
|
7. **v0.1.2 tag + push**
|
|
|
|
---
|
|
|
|
## 验证状态
|
|
|
|
| 检查 | 结果 |
|
|
|------|------|
|
|
| Jest | ✅ 68/68(3 suites)— **在 feature 分支验证过**,main 上 0.1.2 没跑过 |
|
|
| pytest | ✅ 73/73(同上,feature 分支) |
|
|
| `tsc --noEmit` | ✅ exit 0(feature 分支) |
|
|
| ESLint | ⚠️ 2 pre-existing 命名错(`FlatProvider`/`BlockEntry` 接口名,不符合 `/^I[A-Z]/u`),我没引入 |
|
|
| `jlpm build:prod` | ⚠️ 未跑(见下) |
|
|
|
|
---
|
|
|
|
## ⚠️ 下个 agent 必须知道的几件事
|
|
|
|
### 1. Codex 在本会话里基本不可用 ⚠️⚠️⚠️
|
|
|
|
CLAUDE.md 强制 `model: kimi/kimi-k2.7-code`(或后来的 `kimi/kimi-k2.6`),但火山方舟 Coding Plan proxy 反复拒绝:
|
|
|
|
- `kimi-k2.7-code` — HTTP 400 "model not valid"(模型名错)
|
|
- `kimi/kimi-k2.7-code`(CLAUDE.md 当前版本) — 同样被拒
|
|
- `kimi-k2.6` — HTTP 400 "reasoning is not supported"
|
|
- `kimi/kimi-k2.7-code` noop 偶尔通一次,然后实际任务又失败
|
|
|
|
**实际代码工作几乎全是 CC 手动做的**。Codex 临死前对 spec 文件做了一次有用的部分重写(改完了 65% 然后挂了)。
|
|
|
|
**建议下次**:
|
|
- 先 noop 测一次 Codex,通了再用;不通直接走 CC fallback(CLAUDE.md 规则 `codex-fail-3x → switch-to-cc`)
|
|
- 如果必须用 Codex,可能需要你这边再调一次 proxy 配置
|
|
|
|
### 2. d412130 bug 的防御性修复 + 测试局限
|
|
|
|
**症状**:点悬浮按钮 → 显示 panel。再点 → 隐藏。再点 → **看到 2 个 prompt 同时显示**(节点累积)。
|
|
|
|
**根因**:`OpenCodeFloatingPanel` 用 `Widget.attach(prompt, this._panelEl)` 把 Lumino Widget 挂到裸 `HTMLDivElement` 上(host 不是 Widget),所以 prompt 的 Lumino `_parent` 是 null。真实 Lumino `Widget.dispose()` 在 parent=null 时走 `Widget.detach(this)` 分支按理能清 DOM,但实际有遗漏场景。
|
|
|
|
**修法**(`src/components/opencode_floating_panel.ts` 的 `_hidePrompt`):
|
|
```ts
|
|
if (this._prompt) {
|
|
const node = this._prompt.node;
|
|
this._prompt.dispose();
|
|
if (node.parentNode === this._panelEl) { // defensive
|
|
this._panelEl.removeChild(node);
|
|
}
|
|
this._prompt = null;
|
|
}
|
|
```
|
|
|
|
**回归测试局限**:`src/__tests__/opencode_floating_panel.spec.ts` 的测试 mock `Widget.dispose()` 直接用 `node.parentNode.removeChild` 清 — **比真实 Lumino 更激进**,所以这个回归测试在 mock 下永远过。**真实 bug 只能在真实 JupyterLab 里复现和验证**。如果你看到类似累积 bug,**必须真跑 JupyterLab**,别只信 jest pass。
|
|
|
|
### 3. 几个 `_onShellChanged` / `as any` 的取舍
|
|
|
|
- `_onShellChanged` 写成 **arrow function class field**(`= (): void => { ... }`)而不是 method,这样 `this` 锁定到实例上(Lumino signal 调用 slot 时 `this` 不可靠)
|
|
- `this._app.shell as any` 出现过几次 — 因为 `JupyterFrontEnd.shell` 在不同 JupyterLab 版本里类型签名是 `JupyterShell | null`,严格模式要求 cast。可以后续更精确处理,但当前能用
|
|
|
|
### 4. `jlpm build:prod` 没跑成功
|
|
|
|
`.venv/bin/jlpm` 是 Python 入口脚本,直接 `jlpm build:prod` 找不到。我试过 `python -m jupyter_builder.jlpm build:prod` 但也失败(参数解析对不上)。**完整 labextension 打包未验证** — 只跑了 `jest` + `tsc --noEmit` 间接确认编译能过。如果发版前要打包验证,你可能要在终端手动跑。
|
|
|
|
### 5. `v0.1.2` 是个"假版本"
|
|
|
|
只 bump 了 `package.json` 的 version 字段(`pyproject.toml` 是 hatch dynamic,从 git tag 自动读),**没有功能变更**。发这个 tag 大概是为了占位 / 触发 CI。下次真发版时需要把 `feature/floating-ai-button` 合并到 main,然后重新打 tag。
|
|
|
|
---
|
|
|
|
## 仍然没做的事
|
|
|
|
- [ ] 把 `feature/floating-ai-button` 合到 main(用户说"暂时不管",所以还没合)
|
|
- [ ] **真实 JupyterLab + OpenCode Serve 端到端测试** — 没在活的 JupyterLab 里点过按钮。bug d412130 是用户手测报的
|
|
- [ ] **Playwright UI tests** — 项目交接文档里说写过 spec 但没跑,本次也没动
|
|
- [ ] **pre-existing lint 错清理**:`FlatProvider` → `IFlatProvider`,`BlockEntry` → `IBlockEntry`(2 处改名,小 PR)
|
|
- [ ] **`jlpm build:prod`** — 没跑通(见上)
|
|
- [ ] **CI 验证**:`v0.1.2` tag push 触发 CI,看一下 `.github/workflows/build.yml` 跑通没
|
|
|
|
---
|
|
|
|
## 关键文件速查(给下任的 quick map)
|
|
|
|
```
|
|
src/components/opencode_floating_panel.ts ← 新文件,核心逻辑都在这(310+ 行)
|
|
src/components/opencode_inline_prompt.ts ← 解耦 Cell,加了 getActiveCell 选项
|
|
src/__tests__/opencode_floating_panel.spec.ts ← 重写后的测试(1556 行,68 tests)
|
|
src/index.ts ← 极简,只剩 activate() + 挂 floating panel
|
|
style/base.css ← 找 .opencode-floating-* 块
|
|
```
|
|
|
|
参考架构/HTTP 细节(未变)参考本仓库 HANDOVER.md 之前章节的 [架构](#架构) / [主要路由](#主要路由) / [关键设计决策](#关键设计决策-避免来回改)。
|
|
|
|
---
|
|
|
|
## 测试命令
|
|
|
|
```bash
|
|
# 后端
|
|
.venv/bin/pytest opencode_bridge/tests/ -q # 73 passed
|
|
|
|
# 前端
|
|
./node_modules/.bin/jest --no-coverage # 68 passed
|
|
./node_modules/.bin/tsc --noEmit # exit 0
|
|
./node_modules/.bin/eslint --ext .ts,.tsx src/ # 仅 pre-existing 错
|
|
|
|
# 在哪个分支跑? feature/floating-ai-button 上跑过了,main 上 v0.1.2 没跑
|
|
```
|
|
|
|
---
|
|
|
|
## 上下文管理提示
|
|
|
|
上下文快满了。新 agent 第一件事:
|
|
|
|
1. **读这份 HANDOVER.md 全文**(包括本节之前的所有内容)
|
|
2. `git log --oneline -5` 确认 commit hash 没变
|
|
3. 跑上面 4 个验证命令
|
|
4. 如果要继续 feature 工作 → `git checkout feature/floating-ai-button`
|
|
5. 如果只是在 main 上发版 → 留在这里,准备好就 `git merge feature/floating-ai-button`(或 PR 流程)
|
|
|
|
**不要**:
|
|
- 不要从 main 重新开发 — 浪费时间
|
|
- 不要相信 jest 单测覆盖 d412130 那类 bug — 必须在真 JupyterLab 里点
|
|
- 不要相信 Codex 能用 — 先 noop 测一下 |