Files

8.1 KiB

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.2d650736(已推到远端,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 + pushfeature/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 同时显示(节点累积)。

根因:OpenCodeFloatingPanelWidget.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):

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 错清理:FlatProviderIFlatProvider,BlockEntryIBlockEntry(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 之前章节的 架构 / 主要路由 / 关键设计决策


测试命令

# 后端
.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 测一下