NotebookLM 增强器

发布: (2026年2月5日 GMT+8 05:06)
10 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的具体文本内容,我将按照要求保留源链接并将文本翻译成简体中文。

项目概述

一个 Chrome 扩展,将 NotebookLM 那混乱的侧边栏转变为美观有序的文件夹系统,因为 47 条研究笔记不该看起来像一堆数字洗衣。

如果你使用过 NotebookLM,你会知道它在研究方面非常神奇——上传 PDF,粘贴 URL,提问……它就像一个永不睡觉的研究助理。唯一让人抓狂的地方?当笔记超过十条时,侧边栏会变成噩梦。

问题(示例)

15 篇关于 Spring Framework 的研究论文
8 篇关于微服务的文章
12 条你保存的“以后再看”的随机书签

全部。都。在。一个。巨大的。列表中。
没有文件夹。没有组织。只有……混乱。

Source:

解决方案概述

我构建了一个 Chrome 扩展,将完整的文件夹管理系统直接注入 NotebookLM 的侧边栏

智能文件夹组织

  • 创建文件夹和子文件夹(仅 1 层深,保持简洁)
  • 拖拽笔记在文件夹之间移动,伴随流畅动画
  • “收件箱”视图,用于未分配的笔记
  • 每个笔记本项目拥有独立的文件夹(不交叉污染)

与 NotebookLM 匹配的精致 UI

  • 使用 Angular + Tailwind CSS 构建
  • 暗色 / 亮色 / 系统主题切换
  • 极简设计,感觉原生
  • 平滑的展开 / 收起动画

国际化

  • 完整的 i18n 支持(目前提供英文 / 西班牙文)
  • 一键语言切换器
  • 所有 UI 文本均可翻译

智能集成

  • 点击任意笔记 → 打开原生 NotebookLM
  • 点击三点菜单 → 原生菜单出现在右侧(匹配原生位置)
  • 从原生侧边栏拖拽笔记 → 放入我们的文件夹
  • “新建笔记”按钮触发原生 NotebookLM

稳健的架构

  • Chrome Extension MV3(最新 Manifest 版本)
  • 内容脚本 + Shadow DOM 实现样式隔离
  • 基于 Iframe 的 Angular 应用提供 UI
  • postMessage 桥接 iframe ↔ 页面通信
  • chrome.storage.sync 实现跨设备持久化

这不是一个简单的内容脚本,只是添加几个按钮。它是一个完整的微前端架构:

┌─────────────────────────────────────────────────────────┐
│  NotebookLM Page                                        │
│  ┌──────────────────────────────────────────────────┐ │
│  │  Native Sidebar (hidden but functional)          │ │
│  │  • Still handles clicks & menus                  │ │
│  │  • We extract data from it                       │ │
│  └──────────────────────────────────────────────────┘ │
│                       ↓                                 │
│  ┌──────────────────────────────────────────────────┐ │
│  │  Our Injected Host (Shadow DOM)                  │ │
│  │  ┌───────────────────────────────────────────┐   │ │
│  │  │  Iframe (Angular App)                     │   │ │
│  │  │  • Folder tree                            │   │ │
│  │  │  • Drag & drop (Angular CDK)              │   │ │
│  │  │  • Theme toggle                           │   │ │
│  │  │  • Note add / folder add…                 │   │ │
│  │  │  • i18n                                   │   │ │
│  │  └───────────────────────────────────────────┘   │ │
│  └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

为什么在 Shadow DOM 中使用 iframe?

Concern(关注点)Reason(原因)
Isolation(隔离)NotebookLM 使用 Angular Material 并带有全局样式;我们的 iframe 能保持 Tailwind 样式的纯净
Security(安全)内容脚本难以直接访问 iframe 内部,反之亦然
Performance(性能)Angular 应用独立运行,不会污染主页面

通信流程

  1. 内容脚本读取原生 DOM → 提取笔记本数据
  2. postMessage → Angular 显示组织好的文件夹
  3. 用户将笔记拖入文件夹 → postMessage 发送回内容脚本
  4. 内容脚本更新 chrome.storage.sync

技术亮点

Storage V3 与 Notebook 隔离

不再使用全局文件夹结构,每个 NotebookLM 项目都有自己的独立状态:

// StorageStateV3
{
  "byNotebook": {
    "uuid-abc-123": {
      "folders": [ /* … */ ],
      "notebookFolderByKey": { /* … */ }
    },
    "uuid-def-456": {
      "folders": [ /* … */ ],
      "notebookFolderByKey": { /* … */ }
    }
  }
}

这意味着你的 “Work” 文件夹结构不会泄漏到 “Personal” 研究中,实现了干净的分离。

处理 MV3 Service Worker 休眠

Chrome MV3 Service Worker 在 30 秒无活动后会进入休眠,导致 chrome.runtime 调用失效。
我们没有使用 “keep‑alive” 的 hack,而是:

  • 优雅地检测上下文失效
  • 在下一帧时静默重试
  • 将日志写入我们自己的 NLE.log(),而不是刷屏 console.warn

原生拖拽桥接

让原生 NotebookLM 侧边栏项目可拖拽相当棘手。我们:

  • 在原生项目上挂载 dragstart 事件
  • 在拖拽期间在 iframe 上方创建不可见的覆盖层
  • 使用 elementFromPoint() 并结合坐标计算放置目标

结果: 原生笔记可以无缝拖入我们的文件夹。

模态框自动聚焦输入

一个小小的 UX 细节,却能带来巨大差异:

  • 创建文件夹 → 输入框已自动聚焦,直接键入
  • 重命名文件夹 → 文本已预选,直接键入覆盖
  • 无需额外点击

前后对比

之前(没有聚焦)

之后(自动聚焦)

(如有需要,可在此插入截图)

演示

  • 完整视频: (link or embed placeholder)

我使用 GitHub Copilot CLI 的经验

本项目几乎全部通过 GitHub Copilot CLI 交互构建,将自然语言转化为可投入生产的代码。

架构决策

# Asked Copilot: "Best way to inject UI into an existing Angular Material page?"
# Copilot suggested: Shadow DOM + iframe for isolation
# Result: Zero style conflicts with NotebookLM's Material Design

内容脚本结构

# Asked: "How to structure 8 content scripts that share state?"
# Copilot proposed: Module pattern with window.__NLE__ namespace
# Result: Clean separation, no global pollution

拖拽实现

# Asked: "Bridge native HTML5 drag with Angular CDK drop?"
# Copilot designed: Overlay system with postMessage bridging

(为简洁起见,省略了后续提示和迭代。)

结束语

“NotebookLM Enhancer” 展示了一个结构良好的 Chrome 扩展如何 将混乱的研究工作流转变为整洁高效的体验,同时利用现代网页技术(Angular、Tailwind、MV3)以及 GitHub Copilot CLI 的强大功能。

欢迎随意浏览代码仓库,尝试该扩展,并告诉我你的感受!

坐标翻译

结果: 从原生侧边栏无缝拖动到我们的文件夹

调试上下文失效

提问: “Chrome MV3 扩展上下文失效错误?”
Copilot 实现: 优雅检测 + 静默重试逻辑
结果: 没有控制台垃圾信息,平滑恢复

i18n 系统

Asked: “Lightweight i18n without ngx‑translate bloat?”
Copilot built: Custom TranslationService with lazy loading
Result: ~3 KB vs ~50 KB, full interpolation support

Highlights

  • Speed – 本来需要数周的工作在几天内完成。像 drag bridge 这样的复杂功能在数小时内实现,而不是数天。
  • Architecture – Copilot 提出了我之前想不到的模式(例如 iframe‑in‑shadow 方法),优雅地解决了隔离问题。
  • Edge Cases – MV3 的怪癖、Material Design 菜单定位、SPA 导航检测——Copilot 都处理得很顺畅。
  • Learning – 每一次交互都是学习的时刻 🙂。我现在了解了 Chrome Extension 架构、Angular 独立组件以及 Tailwind 的自定义方式。

即将推出的功能

  • Chrome Web Store 上线 – 打磨、打包、发布
  • 更多语言 – 法语、德语、葡萄牙语(使用我们的 i18n 系统轻松实现)
  • 搜索与过滤 – 在文件夹中即时查找笔记
  • 键盘快捷键 – 高级用户功能(例如 Ctrl+Shift+N 用于新建文件夹)

🤝 开源

该项目将开源。想要贡献吗?

  • 欢迎 PR
  • 适合新手的 issue: 翻译、主题、文档

资源与致谢

  • Google for NotebookLM – 一个令人惊叹的研究工具
  • GitHub Copilot CLI – 将想法转化为代码的速度前所未有 <3
  • Tailwind CSS – 让暗黑模式变得轻而易举
  • DEV.to – 承办此挑战并凝聚社区

GitHub 仓库

Built with ❤️ and a lot of help from GitHub Copilot CLI.

devchallenge
githubchallenge
cli
githubcopilot
Back to Blog

相关文章

阅读更多 »

我能在脑海中看到我的成功

成功的幻象 我看得很清楚。我的 app 已经上线,毫无 bug,用户们赞不绝口。投资者们接连来电。我的 GitHub repo 的 stars 像潮水般涌入。

GitHub Issues 置顶评论

我们已发布了两项针对 GitHub Issues 的更新,使其更易于浏览并帮助降低噪音。现在,您可以从评论中将评论置顶到议题的顶部。