-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture zh
English | 中文 | 日本語 | 한국어 | Español | Português | Русский
browsa 是 Chrome MV3 扩展,侧边栏对话 UI。扩展源码零构建——所有 JS 由 Chrome 直接加载,唯一的构建步骤(build/build.mjs)只负责用 esbuild 打包 vendor 库。
页面 content scripts(MAIN world 拦截 / ISOLATED world 划词条)
│ chrome.runtime.sendMessage / port
▼
background.js(service worker,单一消息路由器)
│ handle() 大 switch —— case 体大都在 lib/handlers/* 模块
▼
侧边栏 sidepanel.js(UI 编排者)
▲
├── browsa-nav 长驻端口:NAVIGATED / XHS 推送 / SELECTION_ACTION
├── browsa-chat 每回合新开:主聊天流(chunk 推送协议)
└── browsa-subchat 每次发送新开:追问卡流
-
background.js是唯一的chrome.runtime.onMessage路由器:一个handle()switch 仍是测试导入的单一出口,最大的 case 体拆在lib/handlers/(chat / subchat / session / attach 系列 / mermaid-repair / provider-resolver / approval-relay / agent-stream-session / prompt-assembly / site-cache-store 等)。 - 流式状态(
streamPorts/streamState/chatControllers/ 待审批 Map 等)单份住在lib/state.js,background.js re-export——测试import { ... } from '../background.js'拿到的是同一批 Map 实例。
-
browsa-nav长驻:面板 init 时连一次,SW 重启后经connectNavPort()模式重连(1s 退避;新 port 对象必须重新挂全部 onMessage 监听)。它代表「面板当前在看哪个 tab」,切 tab 时经NAV_FOLLOW改注册即可,符合语义。 -
browsa-chat/browsa-subchat每回合/每次发送新开:一回合 = 一个端口。SW 睡死导致的断连不需要自愈——下一次发送自然开新的。这是故意设计:一回合一条生命周期,状态不会跨回合泄漏。
- 多数 handler:成功
{ ok: true, data }/ 抛错{ ok: false, error, code, hint }。 - 少数 handler(
APPROVAL_RESPOND/CLARIFY_RESPOND等)内部再包一层{ ok, ... },因为它们自己 catch 中继失败而不抛。 - 判断某个 case 属于哪种,读那个 case 的实现,别猜。错层读信封是 2026-08 全库排雷踩过的一族真 bug(如
LOAD_SESSION未命中返回 -1、res.data.ok才是内层成败)。
切走会话不再取消进行中的回合。核心路由规则一句话:面板正看着这条流时回合写入 LIVE history(bg === false);一旦后台化就写入 origin 会话快照。persistTurnEntry 是唯一写入者;REASSIGN_STREAM_SESSION(切走自动保存时)与 STREAM_PEEK(切回重挂)是仅有的两个改 bg 的消息。中止带流文本的回合按 { interrupted: true } 收尸进 origin(Esc/空闲超时/断网),显式清空历史才 salvage:false。
- SW 空闲 ~30s 睡眠。模块级 Map 每次重启清零——持久状态不许放 Map。
- SW 内
setTimeout在消息处理返回后不可靠——用chrome.alarms或chrome.storage.session。 -
监听器按需注册是本库的常态化纪律:
chrome.webNavigation三监听只在有 navPort 时注册、tabs.onRemoved按需注册、流 GC alarm 只在streamState非空时存在——否则每次导航/关 tab 都冷启动 SW(644KB 模块解析)去空跑。 -
chrome.storage.session跨 SW 重启存活(同浏览器会话内),用于站点缓存 restore、pending SELECTION_ACTION 等。
chrome.tabs.onActivated 不许碰 DOM——Chrome 让侧边栏 document 跨 tab 存活。只更新 currentTabId、页眉文字,并向 navPort 发 NAV_FOLLOW。流中止(STREAM_ABORT)按流自己的 tab 寻址(streamTabIdOf()),不是面板当前 tab。
| 路径 | 职责 |
|---|---|
background.js |
SW;handle() 分发 + 内联小 case(ATTACH_PAGE 等) |
lib/handlers/* |
大 case 体:chat / subchat / session / attach-* / approval-relay / provider-resolver / stream-dispatch / agent-stream-session / site-cache-store / attach-store / attach-modes |
lib/state.js |
流式状态 Maps + pushChunk 协议 + 终态墓碑 |
lib/llm-client.js |
wire protocol 层:四条流共用 openSseStream() 骨架 |
lib/message-builder.js |
四种 provider 形状的请求构造 + ageStaleAttachments
|
lib/agent-turn.js / lib/image-budget.js
|
agent 回合公共层(文本/图片预算/回填) |
lib/prompt-assembly.js |
CAPABILITY_HINTS_ENTRIES 单一文本源(渲染契约不分叉) |
lib/storage.js |
chrome.storage.local 包装;全局 history + 会话拆键 |
lib/sidepanel/* |
UI 侧 26 个模块(渲染管线、会话抽屉、追问卡、时间线……见渲染管线页) |
lib/content-scripts/* |
MAIN world 站点拦截器 + ISOLATED 划词条;站点知识库 SITES.md
|
lib/page-extractor.js 等 |
附加抽取层(reader/dom/full/auto 级联 + 站点 fast-path + PDF/Office/ASR 交接) |
源头:AGENTS.md「Message flow」「Port lifecycle」「MV3 service worker gotchas」「Background streams across session switches」等节;CONTEXT.md 词汇表。同步于 2026-10-01。
English
- Home
- Architecture
- Rendering Pipeline
- Storage Model
- Providers and Agents
- ASR and Video Analysis
- Security Model
- Design Decisions
- Contributing
中文
相关 / Related
日本語
한국어
Español
- Inicio
- Arquitectura
- Pipeline de renderizado
- Modelo de almacenamiento
- Proveedores y agentes
- ASR y análisis de vídeo
- Modelo de seguridad
- Decisiones de diseño
- Contribuir
Português
- Início
- Arquitetura
- Pipeline de renderização
- Modelo de armazenamento
- Provedores e agentes
- ASR e análise de vídeo
- Modelo de segurança
- Decisões de design
- Contribuindo
Русский