feat: 服务化 API 新增 urlTarget 外链认领 + 浏览器 HTTP/HTTPS 二级设置开关

基于 PR #74 的颗粒度讨论向前兼容拓展服务化 API:
- TabDescriptor 新增可选 urlTarget(url) 谓词:聊天/界面外链被拦截时按注册
  顺序路由到第一个命中的插件 tab 类型(openTab({ type, url, title })),
  内置 browser 退居隐式兜底;SIDEBAR_FEATURES 追加 'urlTarget'
- 浏览器链接设置改为二级菜单(齿轮弹窗):新增 browserInterceptHttp
  (默认开)+ browserInterceptHttps(默认关);browserInterceptLinks
  保留为总闸(默认开,旧文档零迁移)
- 拦截管线:registerLinkInterception 的 takeoverEnabled 改收解析后的
  URL,协议/同源纯判定(shouldInterceptLink)签名不变
- 测试:matchUrlTarget(注册顺序/抛错吞掉/browser 永不命中)、jsdom
  点击接管门控、parsePrefs 新字段默认值;全默认字面量同步
- 文档:设计文档 + AGENTS.md(字段/示例/设置键)+ README(外链分流)
This commit is contained in:
Menghuan1918
2026-08-15 15:05:06 +08:00
parent f842fa0029
commit 29f162dac0
18 changed files with 425 additions and 49 deletions
+2
View File
@@ -95,6 +95,8 @@ export const PrefsSchema: z<SidebarPrefs> = z.object({
htmlViewerDefaultUnsafe: z.boolean().default(false),
browserNoSandbox: z.boolean().default(false),
browserInterceptLinks: z.boolean().default(true),
browserInterceptHttp: z.boolean().default(true),
browserInterceptHttps: z.boolean().default(false),
// Per-feature enable switches are OPEN maps (any tab/viewer id, built-in or
// external): an absent key means enabled, so old documents resolve to {}
// (everything on) with no migration. Non-boolean values fail validation.