bookmark-research 0.5.0-beta.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.codex-plugin/plugin.json +6 -1
  3. package/README.md +78 -56
  4. package/README.zh.md +74 -52
  5. package/bin/bookmark-research.js +9 -1
  6. package/config/providers.json +41 -0
  7. package/config/settings.example.json +36 -0
  8. package/docs/bookmark-research-architecture.md +8 -119
  9. package/docs/canvas-tree-reading-acceptance.md +98 -0
  10. package/docs/configuration.en.md +70 -0
  11. package/docs/configuration.md +70 -0
  12. package/docs/details.en.md +35 -32
  13. package/docs/details.md +12 -13
  14. package/docs/distribution.md +4 -7
  15. package/docs/harness-compatibility.md +10 -299
  16. package/docs/installation.en.md +21 -47
  17. package/docs/installation.md +24 -56
  18. package/docs/instructions.en.md +3 -3
  19. package/docs/instructions.md +3 -3
  20. package/docs/prompt-reference.en.md +3 -3
  21. package/docs/prompt-reference.md +3 -3
  22. package/docs/user-guide.en.md +5 -4
  23. package/docs/user-guide.md +7 -6
  24. package/hosts/claude/commands/research.md +7 -0
  25. package/hosts/codex/delegate.md +3 -1
  26. package/hosts/dsh/plugin.js +5 -0
  27. package/hosts/dsh/workflow-call.py +8 -4
  28. package/hosts/shared/research-call.py +15 -3
  29. package/hosts/shared/research-flow.js +3 -1
  30. package/install.sh +8 -8
  31. package/package.json +3 -8
  32. package/scripts/bench_preflight.py +189 -0
  33. package/scripts/bench_sync.py +191 -0
  34. package/scripts/bench_tools_list.py +129 -0
  35. package/scripts/build_zip.py +1 -10
  36. package/scripts/evaluate_ladder.py +149 -0
  37. package/scripts/export_bundle.py +6 -68
  38. package/scripts/host_assets.py +31 -31
  39. package/scripts/host_clients.py +32 -61
  40. package/scripts/host_install.py +24 -12
  41. package/scripts/install.py +233 -77
  42. package/scripts/launcher.py +28 -5
  43. package/scripts/npm_source.py +41 -0
  44. package/scripts/verify_fixture.py +1 -1
  45. package/scripts/verify_live.py +2 -2
  46. package/scripts/verify_wiki_retrieval.py +158 -0
  47. package/skills/bookmark-research/SKILL.md +31 -31
  48. package/skills/bookmark-research/references/cli.md +20 -8
  49. package/skills/bookmark-research/references/deep-research.md +12 -4
  50. package/skills/bookmark-research/references/host-workflows.md +4 -23
  51. package/skills/bookmark-research/references/package-semantics.md +67 -10
  52. package/skills/bookmark-research/references/research-methods.md +1 -1
  53. package/skills/bookmark-research/references/research-services.md +25 -47
  54. package/skills/bookmark-research/references/research-workflow.md +8 -4
  55. package/skills/bookmark-research/references/settings-and-archive.md +29 -11
  56. package/skills/bookmark-research/references/wiki.md +92 -0
  57. package/skills/bookmark-research/references/zh/cli.md +20 -8
  58. package/skills/bookmark-research/references/zh/deep-research.md +12 -4
  59. package/skills/bookmark-research/references/zh/host-workflows.md +4 -23
  60. package/skills/bookmark-research/references/zh/package-semantics.md +67 -10
  61. package/skills/bookmark-research/references/zh/research-methods.md +1 -1
  62. package/skills/bookmark-research/references/zh/research-services.md +27 -47
  63. package/skills/bookmark-research/references/zh/research-workflow.md +8 -4
  64. package/skills/bookmark-research/references/zh/settings-and-archive.md +28 -10
  65. package/skills/bookmark-research/references/zh/skill-guide.md +26 -33
  66. package/skills/bookmark-research/references/zh/wiki.md +94 -0
  67. package/src/archive.py +560 -25
  68. package/src/bookmark_dependencies.py +56 -0
  69. package/src/bookmark_index.py +1237 -58
  70. package/src/browser_client.py +342 -0
  71. package/src/cli.py +399 -33
  72. package/src/context_output.py +53 -0
  73. package/src/credentials.py +2 -1
  74. package/src/deepseek.py +137 -0
  75. package/src/discovery.py +118 -0
  76. package/src/dsh_client.py +206 -0
  77. package/src/fetch_cache.py +60 -0
  78. package/src/grok_search.py +272 -0
  79. package/src/jina.py +1 -1
  80. package/src/jobs.py +349 -0
  81. package/src/junk.py +33 -0
  82. package/src/locate.py +862 -0
  83. package/src/mcp_dispatch.py +99 -0
  84. package/src/mcp_server.py +899 -93
  85. package/src/netscape.py +124 -0
  86. package/src/onboarding.py +339 -114
  87. package/src/package_paths.py +137 -0
  88. package/src/perplexity.py +78 -0
  89. package/src/raw_library.py +255 -48
  90. package/src/readiness.py +43 -9
  91. package/src/ref_codec.py +70 -0
  92. package/src/release.py +1 -1
  93. package/src/research.py +449 -41
  94. package/src/research_plan.py +171 -0
  95. package/src/research_services.py +48 -21
  96. package/src/routing.py +50 -16
  97. package/src/search_results.py +84 -3
  98. package/src/settings.py +135 -18
  99. package/src/source_inputs.py +156 -23
  100. package/src/source_manager.py +79 -15
  101. package/src/source_versions.py +115 -0
  102. package/src/source_watcher.py +4 -2
  103. package/src/storage.py +60 -0
  104. package/src/tui.py +5 -2
  105. package/src/url_classify.py +45 -0
  106. package/src/web_search.py +662 -70
  107. package/src/wiki.py +788 -47
  108. package/src/wiki_search.py +251 -0
  109. package/src/wiki_work.py +229 -0
  110. package/docs/cli-launcher-plan.md +0 -58
  111. package/docs/diff-review-2026-10-09.md +0 -36
  112. package/docs/harness-sources.json +0 -342
  113. package/docs/host-validation.json +0 -340
  114. package/docs/install-design-0.2.0.md +0 -57
  115. package/docs/knowledge-storage-plan.md +0 -43
  116. package/docs/mcp-aggregation-0.2.0.md +0 -92
  117. package/docs/multi-host-installation-plan.md +0 -163
  118. package/docs/provider-smoke-0.2.0.json +0 -235
  119. package/docs/release-notes-0.5.0-beta.1.md +0 -33
  120. package/docs/release-notes-0.5.0-beta.2.md +0 -23
  121. package/docs/release-notes-0.5.0-beta.3.md +0 -28
  122. package/docs/release-notes-0.5.0-beta.4.md +0 -39
  123. package/docs/release-notes-0.5.0-beta.5.md +0 -31
  124. package/docs/release-notes-0.5.0-beta.6.md +0 -30
  125. package/docs/release-notes-0.5.0-beta.7.md +0 -57
  126. package/docs/release-notes-0.5.0-beta.8.md +0 -34
  127. package/docs/release-notes-0.5.0-beta.9.md +0 -35
  128. package/docs/research-0.2.0.md +0 -140
  129. package/docs/research-sources-0.2.0.json +0 -9360
  130. package/docs/validation-0.2.0.md +0 -126
  131. package/docs/validation-0.4.0.md +0 -154
  132. package/docs/wiki-quality.md +0 -107
  133. package/docs/wiki-quality.zh.md +0 -107
  134. package/hosts/pi/register-workflow.py +0 -72
  135. package/hosts/pi/runtime.js +0 -18
  136. package/scripts/verify_quality.py +0 -87
  137. package/skills/bookmark-research/references/wiki-and-evaluation.md +0 -69
  138. package/skills/bookmark-research/references/zh/wiki-and-evaluation.md +0 -69
  139. package/src/evaluation.py +0 -337
@@ -1,124 +1,13 @@
1
- # Bookmark Research 0.4.0 结构图
1
+ # 三个宿主,共用三项基础能力
2
2
 
3
- 用户可以直接用自然语言说明“查什么、查多大范围、要什么结果”,不用背固定提示词。安装并加载 Skill 后,由 Codex、Claude Code、Pi 或 DSH 理解请求,再调用插件工具执行。下面先看使用过程,再看内部结构。
3
+ Codex、Claude Code、DeepSeek Harness 负责推理、工具选择、并发和最终表达。插件保留三项职责:
4
4
 
5
- | 研究方式 | 用户可以这样说 | 对书签/画布包怎样处理 | 交付 |
6
- | --- | --- | --- | --- |
7
- | ① 快速查证 `quick` | “打开包里 Exa 的官方文档,查一下它是否支持 MCP。” | 找到对应书签,读取已有 URL;找不到明确来源时,搜索后读取关键页。 | 简短答案与来源链接。 |
8
- | ② 主动搜索 `agentic` | “比较我收藏的搜索服务,查清检索、正文读取和研究能力的区别。” | 读取相关卡片说明、书签和分组语境;拆出问题,搜索、读文、比较,再根据证据缺口补查。 | 带证据的比较与结论。 |
9
- | ③ 深度研究 `deep` | “把整个 AI 调研包全量调查,核验排行榜,与我们的插件比较,交付报告和 Wiki。” | 冻结完整来源清单,按专题组织持续调查,保存证据,逐项审阅,检查遗漏与冲突后交付。 | 研究档案、覆盖明细、报告;按要求整理 Wiki。 |
5
+ 1. **上下文**:读取 JSON Canvas 节点、连接线、卡片与空间关系。时间信息保留来源与可信度;Git 历史直接交给宿主 shell。
6
+ 2. **外部调研**:已知 URL 直接读取;Agentic Search 由宿主判断缺口并迭代搜索/阅读,插件提供补充搜索、并发抓取与归档。Deep Research 可直接提交 OpenAI/Parallel API,无需本地研究会话。宿主已有的浏览器、爬虫或研究工具也可供稿。
7
+ 3. **LLM Wiki**:检索已有知识,一次提交正文与精确引用,保留来源、修订和页面关系,供后续调研复用。
10
8
 
11
- 第一行是插件的“快速查证”流程。[OpenAI 官方文档](https://developers.openai.com/api/docs/guides/tools-web-search)中的 **Non-reasoning** 指模型不进行主动的多轮搜索规划,并不要求用户已经有 URL。插件可以提供短流程,但不会把宿主模型自动切成非推理模型。Exa、Parallel、Tavily 是供这些流程使用的检索服务,不与三种研究深度一一对应。
9
+ 日常流程是:**取上下文 → 独立检索 Wiki/归档 → 阅读与搜索 → 宿主形成结论 → 按授权保存 Wiki**。`plan_research` 只提供候选,既不设相关性硬门槛,也不决定研究路线;没有书签命中仍会查询其他存储。默认工具面为 22 个。`search_web` 聚合插件管理的 URL provider;Perplexity Search 返回结构化来源。Grok 和自定义 OpenAI 兼容端点通过 `agentic_search` 独立返回模型回答与引用,引用未经独立核验,不参加 URL 排名。宿主和其他 MCP 工具仍由宿主模型编排。
12
10
 
13
- 默认 `research.depth=auto`:宿主根据任务判断深度,也可以遵循用户明确提出的“这次快速查证”或“这次深度研究”。`research_route` 只根据宿主报告的任务类型和可用工具建议入口;真正的工具调用、子代理启动或工作流执行由宿主发起。一般用户不需要手写这些参数。
11
+ 只有明确要求整包覆盖、持久化任务或中断后续做时,启用 `deep` 预设的完整 44 个工具及分组工作流。高级功能复用现有证据与存储;普通提问不要求经过 readiness、route、inventory 或 coverage 等阶段。
14
12
 
15
- ```mermaid
16
- flowchart TB
17
- Request["你说明范围、问题和交付要求"] --> Host["宿主读取 Skill<br/>判断采用哪种研究方式"]
18
- Host --> Context["按任务范围定位书签<br/>读取卡片说明、文件夹、组与连线语境"]
19
- Context -->|快速查证| Quick["读取目标网页<br/>必要时搜索发现来源"]
20
- Context -->|主动搜索| Agentic["拆问题 → 搜索 → 读文 → 比较"]
21
- Context -->|深度研究| Deep["冻结完整范围<br/>分组调查、记录证据、审阅与核验"]
22
- Quick --> Answer["简短答复与来源"]
23
- Agentic --> Check{"证据足够回答问题?"}
24
- Check -->|还不够,补查| Agentic
25
- Check -->|足够| Comparison["比较结论与证据"]
26
- Deep --> Coverage{"原始来源与研究问题有缺口?"}
27
- Coverage -->|有,继续调查| Deep
28
- Coverage -->|完成条件满足| Report["报告与覆盖明细<br/>按要求编写 Wiki"]
29
- ```
30
-
31
- 深度研究有两条执行路线:宿主自身持续搜索、阅读、推理,必要时使用可用子代理/工作流;或者调用已启用并配置凭据的 OpenAI Deep Research API/Parallel Task API。插件实现了专业服务接口,但安装插件或在提示词里写“Deep Research”不会自动启用账户访问。实际是否可用,以当前配置和服务调用结果为准。特定宿主的专用命令,例如已加载的 Claude `/deep-research`,还要按该命令的调用方式启动。
32
-
33
- 交给专业服务时,插件把明确的研究问题与选定原 URL 整理成请求;画布语境由宿主用于构造问题,本机目录不会自动变成云端可读资料。服务返回的报告进入证据档案,所引原页仍需核验,不能用一份外部报告代替整包覆盖检查。
34
-
35
- **研究深度与研究范围分别决定。** 只查一个书签就处理该书签;研究指定卡片就保留该卡片的范围;要求“研究整个包”时,默认保留整包全部原始 URL 和每个重复书签的语境。分批、子代理数量和搜索结果页数都不能缩小这个范围。深度研究中也会反复使用直接读取和主动搜索。
36
-
37
- 目录、ZIP 和单卡经过同一套接入程序。书签提供要读的 URL,卡片说明、文件夹、分组和连线提供研究语境;它们保存在本地索引中。仅问“某个书签在哪张卡片”时,查本地数据即可。接入包本身不会自动开始联网研究。
38
-
39
- 下面两张图对应当前 0.4.0 实现。宿主负责理解问题、模型推理、子代理或已有工作流;Plugin 提供安装封装,Skill 提供方法指令,Python 提供实际工具。CLI 和 MCP 共用同一套实现,也可以配置为共用本地数据。实线表示调用或数据流,虚线表示指令或配置影响。
40
-
41
- ```mermaid
42
- flowchart TB
43
- User["用户<br/>自然语言问题与数据包路径"] --> Host["AI 宿主<br/>Codex / Claude Code / Pi / DSH<br/>模型推理、任务组织与审阅"]
44
-
45
- subgraph Plugin["Bookmark Research Plugin"]
46
- Skill["Skill:Markdown 指令<br/>查询方法、研究规则与宿主路由"]
47
- MCP["本地 MCP 入口<br/>src/mcp_server.py · 工具随能力增长(本版 40 个)"]
48
- CLI["Python CLI 入口<br/>src/cli.py"]
49
- Core["共用 Python 运行时<br/>Python 3.9+ 标准库"]
50
- Sources["来源接入、增量同步与本地查询"]
51
- Research["搜索、正文读取与研究记录"]
52
- Knowledge["Wiki 保存、引用核验与质量评测"]
53
- MCP --> Core
54
- CLI --> Core
55
- Core --> Sources
56
- Core --> Research
57
- Core --> Knowledge
58
- end
59
-
60
- Skill -.->|提供方法指令| Host
61
- Host -->|工具调用| MCP
62
- Host -->|命令调用| CLI
63
- Settings["用户配置<br/>settings.json"] -.->|服务选择与存储位置| Core
64
- Input["用户的画布数据<br/>目录 / ZIP / 单卡 JSON"] --> Sources
65
- Research --> Remote["外部服务<br/>搜索、正文读取与可选研究 API"]
66
-
67
- subgraph Local["本地持久化数据:位于原包和插件缓存之外"]
68
- DB[("SQLite 查询索引<br/>index.sqlite3")]
69
- Snapshots["来源版本快照<br/>index.sqlite3.sources/"]
70
- Pages["网页响应与正文<br/>knowledge/"]
71
- Runs["研究清单、证据、覆盖与报告<br/>research/"]
72
- Wiki["Wiki 页面与不可变修订<br/>wiki/"]
73
- end
74
-
75
- Sources --> DB
76
- Sources --> Snapshots
77
- Research -->|读取书签与关系| DB
78
- Research --> Pages
79
- Research --> Runs
80
- Knowledge -->|读取已审阅证据| Runs
81
- Knowledge --> Wiki
82
- ```
83
-
84
- 各宿主的接入方式有所不同:Codex、Claude Code 使用 Skill + MCP;Pi 使用 Skill + CLI/stdio 桥,子代理工作流依赖已有扩展;DSH 使用 MCP 适配,并配置 Skill 发现和工作流服务。图中的宿主能力取决于实际安装与配置,适配实现及验证范围见[宿主支持说明](details.en.md#client-support)。
85
-
86
- SQLite 是随 Python 工具读写的本地数据库文件,用来查询书签、栏目、文件夹和画布关系,并记录来源与同步状态。它可以从来源快照重建,不需要单独启动数据库服务器。
87
-
88
- 默认数据目录为 `~/.local/share/bookmark-research/`,默认配置文件为 `~/.config/bookmark-research/settings.json`。安装插件提供工具与默认设置;首次接入用户数据后才建立来源记录。本地查询无需 API 密钥,网络服务按各自的认证要求配置。
89
-
90
- 数据接入与同步的关键是把**输入载体**和**来源寿命**分开。单卡中的“永久/临时”是内容类型;`snapshot`/`live` 决定后续怎样更新。
91
-
92
- ```mermaid
93
- flowchart TB
94
- Export["手动导出目录<br/>JSON + .canvas"] --> Read
95
- Zip["ZIP 数据包<br/>含完整包或单卡"] --> Read
96
- Card["单个卡片 JSON<br/>永久卡片 / 临时卡片"] --> Read
97
- Git["GitHub 等现有同步工具"] -->|将变化同步到磁盘| Directory["长期保留的本地目录"]
98
- Directory --> Read
99
-
100
- Read["统一读取与校验<br/>source_inputs.py"] --> Register["来源登记<br/>source_manager.py<br/>source_id、路径别名、mode、completeness"]
101
- Register --> Mode{"来源寿命"}
102
- Mode -->|snapshot| Fixed["固定快照<br/>新导出需主动重新接入"]
103
- Mode -->|live:仅目录| Live["持续目录<br/>首次接入及后续变化检查"]
104
- Trigger["更新触发<br/>MCP 进程内轮询 / CLI watch<br/>查询前补检查"] --> Live
105
-
106
- Fixed --> Sync["增量索引<br/>bookmark_index.py<br/>文件哈希比较与事务写入"]
107
- Live --> Sync
108
- Sync --> DB[("SQLite<br/>当前有效索引与来源状态")]
109
- Sync --> Versions["来源版本快照<br/>package/:必要原始协议文件<br/>manifest.json:哈希、路径与关系"]
110
- Versions -->|选择历史版本重新导入| Read
111
- DB --> Query["本地书签查询与画布关系查询"]
112
- ```
113
-
114
- 新的普通导出默认使用 `snapshot`,Git 仓库内目录默认使用 `live`;已登记来源沿用原模式。同一画布换路径导出时显式沿用 `source_id`,以后记住路径别名;不同画布不会因标题或 URL 相同而合并。
115
-
116
- 两种模式都会保存版本快照。局部导入保留下来的旧栏目也进入快照,因此删除原下载包后仍可使用已接入的 snapshot,并能从保存的版本恢复。默认 `completeness=partial` 保留此次未提供的文件;明确指定 `complete` 才按完整镜像删除缺失文件。已提供栏目内删除的书签仍会同步,单卡固定使用 `partial`。
117
-
118
- `live` 的后台检查跟随 MCP 进程:默认每 1 秒检查,普通变化稳定 2 秒后同步,整文件删除等待 5 秒。关闭进程后停止,重连和查询时补查。一次性 CLI 命令执行完即退出,持续监控需要运行前台 `watch`。Git 拉取、推送和登录由原有同步工具或宿主承担。
119
-
120
- 无效 JSON、目录暂时消失等情况会保留上次有效索引,并返回待更新或错误状态。这部分借鉴 CodeGraph 的增量更新和恢复机制,CodeGraph 本身不是运行依赖。详细参数与恢复命令见[来源生命周期说明](../skills/bookmark-research/references/source-lifecycle.md)。
121
-
122
- 普通书签查询和单个 URL 读取可以直接调用工具,无需先建立正式研究任务。正式全包研究中的搜索摘要、外部研究报告不能自动算作原始页面已读;覆盖不足时继续补查,或保存明确标记为未完成的报告。质量评测依据显式标注和运行数据,方法见[Wiki 与评测说明](wiki-quality.md)。
123
-
124
- **自动更新的边界:`live` 目录在检查时同步本地索引,不会自动抓网页、调用 LLM 或改写 Wiki。** 研究状态检查会比较冻结输入与当前索引;发生变化时提示 `source_freshness.requires_review`,Wiki 读取/核验会标记 `needs_review`。宿主据此发起补充调查和修订,旧正文、研究清单与 Wiki 修订继续保留。
13
+ Wiki 一次写入采用 `page.sections[].citations` 与顶层 `sources`,也兼容旧的 research claim 引用格式。程序校验引文与来源完整性,语义支持由宿主或人工审阅。API 报告是二手来源,关键结论仍应核查原文。
@@ -0,0 +1,98 @@
1
+ # Bookmark Canvas 树状定位手动验收
2
+
3
+ 本文用于在两个 GitHub 仓库的改动推送后,安装本地 Bookmark Research npm 包并重启 Codex 后验收。验收范围是新 AGENTS 模板对 Agent 的约束,以及 Bookmark Research 插件的局部树查询约束。它不验证浏览器导出代码是否已清理历史占位字段,也不授权修改书签包。
4
+
5
+ ## 测试前准备
6
+
7
+ 测试数据目录:`<画布包目录>`(例如 `~/Bookmark-Canvas/bookmark/书签画布`)。换环境时替换为实际画布包目录。
8
+
9
+ 1. 确认两个仓库的模板与插件改动已推送。
10
+ 2. 使用 Bookmark Research 仓库生成的本地 `.tgz` 安装/升级 Codex 插件,不从 npm 拉取线上版本。
11
+ 3. 完全退出并重启 Codex,重新打开测试数据目录对应的会话。
12
+ 4. 测试前记录包内文件列表及目标 JSON 的字节大小。不要把全包或大 JSON 全文贴进对话。
13
+ 5. 选择一个含多个层级的临时栏目 JSON。记录文件路径、栏目 ID、目标 folder/bookmark ID,以及目标附近的父子关系,作为本地核对依据。
14
+
15
+ 小型 JSON 可直接读入上下文;大型 JSON 必须由本地解析工具或插件索引读取必要节点。测试过程只读,不写回源文件。
16
+
17
+ ## 场景 A:仅模板,无 Bookmark Research 插件
18
+
19
+ 在 Codex 中关闭或暂时不可用 Bookmark Research MCP/Skill,只保留画布包提供的 AGENTS 模板及本地文件/终端工具。提交以下提示:
20
+
21
+ > 请按当前画布包的 AGENTS 模板,只读检查临时栏目中的目标书签。先确认目标文件大小;小文件可直接阅读,大文件请用本地解析工具按目标 ID 或标题定位,不要把整份 JSON 输出到对话。按显式 `type` 区分 folder 和 bookmark,不要因 folder 有 `url: ""` 或 bookmark 有 `children: []` 而误判。请返回源文件路径、栏目/section ID、目标 item ID、准确的父级路径、同级顺序、目标的必要字段,以及为回答读取了哪些父子节点、还有哪些范围未读取。不要改文件;没有 `.canvas` 证据时不要描述卡片坐标或空间关系。
22
+
23
+ 分别选择一个目标书签和一个目标文件夹运行。文件夹测试需说明其直接子项与更深后代的区别;同名候选存在时必须列出候选并用 ID/路径消歧,不能按标题猜唯一结果。
24
+
25
+ **通过标准**
26
+
27
+ - 使用本地解析/读取工具,且大型文件没有全文进入对话上下文。
28
+ - 目标类型以显式 `type` 判定,空占位字段没有改变判型。
29
+ - 返回的文件路径、ID、父路径和同级顺序能与源 JSON 核对一致。
30
+ - 明确区分已读取与未读取范围;不把局部样本称作全量检查。
31
+ - 源文件在测试前后保持不变;不臆造 `.canvas` 坐标、分组或连线。
32
+
33
+ ## 场景 B:模板与 Bookmark Research 插件共同工作
34
+
35
+ 启用本地安装的 Bookmark Research 插件并重启 Codex。先让 Agent 报告本会话中实际可调用的 Skill/MCP 工具;不能仅凭安装成功推断工具已经加载。随后提交:
36
+
37
+ > 请依照当前画布包的 AGENTS 模板,只读定位临时栏目中这个目标:`<填入目标书签标题或 item ID>`。优先使用当前会话实际可调用的 Bookmark Research 查询工具;先从指定包/source 找到唯一栏目和 section ID,再按 item ID 读取目标及祖先路径。如果目标是文件夹,请用 `folder_id` 查询其子树并按页读取,只取回答所需节点。明确报告查询的 source/section/item ID、父路径、同级位置、已读条数、总数与 `next_offset`/未读范围。请核对临时项按 `type` 判型,忽略空 `url`/`children` 对类型的干扰。插件结果是索引投影,不要将其当作完整源对象;不要修改文件。若工具不可调用,请说明并退回场景 A 的本地解析流程。
38
+
39
+ 至少执行三次查询:一条已知书签 ID;一个有多层后代的文件夹 ID;一个同名或重复 URL 候选(若数据中存在)。文件夹查询使用有限页大小,至少一次停在非空 `next_offset`,然后继续翻页确认分页边界。
40
+
41
+ **通过标准**
42
+
43
+ - 工具来自当前重启后的 Codex 会话,且检索的 source 与实际包一致;没有可用工具时清楚回退。
44
+ - 定点结果的祖先链与 `folder_id` 子树结果能用源 JSON 核验;分页的 `total`、每页条数和下一页偏移一致。
45
+ - 搜索结果保持书签实例、URL 和不同栏目/路径的区别;重复标题或 URL 不被错误合并为一个位置。
46
+ - 条目投影不把空 folder URL 当作链接,也不把 bookmark 的空 children 当作文件夹;原始文件中的这些字段仍然保留。
47
+ - 测试前后源包无变化;没有把精简索引结果写回 JSON,也没有声称未读取部分已检查。
48
+
49
+ ## 场景 C:增量同步(新增书签秒级可见)
50
+
51
+ 在已配置为 live 模式的画布包某栏目 JSON 中,手动追加一条带有唯一标题和 URL 的测试书签(记录其 item ID、title、url 及所属父节点)。
52
+ 在 Codex 中不显式执行 `sync_package`,也不重启插件,直接提交提示词:
53
+
54
+ > 请定位刚在临时栏目中新增的书签:`<填入新增书签标题或 item ID>`。使用 Bookmark Research 查询工具读取其完整层级路径、父节点与同级位置。明确报告该书签当前的 revision、所在 section ID 及父路径。
55
+
56
+ **通过标准**
57
+
58
+ - 监控与查询层自动触发增量刷新,新增书签在秒级内可被检索工具定位。
59
+ - 检索返回的新增书签路径、父节点及同级索引与手动编辑的源 JSON 完全一致。
60
+ - 仅被修改文件的书签条目其 `revision` 发生递增,画布包内其他未修改文件的条目其 `revision` 与状态保持稳定。
61
+ - 画布包内所有源文件保持只读,未被插件回写或篡改。
62
+
63
+ ## 场景 D:多源去重与合并(同路径重复源清理与唯一性)
64
+
65
+ 针对同一画布包路径下重复注册了多个旧源(例如 `index_status` 报告同路径存在多个 source_id,或旧源带着包内已不存在的文件而导致 `retained_missing_files` 非空)的场景:
66
+
67
+ 1. 先使用 CLI 进行干跑比对:
68
+ ```sh
69
+ python3 src/cli.py source merge <重复源ID> <保留源ID>
70
+ ```
71
+ 2. 确认计数与版本一致后执行正式合并(若内容哈希冲突则改用确认移除):
72
+ ```sh
73
+ python3 src/cli.py source merge <重复源ID> <保留源ID> --confirm
74
+ # 或
75
+ python3 src/cli.py source remove <重复源ID> --confirm
76
+ ```
77
+ 3. 在 Codex 中提交提示:
78
+ ```
79
+ 请检查当前的索引状态及源列表,确认画布包对应的源是否已唯一,且 retained_missing_files 是否已归零。
80
+ ```
81
+
82
+ **通过标准**
83
+
84
+ - 目标路径仅保留一个唯一的有效 source_id,重复源被完全移除或合并。
85
+ - 运行 `index_status` 后,所有源的 `retained_missing_files` 计数均为 0。
86
+ - 合并/清理后,条目检索与上下文定位均指向唯一保留源,不存在跨源冗余命中或已废弃文件的陈旧投影。
87
+ - 整个清理过程未对画布包物理文件产生任何写操作。
88
+
89
+ ## 记录结果
90
+
91
+ 每个场景记录:Codex 会话日期、插件工具是否实际可用、测试文件大小、目标 ID、期望路径、Agent 返回路径、分页/未读范围、源文件是否变化,以及通过/失败和复现步骤。失败时保留最小提示词、目标文件相对路径与相关 ID;不要复制整份用户 JSON 到 issue 或测试文档。
92
+
93
+ | 场景 | 插件实际可用 | 定点路径正确 | 分页/范围正确 | 占位字段判型正确 | 源文件未变 | 结果/备注 |
94
+ | --- | --- | --- | --- | --- | --- | --- |
95
+ | A:仅模板 | 否 | 待测 | 待测 | 待测 | 待测 | 待测 |
96
+ | B:模板 + 插件 | 待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
97
+ | C:增量同步 | 待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
98
+ | D:多源去重 | 待测 | 待测 | 待测 | 待测 | 待测 | 待测 |
@@ -0,0 +1,70 @@
1
+ # User Settings JSON
2
+
3
+ [中文](configuration.md) · **English**
4
+
5
+ Bookmark Research keeps its cross-host preferences in its own `settings.json`. Configure them in the terminal wizard during installation, rerun `bookmark-research setup`, or copy and import the [partial JSON example](../config/settings.example.json). The default path is `~/.config/bookmark-research/settings.json`; `BOOKMARK_RESEARCH_CONFIG` or `XDG_CONFIG_HOME` can change it. Multiple hosts can share settings by using the same path.
6
+
7
+ ```sh
8
+ bookmark-research config show
9
+ bookmark-research config set --input /absolute/path/to/my-settings.json
10
+ ```
11
+
12
+ `config set` merges the fields in this partial JSON and keeps settings you did not include. Provider names and choices go in `settings.json`; API keys go in a separate `credentials.json` beside it, or can be entered through the hidden `setup` prompt or supplied as environment variables. Environment variables take precedence. `config set --input` imports preferences only and rejects key fields. `config show` displays effective settings and the config path, never key values.
13
+
14
+ ## What Belongs Here
15
+
16
+ Use this file for long-term preferences and connection parameters that Bookmark Research reads directly:
17
+
18
+ - Search and reading sources: `search.providers`, `search.fallback_providers`, `fetch.provider`, `fetch.providers` and concurrency strategies. Perplexity provides structured URL search, not page extraction.
19
+ - User preferences: `research.depth`, `research.response_language`, `research.methods`, `archive.enabled`, `wiki.after_research`, `output.mode`, cache and limit settings, and readiness checks.
20
+ - Model endpoints: Base URL, model ID, protocol and search mode under `custom_agentic`. It returns a separate model answer through `agentic_search` and is not fused into `search_web` URL results.
21
+ - Professional research APIs called directly by this plugin: the OpenAI Deep Research or Parallel Task API selection under `professional_research`.
22
+
23
+ `config/settings.example.json` is an importable partial config; remove or change fields to suit your setup. Values must match the current settings schema. Invalid settings are rejected. For defaults, field details and the complete effective settings shape, see the [settings and archives reference](../skills/bookmark-research/references/settings-and-archive.md).
24
+
25
+ ## MCP And Credentials
26
+
27
+ Do not put every MCP in the plugin's `settings.json`. MCPs launched or authorized directly by the host, such as Exa Agent, Parallel Task and Tavily Research, use host-specific endpoint, command, OAuth and header formats managed by Codex, Claude Code or DSH. The installer/setup can show connection steps, but the plugin JSON does not register host MCPs or store their OAuth credentials.
28
+
29
+ When Bookmark Research calls a service through its own API, its selection and non-secret connection settings can live here; the key stays separate. For example:
30
+
31
+ ```json
32
+ {
33
+ "custom_agentic": {
34
+ "enabled": true,
35
+ "base_url": "https://gateway.example/v1",
36
+ "model": "provider/model-name",
37
+ "api_mode": "responses",
38
+ "search_mode": "native"
39
+ }
40
+ }
41
+ ```
42
+
43
+ `search_mode: "native"` requests the Responses `web_search` tool and requires upstream support. Chat Completions can only be prompted to search; it cannot guarantee that the upstream will go online. Set the key separately as `CUSTOM_AGENTIC_API_KEY`; never put it in JSON, command-line arguments or chat.
44
+
45
+ Bookmark Research accepts these API keys for its service adapters. Configure only the keys your selected services need. The setup prompt hides input and saves it for you. You can also maintain the credentials JSON directly:
46
+
47
+ | Key | Service called by the plugin |
48
+ | --- | --- |
49
+ | `EXA_API_KEY` | Exa search and page reading |
50
+ | `PARALLEL_API_KEY` | Parallel search and page reading |
51
+ | `TAVILY_API_KEY` | Tavily fallback search and extraction |
52
+ | `JINA_API_KEY` | Jina Search; Reader can fetch anonymously |
53
+ | `DEEPSEEK_API_KEY` | DeepSeek Search / Fetch |
54
+ | `PERPLEXITY_API_KEY` | Perplexity structured Search |
55
+ | `XAI_API_KEY` | Grok `agentic_search` |
56
+ | `CUSTOM_AGENTIC_API_KEY` | Custom OpenAI-compatible model endpoint |
57
+ | `OPENAI_API_KEY` | OpenAI Deep Research |
58
+
59
+ ```json
60
+ {
61
+ "EXA_API_KEY": "your-exa-key",
62
+ "PARALLEL_API_KEY": "your-parallel-key",
63
+ "PERPLEXITY_API_KEY": "your-perplexity-key",
64
+ "CUSTOM_AGENTIC_API_KEY": "your-custom-endpoint-key"
65
+ }
66
+ ```
67
+
68
+ The default path is `~/.config/bookmark-research/credentials.json`. This is an unencrypted local file and must have mode `0600` (owner-readable only). Use `setup` to save keys so the permissions are set correctly. Set `BOOKMARK_RESEARCH_CREDENTIALS` to change its path. Host-launched MCPs do not read this file; configure their keys through the host's own mechanism.
69
+
70
+ You can also ask the host to call `update_settings` for a lasting preference or run `bookmark-research config show` to inspect the current config. Installation and update receipts print this guide and the command to reopen setup.
@@ -0,0 +1,70 @@
1
+ # 用户配置 JSON
2
+
3
+ [English](configuration.en.md) · **中文**
4
+
5
+ Bookmark Research 使用一份插件自己的 `settings.json` 保存跨宿主共享的偏好。首次安装可在终端向导中配置;之后可运行 `bookmark-research setup`,或复制本页的 [部分配置示例](../config/settings.example.json) 并导入。配置路径默认为 `~/.config/bookmark-research/settings.json`,可用 `BOOKMARK_RESEARCH_CONFIG` 或 `XDG_CONFIG_HOME` 更改。多个宿主使用同一路径即可共享设置。
6
+
7
+ ```sh
8
+ bookmark-research config show
9
+ bookmark-research config set --input /absolute/path/to/my-settings.json
10
+ ```
11
+
12
+ `config set` 会按字段合并示例里的部分 JSON,不会清掉未提及的设置。provider 名称和选择写在 `settings.json`;API Key 放在同目录的独立 `credentials.json`,也可通过 `setup` 隐藏输入或环境变量设置;环境变量优先。`config set --input` 只导入偏好,不接受 Key。`config show` 会显示生效后的设置和配置路径,不显示密钥。
13
+
14
+ ## 放在这份 JSON 中的内容
15
+
16
+ 这份文件适合保存 Bookmark Research 自己读取的长期偏好和连接参数:
17
+
18
+ - 搜索与读取来源:`search.providers`、`search.fallback_providers`、`fetch.provider`、`fetch.providers` 和并发策略。Perplexity 可用于结构化 URL 搜索,不能作为网页正文读取器。
19
+ - 用户习惯:`research.depth`、`research.response_language`、`research.methods`、`archive.enabled`、`wiki.after_research`、`output.mode` 以及缓存、限额和可用性检查选项。
20
+ - 模型端点:`custom_agentic` 中的 Base URL、模型名、协议和搜索模式。它通过独立 `agentic_search` 返回模型回答,不参加 `search_web` 的 URL 聚合。
21
+ - 插件直接调用的专业研究服务:`professional_research` 中的 OpenAI Deep Research 或 Parallel Task API 选择。
22
+
23
+ `config/settings.example.json` 是可导入的部分配置,可按需删除或修改字段。字段必须符合当前版本的设置 schema;无效值会被拒绝。配置项说明、默认值和完整有效设置结构见 [配置与归档参考](../skills/bookmark-research/references/zh/settings-and-archive.md)。
24
+
25
+ ## MCP 与认证的边界
26
+
27
+ 不要把所有 MCP 都塞进插件的 `settings.json`。Exa Agent、Parallel Task、Tavily Research 等由宿主直接启动或授权的 MCP,其 endpoint、启动命令、OAuth 和 header 格式由 Codex、Claude Code 或 DSH 自己管理;不同宿主格式不同,OAuth 凭据也应留在宿主。安装器/向导可以给出对应的接入步骤,但插件 JSON 不会注册或保存这些 host MCP。
28
+
29
+ 如果某个服务由 Bookmark Research 自己通过 API 调用,它的选择和非敏感连接参数可以保存在插件 JSON 中,密钥仍单独管理。例如自定义模型:
30
+
31
+ ```json
32
+ {
33
+ "custom_agentic": {
34
+ "enabled": true,
35
+ "base_url": "https://gateway.example/v1",
36
+ "model": "provider/model-name",
37
+ "api_mode": "responses",
38
+ "search_mode": "native"
39
+ }
40
+ }
41
+ ```
42
+
43
+ `search_mode: "native"` 会请求 Responses `web_search` 工具,需要上游实现该工具;Chat Completions 只能提示上游搜索,不能保证它联网。把对应密钥单独设置为 `CUSTOM_AGENTIC_API_KEY`,不要写入 JSON、命令行参数或对话。
44
+
45
+ 插件支持的 API Key 与服务对应如下。只需配置已启用服务所需的 Key;用 `bookmark-research setup` 输入时会隐藏显示并自动保存。也可以手动维护凭据 JSON:
46
+
47
+ | Key | 插件调用的服务 |
48
+ | --- | --- |
49
+ | `EXA_API_KEY` | Exa 搜索与网页读取 |
50
+ | `PARALLEL_API_KEY` | Parallel 搜索与网页读取 |
51
+ | `TAVILY_API_KEY` | Tavily 备用搜索与提取 |
52
+ | `JINA_API_KEY` | Jina 搜索;Reader 可匿名读取 |
53
+ | `DEEPSEEK_API_KEY` | DeepSeek Search / Fetch |
54
+ | `PERPLEXITY_API_KEY` | Perplexity 结构化搜索 |
55
+ | `XAI_API_KEY` | Grok `agentic_search` |
56
+ | `CUSTOM_AGENTIC_API_KEY` | 自定义 OpenAI 兼容模型端点 |
57
+ | `OPENAI_API_KEY` | OpenAI Deep Research |
58
+
59
+ ```json
60
+ {
61
+ "EXA_API_KEY": "your-exa-key",
62
+ "PARALLEL_API_KEY": "your-parallel-key",
63
+ "PERPLEXITY_API_KEY": "your-perplexity-key",
64
+ "CUSTOM_AGENTIC_API_KEY": "your-custom-endpoint-key"
65
+ }
66
+ ```
67
+
68
+ 默认凭据路径为 `~/.config/bookmark-research/credentials.json`,文件为未加密的本地明文,权限要求为 `0600`(仅当前用户可读)。建议用 `setup` 写入,避免手动编辑后权限不正确。可用 `BOOKMARK_RESEARCH_CREDENTIALS` 改路径。宿主直接运行的 MCP 不读取这份凭据文件;它需要的 Key 应按该宿主的方式配置。
69
+
70
+ 其他入口:在宿主会话中调用 `update_settings` 改长期设置;用 `bookmark-research config show` 查看当前配置。安装或升级后,收据会打印本指南和重开向导的命令。
@@ -10,13 +10,13 @@ Reference material moved from the README: components, data model, research modes
10
10
  | --- | --- | --- |
11
11
  | **Skill** | [`skills/bookmark-research/SKILL.md`](../skills/bookmark-research/SKILL.md) | Guides package reading, local queries, source verification, and research reports |
12
12
  | **MCP server** | [`src/mcp_server.py`](../src/mcp_server.py), started with `python3 src/cli.py serve` | One local `bookmark-research` server with the [shared tool catalog](#mcp-tools) |
13
- | **Python CLI** | [`src/cli.py`](../src/cli.py) | Runs the same queries and research workflows directly, including from Pi |
14
- | **Web providers** | [`config/providers.json`](../config/providers.json), [`src/provider_adapters.py`](../src/provider_adapters.py), [`src/jina.py`](../src/jina.py) | Exa, Parallel, Jina HTTP and Tavily behind one MCP; schema checks, session reuse and visible partial failures |
13
+ | **Python CLI** | [`src/cli.py`](../src/cli.py) | Runs the same queries and research workflows directly, including from a host without MCP |
14
+ | **Web providers** | [`config/providers.json`](../config/providers.json), [`src/provider_adapters.py`](../src/provider_adapters.py), [`src/jina.py`](../src/jina.py) | Exa, Parallel, Jina HTTP, DeepSeek Search/Fetch, Perplexity structured Search and Tavily behind one MCP; Grok and custom OpenAI-compatible model answers are exposed separately |
15
15
  | **Research and coverage** | [`src/research.py`](../src/research.py), [`src/research_coverage.py`](../src/research_coverage.py) | Complete source inventory, all bookmark instances, budgets, evidence, substantive review and reports |
16
- | **Host workflows** | [`hosts/`](../hosts/) and [`src/routing.py`](../src/routing.py) | Native Codex delegation, Claude workflow, Pi extension recipe and DSH workflow adapter |
16
+ | **Host workflows** | [`hosts/`](../hosts/) and [`src/routing.py`](../src/routing.py) | Native Codex delegation, Claude workflow and DSH workflow adapter |
17
17
  | **Professional research** | [`src/research_services.py`](../src/research_services.py) | Optional provider-owned background tasks, saved run IDs and secondary-report import |
18
- | **Wiki and evaluation** | [`src/wiki.py`](../src/wiki.py), [`src/evaluation.py`](../src/evaluation.py) | Reviewed knowledge, immutable revisions, source/link lint and metrics from explicit labels |
19
- | **Client integrations** | Native manifests, [`bin/bookmark-research.js`](../bin/bookmark-research.js), [`scripts/launcher.py`](../scripts/launcher.py), [`install.sh`](../install.sh), [`scripts/install.py`](../scripts/install.py) and [`scripts/export_bundle.py`](../scripts/export_bundle.py) | The `bookmark-research` command, guided installation and native install/update/verify for all four hosts |
18
+ | **Wiki** | [`src/wiki.py`](../src/wiki.py) | Reviewed knowledge, immutable revisions, source/link lint and freshness checks |
19
+ | **Client integrations** | Native manifests, [`bin/bookmark-research.js`](../bin/bookmark-research.js), [`scripts/launcher.py`](../scripts/launcher.py), [`install.sh`](../install.sh), [`scripts/install.py`](../scripts/install.py) and [`scripts/export_bundle.py`](../scripts/export_bundle.py) | The `bookmark-research` command (alias `bookmark`, or `bookmark research`), guided installation and native install/update/verify for all three hosts |
20
20
 
21
21
  The runtime requires Python 3.9+ and SQLite with FTS5; `doctor` checks these requirements. It uses the Python standard library and does not require a separate database service.
22
22
 
@@ -26,12 +26,9 @@ The runtime requires Python 3.9+ and SQLite with FTS5; `doctor` checks these req
26
26
  | --- | --- | --- | --- | --- |
27
27
  | **Codex** | Included | MCP | Native plugin and marketplace | Native install/update and stdio checks in isolated profiles |
28
28
  | **Claude Code** | Included | MCP | Persistent marketplace/plugin plus Dynamic Workflow | Native install/update/cache checks in isolated profiles; model execution is separate |
29
- | **Pi** | Included through `pi.skills` | CLI / stdio bridge | Persistent package plus project workflow registrar | Installer/adapter scenarios; subagent workflows require optional extensions |
30
29
  | **DSH / DeepSeek Harness** | Included through Skill provider | MCP through the official client | Relocatable `dsh.bundle` plus optional workflow adapter | Installer/adapter scenarios; workflows require a configured service, engine and tool |
31
30
 
32
- Install verification does not mean all four live clients completed a research task. Pi's basic Skill + CLI works without subagent extensions. DSH's bundle registers the Skill and resolves the bundled Python path after installation; its legacy `cordis.patch.yml` export remains specific to its original location. See [host workflows](../skills/bookmark-research/references/host-workflows.md) for optional collaboration and actual resume limits.
33
-
34
- **Agent Plugins 1.0.0** is also available as a separate standard export: root `plugin.json` + `mcp.json`. It is a package format, not another client or the Codex native manifest. See [export formats](#export-formats) for commands and the [compatibility notes (Chinese)](harness-compatibility.md) for first-party references and verification boundaries.
31
+ Install verification does not mean all three live clients completed a research task. DSH's bundle registers the Skill and resolves the bundled Python path after installation; its legacy `cordis.patch.yml` export remains specific to its original location. See [host workflows](../skills/bookmark-research/references/host-workflows.md) for optional collaboration and actual resume limits.
35
32
 
36
33
  ## Data and query model
37
34
 
@@ -117,17 +114,17 @@ This version has no embeddings, vector database or background page monitoring. R
117
114
  | --- | --- | --- |
118
115
  | Quick lookup | Read a known URL, or search once to discover it | A concise sourced answer |
119
116
  | Agentic search | The current host model first plans, searches/reads, judges evidence and follows gaps | A sourced answer; ordinary questions need no full research session |
120
- | Deep research | Extend the host loop with sustained investigation, optional native collaboration, independent review and coverage checks | A persistent research archive with original inventory, evidence, coverage, report and optional Wiki |
117
+ | Deep research | Submit the question to a research API, observe the job and review the report | A sourced report; persistent inventories and coverage audits are optional |
121
118
 
122
119
  These modes follow [OpenAI's web search guide](https://developers.openai.com/api/docs/guides/tools-web-search). Having a URL does not determine whether a model reasons. `research_route` recommends an entrypoint from reported current tools and commands without launching it. Professional APIs have separate authentication and lifecycle contracts; anonymous Search MCP access does not authorize a Task API.
123
120
 
124
- One MCP entry point aggregates several backend services, and one Skill executes all three workflows. Reading defaults to Exa followed by concurrent Parallel + Jina Reader fallback for unresolved URLs; Tavily extraction can be added to `fetch.providers`. Search starts with Exa + Parallel, then calls `search.fallback_providers` (Tavily + keyed Jina) concurrently only for queries with no usable URL. Missing fallback credentials are skipped; successful results stay intact. Set the search fallback list to `[]` to disable it. An existing saved search provider list without a fallback field retains its original service scope.
121
+ One MCP entry point aggregates several backend services, and one Skill executes all three workflows. Reading starts with Exa under `fetch.strategy` (staggered by default: the next provider joins once the current one stalls past `fetch.grace_seconds`; hedged and sequential are the alternatives; abandoned providers are listed in `abandoned_providers`), then concurrent Parallel + Jina Reader fallback for unresolved URLs; Tavily extraction can be added to `fetch.providers`. `fetch.reuse_seconds` can return text saved within that window as `reused_sources` without a new request, and `search.cache_seconds` serves a repeated identical search from a short-lived cache. Search starts with Exa + Parallel under `search.strategy` (hedged by default, with staggered, sequential and wait_all alternatives) and the `search.grace_seconds` / `search.deadline_seconds` bounds; dropped or uncalled providers are listed in `routing`. Then `search.fallback_providers` (Tavily + keyed Jina) run concurrently only for queries with no usable URL. Missing fallback credentials are skipped; successful results stay intact. Set the search fallback list to `[]` to disable it. An existing saved search provider list without a fallback field retains its original service scope.
125
122
 
126
- The host model leads both research modes. Codex native subagents, Claude ordinary subagents or enabled teams, Pi extensions, and configured DSH subagents/workflows supply collaboration; see [host capabilities](harness-compatibility.md). The grouped package scripts are optional for batch research. Exa `agent_run`, complete Parallel Task MCP tools and enabled OpenAI/Parallel APIs can handle scoped external work after host assessment. A saved API preference orders these optional services; an explicit provider selects it exclusively. On confirmed failure, use cumulative `failed_routes` to continue the same investigation, preserving running/unknown/cancelled jobs. API execution follows prepare → start → status → result → import and requires separate credentials. Scrapling, Firecrawl and MarkItDown remain researched projects. A public GitHub README fetch does not inspect the whole repository.
123
+ The host model leads both research modes. Codex native subagents, Claude ordinary subagents or enabled teams, and configured DSH subagents/workflows supply collaboration; see [host capabilities](harness-compatibility.md). The grouped package scripts are optional for batch research. Exa `agent_run`, complete Parallel Task MCP tools and enabled OpenAI/Parallel APIs can handle scoped external work after host assessment. A saved API preference orders these optional services; an explicit provider selects it exclusively. On confirmed failure, use cumulative `failed_routes` to continue the same investigation, preserving running/unknown/cancelled jobs. API execution follows prepare → start → status → result → import and requires separate credentials. Scrapling, Firecrawl and MarkItDown remain researched projects. A public GitHub README fetch does not inspect the whole repository.
127
124
 
128
125
  Read the [deep research guide](../skills/bookmark-research/references/deep-research.md) for inputs and CLI examples. `research_start` freezes the complete indexed packages selected by `source_ids`; a subset requires explicit `scope_mode:"subset"`. Paginate `research_inventory` to the end. `bookmark_refs` identify focus items without silently narrowing whole-package scope.
129
126
 
130
- `research_search` and `research_fetch` reserve retrieval attempts; repeating the same `operation_id` returns its recorded outcome. The default fetch budget accounts for the selected input size: 207 URLs require at least 26 full batches and receive 38 calls, within an 80-call limit. Explicit budgets are retained; insufficient capacity is reported without removing URLs. These controls do not measure or limit invisible host/model calls.
127
+ `research_search` and `research_fetch` reserve retrieval attempts; repeating the same `operation_id` returns its recorded outcome. The default fetch budget accounts for the selected input size: 207 URLs require at least 13 full batches and receive 25 calls, within an 80-call limit. Explicit budgets are retained; insufficient capacity is reported without removing URLs. These controls do not measure or limit invisible host/model calls.
131
128
 
132
129
  `research_source` reads saved text. Record content acceptance, quoted claims and each original URL's substantive judgment. A rejected source or retracted claim reopens affected questions. `research_coverage` reports gaps; `research_finish` refuses completion while original-source reviews, questions, conflicts or active/unknown external runs remain unresolved. Blocked and excluded sources remain visible in the original denominator. An `incomplete` report preserves the remaining work.
133
130
 
@@ -139,7 +136,7 @@ Active tasks can continue directly. After exporting an `incomplete` report, use
139
136
 
140
137
  [Professional service tools](../skills/bookmark-research/references/research-services.md) prepare the exact brief/source payload, start once, observe the existing run, and archive its report. OpenAI cancellation is supported; Parallel cancellation is not established by this adapter. Unknown create outcomes are retained without resubmission. Imported reports remain secondary evidence and never mark all cited original URLs as read.
141
138
 
142
- [Wiki and quality evaluation](wiki-quality.md) track reviewed knowledge and measure supplied run results. Semantic citation accuracy requires actual reviewer labels. The included synthetic fixture demonstrates the scorer; it provides no evidence that a host, workflow or provider produces better research.
139
+ [Wiki](../skills/bookmark-research/references/wiki.md) stores reviewed knowledge with immutable revisions, evidence links and freshness checks. It is a knowledge base, not an automatic scorer; quality claims still need actual reviewer labels and real runs.
143
140
 
144
141
  ## Duplicate bookmarks, context, and result merging
145
142
 
@@ -155,7 +152,7 @@ Duplicate item IDs within one section are identity conflicts and cause import fa
155
152
 
156
153
  Ask "Show the plugin settings," "Use only Exa for future searches," "Save page text to my knowledge directory," or "Read this page without archiving." The model uses `get_settings`, `update_settings`, or parameters for the current `fetch_web` call. There is no separate graphical settings page.
157
154
 
158
- Run `python3 src/cli.py setup` to revisit the terminal wizard. Before each new web research question, the Skill calls `research_readiness`: by default it refreshes checks on first use, configuration/key changes, or after 15 minutes. Choose `always` or `manual` in setup. Local bookmark queries stay offline. Readiness separates missing keys, reachable catalogs, tested retrieval, and host-managed OAuth; it never starts a professional research job.
155
+ Run `python3 src/cli.py setup` to revisit the terminal wizard. Use `research_readiness` from the advanced catalog when diagnosing access; explicit checks refresh on first use, configuration/key changes, or after 15 minutes. Choose `always` or `manual` in setup. Local bookmark queries stay offline. Readiness separates missing keys, reachable catalogs, tested retrieval, and host-managed OAuth; it never starts a professional research job.
159
156
 
160
157
  The default configuration file is `~/.config/bookmark-research/settings.json`, created on the first update. Page archives default to `~/.local/share/bookmark-research/knowledge/`; XDG and plugin data-directory environment variables are respected. You can choose your own absolute paths. These files live outside the plugin and canvas package, so plugin updates do not replace them.
161
158
 
@@ -182,11 +179,14 @@ The [shared Skill](../skills/bookmark-research/SKILL.md) guides the agent's work
182
179
  | `index_status` | Inspect registered sources and index status |
183
180
  | `sync_package` | Import a package or synchronize changes |
184
181
  | `source_history` | List reusable source snapshots and recovery paths |
182
+ | `source_remove` / `source_merge` | Preview or confirm removal and merging of registered sources |
185
183
  | `search_bookmarks` | Query bookmarks for multiple targets while retaining item context |
186
- | `get_context` | Read section, card, group, connection, and item-ancestor context |
187
- | `search_providers` | List configured web providers |
188
- | `search_web` | Search through Exa / Parallel / Tavily / keyed Jina and merge results per target |
189
- | `fetch_web` | Read known URLs and optionally archive responses and page text |
184
+ | `get_context` | Read section, card, group, connection, and item-ancestor context; `compact:true` drops raw JSON, descriptions and revisions |
185
+ | `plan_research` | Local preflight for one question: ranked cards and bookmarks, Wiki and archive pointers, relevance, freshness, fetch ownership, and a route; missing-file cards are flagged and their URLs are kept |
186
+ | `search_providers` | List configured web providers and per-operation authentication requirements |
187
+ | `search_web` | Search through configured Exa / Parallel / Tavily / Jina / DeepSeek / Perplexity providers and merge results per target |
188
+ | `agentic_search` | Optional Grok or configured custom-model answer/search channel with citations; not URL-fused |
189
+ | `fetch_web` | Read known URLs under a per-page and batch budget, optionally archive text, and continue a saved extract with `capture_id`/`offset` |
190
190
  | `search_archive` | Literal full-text search over saved page text in the knowledge archive and all research evidence, merged by content hash |
191
191
  | `get_settings` | Read current settings and storage paths |
192
192
  | `update_settings` | Update persistent settings |
@@ -201,9 +201,11 @@ The [shared Skill](../skills/bookmark-research/SKILL.md) guides the agent's work
201
201
  | `research_inventory` / `research_coverage` | Paginate original sources and compare actual review against the complete frozen scope |
202
202
  | `research_import_evidence` | Import actual host-read original text or explicitly secondary reports with provenance |
203
203
  | `research_route` | Recommend a route using current host observations and saved preferences |
204
+ | `discovery_bundle` | Own the route-② budget check and assemble the citable evidence bundle (excerpts, then digest, then a URL list) from the sources the host read; only usable pages become evidence |
204
205
  | `research_services` / `research_service_*` | Describe, prepare, start, observe, read, cancel, attach and import optional professional runs |
205
- | `wiki_write` / `wiki_get` / `wiki_list` / `wiki_search` / `wiki_lint` | Maintain reviewed knowledge and immutable evidence-linked revisions |
206
- | `evaluate_research` | Compute metrics from explicit tasks, outputs, measurements and reviewer labels |
206
+ | `wiki_write` / `wiki_get` / `wiki_list` / `wiki_search` / `wiki_lint` / `wiki_acknowledge` | Maintain reviewed knowledge, immutable evidence-linked revisions and input review acknowledgements |
207
+ | `wiki_refresh` | Fetch cited URLs, record source observations and identify pages that need review |
208
+ | `wiki_work` | Resume compilation and review using saved work states and committed publication receipts |
207
209
 
208
210
  ### Web providers
209
211
 
@@ -213,11 +215,15 @@ The [shared Skill](../skills/bookmark-research/SKILL.md) guides the agent's work
213
215
  | **Parallel** | Built into the MCP server and CLI for search and URL reading |
214
216
  | **Jina** | HTTP Reader supports anonymous webpage/PDF reading; Search requires `JINA_API_KEY`. The hosted Jina MCP is not used. |
215
217
  | **Tavily** | Built-in search fallback and selectable extraction; `TAVILY_API_KEY` uses Bearer, otherwise explicit keyless mode |
218
+ | **DeepSeek Search / Fetch** | Optional raw JSON tools API (`/v1/tools/search`, `/v1/tools/fetch`); requires `DEEPSEEK_API_KEY`; OpenAI-compatible error shape, not a Chat Completions tool |
219
+ | **Perplexity Search** | Optional structured Search API provider; requires `PERPLEXITY_API_KEY`; returns sources only and does not read pages |
220
+ | **xAI Grok** | Optional Responses API tool `agentic_search`; requires `XAI_API_KEY`; returns a model answer and citations outside URL fusion |
221
+ | **Custom model endpoint** | Optional OpenAI-compatible Chat Completions or Responses endpoint; configured Base URL/model/protocol and `CUSTOM_AGENTIC_API_KEY`; separate answer channel, upstream search support is not inferred |
216
222
  | **GitHub** | Use the host's existing GitHub MCP or `gh` for repository-specific tasks. No GitHub MCP is bundled; public pages can also be read through Exa / Parallel. |
217
223
 
218
- All four retrieval providers run through the plugin's own MCP or CLI; additional host MCP registrations are unnecessary. Search starts with Exa + Parallel and uses configured fallbacks for unresolved queries; reading falls back to Parallel + Jina after Exa. Anonymous/keyless access and quotas depend on each service's policy; optional credentials use `EXA_API_KEY`, `PARALLEL_API_KEY`, `TAVILY_API_KEY` or `JINA_API_KEY` in the launching environment. Local queries work offline.
224
+ Bookmark Research aggregates only its configured providers; the host model may call other visible host/MCP search tools and compare their evidence. Search starts with Exa + Parallel under a selectable strategy (hedged by default) with a grace window and total deadline, and uses configured fallbacks for unresolved queries; Perplexity can be added to either search tier. Reading falls back to Parallel + Jina after Exa. Grok and the custom OpenAI-compatible endpoint are separate answer channels; custom search behavior depends on the configured upstream. Anonymous/keyless access and quotas depend on each service's policy; optional credentials use `EXA_API_KEY`, `PARALLEL_API_KEY`, `TAVILY_API_KEY`, `JINA_API_KEY`, `DEEPSEEK_API_KEY` or `PERPLEXITY_API_KEY` for retrieval, `XAI_API_KEY` for Grok, and `CUSTOM_AGENTIC_API_KEY` for the custom model. Local queries work offline.
219
225
 
220
- `search_providers` describes configuration without network access; `probe:true` discovers remote MCP tools, while Jina's HTTP mapping remains explicitly `not_probed`. Discovery does not prove successful retrieval. Each MCP process reuses remote sessions and a bounded tool catalog. Calls are not automatically replayed after errors. See [MCP architecture and observed service behavior](mcp-aggregation-0.2.0.md) for the initial implementation and checks.
226
+ `search_providers` describes configuration without network access; `probe:true` discovers remote MCP tools, while Jina, DeepSeek and Perplexity HTTP mappings remain explicitly `not_probed`. Discovery does not prove successful retrieval. Each MCP process reuses remote sessions and a bounded tool catalog. Calls are not automatically replayed after errors. Historical implementation notes remain available in Git history.
221
227
 
222
228
  ### Package rules and AGENTS.md
223
229
 
@@ -225,32 +231,30 @@ Analysis rules are included in the Skill. The [package reading protocol](../skil
225
231
 
226
232
  Routine analysis of supported formats does not require rereading the entire package `AGENTS.md`, and the runtime does not depend on it. Consult relevant original instructions for new formats, field conflicts, or package-specific conventions. Applicable directory instructions already loaded by the client still apply.
227
233
 
234
+ An exported guide may name this plugin as an optional read-only companion. That mention does not grant write access; the guide's hard constraints still govern any edit to the package.
235
+
228
236
  GitHub references and Git sync rules in a package's `AGENTS.md` do not automatically connect a GitHub service. See [GitHub and sync boundaries](../skills/bookmark-research/references/github-and-sync.md).
229
237
 
230
- The Skill currently produces answers and research reports. It does not generate importable bookmark packages or write changes back to source data. A future generation Skill could reuse the reading protocol with additional writing rules and validation.
238
+ The Skill currently produces answers and research reports. It does not generate importable bookmark packages or write changes back to source data. A future generation Skill could reuse the reading protocol with additional writing rules and validation, but the package's exported guide remains the write protocol.
231
239
 
232
240
  ## Export formats
233
241
 
234
- This directory is the **Codex native plugin**, with its manifest at `.codex-plugin/plugin.json`. In Codex 0.153.4, the MCP configuration explicitly uses `cwd: "."` and runs `python3 src/cli.py serve` from the installed plugin directory. That native entry does not expand `${PLUGIN_ROOT}`; the Agent Plugins and Claude exports use their own path conventions.
242
+ This directory is the **Codex native plugin**, with its manifest at `.codex-plugin/plugin.json`. In Codex 0.153.4, the MCP configuration explicitly uses `cwd: "."` and runs `python3 src/cli.py serve` from the installed plugin directory. That native entry does not expand `${PLUGIN_ROOT}`; the Claude export uses its own path convention.
235
243
 
236
- The Codex manifest forwards these environment variable names through `env_vars`: `BOOKMARK_RESEARCH_DATA_DIR`, `BOOKMARK_RESEARCH_CONFIG`, `XDG_DATA_HOME`, `XDG_CONFIG_HOME`, `EXA_API_KEY`, `PARALLEL_API_KEY`, `TAVILY_API_KEY`, and `OPENAI_API_KEY`. Actual paths and credentials come from the user's runtime environment.
244
+ The Codex manifest and DSH adapter forward provider credentials including `EXA_API_KEY`, `PARALLEL_API_KEY`, `TAVILY_API_KEY`, `JINA_API_KEY`, `DEEPSEEK_API_KEY`, `PERPLEXITY_API_KEY`, `XAI_API_KEY` and `CUSTOM_AGENTIC_API_KEY`, along with the configured data/config paths. Actual paths and credentials come from the user's runtime environment.
237
245
 
238
246
  Run the relevant command **from this directory** to generate another format:
239
247
 
240
248
  ```sh
241
249
  python3 scripts/export_bundle.py --format codex --output exports/codex/bookmark-research
242
250
  python3 scripts/export_bundle.py --format claude --output exports/claude/bookmark-research
243
- python3 scripts/export_bundle.py --format pi --output exports/pi/bookmark-research
244
251
  python3 scripts/export_bundle.py --format dsh --output exports/dsh/bookmark-research
245
- python3 scripts/export_bundle.py --format agent-plugin --output exports/agent-plugin/bookmark-research
246
252
  ```
247
253
 
248
254
  The destination must be new or empty. Exports include their own English setup README with links to bundled Chinese and English user guides, and exclude indexes, caches, tests, and credentials. The exporter writes files; follow the generated README or [installation guide](installation.en.md) to load them in your client.
249
255
 
250
256
  - **Claude Code:** plugin + marketplace manifests, `.mcp.json` and a Dynamic Workflow; supports persistent native installation or session loading with `--plugin-dir`.
251
- - **Pi:** `package.json` declares `pi.skills`; the Skill calls the CLI. Register the project workflow for the separately installed subagent extensions when available.
252
257
  - **DSH:** a relocatable `dsh.bundle` that connects the Skill and MCP, plus the legacy absolute-path patch and workflow call generator. Workflow components remain optional and host-managed.
253
- - **Agent Plugins 1.0.0:** root `plugin.json` + `mcp.json`, for clients implementing that specification; generated separately from Codex's native manifest.
254
258
 
255
259
  See the [client support table](#client-support) for verification status and [compatibility notes (Chinese)](harness-compatibility.md) for format differences and official sources.
256
260
 
@@ -263,13 +267,12 @@ From this plugin directory **in a full repository checkout**, developers can run
263
267
  ```sh
264
268
  python3 -m unittest discover -s tests -v
265
269
  python3 scripts/verify_fixture.py --output /tmp/bookmark-research-verification
266
- python3 scripts/verify_quality.py
267
270
  python3 scripts/build_zip.py --output dist/bookmark-research-0.5.0-beta.3.zip
268
271
  python3 scripts/build_zip.py --include-tests --output dist/bookmark-research-test-pack-0.5.0-beta.3.zip
269
272
  ```
270
273
 
271
274
  The fixture verifier checks independent bookmark counts, copy-card semantics, scoped queries, unchanged source hashes, incremental sync, and a two-round research lifecycle with a failed page and resumed operation. To additionally validate your own package, append `--package /absolute/path/to/package`; this stays offline and writes derived files only to the new output directory.
272
275
 
273
- Network verification is explicit: `python3 tests/live_provider_smoke.py --run-live --output /tmp/provider-smoke.json` makes at most three searches and three fetches. The [0.4.0 validation record](validation-0.4.0.md) combines source lifecycle, whole-package research, bilingual instructions and host/service boundaries; [0.2.0](validation-0.2.0.md) retains the earlier provider evidence.
276
+ Network verification is explicit: `python3 tests/live_provider_smoke.py --run-live --output /tmp/provider-smoke.json` makes at most three searches and three fetches. Historical validation records remain available in Git history.
274
277
 
275
278
  The local stdio server exposes fixed tools. Its remote client implements the selected providers' Streamable HTTP lifecycle, bounded paginated tool discovery and limited session recovery; it is not a general OAuth client or a complete MCP SDK.