dsh-zotero-skill 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -1,23 +1,27 @@
1
1
  # Zotero Skill for DeepSeek Harness
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/dsh-zotero-skill.svg)](https://www.npmjs.com/package/dsh-zotero-skill)
3
4
  ![Python](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)
4
5
  ![License](https://img.shields.io/badge/License-MIT-green)
5
6
  ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)
6
7
 
7
- 让 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 直接操作你本机的 Zotero 文献库:检索论文、导出 BibTeX、给 LaTeX / Markdown 草稿插入引用,按需读取附件全文。
8
+ 让 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 把文献工作串成一条流水线:**找文献 → 追前沿 → 筛核心 → 管理归集 → 批量阅读 → 分类整理 → 提炼脉络 → 发现空白**,再加上导出 BibTeX 与给 LaTeX / Markdown 草稿插入引用。
8
9
 
9
10
  纯 Python 标准库实现,**不需要 pip、MCP 服务或 Zotero 云端 API Key**;默认只与本机 `127.0.0.1:23119` 通信。
10
11
 
11
12
  ## 特性
12
13
 
13
- - **检索**:按关键词搜索顶层条目,返回题名、作者、年份、item key 与 BibTeX key。
14
- - **浏览**:列出集合、标签、分组,或导出整个文献库清单。
15
- - **引用**:读取你指定的 `.tex` / `.md` 草稿,在唯一标记处插入 `\cite{key}` 或 Pandoc `[@key]`,并同步 `references.bib`。
16
- - **安全写入**:修改草稿或 `.bib` 前自动备份;`.bib` 按 key 去重,不重复追加。
17
- - **按需读取**:只有你明确要求时才读取附件路径或 PDF 全文,避免把本地路径和正文无谓地送进上下文。
18
- - **导入**:通过 Zotero Connector 导入 BibTeX / RIS,属于写库操作,脚本会用 `--yes` 显式确认。
19
- - **每日收录**:按你设定的主题,每天从 OpenAlex 抓取新论文,按期刊影响力、引用速度、相关度和新鲜度排序,自动导入指定分类;数量、开关、时间都由你决定。
20
- - **不碰数据库**:只走 Zotero 官方本地 API,不直接读写 `zotero.sqlite`。
14
+ - **找文献**:从 OpenAlex 按主题检索,按期刊影响力、引用速度、相关度、新鲜度排序,并与本地库去重。
15
+ - **追前沿**:把常读方向存成 watch,每次只拉「上次运行以来」的新论文,不重复推送。
16
+ - **筛核心论文**:把候选或库内条目分成 核心 / 重要 / 参考 三档,输出可复制的短名单。
17
+ - **管理文献**:批量打标签、归集到分类、按 DOI / 标题查重并清理副本。
18
+ - **批量阅读**:一次为几十篇生成阅读包(元数据 + 摘要 + 章节大纲 + 笔记骨架),不必把原文全塞进上下文。
19
+ - **分类整理**:从题名和摘要识别方法与数据集,生成 `auto:method:*` / `auto:dataset:*` 标签与集合计划,预览后写入。
20
+ - **提炼脉络**:统计年份、期刊、方法、数据集及共现,直接产出综述可用的表格。
21
+ - **发现空白**:按项目分组找「方法 × 数据集」从未交叉的组合、停更标签与标注缺失。
22
+ - **检索与引用**:按关键词搜索条目,返回题名、作者、年份、item key 与 BibTeX key;在草稿唯一标记处插入 `\cite{key}` 或 `[@key]` 并同步 `.bib`。
23
+ - **每日收录**:按主题每天从 OpenAlex 抓新论文,去重排序后自动导入指定分类,数量 / 开关 / 时间都由你决定。
24
+ - **不碰数据库**:只走 Zotero 官方本地 API,不直接读写 `zotero.sqlite`;改库前先 `--dry-run`,写入需要你在 Zotero 弹窗里点一次「Always Allow」。
21
25
 
22
26
  ## 安装
23
27
 
@@ -33,7 +37,13 @@
33
37
 
34
38
  **方式 A:作为 DSH 插件安装(推荐)**
35
39
 
36
- 仓库自带 `dsh.bundle` 清单,装成插件后 skill 自动出现在技能目录,不需要复制文件:
40
+ 包已发布到 npm,自带 `dsh.bundle` 清单,装成插件后 skill 自动出现在技能目录,不需要复制文件:
41
+
42
+ ```bash
43
+ dsh plugin --profile <你的 profile> add dsh-zotero-skill
44
+ ```
45
+
46
+ 想跟最新代码,或 npm 不可达时,可直接从 GitHub 安装:
37
47
 
38
48
  ```bash
39
49
  dsh plugin --profile <你的 profile> add github:Eason-0712/dsh-zotero-skill
@@ -88,13 +98,21 @@ python zotero/scripts/zotero.py status --json
88
98
 
89
99
  在 Harness 里直接说:
90
100
 
91
- > 检索我文献库中 transformer 相关的论文,给出作者、年份和 BibTeX 键。
101
+ > 帮我找一下 knowledge distillation 用在运动想象 EEG 上的新论文,按重要性排个序。
92
102
 
93
- > 读一下 `/path/to/draft.md`,把相关论断后面补上引用,并更新同目录的 references.bib。
103
+ > 我常看的方向有这几个,做成 watch,以后只给我新出现的。
94
104
 
95
- > 把这篇论文的附件全文读出来,总结方法部分。
105
+ > 从库里 project:MI-EEG 这 18 篇里挑出最核心的几篇,列个短名单。
106
+
107
+ > 把这批论文生成阅读包,我看完再写综述。
108
+
109
+ > 按方法和数据集给整个库打上标签,先给我看计划。
110
+
111
+ > 这个方向现在有哪些明显的空白?
112
+
113
+ > 读一下 `/path/to/draft.md`,把相关论断后面补上引用,并更新同目录的 references.bib。
96
114
 
97
- Skill 会自己决定调用哪些子命令,并在写文件前确认标记和备份。
115
+ Skill 会自己决定调用哪些子命令,并在写库或写文件前先给预览。
98
116
 
99
117
  ## 每日自动收录
100
118
 
@@ -163,6 +181,17 @@ python zotero/scripts/zotero.py daily-schedule --remove
163
181
  | 命令 | 作用 |
164
182
  | --- | --- |
165
183
  | `status` | 检查本地 API、Connector、版本 |
184
+ | `authorize` | 取得本地 API 写权限(Zotero 弹窗点「Always Allow」) |
185
+ | `find <query>` | OpenAlex 检索并按分数排序,`--oa-only` / `--json` / `--out` |
186
+ | `frontier add\|run\|list\|remove` | 保存研究方向,只拉上次之后的新论文 |
187
+ | `screen` | 把候选或库内条目分成 核心 / 重要 / 参考 |
188
+ | `tag` | 批量加 / 删 / 替换标签(`--dry-run`) |
189
+ | `collect <name>` | 归集到分类,不存在则新建 |
190
+ | `classify` | 识别方法与数据集,生成标签/集合计划,`--apply` 写入 |
191
+ | `dupes` | 按 DOI 或标题查重,`--trash` 清理副本 |
192
+ | `digest` | 批量生成阅读包(每篇一个 Markdown + index.md) |
193
+ | `landscape` | 年份 / 期刊 / 方法 / 数据集统计与共现 |
194
+ | `gaps` | 方法 × 数据集空组合、停更标签、标注缺失 |
166
195
  | `inventory` | 列出条目 |
167
196
  | `collections` / `tags` / `groups` | 列出集合、标签、分组 |
168
197
  | `search <query>` | 关键词检索,`--with-bibtex-keys` 附带引用键 |
@@ -179,7 +208,7 @@ python zotero/scripts/zotero.py daily-schedule --remove
179
208
  | `probe` | 探测各 API 路由可用性 |
180
209
  | `enable` / `disable` / `restart` | 管理本地 API 开关与启动 |
181
210
 
182
- 所有命令加 `--json` 输出机器可读结果。
211
+ 所有命令加 `--json` 输出机器可读结果。批量选择统一用 `--keys`、`--query`、`--tag`、`--collection`、`--all`,`--limit` 限制条数。
183
212
 
184
213
  ## 目录结构
185
214
 
@@ -196,6 +225,7 @@ python zotero/scripts/zotero.py daily-schedule --remove
196
225
  │ └── scripts/zotero.py # 全部功能,仅标准库
197
226
  ├── test/provider.test.mjs # provider 的 Node 测试
198
227
  ├── tests/test_zotero.py # 模拟 API 的 Python 单元测试
228
+ ├── tests/test_literature.py # 术语抽取、分类计划、脉络、查重、空组合
199
229
  ├── install.py # 复制式安装器(方式 B)
200
230
  ├── LICENSE
201
231
  └── NOTICE.md
@@ -205,10 +235,12 @@ python zotero/scripts/zotero.py daily-schedule --remove
205
235
 
206
236
  ## 设计取舍
207
237
 
208
- - **只读本地 API**:检索、导出、全文都走 `/api/`;该接口本身只读,写操作交给 Connector。
238
+ - **读写都走官方 API**:检索、导出、全文走 `/api/` 的 GET(免认证);打标签、归集、查重清理走同一套本地 API 的 PATCH/POST,需要本地 API key 与 `Zotero-Server-ID`,脚本用 `authorize` 一次性取得并缓存,绝不直接改 `zotero.sqlite`。
239
+ - **先预览再写入**:所有写命令都支持 `--dry-run`,Skill 要求先把计划给用户看,确认后才加 `--yes`。
240
+ - **规则可解释**:方法 / 数据集识别是正则词表,分歧能被逐条检查;空组合与停更标签都是可复算的统计,而不是模型编的结论。
209
241
  - **写文件前备份**:`cite` 会先校验草稿和标记,再备份草稿与 `.bib`;`sync-bib` / `export-bibtex --out` 会覆盖目标文件,所以 Skill 要求先确认路径。
210
242
  - **本机请求绕过代理**:`localhost`、`127.0.0.1`、`::1` 直连,避免系统代理吞掉本机请求;非回环地址才走代理配置。
211
- - **UTF-8**:Windows 控制台下的中文 JSON 与路径不会乱码。
243
+ - **UTF-8**:Windows 控制台下的中文 JSON 与路径不会乱码;`--input` 也能读 PowerShell 写出的 UTF-16 文件。
212
244
  - **不强制结束 Zotero**:需要改配置时要求先正常退出,避免 `prefs.js` 被覆盖。
213
245
 
214
246
  ## 测试
@@ -226,6 +258,9 @@ node --test test/*.test.mjs # 插件 provider
226
258
  - 远端 / WSL / 容器里 `127.0.0.1` 指向的是运行环境本身,不在同一台机器上时无法直接连到桌面 Zotero。
227
259
  - `enable` / `disable` 只改本机 `prefs.js`,对远端 Zotero 无效。
228
260
  - 本地 API 的能力随 Zotero 版本变化,遇到 403 / 404 先检查开关和版本。
261
+ - 写入需要你在 Zotero 弹窗里授权一次(选「Always Allow」才是持久的);选「Allow」的 key 只能写一次。
262
+ - 方法 / 数据集识别基于固定正则词表,冷门术语可能漏标;`gaps` 会把这些条目列成「标注缺失」供人工补。
263
+ - `landscape` / `gaps` 的结论来自题录与摘要的统计,不是全文精读;写进论文前需要回头看原文。
229
264
  - 每日收录依赖 OpenAlex 的网络访问;离线或被限流时会跳过本次抓取,不会写坏文献库。
230
265
  - 收录只导入题录与摘要,不下载 PDF;需要全文时再按需获取。
231
266
  - 期刊指标来自 OpenAlex,与 JCR 影响因子不是同一套数据,仅用于相对排序。
@@ -241,6 +276,6 @@ node --test test/*.test.mjs # 插件 provider
241
276
 
242
277
  ## English
243
278
 
244
- A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) skill for the local Zotero library: search items, export BibTeX, add citations to LaTeX/Markdown drafts, read attachment full text on demand, and fetch a ranked daily digest of new papers in your topics from OpenAlex.
279
+ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) skill that runs the whole literature loop against your local Zotero library: find papers on OpenAlex, track research fronts with saved watches, screen candidates into core / important / reference tiers, manage items (batch tags, collections, DOI and title de-duplication), generate batch reading packs, classify items by method and dataset, chart the landscape of years / venues / methods / datasets, and surface candidate research gaps. It also exports BibTeX, inserts citations into LaTeX/Markdown drafts, and can run a ranked daily digest of new papers.
245
280
 
246
- Install by copying `zotero/` to `~/.dsh/skills/zotero` (or run `python install.py`), enable Zotero's local API, then ask your agent to search your library. For the daily digest, run `zotero.py daily-config --enable --topics "..."` and optionally `daily-schedule --time 08:00`. Adapted from OpenAI's Zotero plugin 0.1.2 under the MIT license.
281
+ Install with `dsh plugin --profile <name> add dsh-zotero-skill` (or copy `zotero/` to `~/.dsh/skills/zotero`, or run `python install.py`), enable Zotero's local API, and run `zotero.py authorize` once if you want write operations. Adapted from OpenAI's Zotero plugin 0.1.2 under the MIT license.
package/cordis.patch.yml CHANGED
@@ -6,6 +6,7 @@
6
6
  # installed — no copy into ~/.dsh/skills or ~/.agents/skills.
7
7
  #
8
8
  # Install:
9
+ # dsh plugin --profile <name> add dsh-zotero-skill
9
10
  # dsh plugin --profile <name> add github:Eason-0712/dsh-zotero-skill
10
11
  #
11
12
  # Local development (link to a checkout):
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-zotero-skill",
3
- "version": "0.2.0",
4
- "description": "Zotero skill for DeepSeek Harness: search the local library, export BibTeX, cite into LaTeX/Markdown drafts, and import a ranked daily digest of new papers from OpenAlex.",
3
+ "version": "0.3.0",
4
+ "description": "Zotero skill for DeepSeek Harness: find papers on OpenAlex, track research fronts, screen core papers, manage and classify the library, batch-read, map the landscape, and surface research gaps. Also exports BibTeX and cites into LaTeX/Markdown.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -49,6 +49,9 @@
49
49
  "zotero",
50
50
  "skill",
51
51
  "bibtex",
52
- "citation"
52
+ "citation",
53
+ "literature-review",
54
+ "openalex",
55
+ "research"
53
56
  ]
54
57
  }
package/zotero/SKILL.md CHANGED
@@ -1,91 +1,163 @@
1
- ---
2
- name: zotero
3
- description: 操作本机 Zotero 文献库:检索论文、导出 BibTeX、为 LaTeX 或 Markdown 草稿添加引用、按需读取附件全文、导入 BibTeX/RIS,以及按主题每日自动收录新论文。用户提到 Zotero、文献库、references.bib、从文献库添加引用或每日文献推送时使用。
4
- ---
5
-
6
- # Zotero · DeepSeek Harness
7
-
8
- 这是独立目录 skill,不依赖 Codex、OpenAI 工具或 MCP 服务。使用 Harness 当前提供的文件读取、编辑和命令执行能力运行 Python 脚本。若执行工具不可用,说明缺失能力,不要虚构执行结果。
9
-
10
- ## 定位与运行
11
-
12
- 以 Harness 加载本 skill 返回的资源目录为 `<skill-dir>`,不是当前工作目录,也不需要插件根目录。入口为 `scripts/zotero.py`。使用 Python 3.10+,仅依赖标准库。
13
-
14
- - Windows:先检查 `py -3 --version`;不可用时检查 `python --version`,或使用用户提供的 Python 可执行文件。不要假定存在 `python3`;WindowsApps 的别名不等于可用解释器。
15
- - macOS / Linux:通常使用 `python3`。
16
- - 路径包含空格时加引号;PowerShell 运行带引号的可执行文件时使用 `&`。
17
-
18
- 下文 `<python>` 表示已经验证可用的解释器命令。脚本可从任意目录运行:
19
-
20
- ```text
21
- <python> "<skill-dir>/scripts/zotero.py" status --json
22
- <python> "<skill-dir>/scripts/zotero.py" search "transformer" --with-bibtex-keys --json
23
- <python> "<skill-dir>/scripts/zotero.py" export-bibtex --item-key PXW99EKT --out references.bib
24
- ```
25
-
26
- ## 工作流程
27
-
28
- 1. 首先运行 `status --json`。默认连接 `http://127.0.0.1:23119`,不需要 Zotero 云端密钥。
29
- 2. 如果 API 不可用,按 [references/deepseek-harness.md](references/deepseek-harness.md) 排查。优先让用户在 Zotero 的设置 → 高级 → 其他中启用“允许此计算机上的其他应用程序与 Zotero 通信”(实际名称依版本略有差异)。不要把连接失败等同于文献库为空。
30
- 3. 若用户授权自动修改本机设置,先让用户正常关闭 Zotero,再执行 `enable --restart`;它备份 prefs.js、设置本地 API 偏好并启动程序,不强制结束进程。不要在 Zotero 运行时编辑 prefs.js。远端/容器部署不能直接修改另一台机器的 Zotero 配置。
31
- 4. 使用 `inventory`、`collections`、`tags`、`search` 检索本机数据。结果中报告题名、作者、年份、Zotero item key,以及可用的 BibTeX key。不要将 item key 当作引用键。
32
- 5. 添加引用前先读用户指定的草稿,按具体论断匹配文献。缺少草稿时检索可以继续,但应索取路径或正文,不能假装已编辑。不要只根据标题断言论文支持某个具体结论。
33
- 6. `cite --query` 多结果时会拒绝;先检索选定正确条目,再传入 `--item-key`。在目标位置设置唯一标记,然后用 `--marker` 插入。不要默认在文末追加一个脱离上下文的引用。
34
- 7. 操作后核对草稿和 .bib,报告改动路径、引用键、备份路径。`sync-bib` 和 `export-bibtex --out` 会覆盖输出文件,避免无意覆盖用户维护的参考文献文件。
35
-
36
- ## 草稿引用
37
-
38
- 先通过文件编辑工具在用户授权的正确位置加入唯一标记,如 `<cite:transformer>`:
39
-
40
- ```text
41
- <python> "<skill-dir>/scripts/zotero.py" cite --item-key PXW99EKT --tex paper.tex --bib references.bib --marker "<cite:transformer>"
42
- <python> "<skill-dir>/scripts/zotero.py" cite --item-key PXW99EKT --markdown draft.md --bib references.bib --marker "<cite:transformer>"
43
- ```
44
-
45
- LaTeX 输出 `\cite{key}`,Markdown 输出 Pandoc 格式 `[@key]`。脚本会备份已有草稿和 .bib;它不负责配置文档的文献渲染器。Word 的 Zotero 动态引用域不在此脚本能力内,不要用替换 .docx 内部文本冒充已插入 Zotero 引用。
46
-
47
- ## 其他能力
48
-
49
- ```text
50
- <python> "<skill-dir>/scripts/zotero.py" collections --json
51
- <python> "<skill-dir>/scripts/zotero.py" citations --style apa --json
52
- <python> "<skill-dir>/scripts/zotero.py" sync-bib --out references.bib
53
- ```
54
-
55
- 仅当用户要求附件、PDF 路径或全文内容时运行:
56
-
57
- ```text
58
- <python> "<skill-dir>/scripts/zotero.py" children PXW99EKT --json
59
- <python> "<skill-dir>/scripts/zotero.py" fulltext 2JAZS9U8 --out fulltext.txt
60
- <python> "<skill-dir>/scripts/zotero.py" file-url 2JAZS9U8
61
- ```
62
-
63
- 导入是文献库写操作。明确记录来源、内容和目标文献库/集合;用户已明确授权该导入时直接继续,否则先询问。`--yes` 是脚本的执行开关,不是用户授权的替代品。
64
-
65
- ```text
66
- <python> "<skill-dir>/scripts/zotero.py" selected-target --json
67
- <python> "<skill-dir>/scripts/zotero.py" import-bibtex --file new.bib --yes
68
- <python> "<skill-dir>/scripts/zotero.py" import-ris --file new.ris --yes
69
- ```
70
-
71
- ## 每日自动收录
72
-
73
- `daily` 从 OpenAlex 抓取最近 N 天、按主题检索的论文,按期刊 2 年平均被引、年化引用速度、相关度和新鲜度打分,去重后把排名靠前的论文通过 Connector 导入当前选中的 Zotero 分类。OpenAlex 免费、无需 API Key,但需要网络。
74
-
75
- ```text
76
- <python> "<skill-dir>/scripts/zotero.py" daily-config --enable --topics "transformer;large language model" --max 10 --mailto "you@example.com"
77
- <python> "<skill-dir>/scripts/zotero.py" daily --dry-run
78
- <python> "<skill-dir>/scripts/zotero.py" daily
79
- <python> "<skill-dir>/scripts/zotero.py" daily-schedule --time 08:00
80
- ```
81
-
82
- - 每次最多 30 篇(`--max`),同一期刊默认最多 3 篇(`--max-per-venue`),回溯天数默认 7(`--days`)。
83
- - 是否启用由用户决定:`daily-config --enable` / `--disable`;未启用时 `daily` 只返回提示,`--force` 可临时运行。
84
- - 导入前先在 Zotero 中选中目标分类;导入是写库操作,先让用户确认主题、数量和目标分类。
85
- - 定时任务用 Windows 任务计划程序,只在该用户登录时运行;Zotero 未启动时脚本会尝试启动并等待。
86
- - `daily --dry-run` 只排序不写库,适合先给用户看候选名单。
87
- - 配置与去重状态在 `~/.zotero-skill/`(`config.json`、`state.json`),可用 `ZOTERO_SKILL_CONFIG_DIR` 改位置。
88
- - 指标是 OpenAlex 的期刊 2 年平均被引与引用速度,不是 JCR 影响因子;不要把分数说成“影响因子”。
89
- - v1 只导入题录与摘要,不下载 PDF;附件仍需用户按需获取。
90
-
91
- 需要路由细节时再读 [references/local-api-routes.md](references/local-api-routes.md)。本地 API 只读,导入使用 Connector;不要直接写 Zotero SQLite 数据库。
1
+ ---
2
+ name: zotero
3
+ description: 面向科研文献全流程的 Zotero 技能:找文献、追前沿、筛核心论文、管理文献(打标签/归集/查重)、批量阅读、分类整理、提炼脉络、发现空白,并支持导出 BibTeX 与给 LaTeX/Markdown 草稿插入引用。用户提到 Zotero、找文献、查文献、前沿、综述、批量读论文、文献整理或研究空白时使用。
4
+ ---
5
+
6
+ # Zotero · DeepSeek Harness
7
+
8
+ 独立目录 skill,不依赖 Codex、OpenAI 工具或 MCP 服务。使用 Harness 当前提供的文件读取、编辑和命令执行能力运行 Python 脚本。若执行工具不可用,说明缺失能力,不要虚构执行结果。
9
+
10
+ ## 定位与运行
11
+
12
+ 以 Harness 加载本 skill 返回的资源目录为 `<skill-dir>`,不是当前工作目录。入口为 `scripts/zotero.py`,Python 3.10+,仅依赖标准库。
13
+
14
+ - Windows:先检查 `py -3 --version`;不可用时检查 `python --version`。不要假定存在 `python3`。
15
+ - macOS / Linux:通常使用 `python3`。
16
+ - 路径包含空格时加引号;PowerShell 里带引号的路径用 `&` 调用。
17
+
18
+ 下文 `<python>` 表示已验证可用的解释器命令。先运行 `status --json`:默认连 `http://127.0.0.1:23119`,需要 Zotero 在运行且已开启「允许此计算机上的其他应用程序与 Zotero 通信」。连不上不等于文献库为空,按 [references/deepseek-harness.md](references/deepseek-harness.md) 排查;必要时让用户正常关闭 Zotero 后执行 `enable --restart`(备份 prefs.js,不强制结束进程)。
19
+
20
+ ## 读写边界
21
+
22
+ - 读操作(检索、统计、导出、生成阅读包)随时可用。
23
+ - 写操作(打标签、归集、查重清理、分类写入)必须先 `authorize`:Zotero 会弹窗,让用户点「Always Allow」(持久)而不是「Allow」(一次性)。凭据保存在 `~/.zotero-skill/local-key.json`。
24
+ - 写命令一律支持 `--dry-run`;改库前先把 `--dry-run` 结果给用户看,得到确认后再加 `--yes`。
25
+ - 不要直接读写 `zotero.sqlite`,也不要绕过本地 API 改文件。
26
+
27
+ ## 八项能力
28
+
29
+ ### 1. 找文献 `find`
30
+
31
+ 从 OpenAlex 检索,按期刊影响、年化引用、相关度、新鲜度打分,并与本地库去重。
32
+
33
+ ```text
34
+ <python> "<skill-dir>/scripts/zotero.py" find "knowledge distillation motor imagery" --days 730 --limit 15
35
+ <python> "<skill-dir>/scripts/zotero.py" find "bin picking 6d pose" --days 365 --oa-only --json --out find.json
36
+ ```
37
+
38
+ - 分数是启发式排序信号(期刊 2 年平均被引 + 引用速度 + 相关度 + 新鲜度),不是 JCR 影响因子。
39
+ - `--json` 输出可交给 `screen` 或 `import`;`--oa-only` 只留开放获取。
40
+
41
+ ### 2. 追前沿 `frontier`
42
+
43
+ 把常读方向存成 watch,之后每次只拉「上次运行以来」的新论文。
44
+
45
+ ```text
46
+ <python> "<skill-dir>/scripts/zotero.py" frontier add eeg-kd --query "knowledge distillation motor imagery" --query "transformer EEG decoding" --days 60
47
+ <python> "<skill-dir>/scripts/zotero.py" frontier run eeg-kd --since-last --max 10
48
+ <python> "<skill-dir>/scripts/zotero.py" frontier list
49
+ <python> "<skill-dir>/scripts/zotero.py" frontier remove eeg-kd
50
+ ```
51
+
52
+ 多次 `frontier run` 不会重复给同一篇(seen 记在 `~/.zotero-skill/state.json`)。需要直接入库时加 `--import --yes`。
53
+
54
+ ### 3. 筛核心论文 `screen`
55
+
56
+ 把候选(`find`/`frontier` 的 JSON)或库内条目分成 核心 / 重要 / 参考 三档。
57
+
58
+ ```text
59
+ <python> "<skill-dir>/scripts/zotero.py" screen --input find.json --top 12
60
+ <python> "<skill-dir>/scripts/zotero.py" screen --library --tag "project:MI-EEG" --top 10
61
+ <python> "<skill-dir>/scripts/zotero.py" screen --query "grasp pose estimation" --top 10 --out shortlist.md
62
+ ```
63
+
64
+ - 有引用数据时按分档阈值判定;库内条目没有引用数据,改用相对排名,输出里会注明。
65
+ - 报告是给人看的短名单,不要把它当成事实性结论。
66
+
67
+ ### 4. 管理文献 `authorize` / `tag` / `collect` / `dupes`
68
+
69
+ ```text
70
+ <python> "<skill-dir>/scripts/zotero.py" authorize
71
+ <python> "<skill-dir>/scripts/zotero.py" tag --tag "project:MI-EEG" --add "reviewed:2026-10" --dry-run
72
+ <python> "<skill-dir>/scripts/zotero.py" tag --keys ABC12345 --replace "topic:kd,topic:eeg"
73
+ <python> "<skill-dir>/scripts/zotero.py" collect 核心-EEG --tag "project:MI-EEG" --dry-run
74
+ <python> "<skill-dir>/scripts/zotero.py" dupes --all --json
75
+ <python> "<skill-dir>/scripts/zotero.py" dupes --all --trash --yes
76
+ ```
77
+
78
+ - 选择参数统一:`--keys`、`--query`、`--tag`、`--collection`、`--all`(`--limit` 限制条数)。
79
+ - `collect` 找不到同名分类会新建;`--parent` 可建成子分类。
80
+ - `dupes` 按 DOI(大小写不敏感)与归一化标题聚类,保留标签/摘要更全的一条;`--trash` 只把多余副本放进回收站。
81
+
82
+ ### 5. 批量阅读 `digest`
83
+
84
+ 为一批条目生成阅读包:每篇一个 Markdown(元数据 + 摘要 + 章节大纲 + 笔记骨架),加一个 `index.md`。
85
+
86
+ ```text
87
+ <python> "<skill-dir>/scripts/zotero.py" digest --tag "project:BIN-PICKING" --out reading/bin-picking
88
+ <python> "<skill-dir>/scripts/zotero.py" digest --tag "project:BIN-PICKING" --fulltext --out reading/bin-picking
89
+ ```
90
+
91
+ - 章节大纲来自 Zotero 已索引的全文;没有 PDF 时只有摘要,不要假装读到了正文。
92
+ - 生成后按需读这些文件再写综述,不要一次把几十篇原文塞进上下文。
93
+
94
+ ### 6. 分类整理 `classify`
95
+
96
+ 从题名+摘要识别方法与数据集,生成标签/集合计划,可写入。
97
+
98
+ ```text
99
+ <python> "<skill-dir>/scripts/zotero.py" classify --all
100
+ <python> "<skill-dir>/scripts/zotero.py" classify --tag "project:MI-EEG" --apply --yes
101
+ <python> "<skill-dir>/scripts/zotero.py" classify --all --by-venue --apply --yes
102
+ ```
103
+
104
+ - 默认生成 `auto:method:*`、`auto:dataset:*`;`--tag-prefix` 可改前缀。
105
+ - 写入前务必先跑一次不带 `--apply` 的版本给用户看。
106
+
107
+ ### 7. 提炼脉络 `landscape`
108
+
109
+ 统计年份、期刊、方法、数据集与共现,输出可直接放进综述的表格。
110
+
111
+ ```text
112
+ <python> "<skill-dir>/scripts/zotero.py" landscape --all --out landscape.md
113
+ <python> "<skill-dir>/scripts/zotero.py" landscape --tag "project:MI-EEG" --json
114
+ ```
115
+
116
+ ### 8. 发现空白 `gaps`
117
+
118
+ 按 `project:`/`topic:` 分组,找「方法 × 数据集」从未交叉的组合、停更标签和标注缺失。
119
+
120
+ ```text
121
+ <python> "<skill-dir>/scripts/zotero.py" gaps --all --out gaps.md
122
+ <python> "<skill-dir>/scripts/zotero.py" gaps --tag "project:MI-EEG" --min-freq 2
123
+ ```
124
+
125
+ - 输出是规则推导的候选空白,必须回到原文核实后再写进论文或汇报。
126
+
127
+ ## 每日自动收录
128
+
129
+ `daily` 按主题从 OpenAlex 抓取最近 N 天的论文,打分去重后用 Connector 导入当前选中的分类。
130
+
131
+ ```text
132
+ <python> "<skill-dir>/scripts/zotero.py" daily-config --enable --topics "transformer;large language model" --max 10 --mailto "you@example.com"
133
+ <python> "<skill-dir>/scripts/zotero.py" daily --dry-run
134
+ <python> "<skill-dir>/scripts/zotero.py" daily-schedule --time 08:00
135
+ ```
136
+
137
+ 每次最多 30 篇,同刊默认最多 3 篇。配置与状态在 `~/.zotero-skill/`,可用 `ZOTERO_SKILL_CONFIG_DIR` 改位置。定时任务用 Windows 任务计划程序,只在用户登录时运行。
138
+
139
+ ## 引用与导出
140
+
141
+ ```text
142
+ <python> "<skill-dir>/scripts/zotero.py" search "transformer" --with-bibtex-keys --json
143
+ <python> "<skill-dir>/scripts/zotero.py" export-bibtex --item-key PXW99EKT --out references.bib
144
+ <python> "<skill-dir>/scripts/zotero.py" sync-bib --out references.bib
145
+ <python> "<skill-dir>/scripts/zotero.py" cite --item-key PXW99EKT --tex paper.tex --bib references.bib --marker "<cite:transformer>"
146
+ ```
147
+
148
+ - 插入引用前先读草稿,按具体论断匹配文献;`cite --query` 命中多条时会拒绝,请先选定 `--item-key`。
149
+ - `sync-bib`、`export-bibtex --out` 会覆盖目标文件,先确认这是用户想要的路径。
150
+ - item key 不是引用键,报告时同时给出 BibTeX key。
151
+ - 附件与全文:`children <key> --json`、`fulltext <attachmentKey> --out fulltext.txt`、`file-url <attachmentKey>`。
152
+
153
+ ## 导入
154
+
155
+ 导入是写操作:先确认来源、内容与目标分类,用户同意后执行。
156
+
157
+ ```text
158
+ <python> "<skill-dir>/scripts/zotero.py" selected-target --json
159
+ <python> "<skill-dir>/scripts/zotero.py" import-bibtex --file new.bib --yes
160
+ <python> "<skill-dir>/scripts/zotero.py" import-ris --file new.ris --yes
161
+ ```
162
+
163
+ 需要路由细节时读 [references/local-api-routes.md](references/local-api-routes.md)。本地 API 的 GET 免认证,写入需要本地 API key 与 `Zotero-Server-ID`,脚本已封装;不要直接改 Zotero 数据库。
@@ -10,7 +10,7 @@ Important constraints:
10
10
 
11
11
  - Use `/api/users/0/...` for the local user by default.
12
12
  - Local API reads do not require an API key.
13
- - The local API is read-only; write requests are not supported there.
13
+ - Local API **writes** (POST / PUT / PATCH / DELETE) require a local API key plus a `Zotero-Server-ID` header; see below.
14
14
  - Atom output is not supported locally.
15
15
  - Attachment file URLs and full text can expose local file paths or document text; only retrieve them when the user asks.
16
16
 
@@ -45,6 +45,18 @@ Safe read routes:
45
45
  /api/users/0/items/<attachmentKey>/file/view/url
46
46
  ```
47
47
 
48
+ ## Local API writes (tags, collections, duplicate cleanup)
49
+
50
+ Write requests are supported but gated. The observed flow on Zotero 10.0.7:
51
+
52
+ 1. Every response carries `Zotero-Server-ID`. Writes must echo it back in a `Zotero-Server-ID` header, otherwise the server answers `428 Zotero-Server-ID not provided` (mismatch: `412`).
53
+ 2. Without a key: `401 API key required -- POST /api/local/authorize to obtain one`.
54
+ 3. `POST /api/local/authorize` with `{"appName": "<name>"}` opens a Zotero dialog with **Allow** (single-use key, consumed by the first successful write), **Always Allow** (`remember: true`, persistent) and **Deny**. The response is `{"key": "...", "remember": false|true}`.
55
+ 4. Send the key as `Zotero-API-Key: <key>` on PATCH/POST/DELETE. Include `If-Unmodified-Since-Version: <item version>` to avoid clobbering concurrent edits.
56
+ 5. Send JSON bodies from a file (`curl --data-binary "@body.json"`); shell-quoted JSON is easily mangled into `Invalid JSON provided`.
57
+
58
+ `zotero.py authorize` performs step 3, caches `{key, serverId}` in `~/.zotero-skill/local-key.json`, and every write command (`tag`, `collect`, `classify --apply`, `dupes --trash`) handles steps 1, 2 and 4 automatically, re-authorizing on 401. Never edit `zotero.sqlite` directly.
59
+
48
60
  ## Connector server
49
61
 
50
62
  The Zotero Connector server shares port `23119` and is used for desktop writes/imports.